<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Developers, Developers, Developers! &#187; Java</title>
	<atom:link href="http://maksim.sorokin.dk/it/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://maksim.sorokin.dk/it</link>
	<description>Maksim Sorokin IT Blog</description>
	<lastBuildDate>Sun, 05 Feb 2012 19:37:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.3</generator>
		<item>
		<title>Java SE 7 Certificates Are Almost Out!</title>
		<link>http://maksim.sorokin.dk/it/2011/10/04/java-se-7-certificates-are-almost-out/</link>
		<comments>http://maksim.sorokin.dk/it/2011/10/04/java-se-7-certificates-are-almost-out/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 13:09:47 +0000</pubDate>
		<dc:creator>Maksim Sorokin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[certification]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[oracle]]></category>

		<guid isPermaLink="false">http://maksim.sorokin.dk/it/?p=842</guid>
		<description><![CDATA[Check the Oracle certification page. Java SE 7 certificates are now in beta (programmer certificate is not available yet, however). The price is 50$, instead of ordinary 300$. However, it has twice more questions and is twice longer.]]></description>
			<content:encoded><![CDATA[<p>Check the <a href="http://education.oracle.com/pls/web_prod-plq-dad/db_pages.getpage?page_id=140">Oracle certification page</a>. Java SE 7 certificates are now in beta (programmer certificate is not available yet, however). The price is 50$, instead of ordinary 300$. However, it has twice more questions and is twice longer.</p>
]]></content:encoded>
			<wfw:commentRss>http://maksim.sorokin.dk/it/2011/10/04/java-se-7-certificates-are-almost-out/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Maven + Apache Felix + CXF + DOSGi: An Example of DOSGi Service</title>
		<link>http://maksim.sorokin.dk/it/2011/09/18/maven-apache-felix-cxf-dosgi-an-example-of-dosgi-service/</link>
		<comments>http://maksim.sorokin.dk/it/2011/09/18/maven-apache-felix-cxf-dosgi-an-example-of-dosgi-service/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 22:04:29 +0000</pubDate>
		<dc:creator>Maksim Sorokin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Apache Felix]]></category>
		<category><![CDATA[DOSGi]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[OSGi]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://maksim.sorokin.dk/it/?p=827</guid>
		<description><![CDATA[Link in series Link to two Felix instances Here is yet another post in Maven + Apache Felix + CXF + DOSGi series. Here I will show how to use Apache CXF DOSGi for cosuming remote services. You may see the sources on my GitHub account. We will have three projects dosgiRemote.service, dosgiRemote.service.api and dosgiRemote.consumer. [...]]]></description>
			<content:encoded><![CDATA[<p>Link in series</p>
<p>Link to two Felix instances</p>
<p>Here is yet another post in <a href="http://maksim.sorokin.dk/it/2011/07/19/maven-apache-felix-cxf-dosgi-series/">Maven + Apache Felix + CXF + DOSGi series</a>.</p>
<p>Here I will show how to use <a href="http://cxf.apache.org/dosgi-releases.html">Apache CXF DOSGi</a> for cosuming remote services. You may see the sources on <a href="https://github.com/mah01/examples/tree/master/dosgiRemote">my GitHub account</a>.</p>
<p>We will have <span id="more-827"></span> three projects <code>dosgiRemote.service</code>, <code>dosgiRemote.service.api</code> and <code>dosgiRemote.consumer</code>. <code>dosgiRemote.service.api</code> provides an interface for a service. <code>dosgiRemote.service</code> provides implementation for the service. <code>dosgiRemote.consume</code> will consume the service.<br />
<code>dosgiRemote.service.api</code> has to be shared between <code>dosgiRemote.service</code> and <code>dosgiRemote.consumer</code> as both has to know which service they are publishing and consuming. <code>dosgiRemote.service.api</code> and <code>dosgiRemote.service</code> will run in one OSGi container. <code>dosgiRemote.service.api</code> and <code>dosgiRemote.consumer</code> will run in another OSGi container. You may see how to do that in Eclipse in the <a href="http://maksim.sorokin.dk/it/2011/08/11/apache-felix-running-two-instances-of-felix-launcher-in-the-eclipse/">previous post</a>.</p>
<p><code>dosgiRemote.service.api</code> contains the following interface to a service:</p>
<pre class="brush: java; title: ;">
package dk.sorokin.maksim.dosgiRemote.service.api;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path(&quot;greeter&quot;)
public interface Greeter {

  @GET
  @Path(&quot;sayHello/{name}&quot;)
  @Produces(MediaType.TEXT_PLAIN)
  String sayHello(@PathParam(&quot;name&quot;) String name);
}
</pre>
<p><code>dosgiRemote.service</code> provides the following implementation:</p>
<pre class="brush: java; title: ;">
package dk.sorokin.maksim.dosgiRemote.internal.service;

import dk.sorokin.maksim.dosgiRemote.service.api.Greeter;

public class GreeterImpl implements Greeter {

  public String sayHello(String name) {
    return &quot;Hello, &quot; + name;
  }
}
</pre>
<p>Also, <code>dosgiRemote.service</code> registers a service in the following way:</p>
<pre class="brush: java; title: ;">
package dk.sorokin.maksim.dosgiRemote.internal;

import java.util.Dictionary;
import java.util.Hashtable;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

import dk.sorokin.maksim.dosgiRemote.internal.service.GreeterImpl;
import dk.sorokin.maksim.dosgiRemote.service.api.Greeter;

public class Activator implements BundleActivator {

  public void start(BundleContext context) throws Exception {
    Dictionary&lt;String, String&gt; restProps = new Hashtable&lt;String, String&gt;();

    restProps.put(&quot;service.exported.interfaces&quot;, &quot;*&quot;);
    restProps.put(&quot;service.exported.configs&quot;, &quot;org.apache.cxf.rs&quot;);
    restProps.put(&quot;service.exported.intents&quot;, &quot;HTTP&quot;);
    restProps.put(&quot;org.apache.cxf.rs.address&quot;, &quot;http://localhost:8080/&quot;);
    context.registerService(Greeter.class.getName(), new GreeterImpl(), restProps);
  }

  public void stop(BundleContext context) throws Exception {
    //
  }
}
</pre>
<p><code>dosgiRemote.consumer</code> will have <code>OSGI-INF\remote-service\remote-services.xml</code>, according to <a href="http://cxf.apache.org/distributed-osgi-reference.html#DistributedOSGiReference-%7B%7Bremoteservices.xml%7D%7Dfiles">DOSGi documentation</a>:</p>
<pre class="brush: xml; title: ;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;service-descriptions xmlns=&quot;http://www.osgi.org/xmlns/sd/v1.0.0&quot;&gt;
  &lt;service-description&gt;
    &lt;provide interface=&quot;dk.sorokin.maksim.dosgiRemote.service.api.Greeter&quot; /&gt;
    &lt;property name=&quot;service.exported.interfaces&quot;&gt;*&lt;/property&gt;
    &lt;property name=&quot;service.exported.configs&quot;&gt;org.apache.cxf.rs&lt;/property&gt;
    &lt;property name=&quot;service.exported.intents&quot;&gt;HTTP&lt;/property&gt;
    &lt;property name=&quot;org.apache.cxf.rs.address&quot;&gt;http://localhost:8080&lt;/property&gt;
  &lt;/service-description&gt;
&lt;/service-descriptions&gt;
</pre>
<p>And the Activator class for <code>dosgiRemote.consumer</code> will be:</p>
<pre class="brush: java; title: ;">
package dk.sorokin.maksim.dosgiRemote.consumer.internal;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;

import dk.sorokin.maksim.dosgiRemote.service.api.Greeter;

public class Activator implements BundleActivator {

  @Override
  public void start(BundleContext context) throws Exception {
    ServiceTracker serviceTracker = new ServiceTracker(context, Greeter.class.getName(), null) {
      @Override
      public Object addingService(ServiceReference reference) {
        Object result = super.addingService(reference);

        Object svc = context.getService(reference);
        if (svc instanceof Greeter) {
          final Greeter greeter = (Greeter) svc;
          System.out.println(greeter.sayHello(&quot;Max&quot;));
        }

        return result;
      }
    };
    serviceTracker.open();
  }

  public void stop(BundleContext context) throws Exception {
    //
  }
}
</pre>
<p>We will have two startup configuration for Apache Felix, as described above. The first one:</p>
<pre class="brush: plain; title: ;">
felix.auto.deploy.action=install,start
felix.log.level=1

org.osgi.framework.storage.clean=onFirstInit

felix.auto.start.1 = \
 assembly:/C:/projects/dosgiRemote/dosgiRemote.service.api/target/classes \
 assembly:/C:/projects/dosgiRemote/dosgiRemote.service/target/classes
</pre>
<p>And the second one:</p>
<pre class="brush: plain; title: ;">
felix.auto.deploy.action=install,start
felix.log.level=1

org.osgi.framework.storage.clean=onFirstInit

felix.auto.start.1 = \
 assembly:/C:/projects/dosgiRemote/dosgiRemote.service.api/target/classes \
 assembly:/C:/projects/dosgiRemote/dosgiRemote.service/target/classes
</pre>
<p>Launch the first configuration and then the second. You should see the following message in the console:</p>
<pre class="brush: plain; title: ;">
Hello, Max
</pre>
<p>You could also see the same message in the browser on <a href="http://localhost:8080/greeter/sayHello/Max">http://localhost:8080/greeter/sayHello/Max</a>.</p>
<p>You may pass objects as well. Refer to <a href="http://maksim.sorokin.dk/it/2011/07/24/maven-apache-felix-cxf-creating-a-restful-webservice-with-cxf-returning-and-object/">previous</a> <a href="http://maksim.sorokin.dk/it/2011/07/26/maven-apache-felix-cxf-creating-a-restful-webservice-with-cxf-consuming-an-object/">posts</a> to do that.</p>
<p>You can take the sources from may <a href="https://github.com/mah01/examples/tree/master/dosgiRemote">GitHub account</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://maksim.sorokin.dk/it/2011/09/18/maven-apache-felix-cxf-dosgi-an-example-of-dosgi-service/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Maven + Apache Felix + CXF: Securing a Service with HTTP Basic Authentication</title>
		<link>http://maksim.sorokin.dk/it/2011/08/06/maven-apache-felix-cxf-securing-a-service-with-http-basic-authentication/</link>
		<comments>http://maksim.sorokin.dk/it/2011/08/06/maven-apache-felix-cxf-securing-a-service-with-http-basic-authentication/#comments</comments>
		<pubDate>Sat, 06 Aug 2011 08:35:32 +0000</pubDate>
		<dc:creator>Maksim Sorokin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[basic authentication]]></category>
		<category><![CDATA[CXF]]></category>
		<category><![CDATA[DOSGi]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[OSGi]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://maksim.sorokin.dk/it/?p=808</guid>
		<description><![CDATA[This is another post in series Maven + Apache Felix + CXF + DOSGi Series. Here I will describe how to secure CXF published web services with HTTP basic authentication. You can find the sources on my GitHub account. We will have three projects here. The first one defines an interface for a service. Another [...]]]></description>
			<content:encoded><![CDATA[<p>This is another post in series <a href="http://maksim.sorokin.dk/it/2011/07/19/maven-apache-felix-cxf-dosgi-series/">Maven + Apache Felix + CXF + DOSGi Series</a>. Here I will describe how to secure CXF published web services with HTTP basic authentication. You can find the sources on <a href="https://github.com/mah01/examples/tree/master/dosgiSecurity">my GitHub account</a>.</p>
<p>We will have three projects here. The first one defines an interface for a service. Another one provides implementation for it. And the third one will provide security.</p>
<pre class="brush: plain; title: ;">
dosgiSecurity
    dosgiSecurity-api
    dosgiSecurity-impl
    dosgiSecurity-security
</pre>
<p><code>dosgiSecurity</code> will be just a holder project.</p>
<p>Our interface <code>HelloService</code> in bundle <code>dosgiSecurity-api</code> will be similar to the one we defined in<span id="more-808"></span> previous posts:</p>
<pre class="brush: java; title: ;">
package dk.sorokin.maksim.dosgiSecurity.api;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path(&quot;helloService&quot;)
public interface HelloService {

  @GET
  @Path(&quot;sayHello/{name}&quot;)
  @Produces(MediaType.TEXT_PLAIN)
  String sayHello(@PathParam(&quot;name&quot;) String name);
}
</pre>
<p>And implementation class <code>HelloServiceImpl</code> in bundle <code>dosgiSecurity-impl</code>:</p>
<pre class="brush: java; title: ;">
package dk.sorokin.maksim.dosgiSecurity.impl.internal.service;

import dk.sorokin.maksim.dosgiSecurity.api.HelloService;

public class HelloServiceImpl implements HelloService {

  public String sayHello(String name) {
    return &quot;Hello &quot; + name;
  }
}
</pre>
<p>And <code>SecurityFilter</code> in bundle <code>dosgiSecurity-security</code>, is just a servlet filter. It checks for <code>Authorization</code> header and verifies it:</p>
<pre class="brush: java; title: ;">
package dk.sorokin.maksim.dosgiSecurity.impl.internal.service;

import dk.sorokin.maksim.dosgiSecurity.api.HelloService;

public class HelloServiceImpl implements HelloService {

  public String sayHello(String name) {
    return &quot;Hello &quot; + name;
  }
}
</pre>
<p>The service is published in an <code>Activator</code> in <code>dosgiSecurity.impl</code>:</p>
<pre class="brush: java; title: ;">
package dk.sorokin.maksim.dosgiSecurity.impl.internal;

import java.util.Dictionary;
import java.util.Hashtable;

import javax.servlet.Filter;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

import dk.sorokin.maksim.dosgiSecurity.api.HelloService;
import dk.sorokin.maksim.dosgiSecurity.impl.internal.service.HelloServiceImpl;
import dk.sorokin.maksim.dosgiSecurity.security.SecurityFilter;

public class Activator implements BundleActivator {

  public void start(BundleContext context) throws Exception {
    Dictionary&lt;String, String&gt; restProps = new Hashtable&lt;String, String&gt;();

    restProps.put(&quot;service.exported.interfaces&quot;, &quot;*&quot;);
    restProps.put(&quot;service.exported.configs&quot;, &quot;org.apache.cxf.rs&quot;);
    restProps.put(&quot;service.exported.intents&quot;, &quot;HTTP&quot;);
    restProps.put(&quot;org.apache.cxf.rs.httpservice.context&quot;, &quot;/secured&quot;);
    restProps.put(&quot;org.apache.cxf.rs.address&quot;, &quot;http://localhost:8080/&quot;);
    context.registerService(HelloService.class.getName(), new HelloServiceImpl(), restProps);

    Dictionary&lt;String, String&gt; filterProps = new Hashtable&lt;String, String&gt;();
    filterProps.put(&quot;org.apache.cxf.httpservice.filter&quot;, Boolean.TRUE.toString());
    filterProps.put(&quot;servletNames&quot;, &quot;none&quot;);
    context.registerService(Filter.class.getName(), new SecurityFilter(), filterProps);
  }

  public void stop(BundleContext context) throws Exception {
    //
  }
}
</pre>
<p>And a Felix Launcher (refer to the <a href="http://maksim.sorokin.dk/it/2011/07/19/maven-apache-felix-easy-development-and-debugging-with-eclipse/">first post in series</a>) is:</p>
<pre class="brush: plain; title: ;">
felix.auto.deploy.action=install,start
felix.log.level=1

org.osgi.framework.storage.clean=onFirstInit

felix.auto.start.1 = \
 assembly:/C:/projects/dosgiSecurity/dosgiSecurity.security/target/classes \
 assembly:/C:/projects/dosgiSecurity/dosgiSecurity.api/target/classes \
 assembly:/C:/projects/dosgiSecurity/dosgiSecurity.impl/target/classes
</pre>
<p>Now build all that with Maven using <code>mvn clean install</code> and run it (assuming that you have DOSGi Single Bundle Distribution in Felix, as we discussed in previous posts). When Felix is launched, go to <a href="http://localhost:8080/secured/helloService/sayHello/Max">http://localhost:8080/secured/helloService/sayHello/Max</a>. You should see:</p>
<pre class="brush: plain; title: ;">
HTTP ERROR: 403

FORBIDDEN
RequestURI=/secured/helloService/sayHello/Max

Powered by Jetty://
</pre>
<p>Now launch Fiddler2 (or similar program) and build custom request with Request Builder with the same url as shown above. And add the following line in "Request Headers":</p>
<pre class="brush: plain; title: ;">
Authorization: Basic U3V6eTpyb2NrZXQ=
</pre>
<p>You should get:</p>
<pre class="brush: plain; title: ;">
HTTP/1.1 200 OK
Content-Type: text/plain
Date: Tue, 02 Aug 2011 15:15:43 GMT
Content-Length: 9
Server: Jetty(6.1.x)

Hello max
</pre>
<p>Source files can be found <a href="https://github.com/mah01/examples/tree/master/dosgiSecurity">here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://maksim.sorokin.dk/it/2011/08/06/maven-apache-felix-cxf-securing-a-service-with-http-basic-authentication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Discovering Version of Java in a BAT File</title>
		<link>http://maksim.sorokin.dk/it/2011/07/28/discovering-version-of-java-in-a-bat-file/</link>
		<comments>http://maksim.sorokin.dk/it/2011/07/28/discovering-version-of-java-in-a-bat-file/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 10:09:01 +0000</pubDate>
		<dc:creator>Maksim Sorokin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[32bit]]></category>
		<category><![CDATA[32bit-64bit]]></category>
		<category><![CDATA[64bit]]></category>
		<category><![CDATA[BAT]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://maksim.sorokin.dk/it/?p=796</guid>
		<description><![CDATA[Sometimes in a BAT file we need to know what Java version are we running -- is it 32bit or 64bit. Here is a sample bat file, which depending on a Java version uses different native library directory: @echo off :: At this point you can place assumptions about Java version. It is still better [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes in a BAT file we need to know what Java version are we running -- is it 32bit or 64bit. Here is a sample bat file, which depending on a Java version uses different native library directory:</p>
<pre class="brush: plain; title: ;">
@echo off

:: At this point you can place assumptions about Java version. It is still better than nothing anyway. In this particular case, we rely on a knowledge of Java version during installation time (with IzPack). Or you can just specify default value here, for example by default assume that 32 version is being run
set JVM_VERSION=&quot;&quot;
if $SYSTEM_os_arch==x86 (
  set JVM_VERSION=32
) else (
  set JVM_VERSION=64
)
:: End of assumption section

:: Now trying to find out, what is current jvm version.

set TEMP_FILE=%TEMP%\javaCheck%RANDOM%%TIME:~9,5%.txt

java -version 2&gt;%TEMP_FILE%
FOR /F &quot;tokens=*&quot; %%i in (%TEMP_FILE%) do (
  echo %%i | find &quot;HotSpot&quot; &gt;nul
  if not errorlevel 1 (
    echo %%i | find &quot;64-Bit&quot; &gt;nul
    if not errorlevel 1 (
      set JVM_VERSION=64
    ) else (
      set JVM_VERSION=32
    )
  )
)

del %TEMP_FILE%

if %JVM_VERSION%==32 (
  set NATIVE_JARS=$INSTALL_PATH/lib/32
) else (
  set NATIVE_JARS=$INSTALL_PATH/lib/64
)

start &quot;App&quot; javaw -classpath .;&quot;%NATIVE_JARS%/*&quot; my.app.App
</pre>
<p>The trick is to redirect <code>java -version</code> to a temporary file. Then try to find a line with "HotSpot" substring. If that line contains "64-Bit", then it is 64bit version Java. Otherwise it is 32bit.</p>
]]></content:encoded>
			<wfw:commentRss>http://maksim.sorokin.dk/it/2011/07/28/discovering-version-of-java-in-a-bat-file/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Yahoo Query Language &#8212; Finding Geographic Coordinates of ZIP Codes in Denmark</title>
		<link>http://maksim.sorokin.dk/it/2011/04/18/yahoo-query-language-finding-geographic-coordinates-of-zip-codes-in-denmark/</link>
		<comments>http://maksim.sorokin.dk/it/2011/04/18/yahoo-query-language-finding-geographic-coordinates-of-zip-codes-in-denmark/#comments</comments>
		<pubDate>Mon, 18 Apr 2011 09:19:46 +0000</pubDate>
		<dc:creator>Maksim Sorokin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[URL]]></category>
		<category><![CDATA[Yahoo]]></category>
		<category><![CDATA[Yahoo Query Language]]></category>
		<category><![CDATA[YQL]]></category>

		<guid isPermaLink="false">http://maksim.sorokin.dk/it/?p=706</guid>
		<description><![CDATA[This post will describe a simply way to get geographic coordinates (latitude and longitude) for ZIP codes in Denmark using Yahoo Query Language (YQL). The motivation is quite simple. One may need an estimate of the distance between two points on the map using ZIP codes. This may be because you do not have any [...]]]></description>
			<content:encoded><![CDATA[<p>This post will describe a simply way to get geographic coordinates (latitude and longitude) for ZIP codes in Denmark using <a href="http://query.yahooapis.com/v1/public/yql?q=select%20centroid%20from%20geo.places%20where%20text%3D%222900%2C%20Denmark%22&amp;diagnostics=true">Yahoo Query Language</a> (YQL).</p>
<p>The motivation is quite simple. One may need an estimate of the distance between two points on the map using ZIP codes. This may be because you do not have any real addresses. Or just you are totally fine with just a direct distance between two ZIP codes areas.<br />
One could go several ways. Hire a lady to query all possible into Google Maps and get coordinates from there. Or try getting some information from the post office. Or just try finding coordinates on the Internet. But we will go slightly different way using the power of Yahoo Query Language (YQL).</p>
<p>First, let's have some tests.<span id="more-706"></span> We will query Google Maps for a zip code and compare coordinates with Yahoo Query Language (YQL) results.<br />
Let's test with <a href="http://en.wikipedia.org/wiki/Hellerup">Hellerup</a>. We go to Google Maps and query for "2900, Denmark".<br />
<img src="http://maksim.sorokin.dk/it/wp-content/uploads/2011/04/google_maps_2900.png" alt="" width="400" height="300" class="alignnone size-full wp-image-707" /></p>
<p>Now we go to <a href="http://developer.yahoo.com/yql/console/">YQL Console</a> and use "get san francisco geo data" example from the right. And change the query to the following <code>select centroid from geo.places where text="2900, Denmark"</code>. After querying, we check <code>centroid</code> tag from XML output:</p>
<pre class="brush: xml; title: ;">
&lt;centroid&gt;
	&lt;latitude&gt;55.736462&lt;/latitude&gt;
	&lt;longitude&gt;12.561010&lt;/longitude&gt;
&lt;/centroid&gt;
</pre>
<p>Then we use these coordinates in Google Maps to check the location.<br />
<img src="http://maksim.sorokin.dk/it/wp-content/uploads/2011/04/yql_2900.png" alt="" width="400" height="300" class="alignnone size-full wp-image-708" /></p>
<p>One may also try querying <code>select centroid from geo.places where text="2900, Hellerup Denmark"</code> (Hellerup was added to the query), which would result in a little North-East location. But it actually does not really matter. First of all, 500-1000 meters error is tolerable. The second thing, both results can be right since the real ZIP code center may not exist.</p>
<p>We will use YQL the rest query. So for instance Hellerup ZIP code query url would look like:</p>
<pre class="brush: plain; title: ;">

http://query.yahooapis.com/v1/public/yql?q=select%20centroid%20from%20geo.places%20where%20text%3D%222900%2C%20Denmark%22
</pre>
<p>The HTTP response to this query is the following:</p>
<pre class="brush: xml; title: ;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;query xmlns:yahoo=&quot;http://www.yahooapis.com/v1/base.rng&quot;
	yahoo:count=&quot;1&quot; yahoo:created=&quot;2011-04-18T07:34:03Z&quot; yahoo:lang=&quot;en-US&quot;&gt;
	&lt;results&gt;
		&lt;place xmlns=&quot;http://where.yahooapis.com/v1/schema.rng&quot;&gt;
			&lt;centroid&gt;
				&lt;latitude&gt;55.650162&lt;/latitude&gt;
				&lt;longitude&gt;12.534110&lt;/longitude&gt;
			&lt;/centroid&gt;
		&lt;/place&gt;
	&lt;/results&gt;
&lt;/query&gt;
&lt;!-- total: 124 --&gt;
&lt;!-- engine5.yql.ird.yahoo.com --&gt;
</pre>
<p>Next what we need are Denmark's ZIP codes. One may find them somwhere on the internet.<br />
We write a simple Java program which would use the YQL rest query with all ZIP codes.</p>
<p>In our case we have 580 ZIP codes, so for easier maintenance we move them to a separate class.</p>
<pre class="brush: java; title: ;">
package dk.sorokin.maksim.zipCodes;

public class ZipCodes {

  static int ZIP_CODES[] = { 1000, 1600, 2000, 2100, 2200, ...};
}
</pre>
<p>And then querying class. YQL has some <a href="http://developer.yahoo.com/yql/faq/">limits and restrictions</a>. Since we are not using any authentication, we are not allowed to make queries rapidly. Therefore, in current case we limit querying to 1 time per 4 seconds:</p>
<pre class="brush: java; title: ;">
package dk.sorokin.maksim.zipCodes;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URL;

public class App {

  private final static String YQL_ZIP_QUERY_SCHEME = &quot;http&quot;;
  private final static String YQL_ZIP_QUERY_HOST = &quot;query.yahooapis.com&quot;;
  private final static String YQL_ZIP_QUERY_PATH = &quot;/v1/public/yql&quot;;
  private final static String YQL_ZIP_QUERY_QUERY = &quot;q=select centroid from geo.places where text=\&quot;%d, Denmark\&quot;&quot;;

  private final static String CENTROID_TAG_OPEN = &quot;&lt;centroid&gt;&quot;;
  private final static String LATITUDE_TAG_OPEN = &quot;&lt;latitude&gt;&quot;;
  private final static String LATITUDE_TAG_CLOSE = &quot;&lt;/latitude&gt;&quot;;
  private final static String LONGITUDE_TAG_OPEN = &quot;&lt;longitude&gt;&quot;;
  private final static String LONGITUDE_TAG_CLOSE = &quot;&lt;/longitude&gt;&quot;;

  public static void main(String[] args) throws Exception {
    for (int zipCode : ZipCodes.ZIP_CODES) {
      Thread.sleep(4000);
      URL url = buildYQLURL(zipCode);
      // System.out.println(url);

      BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
      String str;
      while ((str = in.readLine()) != null) {
        tryParsingCentroid(str);
      }
      System.out.println(zipCode + &quot;;&quot;);
      in.close();
    }
  }

  private static URL buildYQLURL(int zipCode) throws Exception {
    return new URI(
        YQL_ZIP_QUERY_SCHEME,
        YQL_ZIP_QUERY_HOST,
        YQL_ZIP_QUERY_PATH,
        String.format(YQL_ZIP_QUERY_QUERY, zipCode), null).toURL();
  }

  private static void tryParsingCentroid(String s) {
    if (s.contains(CENTROID_TAG_OPEN)) {
      System.out.print(
          s.substring(
              s.indexOf(LATITUDE_TAG_OPEN) + LATITUDE_TAG_OPEN.length(),
              s.indexOf(LATITUDE_TAG_CLOSE)));
      System.out.print(&quot;,&quot;);
      System.out.print(
          s.substring(
              s.indexOf(LONGITUDE_TAG_OPEN) + LONGITUDE_TAG_OPEN.length(),
              s.indexOf(LONGITUDE_TAG_CLOSE)));
      System.out.print(&quot;,&quot;);
    }
  }
}
</pre>
<p>And our output is the following:</p>
<pre class="brush: plain; title: ;">
55.676239,12.567470,1000;
55.680271,12.561970,1600;
55.681770,12.516840,2000;
55.706051,12.580990,2100;
55.697071,12.548240,2200;
55.651428,12.582240,2300;
...
</pre>
<p>What we can do with it? Import to a database as CSV or using regular expressions generate SQL insert statements.</p>
]]></content:encoded>
			<wfw:commentRss>http://maksim.sorokin.dk/it/2011/04/18/yahoo-query-language-finding-geographic-coordinates-of-zip-codes-in-denmark/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Comparing Maven String Versions</title>
		<link>http://maksim.sorokin.dk/it/2011/04/03/comparing-maven-string-versions/</link>
		<comments>http://maksim.sorokin.dk/it/2011/04/03/comparing-maven-string-versions/#comments</comments>
		<pubDate>Sun, 03 Apr 2011 22:12:28 +0000</pubDate>
		<dc:creator>Maksim Sorokin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[versioning]]></category>
		<category><![CDATA[versions]]></category>

		<guid isPermaLink="false">http://maksim.sorokin.dk/it/?p=692</guid>
		<description><![CDATA[This posts describes comparint Maven String versions. It is assumed, that you have a Maven-managed project. Add a maven-artifact dependency &#60;dependency&#62; &#60;groupId&#62;org.apache.maven&#60;/groupId&#62; &#60;artifactId&#62;maven-artifact&#60;/artifactId&#62; &#60;version&#62;3.0.3&#60;/version&#62; &#60;/dependency&#62; Then you could write something like this: public int compare(String version1, String version2) { ArtifactVersion mavenVersion1 = new DefaultArtifactVersion(version1); ArtifactVersion mavenVersion2 = new DefaultArtifactVersion(version2); int result = mavenVersion1.compareTo(mavenVersion2); return result; [...]]]></description>
			<content:encoded><![CDATA[<p>This posts describes comparint Maven String versions. It is assumed, that you have a Maven-managed project.</p>
<p>Add a <code>maven-artifact</code> dependency</p>
<pre class="brush: xml; title: ;">
&lt;dependency&gt;
  &lt;groupId&gt;org.apache.maven&lt;/groupId&gt;
  &lt;artifactId&gt;maven-artifact&lt;/artifactId&gt;
  &lt;version&gt;3.0.3&lt;/version&gt;
&lt;/dependency&gt;
</pre>
<p>Then you could write something like this:</p>
<pre class="brush: java; title: ;">
public int compare(String version1, String version2) {
  ArtifactVersion mavenVersion1 = new DefaultArtifactVersion(version1);
  ArtifactVersion mavenVersion2 = new DefaultArtifactVersion(version2);

  int result = mavenVersion1.compareTo(mavenVersion2);

  return result;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://maksim.sorokin.dk/it/2011/04/03/comparing-maven-string-versions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building IzPack installers on the fly</title>
		<link>http://maksim.sorokin.dk/it/2011/03/31/building-izpack-installers-on-the-fly/</link>
		<comments>http://maksim.sorokin.dk/it/2011/03/31/building-izpack-installers-on-the-fly/#comments</comments>
		<pubDate>Thu, 31 Mar 2011 16:59:24 +0000</pubDate>
		<dc:creator>Maksim Sorokin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[installers]]></category>
		<category><![CDATA[IzPack]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://maksim.sorokin.dk/it/?p=685</guid>
		<description><![CDATA[One can grab ideas on how to build IzPack installers on the fly from izpack-maven-plugin. You will of course need to depend on IzPack standalone compiler. Basically, what do you need to do is to have some directory for staging. This is useful, when you want to run some filtering or putting some additional resources [...]]]></description>
			<content:encoded><![CDATA[<p>One can grab ideas on how to build IzPack installers on the fly from <a href="http://izpack.codehaus.org/izpack-maven-plugin/">izpack-maven-plugin</a>.</p>
<p>You will of course need to depend on IzPack standalone compiler.</p>
<p>Basically, what do you need to do is to have some directory for staging. This is useful, when you want to run some filtering or putting some additional resources from somewhere else to the installer. You can use %TEMP% directory (<code>File.createTempFile(...)</code>) for that. Do not forget to wipe it afterwards!<br />
When you have all your installer resources in some staging directory and you know the direct path to your <code>install.xml</code> you are ready to build a installer:</p>
<pre class="brush: java; title: ;">
CompilerConfig compilerConfig = new CompilerConfig(installXmlPath, stagingDirPath, null, targetFilePath);
compilerConfig.executeCompiler();
</pre>
]]></content:encoded>
			<wfw:commentRss>http://maksim.sorokin.dk/it/2011/03/31/building-izpack-installers-on-the-fly/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Panel for Reading Registry in IzPack 4</title>
		<link>http://maksim.sorokin.dk/it/2011/03/30/panel-for-reading-registry-in-izpack-4/</link>
		<comments>http://maksim.sorokin.dk/it/2011/03/30/panel-for-reading-registry-in-izpack-4/#comments</comments>
		<pubDate>Wed, 30 Mar 2011 16:46:00 +0000</pubDate>
		<dc:creator>Maksim Sorokin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[IzPack]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[registry]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://maksim.sorokin.dk/it/?p=689</guid>
		<description><![CDATA[The panel called RegistryReaderPanel. It can be used in automated installation (silent installations). However, it can be used only once (can be easily extended). Code depends on IzPack COI tools. So COI tools classes need to be delivered together with the panel. Panel is built using Maven, so COI tools are shaded with Maven Shade [...]]]></description>
			<content:encoded><![CDATA[<p>The panel called <code>RegistryReaderPanel</code>. It can be used in automated installation (silent installations). However, it can be used only once (can be easily extended). Code depends on IzPack COI tools. So COI tools classes need to be delivered together with the panel. Panel is built using Maven, so COI tools are shaded with <a href="http://maven.apache.org/plugins/maven-shade-plugin/">Maven Shade Plugin</a>. By default we are reading from HKEY_LOCAL_MACHINE registry root. You have to provide an xml file specifying what you want to read and to which variable to store the read value. Here is an example:</p>
<pre class="brush: xml; title: ;">
&lt;registryReader&gt;
  &lt;registry key=&quot;SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\myApp&quot;
      name=&quot;DisplayVersion&quot; default=&quot;null&quot; variable=&quot;myApp.version&quot; /&gt;
&lt;/registryReader&gt;
</pre>
<p>You may have several <code>registry</code> entries to read multiple keys. <code>name</code> specifies registry key. <code>variable</code> specifies to which variable to store the value. <code>default</code> specifies what should be a default value, when key was not found.</p>
<p>You will also need to provide COI dlls in <code>install.xml</code>:</p>
<pre class="brush: xml; title: ;">
&lt;native type=&quot;3rdparty&quot; name=&quot;COIOSHelper.dll&quot; stage=&quot;both&quot;&gt;
  &lt;os family=&quot;windows&quot; /&gt;
&lt;/native&gt;
&lt;native type=&quot;3rdparty&quot; name=&quot;COIOSHelper_x64.dll&quot; stage=&quot;both&quot;&gt;
  &lt;os family=&quot;windows&quot; /&gt;
&lt;/native&gt;
</pre>
<p>You will need to separate COI package yourself and add it to your Maven repository.</p>
<p>And here is the panel source:<a href="http://maksim.sorokin.dk/it/wp-content/uploads/2011/03/izpackExtensions-registryReader.zip">izpackExtensions-registryReader</a></p>
]]></content:encoded>
			<wfw:commentRss>http://maksim.sorokin.dk/it/2011/03/30/panel-for-reading-registry-in-izpack-4/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Custom IzPack Panels. Necessary Changes for Silent Installation.</title>
		<link>http://maksim.sorokin.dk/it/2011/03/17/custom-izpack-panels-necessary-changes-for-silent-installation/</link>
		<comments>http://maksim.sorokin.dk/it/2011/03/17/custom-izpack-panels-necessary-changes-for-silent-installation/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 11:59:11 +0000</pubDate>
		<dc:creator>Maksim Sorokin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[custom panels]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[IzPack]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[silent installation]]></category>

		<guid isPermaLink="false">http://maksim.sorokin.dk/it/?p=672</guid>
		<description><![CDATA[Here I described how to develop and debug your own custom panel. However, in order to have it work with automated installers (aka silent installation) we need to add some changes. You will need to add AutomationHelper class. Here is how you can do it. Assuming you have custom panel with a name MyPanel, create [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://maksim.sorokin.dk/it/2011/02/28/developing-and-debugging-izpack-panels-in-eclipse/">Here</a> I described how to develop and debug your own custom panel. However, in order to have it work with <a href="http://izpack.org/documentation/advanced-features.html#automated-installers">automated installers (aka silent installation)</a> we need to add some changes.</p>
<p>You will need to add <code>AutomationHelper</code> class. Here is how you can do it. Assuming you have custom panel with a name <code>MyPanel</code>, create class <code>MyPanelAutomationHelper</code> in the same package. This class has to extend <code>PanelAutomationHelper</code> and implement <code>PanelAutomation</code>. And then you will have to specify how to run the panel silently.<br />
Basically, you can just repeat all the routine from <code>panelActivate</code> method in <code>MyPanel</code> panel (or if you do not want to repeat yourself, invoke/call <code>MyPanel</code> smartly). But you cannot use UI stuff like <code>emitWarning</code> or <code>emitError</code>. If you need to inform user about something -- write it directly to the output. Silent installer should be silent. </p>
<p>Here is <code>AutomationHelper</code> class for <code>MyPanel</code> panel, which we developed previously:</p>
<pre class="brush: java; title: ;">
package com.izforge.izpack.panels;

import java.util.List;

import com.coi.tools.os.win.MSWinConstants;
import com.izforge.izpack.adaptator.IXMLElement;
import com.izforge.izpack.installer.AutomatedInstallData;
import com.izforge.izpack.installer.InstallerException;
import com.izforge.izpack.installer.PanelAutomation;
import com.izforge.izpack.installer.PanelAutomationHelper;

public class MyPanelAutomationHelper extends PanelAutomationHelper implements PanelAutomation {

  @Override
  public void makeXMLData(AutomatedInstallData installData, IXMLElement panelRoot) {
    //
  }

  @Override
  public void runAutomated(AutomatedInstallData installData, IXMLElement panelRoot) throws InstallerException {
    System.out.println(&quot;Hello, IzPack&quot;);
  }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://maksim.sorokin.dk/it/2011/03/17/custom-izpack-panels-necessary-changes-for-silent-installation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Silent Panels in IzPack</title>
		<link>http://maksim.sorokin.dk/it/2011/03/09/silent-panels-in-izpack/</link>
		<comments>http://maksim.sorokin.dk/it/2011/03/09/silent-panels-in-izpack/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 16:13:51 +0000</pubDate>
		<dc:creator>Maksim Sorokin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[IzPack]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://maksim.sorokin.dk/it/?p=658</guid>
		<description><![CDATA[In your custom IzPack panel you may want to do some routine silently. In this case you would need just to skip your panel: @Override public void panelActivate() { ... parent.skipPanel(); }]]></description>
			<content:encoded><![CDATA[<p>In your custom IzPack panel you may want to do some routine silently. In this case you would need just to skip your panel:</p>
<pre class="brush: java; title: ;">
  @Override
  public void panelActivate() {
    ...
    parent.skipPanel();
  }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://maksim.sorokin.dk/it/2011/03/09/silent-panels-in-izpack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

