Using forceTen components in a non-Platform application

Latest update: January 11, 2010 for forceTen v0.5.7.

In this tutorial we are going to demonstrate how to use some forceTen components in a non-Platform application (such as a plain Java application) using Maven.

For this tutorial you need Java 6 and NetBeans 6.8 or later (but it could work with 6.7.1 too). A similar source is available in the “Example2” module in forceTen sources.

 

Creating a skeleton platform project

  1. Select the menu “File / New Project”.
  2. Select the “Maven” category and “Maven Project” under Projects. Press “Next”.
  3. Select the “Maven Quickstart Archetype” and press “Next”.

If it's the first time you're using Maven, some steps might require a while as Maven download the required artifacts from the network (but you need to do that only once).

Now, you should be in the “Name and Location” window; fill in as indicated:

  1. Project name: example2
  2. Project location: your favourite path
  3. Group Id: it.tidalwave.geo.examples
  4. Version: 1.0-SNAPSHOT
  5. Package: it.tidalwave.geo.examples.example2

Now press the “Finish” button. After the operation completes, you'll find a single project in the “Projects” tab. Make sure that it is the main project (eventually click on it and select the menu “Set as Main Project”). Execute the “Clean and Build” operation to compile it (again, the first time this might take a while as artifacts are downloaded from the network).

Now execute the “Run” action. You should see the application running - and doing nothing, as there is an App class with an empty main().

 

Adding the repositories and configuring the compiler

Open the pom.xml file of the project, locate the repositories section and add the following part:

<repositories>
    <repository>
        <id>netbeans</id>
        <name>NetBeans Platform Maven Repository</name>
        <url>http://bits.netbeans.org/maven2/</url>
    </repository>
    <repository>
        <id>maven2-release-repository.nbpwr.kenai.com</id>
        <name>NBPWR Maven Release Repository</name>
        <url>https://kenai.com/website/nbpwr/maven-repository/releases</url>
    </repository>
    <repository>
        <id>maven2-release-repository.openbluesky.kenai.com</id>
        <name>OpenBlueSky Maven Release Repository</name>
        <url>https://kenai.com/website/openbluesky/maven-repository/releases</url>
    </repository>
    <repository>
        <id>maven2-release-repository.forceten.kenai.com</id>
        <name>forceTen Maven Release Repository</name>
        <url>https://kenai.com/website/forceten/maven-repository/releases</url>
    </repository>
</repositories>

We have added a few repository to retrieve libraries from, most notably the forceTen repository, the OpenBlueSky repository (a set of components used by forceTen) and the NBPWR repository (a set of common open source libraries prepared for the NetBeans Platform).

Then locate the pluginManagement section and make sure you're compiling with Java 6, configuring the compiler plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.0.2</version>
    <configuration>
        <source>1.6</source>
        <target>1.6</target>
    </configuration>
</plugin>

Using the GeoCoding API

In this very short example we are going to use the GeoCoding API, which allows to query a service providing geocoding data. The first thing to do is to add the related components.

If you're not accustomed to manage Maven artifacts with Maven, please have a look at the first tutorial (and the related screencast).

The GeoCoding API artifact is available with these coordinates:

<dependency>
    <groupId>it.tidalwave.geo</groupId>
    <artifactId>it-tidalwave-geo-geocoding</artifactId>
    <version>3.1.0</version>
</dependency>

This is just an abstract API that needs a provider. To add it, repeat the procedure to add an artifact with the following coordinates:

<dependency>
    <groupId>it.tidalwave.geo</groupId>
    <artifactId>it-tidalwave-geo-geocoding-geonamesprovider</artifactId>
    <version>1.0.44</version>
</dependency>

 

Now open the main() method of the App class, and copy the following code:

import javax.annotation.Nonnull;
import java.util.Collection;
import it.tidalwave.netbeans.util.Locator;
import it.tidalwave.netbeans.util.NotFoundException;
import it.tidalwave.geo.Coordinate;
import it.tidalwave.geo.geocoding.GeoCoder;
import it.tidalwave.geo.geocoding.GeoCoderEntity;
import it.tidalwave.geo.geocoding.GeoCoderEntity.FactSheet;
import static it.tidalwave.netbeans.util.Displayable.Displayable;
import static it.tidalwave.geo.geocoding.GeoCoder.GeoCoder;
import static it.tidalwave.geo.geocoding.GeoCoderEntity.FactSheet.*;
import static it.tidalwave.geo.geocoding.GeoCoderEntity.FactSheet.FactSheet;

