Dark Planet Development Platform

Get Dark Planet Development Platform at SourceForge.net. Fast, secure and Free Open Source software downloads

Quick Start 2: Add the Static Data Reference Implementation

This tutorial takes the setup you created in Quick Start 1 and replaces the stub for the static data API with the DPS reference implementation. Don't worry if you didn't read the first tutorial, we'll repeat the key steps here. You do, however, need to have your Eclipse environment set up as described here.

First, either download or checkout all the stubs and the static data reference implementation. For the data reference implementation, you'll also need one of the static data dumps from CCP. At time of writing we provide two: Incursion which is older but smaller, and Incarna which was current at time of writing but is MUCH bigger. It doesn't matter much for this tutorial so pick whichever you like:

If you're extracting the helloworld bundle for the first time, make sure you extract it as a source bundle as we'll need to modify it below. If you've already extracted it as a binary bundle then just delete it and re-extract as a source bundle.

Now we'll add some simple code to print all the agent types listed in the static data dump. Modify the run method in org.dps.app.helloworld.HelloWorld so it looks like this:

	public void run() {
		System.out.println("HelloWorld started!");

		System.out.println("IEveDataModel = " + eveRef);
		System.out.println("IEveDatabase = " + eveDB);
		System.out.println("IEveServerRequest = " + eveServer);
		System.out.println("IEvePersistenceFactory = " + evePersistence);
		System.out.println("IEveMarketData = " + eveMarketData);

		// Let's print out all the agent types as an example of
		// how to use the database API.
		for (IAgtAgentTypes type : eveDB.getAgtAgentTypesFactory().getAll())
			System.out.println(type);

	}
If you read the first Quick Start tutorial, you know that on startup OSGi will resolve all our bundle dependencies and make sure that we have a valid reference for things like IEveDatabase. You also know, however, that the default launch configuration RunHelloWorld.launch pulls in the stub applications. So if we actually run the above we'll get an UnsupportedOperationException. Let's try that real quick, use Run->Run Configurations... to pull up the launcher dialog and select "RunHelloWorld" under the "OSGi Framework" section. You should see something like this:
    EveData registered
    EveDatabase registered
    EveServer registered
    PersistenceFactory registered
    EveMarketData registered
    HelloWorld started!
    IEveDataModel = org.dps.core.impl.model.stub.EveDataModelStub@7f724a9d
    IEveDatabase = org.dps.core.impl.database.stub.EveDatabaseStub@2880cac9
    IEveServerRequest = org.dps.core.impl.server.stub.EveServerStub@1f8166e5
    IEvePersistenceFactory = org.dps.core.impl.persist.stub.EvePersistenceFactoryStub@688a548b
    IEveMarketData = org.dps.core.impl.market.stub.EveMarketStub@2b5356d5
    ERROR 4 [SCR] Exception while activating instance org.dps.app.helloworld.HelloWorld@4afb6354 of component org.dps.app.helloworld  
    java.lang.reflect.InvocationTargetException
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:616)
    ... lots more stacktrace ....
    Caused by: java.lang.UnsupportedOperationException
    	at org.dps.core.impl.database.stub.EveDatabaseStub.getAgtAgentTypesFactory(EveDatabaseStub.java:82)
    	at org.dps.app.helloworld.HelloWorld.startup(HelloWorld.java:40)
    	... 28 more
To fix this we need to change our launch configuration to use the reference implementation bundles in place of the stubs for IEveDatabase. Rather than mangle our existing launch configuration we'll create a new one. Go to Run->Run Configurations... to bring up the launcher dialog again. Select "RunHelloWorld" in the "OSGi Framework" section and select the "duplicate" icon in the tool bar in the top left. This should create a new configuration called "RunHelloWorld (1)". Let's rename it "RunHelloWorldWithDB". To make this configuration work we need to do two things:

  1. Replace the stub bundles with the reference implementation bundles; and
  2. Add VM configuration to properly configure the reference implementation.