public class App
  {
    public static void main (final @Nonnull String ... args)
      throws NotFoundException
      {
        final GeoCoder geoCoder = Locator.find(GeoCoder);
        final Coordinate coordinate = new Coordinate(43.5, 6);
        final Finder<GeoCoderEntity> nearbyPlaces = geoCoder.findNearByEntities(coordinate, 10);

        for (final GeoCoderEntity place : nearbyPlaces.results())
          {
            final String displayName = place.as(Displayable).getDisplayName();
            final String type = place.getTypeAsString();
            final Coordinate c = place.getCoordinate();
            final FactSheet factSheet = place.as(FactSheet);
           
            System.err.printf("%-30s %-5s: %s\n", displayName, type, c);

            if (factSheet.contains(POPULATION))
              {
                System.err.printf("%42s %d\n", "population:", factSheet.get(POPULATION));
              }

            if (factSheet.contains(ELEVATION))
              {
                System.err.printf("%42s %d\n", "elevation: ", factSheet.get(ELEVATION));
              }
          }
      }
  }

Run the application: you should see an output such as the following:

Châteauvert                    PPL  : N 43° 30' 00.000" E 6° 01' 00.000", 0.0
                               population: 147
                               elevation:  0
Miraval                        PPL  : N 43° 28' 00.000" E 6° 02' 00.000", 0.0
                               elevation:  0
Saint-Estève                   PPL  : N 43° 30' 00.000" E 5° 56' 00.000", 0.0
                               elevation:  0
Brue-Auriac                    PPL  : N 43° 32' 00.000" E 5° 57' 00.000", 0.0
                               population: 959
                               elevation:  0
Bras                           PPL  : N 43° 28' 00.000" E 5° 57' 00.000", 0.0
                               population: 1888
                               elevation:  0
Barjols                        PPL  : N 43° 33' 00.000" E 6° 00' 00.000", 0.0
                               population: 2619
                               elevation:  0
Correns                        PPL  : N 43° 29' 00.000" E 6° 05' 00.000", 0.0
                               population: 723
                               elevation:  0
Pontevès                       PPL  : N 43° 34' 00.000" E 6° 03' 00.000", 0.0
                               population: 624
                               elevation:  0
Seillons-Source-d'Argens       PPL  : N 43° 29' 00.000" E 5° 53' 00.000", 0.0
                               elevation:  0

To confirm that you're not bringing into your application tons of dependencies, try to run

mvn dependency:tree

You should see the following output:

[INFO] [dependency:tree {execution: default-cli}]
[INFO] it.tidalwave.geo.examples:example2:jar:1.1-SNAPSHOT
[INFO] +- it.tidalwave.geo:it-tidalwave-geo-geocoding:jar:3.1.0:compile
[INFO] |  +- it.tidalwave.netbeans:it-tidalwave-netbeans-util:jar:1.10.20:compile
[INFO] |  |  \- com.kenai.nbpwr:javax-inject:jar:1.0:compile
[INFO] |  |     \- javax.inject:javax.inject:jar:1:compile
[INFO] |  +- it.tidalwave.geo:it-tidalwave-geo:jar:2.0.32:compile
[INFO] |  +- org.netbeans.api:org-openide-util:jar:RELEASE68:compile
[INFO] |  +- it.tidalwave.netbeans:it-tidalwave-netbeans-capabilitiesprovider:jar:1.1.8:compile
[INFO] |  +- com.kenai.nbpwr:edu-umd-cs-findbugs-annotations:jar:1.3.2.3:compile
[INFO] |  |  \- net.sourceforge.findbugs:annotations:jar:1.3.2:compile
[INFO] |  \- com.kenai.nbpwr:javax-annotation:jar:1.3.7.3:compile
[INFO] |     \- com.google.code.findbugs:jsr305:jar:1.3.7:compile
[INFO] \- it.tidalwave.geo:it-tidalwave-geo-geocoding-geonamesprovider:jar:1.0.44:compile
[INFO]    +- it.tidalwave.netbeans:it-tidalwave-netbeans-workspacemanager:jar:2.2.16:compile
[INFO]    +- it.tidalwave.thesefoolishthings:it-tidalwave-util-logging:jar:1.0.5:compile
[INFO]    |  \- it.tidalwave.thesefoolishthings:it.tidalwave.util.logging:jar:1.0.5:compile
[INFO]    \- com.kenai.nbpwr:org-apache-commons-io:jar:1.3.1.4:compile
[INFO]       \- commons-io:commons-io:jar:1.3.1:compile