To replace the stub bundles, do the following:
  1. Select the "Bundles" tab.
  2. Uncheck "Only show selected" on the right.
  3. Find the bundle "org.dps.core.impl.database.stub" and uncheck it.
  4. Find and check the bundles "org.dps.core.impl.database.sqlite" and "org.dps.core.impl.database.sqlite.incarna10" (or incursion110 if that's what you downloaded).
  5. Scroll down a bit and check the bundle "sqlitejdbc-0.56".
  6. Check your work by clicking "Validate Bundles" on the right.
If "Validate Bundles" passes then we can move on to configuring the new bundles. You can check "Only show selected" again if you like. Now select the "Arguments" tab and append the following string in the VM arguments text area:
  -Dorg.dps.core.impl.database.sqlite.dbdir=${project_loc:/org.dps.core.impl.database.sqlite.incarna10}/db
(replace incarna10 with incursion110 if that's what you downloaded). This VM argument sets a property which tells the reference implementation where to find the sqlite database dump containing static data.

Now we're ready to run the application again. Note that the sqlite database dump files are bundled in zipped form. So the first time we run our application the reference implementation will automatically unzip the database dump before doing anything else. This can take a minute or two for the Incarna dump which is quite large. You can avoid this step by unzipping the dump file yourself in the appropriate workspace directory. Either way, when you're ready click "Apply" on your new launch configuration, then click "Run". You should (eventually) see something like this:

    EveData registered
    EveDatabase registered
    EveServer registered
    PersistenceFactory registered
    EveMarketData registered
    HelloWorld started!
    IEveDataModel = org.dps.core.impl.model.stub.EveDataModelStub@20e183e9
    IEveDatabase = org.dps.core.impl.database.sqlite.SqliteEveDatabase@359b46dc
    IEveServerRequest = org.dps.core.impl.server.stub.EveServerStub@65493102
    IEvePersistenceFactory = org.dps.core.impl.persist.stub.EvePersistenceFactoryStub@2830ae41
    IEveMarketData = org.dps.core.impl.market.stub.EveMarketStub@1cee1ede
    SqliteAgtAgentTypes [agentTypeID=1, agentType=NonAgent]
    SqliteAgtAgentTypes [agentTypeID=2, agentType=BasicAgent]
    SqliteAgtAgentTypes [agentTypeID=3, agentType=TutorialAgent]
    SqliteAgtAgentTypes [agentTypeID=4, agentType=ResearchAgent]
    SqliteAgtAgentTypes [agentTypeID=5, agentType=CONCORDAgent]
    SqliteAgtAgentTypes [agentTypeID=6, agentType=GenericStorylineMissionAgent]
    SqliteAgtAgentTypes [agentTypeID=7, agentType=StorylineMissionAgent]
    SqliteAgtAgentTypes [agentTypeID=8, agentType=EventMissionAgent]
    SqliteAgtAgentTypes [agentTypeID=9, agentType=FactionalWarfareAgent]
    SqliteAgtAgentTypes [agentTypeID=10, agentType=EpicArcAgent]
    SqliteAgtAgentTypes [agentTypeID=11, agentType=AuraAgent]
If you see this, then you've successfully run the "Hello, World!" application using the DPS IEveDatabase reference implementation.

Under the Covers

Just like in the first Quick Start, OSGi is resolving bundles and passing the resolved bundle references to our startup application via the "register" methods we've created. You can see that we're using the reference implementation this time because of the line:
    IEveDatabase = org.dps.core.impl.database.sqlite.SqliteEveDatabase@359b46dc
When we use the reference implementation to get the agent types factory we eventually call getAll() to load all the agent type objects. The reference implementation uses Hibernate with SQLite to convert static data dump rows into objects. So our first call to getAll() causes Hibernate to be loaded. This takes a few seconds while Hibernate processes configuration for all of the static data table definitions. Finally, the getAll() method executes a query on the appropriate table and returns a collection of the type objects. We then iterate and print out each object in the collection. We only need to pay the price for Hibernate startup for the first lookup. Subsequent calls to factory methods will be much faster.

You can get a more detailed description of the static data reference implementation in the "Reference Implementations" section on the main page. The next Quick Start tutorial repeats this same exercise but this time adding the IEveServer reference implementation.