<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Miles To Code Before I Sleep</title>
	<atom:link href="http://bryanhunt.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://bryanhunt.wordpress.com</link>
	<description>It&#039;s all about the code.</description>
	<lastBuildDate>Mon, 02 Jan 2012 22:40:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='bryanhunt.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/a7c516029012cd19a7bc8c7bc87bc02a?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Miles To Code Before I Sleep</title>
		<link>http://bryanhunt.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://bryanhunt.wordpress.com/osd.xml" title="Miles To Code Before I Sleep" />
	<atom:link rel='hub' href='http://bryanhunt.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Restlet Extension for OSGi Environments 0.5.1 Released</title>
		<link>http://bryanhunt.wordpress.com/2011/11/20/restlet-extension-for-osgi-environments-0-5-1-released/</link>
		<comments>http://bryanhunt.wordpress.com/2011/11/20/restlet-extension-for-osgi-environments-0-5-1-released/#comments</comments>
		<pubDate>Mon, 21 Nov 2011 04:26:14 +0000</pubDate>
		<dc:creator>Bryan Hunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">https://bryanhunt.wordpress.com/?p=630</guid>
		<description><![CDATA[Restlet Extension for OSGi Environments 0.5.1 is a maintenance release to be compatible with the latest Restlet p2 repository.  There were no changes to the code &#8211; only fixes to the feature dependencies.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=630&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="https://github.com/BryanHunt/Restlet-Extension-for-OSGi-Environments/wiki">Restlet Extension for OSGi Environments</a> 0.5.1 is a maintenance release to be compatible with the latest <a href="http://p2.restlet.org/2.1/">Restlet p2 repository</a>.  There were no changes to the code &#8211; only fixes to the feature dependencies.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/630/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/630/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/630/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/630/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/bryanhunt.wordpress.com/630/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/bryanhunt.wordpress.com/630/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/bryanhunt.wordpress.com/630/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/bryanhunt.wordpress.com/630/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/630/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/630/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/630/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/630/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/630/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/630/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=630&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2011/11/20/restlet-extension-for-osgi-environments-0-5-1-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>
	</item>
		<item>
		<title>eTrack EMF Tutorial</title>
		<link>http://bryanhunt.wordpress.com/2011/11/07/etrack-emf-tutorial/</link>
		<comments>http://bryanhunt.wordpress.com/2011/11/07/etrack-emf-tutorial/#comments</comments>
		<pubDate>Mon, 07 Nov 2011 14:00:54 +0000</pubDate>
		<dc:creator>Bryan Hunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">https://bryanhunt.wordpress.com/?p=627</guid>
		<description><![CDATA[I&#8217;ve made a little more progress with eTrack and I now have two complete EMF tutorials available.  Creating the Entity Domain Model walks you through creating an EMF ecore model for the Entity domain, the corresponding genmodel, and how to use the generated editor.  Refactoring the Entity Domain Model shows you how to refactor an [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=627&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve made a little more progress with <a href="https://github.com/BryanHunt/eTrack/wiki">eTrack</a> and I now have two complete <a href="http://www.eclipse.org/modeling/emf/">EMF</a> tutorials available.  <a href="https://github.com/BryanHunt/eTrack/wiki/Creating-the-Entity-Domain-Model">Creating the Entity Domain Model</a> walks you through creating an EMF ecore model for the Entity domain, the corresponding genmodel, and how to use the generated editor.  <a href="https://github.com/BryanHunt/eTrack/wiki/Refactoring-the-Entity-Domain-Model">Refactoring the Entity Domain Model</a> shows you how to refactor an EMF model into two separate models.  These are the first tutorials available in a series that will cover the building of an entire application.  If you would like to contribute to the project, please let me know or open an <a href="https://github.com/BryanHunt/eTrack/issues">issue</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/627/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/627/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/bryanhunt.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/bryanhunt.wordpress.com/627/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/bryanhunt.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/bryanhunt.wordpress.com/627/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/627/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/627/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/627/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/627/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=627&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2011/11/07/etrack-emf-tutorial/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>
	</item>
		<item>
		<title>Restlet Extensions for OSGi Environments 0.5.0 Released</title>
		<link>http://bryanhunt.wordpress.com/2011/10/17/restlet-extensions-for-osgi-environments-0-5-0-released/</link>
		<comments>http://bryanhunt.wordpress.com/2011/10/17/restlet-extensions-for-osgi-environments-0-5-0-released/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 14:00:00 +0000</pubDate>
		<dc:creator>Bryan Hunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">https://bryanhunt.wordpress.com/?p=625</guid>
		<description><![CDATA[I have released Restlet Extension for OSGi Environments version 0.5.0.  This project provides a framework for building RESTful OSGi web services using dynamic applications, routers, filters, and resources.  The project has been renamed from Restlet integration with OSGi &#38; Equinox, and has also been refactored to be a Restlet extension.  This build is temporary until the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=625&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I have released <a href="https://github.com/BryanHunt/Restlet-Extension-for-OSGi-Environments/wiki">Restlet Extension for OSGi Environments</a> version 0.5.0.  This project provides a framework for building RESTful <a href="http://www.osgi.org">OSGi</a> web services using dynamic applications, routers, filters, and resources.  The project has been renamed from Restlet integration with OSGi &amp; Equinox, and has also been refactored to be a <a href="http://www.restlet.org/">Restlet</a> extension.  This build is temporary until the extension is officially released as part of Restlet.  This release requires Restlet 2.1M7 or later.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/625/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/625/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/bryanhunt.wordpress.com/625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/bryanhunt.wordpress.com/625/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/bryanhunt.wordpress.com/625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/bryanhunt.wordpress.com/625/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/625/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/625/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/625/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/625/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=625&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2011/10/17/restlet-extensions-for-osgi-environments-0-5-0-released/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>
	</item>
		<item>
		<title>MongoEMF 0.4.0 Released</title>
		<link>http://bryanhunt.wordpress.com/2011/10/05/mongoemf-0-4-0-released/</link>
		<comments>http://bryanhunt.wordpress.com/2011/10/05/mongoemf-0-4-0-released/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 17:54:09 +0000</pubDate>
		<dc:creator>Bryan Hunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">https://bryanhunt.wordpress.com/?p=623</guid>
		<description><![CDATA[I have released MongoEMF 0.4.0.  Some of the notable changes include: Reading objects from a query Result has been significantly improved Write performance for bulk stores has improved Added MongoResourceImpl for improved load performance when using URI mappings Added OPTION_USE_ID_ATTRIBUTE_AS_PRIMARY_KEY to store objects using the ID attribute value as the MongoDB primary key For a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=623&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I have released <a href="https://github.com/BryanHunt/mongo-emf/wiki">MongoEMF</a> 0.4.0.  Some of the notable changes include:</p>
<ul>
<li>Reading objects from a query Result has been significantly improved</li>
<li>Write performance for bulk stores has improved</li>
<li>Added MongoResourceImpl for improved load performance when using URI mappings</li>
<li>Added OPTION_USE_ID_ATTRIBUTE_AS_PRIMARY_KEY to store objects using the ID attribute value as the MongoDB primary key</li>
</ul>
<p>For a complete list of the changes, see the <a href="https://github.com/BryanHunt/mongo-emf/wiki/Release-Notes">Release Notes</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/623/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/623/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/bryanhunt.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/bryanhunt.wordpress.com/623/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/bryanhunt.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/bryanhunt.wordpress.com/623/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/623/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/623/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/623/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=623&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2011/10/05/mongoemf-0-4-0-released/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>
	</item>
		<item>
		<title>OSGi at REST</title>
		<link>http://bryanhunt.wordpress.com/2011/06/30/osgi-at-rest/</link>
		<comments>http://bryanhunt.wordpress.com/2011/06/30/osgi-at-rest/#comments</comments>
		<pubDate>Fri, 01 Jul 2011 03:33:29 +0000</pubDate>
		<dc:creator>Bryan Hunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">https://bryanhunt.wordpress.com/?p=609</guid>
		<description><![CDATA[Introduction I&#8217;ve been working on a project to make building RESTful OSGi web applications as simple as creating a basic OSGi service, and I think I have a solution that comes pretty close to this goal. The project is currently called restlet-integration-with-equinox as hosted on EclipseLabs. I am in the process of moving the project [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=609&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>I&#8217;ve been working on a project to make building <a href="http://en.wikipedia.org/wiki/REST">RESTful</a> OSGi web applications as simple as creating a basic OSGi service, and I think I have a solution that comes pretty close to this goal.  The project is currently called <a href="http://code.google.com/a/eclipselabs.org/p/restlet-integration-with-equinox/">restlet-integration-with-equinox</a> as hosted on <a href="http://code.google.com/a/eclipselabs.org/hosting/">EclipseLabs</a>.  I am in the process of moving the project to <a href="https://github.com/BryanHunt/Restlet-Extension-for-OSGi-Environments">GitHub</a>, and it will be renamed to Restlet Extension for OSGi Environments.  This framework integrates the <a href="http://www.restlet.org/">Restlet</a> RESTful web framework with OSGi allowing you to dynamically register resources, filters, routers, and applications as part of a RESTful web application.</p>
<p>The project originally started out supporting the registration of applications and resources as OSGi services or with an Equinox extension point.  This all worked fine until I started adding the ability to register routers and filters.  The code became complicated and ugly, so I branched the repository and started over.  As the second iteration progressed, it too became complicated, and it occurred to me that the core of the problem (delayed dynamic binding) was identical to the problem that OSGi declarative services has to solve.  That&#8217;s when I had that <em>AH-HA</em> moment where the problem becomes clear, and you get to delete all of that ugly, complicated, code.  The solution is to use OSGi declarative services and its dynamic binding capabilities to stitch together the resources, filters, routers, and applications.  And, since you are using OSGi services, you can add and remove resources at runtime and it all <em>just works</em>.</p>
<h2>Framework</h2>
<p>The Restlet Extension for OSGi Enironments framework is organized as a set of service components and interfaces for you to register as declarative services to form your RESTful web application.  Using these service components, it&#8217;s possible to implement a simple application with a router and some resources, or a very complex graph of filters, routers, and resources as demonstrated below.</p>
<p><img style="display:block;margin-left:auto;margin-right:auto;" title="Application.png" src="http://bryanhunt.files.wordpress.com/2011/06/application.png?w=600&#038;h=217" border="0" alt="Application" width="600" height="217" /></p>
<p>Here is the API specification for the service interfaces:</p>
<p><img style="display:block;margin-left:auto;margin-right:auto;" title="ServiceInterfaces.png" src="http://bryanhunt.files.wordpress.com/2011/06/serviceinterfaces1.png?w=460&#038;h=282" border="0" alt="Service Interfaces" width="460" height="282" /></p>
<p>Here is the API specification for the service components (I have omitted the service interfaces that each provider implements):</p>
<p><img style="display:block;margin-left:auto;margin-right:auto;" title="ServiceComponents.png" src="http://bryanhunt.files.wordpress.com/2011/06/servicecomponents.png?w=565&#038;h=600" border="0" alt="Service Components" width="565" height="600" /></p>
<p><strong>FilterProvider</strong> and <strong>ResourceProvider</strong> are abstract and must be extended as described below.  <strong>RouterProvider</strong> and <strong>ApplicationProvider</strong> can be used without extending them.  The remainder of this post will walk you through examples of creating RESTful web applications using this technology.</p>
<h2>Setup</h2>
<p>Before you begin development of your application, the target platform needs to be crated with the following frameworks:</p>
<ul>
<li>Equinox 3.7</li>
<li><a href="http://www.restlet.org/downloads/stable">Restlet JEE 2.0.8</a></li>
<li><a href="http://code.google.com/a/eclipselabs.org/p/restlet-integration-with-equinox/downloads/list">Restlet Extensions for OSGi Environments 0.3.0</a></li>
</ul>
<p>If you would like to minimize your target platform, the following bundles are the minimum required:</p>
<ul>
<li>javax.servlet</li>
<li>org.eclilpse.equinox.common</li>
<li>org.eclipse.equinox.ds</li>
<li>org.eclispe.equinox.http.jetty</li>
<li>org.eclipse.equinox.http.servlet</li>
<li>org.eclipse.equinox.util</li>
<li>org.eclipse.osgi</li>
<li>org.eclipse.osgi.services</li>
<li>org.mortbay.jetty.server</li>
<li>org.mortbay.jetty.util</li>
<li>org.restlet</li>
<li>org.restlet.ext.servlet</li>
<li>org.eclipselabs.restlet</li>
<li>org.eclipselabs.restlet.servlet</li>
</ul>
<p>If you are not familiar with setting up your target platform, here are the detailed steps:</p>
<ol>
<li>Download Restlet JEE 2.0.8 and Restlet Extensions for OSGi Environments 0.3.0.  You do not need to download Equinox &#8211; we&#8217;ll get that from a p2 repository.</li>
<li>Uncompress the downloads into a targets directory.</li>
<li>Launch Eclipse (I&#8217;m using Indigo) and select Preferences -&gt; Plug-in Development -&gt; Target Platform.</li>
<li>Click Add&#8230;</li>
<li>Choose Nothing: Start with an empty target definition.</li>
<li>Click Next</li>
<li>Name the target platform.</li>
<li>Click Add&#8230;</li>
<li>Choose Directory and click Next.</li>
<li>Add &lt;target directory&gt;/restlet-jee-2.0.8/lib</li>
<li>Click Finish.</li>
<li>Click Add&#8230;</li>
<li>Choose Directory and click Next.</li>
<li>Add &lt;target directory&gt;/restlet-ext-osgi</li>
<li>Click Finish.</li>
<li>Click Add&#8230;</li>
<li>Choose Software Site.</li>
<li>Work with: http://download.eclipse.org/releases/indigo.</li>
<li>Expand EclipseRT Target Platform Components.</li>
<li>Check Equinox Target Components.</li>
<li>Click Finish.</li>
<li>Click Finish.</li>
<li>Check the target definition you just created to make it Active.</li>
<li>Click OK.</li>
</ol>
<p><img style="display:block;margin-left:auto;margin-right:auto;" title="Edit Target Definition-1.jpg" src="http://bryanhunt.files.wordpress.com/2011/06/edit-target-definition-1.jpg?w=729&#038;h=308" border="0" alt="Edit Target Definition 1" width="729" height="308" /></p>
<p>Let&#8217;s test the target definition.  Create an OSGi launch configuration with the following bundles:</p>
<ul>
<li>javax.servlet</li>
<li>org.eclipse.equinox.http.jetty</li>
<li>org.eclipse.equinox.http.servlet</li>
<li>org.eclipse.osgi</li>
<li>org.eclipse.osgi.services</li>
<li>org.mortbay.jetty.server</li>
<li>org.mortbay.jetty.util</li>
</ul>
<p>Set <strong>Default Auto-Start: true</strong> (not ideal, but it gets you up and running quickly) and add the following VM argument: <strong>-Dorg.osgi.service.http.port=8080</strong>.</p>
<p><img style="display:block;margin-left:auto;margin-right:auto;" title="Run Configurations-3.jpg" src="http://bryanhunt.files.wordpress.com/2011/06/run-configurations-3.jpg?w=867&#038;h=285" border="0" alt="Run Configurations 3" width="867" height="285" /></p>
<p>Run the application and point your web browser to <a href="http://localhost:8080/">http://localhost:8080/</a>.  You should get a 404 error.  This lets you know that jetty is responding to your request, but there are currently no resources to handle the request.  For more information on setting up OSGi as a web server, see my blog post: <a href="http://bryanhunt.wordpress.com/2010/05/14/osgi-as-a-web-application-server/">OSGi as a Web Application Server</a>.</p>
<h2>Hello RESTful World</h2>
<p>For this tutorial we are going to create a single resource at the URI <a href="http://localhost:8080/hello">http://localhost:8080/hello</a> with a plain text representation.  We need to create and wire together three objects: Application, Router, and ServerResource.  Start by creating a new Plug-in Project called <strong>org.eclipselabs.restlet.examples.app</strong>.  You do not need a bundle activator.</p>
<p>Open the <strong>MANIFEST.MF</strong> and add the following imported packages:</p>
<ul>
<li>org.eclipselabs.restlet</li>
<li>org.restlet</li>
<li>org.restlet.resource</li>
</ul>
<p>Create a new package: <strong>org.eclipselabs.restlet.examples.app</strong> and add the following <strong>HelloResource</strong>:</p>
<p><pre class="brush: java;">
package org.eclipselabs.restlet.examples.app;

import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;

public class HelloResource extends ServerResource
{
  @Get(&quot;txt&quot;)
  public String sayHello()
  {
    return &quot;Hello RESTful World&quot;;
  }
}
</pre></p>
<p>In that same package, add the following <strong>HelloResourceProvider</strong>:</p>
<p><pre class="brush: java;">
import org.eclipselabs.restlet.ResourceProvider;
import org.restlet.Context;
import org.restlet.resource.Finder;

public class HelloResourceProvider extends ResourceProvider
{
  @Override
  protected Finder createFinder(Context context)
  {
    return new Finder(context, HelloResource.class);
  }
}
</pre></p>
<p>At the root of the project create an <strong>OSGI-INF</strong> folder to hold our service declarations.  In the <strong>OSGi-INF</strong> folder, create the following declarative service as <strong>application.xml</strong>:</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.restlet.examples.app&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.restlet.ApplicationProvider&quot;/&gt;
   &lt;service&gt;
      &lt;provide interface=&quot;org.eclipselabs.restlet.IApplicationProvider&quot;/&gt;
   &lt;/service&gt;
   &lt;property name=&quot;alias&quot; type=&quot;String&quot; value=&quot;/&quot;/&gt;
   &lt;reference bind=&quot;bindRouterProvider&quot; cardinality=&quot;1..1&quot; interface=&quot;org.eclipselabs.restlet.IRouterProvider&quot; name=&quot;IRouterProvider&quot; policy=&quot;static&quot; unbind=&quot;unbindRouterProvider&quot;/&gt;
&lt;/scr:component&gt;
</pre></p>
<p>Create the following declarative service as <strong>router.xml</strong>:</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.restlet.examples.app.router&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.restlet.RouterProvider&quot;/&gt;
   &lt;service&gt;
      &lt;provide interface=&quot;org.eclipselabs.restlet.IRouterProvider&quot;/&gt;
   &lt;/service&gt;
   &lt;reference bind=&quot;bindResourceProvider&quot; cardinality=&quot;1..n&quot; interface=&quot;org.eclipselabs.restlet.IResourceProvider&quot; name=&quot;IResourceProvider&quot; policy=&quot;dynamic&quot; unbind=&quot;unbindResourceProvider&quot;/&gt;
&lt;/scr:component&gt;
</pre></p>
<p>Create the following declarative service as <strong>hello.xml</strong>:</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.restlet.examples.app.hello&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.restlet.examples.app.HelloResourceProvider&quot;/&gt;
   &lt;service&gt;
      &lt;provide interface=&quot;org.eclipselabs.restlet.IResourceProvider&quot;/&gt;
   &lt;/service&gt;
   &lt;property name=&quot;paths&quot; type=&quot;String&quot;&gt;
     /hello
   &lt;/property&gt;
&lt;/scr:component&gt;
</pre></p>
<p>If you are not using the component definition editor to create your declarative services, be sure to add the following to the <strong>MANIFEST.MF</strong>:</p>
<p><strong>Service-Component: OSGI-INF/application.xml, OSGI-INF/router.xml, OSGI-INF/hello.xml</strong></p>
<p>You are now ready to run and test your web application.  Add the following bundles to the launch configuration you created in the Setup step:</p>
<ul>
<li>org.eclipselabs.restlet.examples.app</li>
<li>org.eclipse.equinox.common</li>
<li>org.eclipse.equinox.ds</li>
<li>org.eclipse.equinox.util</li>
<li>org.eclipselabs.restlet</li>
<li>org.eclipselabs.restlet.servlet</li>
<li>org.restlet</li>
<li>org.restlet.ext.servlet</li>
</ul>
<p>Run the application and point your browser to <a href="http://localhost:8080/hello">http://localhost:8080/hello</a>.  You should see &#8220;Hello RESTful World&#8221;.</p>
<p><img style="display:block;margin-left:auto;margin-right:auto;" title="Run Configurations-2.jpg" src="http://bryanhunt.files.wordpress.com/2011/06/run-configurations-2.jpg?w=868&#038;h=486" border="0" alt="Run Configurations 2" width="868" height="486" /></p>
<p>One of the neat features of Restlet is that you can specify more than one representation in a resource.  Let&#8217;s add an HTML representation to our hello resource:</p>
<p><pre class="brush: java;">
package org.eclipselabs.restlet.examples.app;

import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;

public class HelloResource extends ServerResource
{
  @Get(&quot;txt&quot;)
  public String sayHello()
  {
    return &quot;Hello RESTful World&quot;;
  }

  @Get(&quot;html&quot;)
  public String getDocument()
  {
    StringBuilder html = new StringBuilder();
    html.append(&quot;&lt;html&gt;\n&quot;);
    html.append(&quot;  &lt;body&gt;\n&quot;);
    html.append(&quot;    &lt;h2&gt;Hello RESTful World&lt;/h2&gt;\n&quot;);
    html.append(&quot;   &lt;/body&gt;\n&quot;);
    html.append(&quot;&lt;/html&gt;\n&quot;);
    return html.toString();
  }
}
</pre></p>
<p>Now, when you reload <a href="http://localhost:8080/hello">http://localhost:8080/hello</a> in your browser, you should see &#8220;Hello RESTful World&#8221; in a Heading 2 style.  The complete solution for this example application can be downloaded from the Restlet Extensions for OSGi Environments <a href="http://code.google.com/a/eclipselabs.org/p/restlet-integration-with-equinox/downloads/list">downloads</a> page.</p>
<h2>Applications</h2>
<p>Your OSGi web application will consist of one or more Restlet Application instances.  An application is created by declaring an OSGi service component of type <strong>ApplicationProvider</strong> which provides the service <strong>IApplicationProvider</strong>, and has an &#8220;alias&#8221; property that specifies the root path of the application.  The alias of each Restlet application in your OSGi application must be unique, start with &#8220;/&#8221; and not end with &#8220;/&#8221; with the exception of &#8220;/&#8221; itself.  It should not be necessary to extend <strong>ApplicationProvider</strong>, but you must declare the service in your own bundle.  The <strong>ApplicationProvider</strong> has a dependency on the <strong>IRouterProvider</strong> service.  This dependency should be declared as static with a cardinality of 1..1 and bind functions <strong>(un)bindRouterProvider()</strong>.</p>
<p>Suppose you wanted to create more than one Application.  Each Application needs its own instance of a Router.  How does OSGi declarative services know which <strong>IRouterProvider</strong> to bind to which <strong>ApplicationProvider</strong>?  When you declare the dependency from <strong>ApplicationProvider</strong> to <strong>IRouterProvider</strong>, there is a target parameter you can set to specify the exact IRouterProvider to bind against.  Here is an example of declaring two applications each binding to a unique router using the <strong>component.name</strong> property given to the service instance.</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.restlet.examples.app1&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.restlet.ApplicationProvider&quot;/&gt;
   &lt;service&gt;
      &lt;provide interface=&quot;org.eclipselabs.restlet.IApplicationProvider&quot;/&gt;
   &lt;/service&gt;
   &lt;property name=&quot;alias&quot; type=&quot;String&quot; value=&quot;/app1&quot;/&gt;
   &lt;reference bind=&quot;bindRouterProvider&quot; cardinality=&quot;1..1&quot; interface=&quot;org.eclipselabs.restlet.IRouterProvider&quot; name=&quot;IRouterProvider&quot; policy=&quot;static&quot; target=&quot;(component.name=org.eclipselabs.restlet.examples.app.router1)&quot; unbind=&quot;unbindRouterProvider&quot;/&gt;
&lt;/scr:component&gt;
</pre><br />
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.restlet.examples.app2&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.restlet.ApplicationProvider&quot;/&gt;
   &lt;service&gt;
      &lt;provide interface=&quot;org.eclipselabs.restlet.IApplicationProvider&quot;/&gt;
   &lt;/service&gt;
   &lt;property name=&quot;alias&quot; type=&quot;String&quot; value=&quot;/app2&quot;/&gt;
   &lt;reference bind=&quot;bindRouterProvider&quot; cardinality=&quot;1..1&quot; interface=&quot;org.eclipselabs.restlet.IRouterProvider&quot; name=&quot;IRouterProvider&quot; policy=&quot;static&quot; target=&quot;(component.name=org.eclipselabs.restlet.examples.app.router2)&quot; unbind=&quot;unbindRouterProvider&quot;/&gt;
&lt;/scr:component&gt;
</pre></p>
<h2>Routers</h2>
<p>Every Restlet Application instance needs at least one Router instance.  Technically speaking, this isn&#8217;t entirely true, but for all practical purposes, you are going to want a Router.  A router is created by declaring an OSGi service component of type <strong>RouterProvider</strong> which provides the service <strong>IRouterProvider</strong>.  The <strong>RouterProvider</strong> has a dependency on <strong>IResourceProvider</strong> and <strong>IRouterProvider</strong> services.  The dependency on <strong>IResourceProvider</strong> should be declared as dynamic with a cardinality of 1..n and bind functions <strong>(un)bindResourceProvider()</strong>.  This allows more than one resource to bind to a router and allows the resources to come and go without taking down the application.  The dependency on <strong>IRouterProvider</strong> is optional and if declared should be dynamic with a cardinality of 0..1 and bind functions <strong>(un)bindDefaultRouterProvider()</strong>.  The default router is asked to handle the URI routing when none of the resources attached to the router can handle the URI.  The default router will make more sense when I discuss filters below.</p>
<p>When an application contains multiple routers, a target filter must be applied to the <strong>IResourceProvider</strong> services so that the resources are bound to the correct router.  Since there can be many resources attached to a router, and each resource has a unique <strong>component.name</strong>, it&#8217;s not practical to use the <strong>component.name</strong> as a filter.  I recommend giving each resource a property with a common value that is unique to a router.  For example, if a resource has the property: <strong>type = public</strong>, then the router provider can bind to resources with the target <strong>(type = public)</strong>.  For the case of multiple applications, you may want to create a property that identifies the application such as: <strong>app = app1</strong>.  The binding target is an LDAP filter, so you can combine both the app and type properties: <strong>(&amp;(app = app1)(type = public))</strong>.  Here is an example of declaring two routers for two different applications:</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.restlet.examples.app.router1&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.restlet.RouterProvider&quot;/&gt;
   &lt;service&gt;
      &lt;provide interface=&quot;org.eclipselabs.restlet.IRouterProvider&quot;/&gt;
   &lt;/service&gt;
   &lt;reference bind=&quot;bindResourceProvider&quot; cardinality=&quot;1..n&quot; interface=&quot;org.eclipselabs.restlet.IResourceProvider&quot; name=&quot;IResourceProvider&quot; policy=&quot;dynamic&quot; target=&quot;(app=app1)&quot; unbind=&quot;unbindResourceProvider&quot;/&gt;
&lt;/scr:component&gt;
</pre><br />
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.restlet.examples.app.router2&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.restlet.RouterProvider&quot;/&gt;
   &lt;service&gt;
      &lt;provide interface=&quot;org.eclipselabs.restlet.IRouterProvider&quot;/&gt;
   &lt;/service&gt;
   &lt;reference bind=&quot;bindResourceProvider&quot; cardinality=&quot;1..n&quot; interface=&quot;org.eclipselabs.restlet.IResourceProvider&quot; name=&quot;IResourceProvider&quot; policy=&quot;dynamic&quot; target=&quot;(app=app2)&quot; unbind=&quot;unbindResourceProvider&quot;/&gt;
&lt;/scr:component&gt;
</pre></p>
<h2>Resources</h2>
<p>Resources are where you define exactly how an external client interacts with your application by responding to HTTP GET, PUT, POST, and DELETE requests.  You must create two classes for every logical resource your application provides: the resource class itself extending <strong>ServerResource</strong> from the Restlet framework, and a resource provider extending <strong>ResourceProvider</strong> from the Restlet Extension for OSGi Environments framework.  A resource is created by declaring an OSGi service component of the type you extended from <strong>ResourceProvider</strong> which provides the service <strong>IResourceProvider</strong>.  The <strong>ResourceProvider</strong> does not require dependencies on any other services, but does require a property named <strong>paths</strong> which is a string array of paths relative to the application alias.  The resource is registered with the router for each path declared in the <strong>paths</strong> property.  Note that the PDE component definition editor does not support array properties, so you will have to switch to the Source tab to create the <strong>paths</strong> property.  It is necessary to extend <strong>ResourceProvider</strong> to provide the classloading &#8220;glue&#8221; between Restlet and OSGi.  Your resource provider should override <strong>Finder createFinder(Context context)</strong> and return an instance of a new <strong>Finder</strong> passing in the <strong>Context</strong> and the class of your resource.</p>
<p>Here is an example of two resources that respond to <a href="http://localhost:8080/hello">http://localhost:8080/hello</a> and <a href="http://localhost:8080/example">http://localhost:8080/example</a>:</p>
<p><pre class="brush: java;">
package org.eclipselabs.restlet.examples.app;

import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;

public class HelloResource extends ServerResource
{
  @Get(&quot;txt&quot;)
  public String sayHello()
  {
    return &quot;Hello RESTful World&quot;;
  }
}
</pre><br />
<pre class="brush: java;">
import org.eclipselabs.restlet.ResourceProvider;
import org.restlet.Context;
import org.restlet.resource.Finder;

public class HelloResourceProvider extends ResourceProvider
{
  @Override
  protected Finder createFinder(Context context)
  {
    return new Finder(context, HelloResource.class);
  }
}
</pre><br />
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.restlet.examples.app.hello&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.restlet.examples.app.HelloResourceProvider&quot;/&gt;
   &lt;service&gt;
      &lt;provide interface=&quot;org.eclipselabs.restlet.IResourceProvider&quot;/&gt;
   &lt;/service&gt;
   &lt;property name=&quot;paths&quot; type=&quot;String&quot;&gt;
     /hello
   &lt;/property&gt;
&lt;/scr:component&gt;
</pre><br />
<pre class="brush: java;">
package org.eclipselabs.restlet.examples.resource;

import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;

public class ExampleResource extends ServerResource
{
  @Get
  @Override
  public String toString()
  {
    return &quot;Example&quot;;
  }
}
</pre><br />
<pre class="brush: java;">
package org.eclipselabs.restlet.examples.resource;

import org.eclipselabs.restlet.ResourceProvider;
import org.restlet.Context;
import org.restlet.resource.Finder;

public class ExampleResourceProvider extends ResourceProvider
{
  @Override
  protected Finder createFinder(Context context)
  {
    return new Finder(context, ExampleResource.class);
  }
}
</pre><br />
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.restlet.examples.resource&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.restlet.examples.resource.ExampleResourceProvider&quot;/&gt;
   &lt;service&gt;
      &lt;provide interface=&quot;org.eclipselabs.restlet.IResourceProvider&quot;/&gt;
   &lt;/service&gt;
   &lt;property name=&quot;paths&quot; type=&quot;String&quot;&gt;
   	/example
   &lt;/property&gt;
&lt;/scr:component&gt;
</pre></p>
<h2>Filters</h2>
<p>Filters, just as the name implies, provide a mechanism for filtering a request as it is routed to the resource.  The typical use-case for a filter is to protect resources from unauthorized access.  Filters are created similar to resources by extending both <strong>Filter</strong> and <strong>FilterProvider</strong>.  A filter is created by declaring an OSGi service component of the type you extended from <strong>FilterProvider</strong> which provides the service <strong>IFilterProvider</strong>.   The FilterProvider does not require dependencies on any other services.  Your filter provider should override <strong>Filter createFilter(Context context)</strong> and return an instance of a new <strong>Filter</strong> passing in the <strong>Context.</strong></p>
<p>Filters can be wired to routers, resources, and other filters.  The wiring is done by placing a service dependency on <strong>IFilterProvider</strong> in the component being filtered.  Notice that <strong>RouterProvider</strong>, <strong>ResourceProvider</strong> and <strong>FilterProvider</strong> all extend from <strong>RestletProvider</strong> which has a <strong>bindFilterProvider()</strong> function.  When declaring filters, you will probably want to use the <strong>component.name</strong> property as a target.  Here is an example of an authentication and authorization filter:</p>
<p><pre class="brush: java;">
package org.eclipselabs.restlet.examples.security;

import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.Cookie;
import org.restlet.security.Authenticator;
import org.restlet.security.User;

public class SessionAuthenticator extends Authenticator
{
  public SessionAuthenticator(Context context)
  {
    super(context, false, new SessionEnroller());
  }

  @Override
  public boolean authenticate(Request request, Response response)
  {
    Cookie sessionCookie = request.getCookies().getFirst(&quot;session&quot;);
    Account account = AccountManager.getInstance().getAccount(sessionCookie.getSecond());

    if(account != null)
    {
      User user = new User(account.getCredential().getId(), account.getID());
      request.getClientInfo().setUser(user);
      return true;
    }

    return false;
  }
}
</pre><br />
<pre class="brush: java;">
package org.eclipselabs.restlet.examples.security.providers;

import org.eclipselabs.restlet.components.FilterProvider;
import org.restlet.Context;
import org.restlet.routing.Filter;

import org.eclipselabs.restlet.examples.security.SessionAuthenticator;

public class SessionAuthenticationFilterProvider extends FilterProvider
{
  @Override
  protected Filter createFilter(Context context)
  {
    return new SessionAuthenticator(context);
  }
}
</pre><br />
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.restlet.examples.authentication&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.restlet.examples.security.SessionAuthenticationFilterProvider&quot;/&gt;
   &lt;service&gt;
      &lt;provide interface=&quot;org.eclipselabs.restlet.providers.IFilterProvider&quot;/&gt;
   &lt;/service&gt;
&lt;/scr:component&gt;
</pre><br />
<pre class="brush: java;">
package org.eclipselabs.restlet.examples.security;

import org.restlet.Request;
import org.restlet.Response;
import org.restlet.security.Authorizer;
import org.restlet.security.Role;

public class SessionAuthorizer extends Authorizer
{
  @Override
  protected boolean authorize(Request request, Response response)
  {
    String accountID = request.getOriginalRef().getSegments().get(2);
    return accountID != null &amp;&amp; accountID.equals(new String(request.getClientInfo().getUser().getSecret()));
  }
}
</pre><br />
<pre class="brush: java;">
package org.eclipselabs.restlet.examples.security.providers;

import org.eclipselabs.restlet.components.FilterProvider;
import org.restlet.Context;
import org.restlet.routing.Filter;

import org.eclipselabs.restlet.examples.security.SessionAuthorizer;

public class SessionAuthorizerFilterProvider extends FilterProvider
{
  @Override
  protected Filter createFilter(Context context)
  {
    return new SessionAuthorizer();
  }
}
</pre><br />
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; name=&quot;org.eclipselabs.restlet.examples.authorization&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.restlet.examples.security.providers.SessionAuthorizerFilterProvider&quot;/&gt;
   &lt;reference bind=&quot;bindFilterProvider&quot; cardinality=&quot;1..1&quot; interface=&quot;org.eclipselabs.restlet.providers.IFilterProvider&quot; name=&quot;IFilterProvider&quot; policy=&quot;static&quot; target=&quot;(component.name=org.eclipselabs.restlet.examples.authentication)&quot; unbind=&quot;unbindFilterProvider&quot;/&gt;
   &lt;service&gt;
      &lt;provide interface=&quot;org.eclipselabs.restlet.providers.IFilterProvider&quot;/&gt;
   &lt;/service&gt;
&lt;/scr:component&gt;
</pre></p>
<h2>Service Dependency Injection</h2>
<p>The Restlet Extensions for OSGi Environments framework provides support for dependency injection into your resources.  If your resource extends <strong>InjectedServerResource</strong> and your resource provider creates an instance of <strong>InjectedFinder</strong>, you may then use <strong>@Inject</strong> in your resource to obtain references to other services such as the OSGi <strong>LogService</strong>.  Here is an example of creating a resource that uses dependency injection with the OSGi <strong>LogService</strong>.</p>
<p><pre class="brush: java;">
package org.eclipselabs.restlet.examples.resources;

import javax.inject.Inject;

import org.eclipselabs.restlet.di.eclipse.InjectedServerResource;
import org.osgi.service.log.LogService;

public class MyServerResource extends InjectedServerResource
{
  protected void log(int level, String message)
  {
    log(level, message, null);
  }

  protected void log(int level, String message, Throwable exception)
  {
    LogService logService = this.logService;

    if (logService != null)
      logService.log(level, message, exception);
  }

  @Inject
  private LogService logService;
}
</pre></p>
<h2>References</h2>
<ol>
<li><a href="http://www.restlet.org/">Restlet</a> &#8211; RESTful web framework</li>
<li><a href="http://code.google.com/a/eclipselabs.org/p/restlet-integration-with-equinox/">Restlet Extension for OSGi Environments </a> &#8211; Restlet integration with OSGi</li>
<li><a href="http://www.manning.com/louvel/">Restlet in Action</a> &#8211; Book on Restlet</li>
<li><a href="http://bryanhunt.wordpress.com/2010/05/14/osgi-as-a-web-application-server/">OSGi as a Web Application Server</a> &#8211; Blog post on setting up OSGi as a web application server</li>
</ol>
<p><b>Update Sept 28, 2011:</b> Changed the project name to Restlet Extension for OSGi Environments and updated link to GitHub.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/609/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/609/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/609/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/609/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/bryanhunt.wordpress.com/609/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/bryanhunt.wordpress.com/609/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/bryanhunt.wordpress.com/609/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/bryanhunt.wordpress.com/609/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/609/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/609/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/609/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/609/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/609/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/609/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=609&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2011/06/30/osgi-at-rest/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2011/06/application.png" medium="image">
			<media:title type="html">Application.png</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2011/06/serviceinterfaces1.png" medium="image">
			<media:title type="html">ServiceInterfaces.png</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2011/06/servicecomponents.png" medium="image">
			<media:title type="html">ServiceComponents.png</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2011/06/edit-target-definition-1.jpg" medium="image">
			<media:title type="html">Edit Target Definition-1.jpg</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2011/06/run-configurations-3.jpg" medium="image">
			<media:title type="html">Run Configurations-3.jpg</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2011/06/run-configurations-2.jpg" medium="image">
			<media:title type="html">Run Configurations-2.jpg</media:title>
		</media:content>
	</item>
		<item>
		<title>MongoEMF 0.3.2 Released</title>
		<link>http://bryanhunt.wordpress.com/2011/05/30/mongoemf-0-3-2-released/</link>
		<comments>http://bryanhunt.wordpress.com/2011/05/30/mongoemf-0-3-2-released/#comments</comments>
		<pubDate>Mon, 30 May 2011 19:24:53 +0000</pubDate>
		<dc:creator>Bryan Hunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">https://bryanhunt.wordpress.com/?p=562</guid>
		<description><![CDATA[I have released MongoEMF 0.3.2.  This build adds support for storing OSGi log entries to MongoDB, and includes bug fixes for queries against dates and defaults values. OSGi Logging in MongoDB I&#8217;ve added a new bundle, org.eclispelabe.mongo.emf.log, that will convert an OSGi LogEntry into an EMF object and store it into MongoDB.  Storing your OSGi log entries [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=562&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I have released <a href="http://code.google.com/a/eclipselabs.org/p/mongo-emf/">MongoEMF</a> 0.3.2.  This build adds support for storing OSGi log entries to MongoDB, and includes bug fixes for queries against dates and defaults values.</p>
<h2>OSGi Logging in MongoDB</h2>
<p>I&#8217;ve added a new bundle, <strong>org.eclispelabe.mongo.emf.log</strong>, that will convert an OSGi <strong>LogEntry</strong> into an EMF object and store it into MongoDB.  Storing your OSGi log entries into MongoDB is a simple matter of configuring the <strong>ILogService</strong> (declarative service) with the OSGI ConfigurationAdmin service.  I have created a <strong>LogServiceConfigurator</strong> helper class if you&#8217;d rather not deal with ConfigurationAdmin.  The log service requires two properties:</p>
<ul>
<li><strong>baseURI</strong></li>
<li><strong>logLevel</strong></li>
</ul>
<p>The <strong>baseURI</strong> must be a valid MongoEMF collection URI of the form <strong>mongo://host/database/collection/ -</strong> for example: <strong>mongo://localhost/data/logs/</strong>.  The <strong>logLevel</strong> is set to one of the logging levels defined in the OSGi <strong>LogService</strong>: <strong>LOG_ERROR</strong>, <strong>LOG_WARNING</strong>, <strong>LOG_INFO</strong>, and <strong>LOG_DEBUG</strong>.</p>
<p>Here is an example configuration using the <strong>LogServiceConfigurator</strong> for logging errors and warnings:</p>
<p><pre class="brush: java;"> 
LogServiceConfigurator.configureLogService(URI.createURI(&quot;mongo://localhost/junit/logs/&quot;), LogService.LOG_WARNING);
</pre></p>
<h2>Querying Default Values</h2>
<p>The standard EMF serializations: XML, XMI, and Binary do not store default values for attributes.  The Mongo EMF binding was written this way as well to maintain consistency, but has the side effect of not being able to query objects based on attributes set to their default value.  To solve this problem, we&#8217;ve added the option:</p>
<p><strong>MongoDBURIHandlerImpl.OPTION_SERIALIZE_DEFAULT_ATTRIBUTE_VALUES</strong></p>
<p>Setting this option to <strong>Boolean.TRUE</strong> when saving your object to MongoDB will force attributes with default values to be persisted to MongoDB.  Here is a simple example:</p>
<p><pre class="brush: java;">
Resource resource = resourceSet.createResource(uri);
resource.getContents().add(object);
HashMap&lt;String, Object&gt; options = new HashMap&lt;String, Object&gt;(1);
options.put(MongoDBURIHandlerImpl.OPTION_SERIALIZE_DEFAULT_ATTRIBUTE_VALUES, Boolean.TRUE);

try
{
  resource.save(options);
}
catch(IOException w)
{
  e.printStackTrace();
}
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/562/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/562/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/562/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/562/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/bryanhunt.wordpress.com/562/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/bryanhunt.wordpress.com/562/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/bryanhunt.wordpress.com/562/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/bryanhunt.wordpress.com/562/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/562/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/562/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/562/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/562/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/562/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/562/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=562&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2011/05/30/mongoemf-0-3-2-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>
	</item>
		<item>
		<title>Introducing eTrack</title>
		<link>http://bryanhunt.wordpress.com/2011/03/18/introducing-etrack/</link>
		<comments>http://bryanhunt.wordpress.com/2011/03/18/introducing-etrack/#comments</comments>
		<pubDate>Sat, 19 Mar 2011 02:24:50 +0000</pubDate>
		<dc:creator>Bryan Hunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://bryanhunt.wordpress.com/?p=548</guid>
		<description><![CDATA[eTrack is an application that manages tasks. This project is meant to be a comprehensive tutorial that demonstrates the use of several Eclipse technologies, and current best practices for architecture, design, development, testing, build, and deployment.  I would like the architecture to be as open as possible to accommodate different implementations of the various components [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=548&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/a/eclipselabs.org/p/etrack/" target="_blank">eTrack</a> is an application that manages tasks.  This project is meant to be a comprehensive tutorial that demonstrates the use of several <a href="http://www.eclipse.org/" target="_blank">Eclipse</a> technologies, and current best practices for architecture, design, development, testing, build, and deployment.  I would like the architecture to be as open as possible to accommodate different implementations of the various components of the application.  There will, however, be a couple of things set in stone.  The application will be based on <a href="http://www.osgi.org/Main/HomePage" target="_blank">OSGi</a>, have a <a href="http://en.wikipedia.org/wiki/RESTful" target="_blank">RESTful</a> client / server architecture, and will use <a href="http://en.wikipedia.org/wiki/Http">HTTP</a> to communicate between client and server.</p>
<p>To get started, the initial implementation will use <a href="http://www.eclipse.org/modeling/emf/" target="_blank">EMF</a> for the domain model, <a href="http://www.mongodb.org/" target="_blank">MongoDB</a> for the backing store, <a href="http://www.restlet.org/" target="_blank">Restlet</a> for the RESTful web services, <a href="http://www.eclipse.org/jetty/" target="_blank">Jetty</a> for the web container, and simple HTML web pages for the client.  It would also be nice, at some point, to have a <a href="http://code.google.com/webtoolkit/" target="_blank">GWT</a> client, a <a href="http://www.sproutcore.com/" target="_blank">SproutCore</a> client, and <a href="http://www.eclipse.org/mylyn/" target="_blank">Mylyn</a> integration.</p>
<p>The project is hosted at <a href="http://code.google.com/a/eclipselabs.org/hosting/" target="_blank">EclipseLabs</a> and the place to start is:</p>
<p style="text-align:center;"><a href="http://code.google.com/a/eclipselabs.org/p/etrack/" target="_blank">http://code.google.com/a/eclipselabs.org/p/etrack/ </a></p>
<p>I would like to use <a href="http://code.google.com/p/gerrit/" target="_blank">Gerrit</a> for source control, and <a href="http://www.eclipse.org/tycho/" target="_blank">Tycho</a> and <a href="http://jenkins-ci.org/" target="_blank">Jenkins</a> for build, but I&#8217;m currently not aware of any free hosting for these services.  If I can&#8217;t find free hosting, I might consider hosting on my home server and mirroring the source on <a href="https://github.com/" target="_blank">GitHub</a> for public access.  Issue tracking will initially be done on the EclipseLabs <a href="http://code.google.com/a/eclipselabs.org/p/etrack/issues/list" target="_blank">Issues</a> page until we can &#8220;eat our own cooking&#8221;.</p>
<p>Here is a first attempt at a domain model (I&#8217;ve taken a little liberty with the UML notation in that solid diamonds denote containment within the same resource while open diamonds denote cross-document containment):</p>
<p><img style="display:block;margin-left:auto;margin-right:auto;" title="Domain.png" src="http://bryanhunt.files.wordpress.com/2011/03/domain.png?w=595&#038;h=550" border="0" alt="Domain" width="595" height="550" />I hope to start working on the implementation at <a href="http://www.eclipsecon.org/2011/" target="_blank">EclipseCon</a>.  If you are interested in participating, please comment below describing what you would like to work on, or find me at EclipseCon and I&#8217;ll be happy to discuss this with you.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/bryanhunt.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/bryanhunt.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/bryanhunt.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/bryanhunt.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/548/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/548/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/548/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=548&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2011/03/18/introducing-etrack/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2011/03/domain.png" medium="image">
			<media:title type="html">Domain.png</media:title>
		</media:content>
	</item>
		<item>
		<title>Mongo EMF</title>
		<link>http://bryanhunt.wordpress.com/2011/03/15/mongo-emf/</link>
		<comments>http://bryanhunt.wordpress.com/2011/03/15/mongo-emf/#comments</comments>
		<pubDate>Tue, 15 Mar 2011 14:00:10 +0000</pubDate>
		<dc:creator>Bryan Hunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://bryanhunt.wordpress.com/?p=473</guid>
		<description><![CDATA[If you have worked with the Eclipse Modeling Framework (EMF), then you already know how easy it is to create domain models.  If you haven&#8217;t, then I highly recommend giving it a try.  I develop all of my domain models using EMF.  EMF has built-in support for persisting models to files in XMI, XML, and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=473&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>If you have worked with the <a href="http://www.eclipse.org/modeling/emf/" target="_blank">Eclipse Modeling Framework</a> (EMF), then you already know how easy it is to create <a href="http://en.wikipedia.org/wiki/Domain_model" target="_blank">domain models</a>.  If you haven&#8217;t, then I highly recommend giving it a try.  I develop all of my domain models using EMF.  EMF has built-in support for persisting models to files in XMI, XML, and binary format.  The persistence API is highly extensible, and I&#8217;ve recently been working with <a href="http://ed-merks.blogspot.com/" target="_blank">Ed Merks</a> on some code that persists EMF models to <a href="http://www.mongodb.org/" target="_blank">MongoDB</a>.  The project is called <a href="http://code.google.com/a/eclipselabs.org/p/mongo-emf/" target="_blank"><strong>mongo-emf</strong></a> and is hosted on <a href="http://code.google.com/a/eclipselabs.org/hosting/" target="_blank">EclipseLabs</a>. <a href="http://code.google.com/a/eclipselabs.org/p/mongo-emf/downloads/list" target="_blank">Version 0.3.1</a> is being used in a real application and is fairly stable.  This version supports all of the basic <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete" target="_blank">CRUD</a> functions along with a basic query language for finding objects.  This blog post will cover the CRUD functions while Ed Merks will have a blog post soon on using the query model.</p>
<p>One feature that I hope you will find attractive is that there are <span style="color:#ff0000;"><strong>no annotations or XML configuration files required</strong></span>.</p>
<p>If you are attending <a href="http://www.eclipsecon.org/2011/" target="_blank">EclipseCon 2011</a>, I will be giving a talk titled <a href="http://www.eclipsecon.org/2011/sessions/?page=sessions&amp;id=2079" target="_blank">Hardware Developer&#8217;s Workbench: a Case Study</a> in which I will discuss how we are using this technology in our application.</p>
<h2>Quickstart</h2>
<p>Here&#8217;s an example on how easy it is to insert an object into MongoDB using EMF.</p>
<p><pre class="brush: java;">
ResourceSet resourceSet = new ResourceSetImpl();
EList uriHandlers = resourceSet.getURIConverter().getURIHandlers();
uriHandlers.add(0, new MongoDBURIHandlerImpl());

Person user = ModelFactory.eINSTANCE.createMyObject()
user.setName(&quot;Test User&quot;);
user.setEmail(&quot;test@example.org&quot;);

Resource resource = resourceSet.createResource(URI.createURI(&quot;mongo://localhost/app/users/&quot;));
resource.getContents().add(user);

try
{
  resource.save(null);
}
catch(IOException e)
{
  e.printStackTrace();
}
</pre></p>
<p>Let&#8217;s look at the code above in detail.  <strong>Line 1</strong> is the normal way you create an EMF <em>ResourceSet</em>.  <strong>Lines 2 and 3</strong> hook the MongoDB URI handler that interfaces EMF to MongoDB to the <em>ResourceSet</em>. <strong>Lines 5 &#8211; 7</strong> set up the model instance. <strong>Line 9</strong> creates the EMF resource using a URI that has a specific pattern explained below.  <strong>Line 10</strong> simply adds the model instance to the EMF <em>Resource</em>.  <strong>Line 14</strong> saves and inserts the model instance to MongoDB.</p>
<p><span style="color:#ff0000;"><strong>By adding just two additional lines of code and using a <em>mongo</em> URI, you are able to utilize the full power of EMF with your objects persisted in MongoDB.</strong></span></p>
<h2>Mongo EMF URIs</h2>
<p>All EMF resources are identified by a URI.  The URI you use when persisting models to MongoDB must have the form:</p>
<p><strong>mongo://&lt;host&gt;/&lt;database&gt;/&lt;collection&gt;/&lt;id&gt;</strong></p>
<ul>
<li><strong>host </strong>is the hostname of the server running MongoDB (the port may be specified if not default)</li>
<li><strong>database</strong> is the name of the MongoDB database to use</li>
<li><strong>collection</strong> is the name of the MongoDB collection</li>
<li><strong>id</strong> is the unique identifier of the object in MongoDB (optional on create / insert)</li>
</ul>
<p><strong>The URI path must have exactly three segments.  Anything else will cause an <em>IOException</em> on a load() or save().</strong></p>
<h2>Create</h2>
<p>When inserting a new object into MongoDB, the <strong>id</strong> segment of the URI is optional and typically the empty string.  By default, MongoDB assigns a unique ID to an object when it is inserted into the database.  In this mode, the URI of the EMF resource is automatically updated to include the MongoDB generated ID value.  Going back to the example in the Quickstart, the resource URI will be similar to <strong>mongo://localhost/app/users/4d6dc268b03b0db29961472c</strong> after the call to save() on <strong>line 14</strong>.</p>
<p>It is also possible for the client to generate the ID and persist the object to MongoDB using that ID.  The ID can be any string value that is unique within the MongoDB collection.  The quickstart example above would be modified as follows:</p>
<p><pre class="brush: java;">
Resource resource = resourceSet.createResource(URI.createURI(&quot;mongo://localhost/app/users/1&quot;));
resource.getContents().add(user);

try
{
  resource.save(null);
}
catch(IOException e)
{
  e.printStackTrace();
}
</pre></p>
<h2>Retrieve</h2>
<p>To retrieve an object from MongoDB, you load an EMF <em>Resource</em> using the unique URI for the object.</p>
<p><pre class="brush: java;">
ResourceSet resourceSet = new ResourceSetImpl();
EList uriHandlers = resourceSet.getURIConverter().getURIHandlers();
uriHandlers.add(0, new MongoDBURIHandlerImpl());

Resource resource = resourceSet.getResource(URI.createURI(&quot;mongo://localhost/app/users/4d6dc268b03b0db29961472c&quot;), true);
Person user = (Person) resource.getContents().get(0);
</pre></p>
<h2>Update</h2>
<p>To update an object in MongoDB, you simply save the <em>Resource</em> containing the object.</p>
<p><pre class="brush: java;">
user.setEmail(&quot;mongo-emf@example.org);

try
{
  user.eResource().save(null);
}
catch(IOException e)
{
  e.printStackTrace();
}
</pre></p>
<h2>Delete</h2>
<p>To delete an object in MongoDB, you call delete() on the <em>Resource</em> containing the object.</p>
<p><pre class="brush: java;">
try
{
  user.eResource().delete(null);
}
catch(IOException e)
{
  e.printStackTrace();
}
</pre></p>
<h2>Collections</h2>
<p>A collection of objects may be stored (contained) within a parent object, or stored as individual objects in a MongoDB collection.  For objects that are contained as part of a parent object, when you operate on (load, save) the parent object, you operate on (load, save) the entire collection.  When a collection is stored as individual objects in a MongoDB collection, each object is contained its own EMF <em>Resource</em> and must be managed individually by the client.  If you allow MongoDB to generate the object ID, you may bulk insert a collection of objects in a single save() call.  The resource is modified to contain a single <em>Result</em> result object with a proxy to each of the inserted objects.  You may iterate over the proxies to load each object into its own <em>Resource</em>.  Here is an example of bulk insert:</p>
<p><pre class="brush: java;">
ResourceSet resourceSet = new ResourceSetImpl();
EList uriHandlers = resourceSet.getURIConverter().getURIHandlers();
uriHandlers.add(0, new MongoDBURIHandlerImpl());

Resource resource = resourceSet.createResource(URI.createURI(&quot;mongo://localhost/app/users/&quot;));

for(int i = 0; i &lt; 10; i++)
{
  Person user = ModelFactory.eINSTANCE.createMyObject()
  user.setName(&quot;User &quot; + 1);
  user.setEmail(&quot;user&quot; + i + &quot;@example.org&quot;);
  resource.getContents().add(user);
}

try
{
  resource.save(null);
}
catch(IOException e)
{
  e.printStackTrace();
}

Result result = resource.getContents().get(0);

for(EObject eObject : result.getValues()
{
  Person user = (Person) eObject;
  System.out.println(&quot;Person &quot; + user.getName() + &quot; has URI: &quot; + user.eResource.getURI());
}
</pre></p>
<h2>EMF References</h2>
<p>The way in which EMF references are persisted in MongoDB depends on the settings you specified when you created your EMF Ecore and Generator models. Two Ecore settings that affect persistence are: Containment, and Resolve Proxies.  The Generator setting that affects persistence is: Containment Proxies.  There are three types of references to consider: non-containment, containment, and bi-directional cross-document containment.</p>
<h4>Non-containment References</h4>
<p>A non-containment reference is modeled by setting Containment = false in the Ecore model.  A non-containment reference can be to any other object in the database, a file, or on some other server.  The target object may be contained by the referencing object, or could be in some other resource.  Non-containment references are always persisted as a proxy.  If the target object is in a separate resource from the referencing object, the target object must be persisted, on creation, before the object with the reference so that the proxy URI contains the ID of the target object.</p>
<h4>Containment References</h4>
<p>A containment reference is modeled by setting Containment = true in the Ecore model.  A containment reference is persisted as a nested object in the same MongoDB document as the referencing object if Resolve Proxies = false in the Ecore model or Containment Proxies = false in the Generator model.  If Resolve Proxies = true in the Ecore model and Containment Proxies = true in the Generator model, the reference will be persisted as a proxy if the target object is contained in its own <em>Resource</em> (cross-document containment).  If the target object is not contained in its own <em>Resource</em>, it will be persisted as a nested object of the referencing object.</p>
<h4>Bi-directional Cross-document Containment References</h4>
<p>Bi-directional cross-document containment references need special consideration when it comes to saving the objects.  For the proxies to be properly persisted, three calls to save() must be made on creation.  One of the two objects must be saved twice.  The other object must be saved once between the two saves to the other object.  For example, consider a bi-directional reference between a Person and an Address, the code to save the two objects would be as follows:</p>
<p><pre class="brush: java;">
user.setAddress(address);

try
{
  address.save(null);
  user.save(null);
  address.save(null);
}
catch(IOException e)
{
  e.printStackTrace();
}
</pre></p>
<h2>Modeling Restrictions</h2>
<p>There is one minor restriction that you must follow when creating your EMF Ecore model.  The following keys are reserved for internal use and may not be used as attribute or reference names:</p>
<ul>
<li>_id</li>
<li>_eId</li>
<li>_eClass</li>
<li>_timeStamp</li>
<li>_eProxyURI</li>
</ul>
<h2>Mongo EMF Project Bundles</h2>
<p>The project consists of several core bundles, an example project, a JUnit test bundle, and a JUnit test utility bundle.</p>
<ul>
<li><strong>org.eclipselabs.emf.query</strong> &#8211; this bundle contains the model query support</li>
<li><strong>org.eclipselabs.mongo</strong> &#8211; this bundle contains an IMongoDB OSGi service that provides basic connectivity to a MongoDB database</li>
<li><strong>org.eclipselabs.mongo.emf</strong> &#8211; this bundle contains the MongoDBURIHandlerImpl that provides EMF persistence to MongoDB</li>
<li><strong>org.eclipselabs.mongo.freemarker</strong> &#8211; this bundle contains support for persisting <a href="http://freemarker.sourceforge.net/" target="_blank">FreeMarker</a> templates in MongoDB</li>
<li><strong>org.eclipselabs.mongo.emf.examples</strong> &#8211; this bundle contains a simple example using MongoDBURIHandlerImpl</li>
<li><strong>org.eclipselabs.mongo.emf.junit</strong> &#8211; this bundle contains the JUnit tests for the core bundles</li>
<li><strong>org.eclipselabs.mongo.junit</strong> &#8211; this bundle contains utilities for users developing their own JUnit tests</li>
</ul>
<h2>Unit Testing</h2>
<p>The org.eclipselabs.mongo.junit bundle contains two useful classes that can make writing your unit tests easier.</p>
<p><strong>MongoDatabase</strong></p>
<p>This class is a JUnit <em>@Rule</em> that will clear your MongoDB database after each test.  The rule requires the <em>BundleContext</em> and the name of the database to be passed as parameters to its constructor.  Here is an example on how to use that rule:</p>
<p><pre class="brush: java;">
	@Rule
	public MongoDatabase database = new MongoDatabase(Activator.getInstance().getContext(), &quot;junit&quot;);
</pre></p>
<p><strong>MongoUtil</strong></p>
<p>This utility class contains functions for creating a <em>ResourceSet</em>, getting one or more objects from the database, getting the ID of an object, registering the IMongoDB service with OSGi, and comparing two EObjects.  This class has extensive JavaDoc comments that explain the usage of each function.</p>
<h2>Launch Configurations</h2>
<p>Your launch configuration must include the following bundles and their dependencies:</p>
<ul>
<li><strong>org.eclipselabs.emf.query</strong></li>
<li><strong>org.eclipselabs.mongo</strong></li>
<li><strong>org.eclipselabs.mongo.emf</strong></li>
<li><strong>org.eclipse.equinox.ds</strong> (or equivalent)</li>
</ul>
<p>The <strong>org.eclipselabs.mongo</strong> bundle uses OSGi declarative services to register the <em>IMongoDB</em> service.  This service is used by <em>MongoDBURIHandlerImpl</em> to connect to MongoDB.</p>
<h2>References</h2>
<ol>
<li><a href="http://www.eclipse.org/modeling/emf/" target="_blank">Eclipse Modeling Framework</a></li>
<li><a href="http://www.mongodb.org/" target="_blank">MongoDB</a></li>
<li><a href="http://code.google.com/a/eclipselabs.org/p/mongo-emf/" target="_blank">EclipseLabs mongo-emf project</a></li>
</ol>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/473/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/473/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/bryanhunt.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/bryanhunt.wordpress.com/473/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/bryanhunt.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/bryanhunt.wordpress.com/473/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/473/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/473/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/473/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/473/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=473&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2011/03/15/mongo-emf/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>
	</item>
		<item>
		<title>Rational Team Concert 3.0 on OS X</title>
		<link>http://bryanhunt.wordpress.com/2010/11/29/rational-team-concert-3-0-on-os-x/</link>
		<comments>http://bryanhunt.wordpress.com/2010/11/29/rational-team-concert-3-0-on-os-x/#comments</comments>
		<pubDate>Mon, 29 Nov 2010 14:00:10 +0000</pubDate>
		<dc:creator>Bryan Hunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://bryanhunt.wordpress.com/?p=446</guid>
		<description><![CDATA[Update 4/19/2011: The server zips are back and you no longer have to install on linux and move to OS X. Rational Team Concert 3.0 is a nice development tool built on Eclipse that runs just fine on Mac OS X even though it&#8217;s not officially supported.  This guide will help you install and configure [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=446&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>Update 4/19/2011: The server zips are back and you no longer have to install on linux and move to OS X.</strong></p>
<p>Rational Team Concert 3.0 is a nice development tool built on Eclipse that runs just fine on Mac OS X even though <strong>it&#8217;s not officially supported</strong>.  This guide will help you install and configure RTC 3.0 on OS X.  The client is very easy to install.  The server used to be easy to install, but some recent changes in the RTC builds has made it much more difficult.  Basically, you install the server on Linux, and transfer it to your OS X box.</p>
<h2>Installing RTC 3.0 Server on Linux</h2>
<p>Since the RTC Server is no longer available as a zip download, you must install the server on a supported platform such as Linux.  Once the server is installed, you can transfer the content to OS X and it will just work.</p>
<ul>
<li>Fire up a Linux box, Parallels, or VMWare (I use Parallels with Ubuntu)</li>
<li>Head over to <a href="https://jazz.net/downloads">https://j</a><a href="https://jazz.net/downloads">azz.net/downloads</a> and select Rational Team Concert</li>
<li>Select Linux x86-32/64 for your platform and click Download Rational Team Concert</li>
<li>After logging and accepting the the terms, RTC-Web-Installer-Linux-3.0.zip will be downloaded</li>
<li>Unzip the archive into a folder and run launchpad.sh</li>
<li>Uncheck Install in a shared location for multiple users</li>
<li>Click Jazz Team Server and CCM Application under Install the Server</li>
<li>The Installation Manager will start &#8211; login with your jazz.net id and password</li>
<li>Click Next</li>
<li>Agree to the license and click Next</li>
<li>Keep the default directory locations and click Next</li>
<li>Keep the default installation directory and click Next</li>
<li>Select the desired translations and click Next</li>
<li>Click Next</li>
<li>Select Not upgrading from previous product release and click Next</li>
<li>Click Install</li>
<li>After the server is installed, click Finish</li>
</ul>
<h2>Moving RTC Server to OS X</h2>
<p>Transfer the contents of the JazzTeamServer directory to OS X.  Here is the method I used:</p>
<ul>
<li>cd ~/IBM</li>
<li>zip -r jazz.zip JazzTeamServer</li>
<li>Copy jazz.zip to your OS X box (I use a Parallels shared folder)</li>
<li>unzip jazz.zip into the directory of your choice (I use /Library)</li>
<li>cd JazzTeamServer/server</li>
<li>rm -rf jre</li>
</ul>
<h2>Configuring RTC Server</h2>
<p>You configure the RTC 3.0 Server as you would for any other platform.  If you are using OS X Server and want to set up LDAP authentication, skip that configuration during the setup.  The setup wizard will not configure it correctly for OS X.  I have instructions below on how to configure the Tomcat JNDI realm by hand below.</p>
<ul>
<li>./server.startup</li>
<li>Point your web browser to <a href="https://localhost:9443/jts/setup">https://localhost:9443/jts/setup</a></li>
<li>Login id: ADMIN password: ADMIN</li>
<li>Click Next</li>
<li>Set the Public URI Root to https://&lt;hostname&gt;:9443/jts (where &lt;hostname&gt; is the hostname of your system)</li>
<li>Click Test Connection and then click Next</li>
<li>Keep the default Derby database settings and click Next</li>
<li>Set up Email Notification as desired and click Next</li>
<li>Set up your account and click Next</li>
<li>Click Register Applications and click Next</li>
<li>Keep the default URI, click Test Connection and click Next</li>
<li>Keep the default Derby configuration and click Next</li>
<li>Click Finalize Application Setup and click Next</li>
<li>Click Finish</li>
<li>(Optional) Set up LDAP for use with OS X Server
<ul>
<li>./server.shutdown</li>
<li>edit tomcat/conf/server.xml</li>
<li>Disable the database realm</li>
<li>Configure the JNDI realm as shown below</li>
<li>./server.startup</li>
</ul>
</li>
</ul>
<p><pre class="brush: xml;">
&lt;Realm className=&quot;org.apache.catalina.realm.JNDIRealm&quot;
    connectionName=&quot;&quot;
    connectionURL=&quot;ldap://&lt;hostname&gt;:389&quot;
    roleBase=&quot;cn=groups,dc=&lt;host&gt;,dc=&lt;domain&gt;,dc=com&quot;
    roleName=&quot;cn&quot;
    roleSearch=&quot;(memberUid={1})&quot;
    roleSubtree=&quot;true&quot;
    userBase=&quot;cn=users,dc=&lt;host&gt;,dc=&lt;domain&gt;,dc=com&quot;
    userSearch=&quot;(uid={0})&quot;
    userSubtree=&quot;true&quot;/&gt;
</pre></p>
<ul>
<li>Install your license as you normally would</li>
</ul>
<p>You should now have a functional server.  If you are using OS X Server, remember that the LDAP groups are case sensitive, so make sure you create a JazzUsers group and not a jazzusers group.</p>
<h2>Starting RTC Server on Boot</h2>
<p>If you would like the RTC Server automatically started when OS X boots, put the following in /Library/LaunchDaemons/com.ibm.rtc.plist</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;!DOCTYPE plist PUBLIC &quot;-//Apple Computer//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
&lt;plist version=&quot;1.0&quot;&gt;
&lt;dict&gt;
  &lt;key&gt;Label&lt;/key&gt;
  &lt;string&gt;com.ibm.rtc&lt;/string&gt;
  &lt;key&gt;OnDemand&lt;/key&gt;
  &lt;true/&gt;
  &lt;key&gt;Program&lt;/key&gt;
  &lt;string&gt;server.startup&lt;/string&gt;
  &lt;key&gt;AbandonProcessGroup&lt;/key&gt;
  &lt;true/&gt;
  &lt;key&gt;RunAtLoad&lt;/key&gt;
  &lt;true/&gt;
  &lt;key&gt;WorkingDirectory&lt;/key&gt;
  &lt;string&gt;/Library/JazzTeamServer/server&lt;/string&gt;
&lt;/dict&gt;
&lt;/plist&gt;
</pre></p>
<p>At the command prompt: <em>sudo launchctl load com.ibm.rtc.plist</em></p>
<h2>Installing RTC Client on OS X</h2>
<p>Installing the client on OS X is super simple using the P2 repository.</p>
<ul>
<li>From the All Downloads tab on jazz.net, scroll down to the section containing the zips and download the P2 Install Repository</li>
<li>unzip the downlaod</li>
<li>From the Eclipse IDE, choose Help -&gt; Install New Software &#8230;</li>
<li>Add the directory to the unzipped P2 repository</li>
<li>Check Rational Team Concert and install using the wizard</li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/446/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/446/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/bryanhunt.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/bryanhunt.wordpress.com/446/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/bryanhunt.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/bryanhunt.wordpress.com/446/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/446/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/446/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/446/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/446/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=446&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2010/11/29/rational-team-concert-3-0-on-os-x/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>
	</item>
		<item>
		<title>Configuring OSGi Services with Apache Web Console and Metatype</title>
		<link>http://bryanhunt.wordpress.com/2010/07/07/configuring-osgi-services-with-apache-web-console-and-metatype/</link>
		<comments>http://bryanhunt.wordpress.com/2010/07/07/configuring-osgi-services-with-apache-web-console-and-metatype/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 14:30:41 +0000</pubDate>
		<dc:creator>Bryan Hunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://bryanhunt.wordpress.com/?p=352</guid>
		<description><![CDATA[Introduction OSGi services can be easily configured using the ConfigurationAdmin service.  If you add metadata to your services, they can be configured with a nice user interface such as the Apache Web Console.  This can be a very nice way to configure remote servers.  This tutorial will walk you through the steps to create the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=352&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>OSGi services can be easily configured using the <a href="http://www.osgi.org/javadoc/r4v42/org/osgi/service/cm/ConfigurationAdmin.html" target="_blank">ConfigurationAdmin</a> service.  If you add metadata to your services, they can be configured with a nice user interface such as the <a href="http://felix.apache.org/site/apache-felix-web-console.html" target="_blank">Apache Web Console</a>.  This can be a very nice way to configure remote servers.  This tutorial will walk you through the steps to create the metadata, set up the web console, and configure your services.  Here&#8217;s an example of the end result where an OSGi service is configured with the Apache Web Console:</p>
<p><a href="http://bryanhunt.files.wordpress.com/2010/07/apache-felix-web-console-configuration.png"><img class="aligncenter size-full wp-image-366" title="Apache Felix Web Console - Configuration" src="http://bryanhunt.files.wordpress.com/2010/07/apache-felix-web-console-configuration.png" alt="" width="1024" height="649" /></a></p>
<h2>Metatype</h2>
<p>Administrative tools such as the Apache Web Console can provide a nice form based user interface for configuring your OSGi services only if you provide sufficient metadata for your service properties.  Using this metadata, the Apache Web Console knows how to display, for example, a label for each property, display a text box for simple string data, and display a combo box for choosing a value from a list.  This metadata is defined using the <a href="http://www.osgi.org/javadoc/r4v42/org/osgi/service/metatype/package-summary.html" target="_blank">OSGi Metatype Service</a>.</p>
<p>There are two ways to provide metatype data: an XML file, or by registering a <a href="http://www.osgi.org/javadoc/r4v42/org/osgi/service/metatype/MetaTypeProvider.html" target="_blank">MetaTypeProvider</a> as an OSGi service.  Specifying your metatype data in an XML file works well as long as your data is static, and you are not using declarative services.  If you need to specify dynamic metatype data such as the values for options, you must register a provider.  Metatype will not &#8211; yet &#8211; work with declarative services.  I&#8217;ll discuss this in detail in the section below on declarative services.  The metatype service allows you to specify the following datatypes for configuring your services:</p>
<ul>
<li>boolean</li>
<li>byte</li>
<li>char</li>
<li>double</li>
<li>float</li>
<li>int</li>
<li>long</li>
<li>short</li>
<li>String</li>
</ul>
<p>You can also specify a cardinality for arrays, default values, and label/value pairs for choices.</p>
<h4>Metatype XML File</h4>
<p>To specify your metatype data in an XML file, you must create an OSGI-INF/metatype/ directory in your bundle.  In this directory, you may place one or more XML files adhering to the metatype XML schema.  The file contains a number of object class definitions each with a number of attribute definitions.  You then specify a designate to tie an object class definition to a service PID.  Here is a simple example of a metatype XML file that allows a service to be configured with a property called <strong>choice</strong> with the possible values: <strong>normal</strong> and <strong>priority</strong>.</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;MetaData xmlns=&quot;http://www.osgi.org/xmlns/metatype/v1.0.0&quot;&gt;
	&lt;OCD description=&quot;Example Managed Service&quot; name=&quot;Managed Service&quot; id=&quot;ocd&quot;&gt;
		&lt;AD name=&quot;Example Choice Attribute&quot; id=&quot;choice&quot; required=&quot;true&quot; type=&quot;String&quot; default=&quot;normal&quot;&gt;
			&lt;Option label=&quot;Normal&quot; value=&quot;normal&quot; /&gt;
			&lt;Option label=&quot;Priority&quot; value=&quot;priority&quot; /&gt;
		&lt;/AD&gt;
	&lt;/OCD&gt;
	&lt;Designate pid=&quot;org.eclipselabs.metatype.examples.managedService&quot;&gt; &lt;Object ocdref=&quot;ocd&quot;/&gt;
	&lt;/Designate&gt;
&lt;/MetaData&gt;
</pre></p>
<h4>Metatype Provider</h4>
<p>To register a metatype provider, create a class that implements MetaTypeProvider and construct instances of ObjectClassDefinition and AttributeDefinition.  The provider can be registered in your bundle activator, or as a declarative service.  The metatype specification provides interfaces for the datatypes, but not implementations.  You must provide your own implementation of the interfaces, or you may use the <a href="http://www.eclipse.org/modeling/emf/" target="_blank">EMF</a> implementation I have hosted at <a href="http://code.google.com/a/eclipselabs.org/p/metatype-emf-model/" target="_blank">Eclipse Labs</a>.  Here is the source code that specifies the same configuration metadata as the XML file above using the EMF implementation.</p>
<p><pre class="brush: java;">
public class ExampleDeclarativeServiceMetatype implements MetaTypeProvider
{
	@Override
	public ObjectClassDefinition getObjectClassDefinition(String id, String locale)
	{
		ObjectClassDefinitionImpl ocd = MetatypeFactory.eINSTANCE.createObjectClassDefinitionImpl();
		ocd.setID(&quot;org.eclipselabs.metatype.examples.service&quot;);
		ocd.setName(&quot;Declarative Service&quot;);
		ocd.setDescription(&quot;Example Description&quot;);

		AttributeDefinitionImpl ad = MetatypeFactory.eINSTANCE.createAttributeDefinitionImpl();
		ad.setName(&quot;Exampel Chioce Attribute&quot;);
		ad.setDescription(&quot;Attribute Description&quot;);
		ad.setID(&quot;choice&quot;);
		ad.setType(AttributeDefinition.STRING);
		ad.setOptionLabels(new String[] {&quot;Normal&quot;, &quot;Priority&quot;});
		ad.setOptionValues(new String[] {&quot;normal&quot;, &quot;priority&quot;});
		ad.setDefaultValue(new String[] {&quot;normal&quot;});

		ocd.getAttributeDefinitions().add(ad);
		return ocd;
	}

	@Override
	public String[] getLocales()
	{
		return null;
	}
}
</pre></p>
<p>Now that you have seen how easy it is to specify your metatype data, lets write some services and configure them using the web console.  We start by setting up our target platform.</p>
<h2>Target Platform</h2>
<p>Setting up your target platform is really easy with Eclipse and PDE.  Before you configure Eclipse, you need to download the Apache Web Console (Full) <a href="http://mirror.its.uidaho.edu/pub/apache/felix/org.apache.felix.webconsole-3.1.0.jar" target="_blank">bundle</a> since they do not build P2 repositories.  As of this writing, the latest version of the web console is 3.1.0.</p>
<ol>
<li>Start up Eclipse (I&#8217;m using Helios) with a new workspace.</li>
<li>Select <strong>Preferences -&gt; Plug-in Development -&gt; TargetPlatform</strong></li>
<li>Click <strong>Add&#8230;</strong></li>
<li>Select <strong>Nothing: Start with an empty target definition</strong></li>
<li>Click <strong>Next</strong></li>
<li>Name: <strong>Equinox</strong></li>
<li>In the <strong>Locations</strong> tab, click <strong>Add&#8230;</strong></li>
<li>Choose <strong>Software Site</strong> and click <strong>Next</strong></li>
<li>Work with: <strong>Helios &#8211; http://download.eclipse.org/releases/helios</strong></li>
<li>Expand <strong>EclipseRT Target Platform Components</strong></li>
<li>Check
<ol>
<li><strong>EMF &#8211; Eclipse Modeling Framework SDK</strong></li>
<li><strong>Equinox Target Components</strong></li>
</ol>
</li>
<li>Click <strong>Finish</strong></li>
<li>Click <strong>Add&#8230;</strong></li>
<li>Choose <strong>Software Site</strong> and click <strong>Next</strong></li>
<li>Work with:<strong> http://metatype-emf-model.eclipselabs.org.codespot.com/hg/site/org.eclipselabs.metatype.site/</strong></li>
<li>Check <strong>Metatype EMF Model</strong></li>
<li>Click <strong>Finish</strong></li>
<li>Click<strong> Add&#8230;</strong></li>
<li>Choose <strong>Directory</strong> and click <strong>Next</strong></li>
<li>Location: is the path to the directory containing the web console bundle</li>
<li>Click <strong>Finish</strong></li>
</ol>
<p>Your <strong>New Target Definition</strong> should look like:</p>
<p><a href="http://bryanhunt.files.wordpress.com/2010/07/edit-target-definition-2.png"><img class="aligncenter size-full wp-image-414" title="Edit Target Definition 2" src="http://bryanhunt.files.wordpress.com/2010/07/edit-target-definition-2.png" alt="" width="918" height="513" /></a></p>
<p>Click <strong>Finish</strong>, check the target definition to make it active, and click <strong>OK</strong>.  Your target platform is now ready for you to start writing code.</p>
<h2>Managed Services</h2>
<p>There are two interfaces that can be registered to make your service configurable by ConfigurationAdmin: <a href="http://www.osgi.org/javadoc/r4v42/org/osgi/service/cm/ManagedService.html" target="_blank">ManagedService</a> and <a href="http://www.osgi.org/javadoc/r4v42/org/osgi/service/cm/ManagedServiceFactory.html" target="_blank">ManagedServiceFactory</a>.  Use these interfaces for non-factory and factory services respectively.  Let&#8217;s create an Eclipse plug-in project with a ManagedService and ManagedServiceFactory.  Here is the code for the ManagedService:</p>
<p><pre class="brush: java;">
package org.eclipselabs.metatype.examples;

import java.util.Dictionary;
import java.util.Enumeration;

import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;

public class ExampleManagedService implements ManagedService
{
	@SuppressWarnings({ &quot;rawtypes&quot;, &quot;unchecked&quot; })
	@Override
	public void updated(Dictionary properties) throws ConfigurationException
	{
		System.out.println(&quot;Updating configuration properties for ExampleManagedService&quot;);

		if (properties != null)
		{
			Enumeration&lt;String&gt; keys = properties.keys();

			while (keys.hasMoreElements())
			{
				String key = keys.nextElement();
				System.out.println(key + &quot; : &quot; + properties.get(key));
			}
		}
	}
}
</pre></p>
<p>The code for the ManagedServiceFactory is almost identical:</p>
<p><pre class="brush: java;">
package org.eclipselabs.metatype.examples;

import java.util.Dictionary;
import java.util.Enumeration;

import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedServiceFactory;

public class ExampleManagedServiceFactory implements ManagedServiceFactory
{
	@Override
	public String getName()
	{
		return &quot;ManagedServiceFactoryExample&quot;;
	}

	@Override
	@SuppressWarnings({ &quot;rawtypes&quot;, &quot;unchecked&quot; })
	public void updated(String pid, Dictionary properties) throws ConfigurationException
	{
		System.out.println(&quot;Updating configuration properties for ExampleManagedServiceFactory &quot; + pid);

		if (properties != null)
		{
			Enumeration&lt;String&gt; keys = properties.keys();

			while (keys.hasMoreElements())
			{
				String key = keys.nextElement();
				System.out.println(key + &quot; : &quot; + properties.get(key));
			}
		}
	}

	@Override
	public void deleted(String pid)
	{
		System.out.println(&quot;ExampleManagedServiceFactory deleted(&quot; + pid + &quot;)&quot;);
	}
}
</pre></p>
<p>Create a bundle activator to register the two services:</p>
<p><pre class="brush: java;">
package org.eclipselabs.metatype.examples;

import java.util.Hashtable;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.service.cm.ManagedService;
import org.osgi.service.cm.ManagedServiceFactory;

public class Activator implements BundleActivator
{
	private static BundleContext context;

	static BundleContext getContext()
	{
		return context;
	}

	public void start(BundleContext bundleContext) throws Exception
	{
		Activator.context = bundleContext;

		Hashtable&lt;String, String&gt; serviceProperties = new Hashtable&lt;String, String&gt;();
		serviceProperties.put(Constants.SERVICE_PID, &quot;org.eclipselabs.metatype.examples.managedService&quot;);
		context.registerService(ManagedService.class.getName(), new ExampleManagedService(), serviceProperties);

		Hashtable&lt;String, String&gt; serviceFactoryProperties = new Hashtable&lt;String, String&gt;();
		serviceFactoryProperties.put(Constants.SERVICE_PID, &quot;org.eclipselabs.metatype.examples.managedServiceFactory&quot;);
		context.registerService(ManagedServiceFactory.class.getName(), new ExampleManagedServiceFactory(), serviceFactoryProperties);
	}

	public void stop(BundleContext bundleContext) throws Exception
	{
		Activator.context = null;
	}
}
</pre></p>
<p>Now, we need the metatype data for the two services.  In your plug-in project, create the directory <strong>OSGI-INF/metatype/</strong> and in that directory, create the following two files:</p>
<p><strong>managed_service.xml</strong></p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;MetaData xmlns=&quot;http://www.osgi.org/xmlns/metatype/v1.0.0&quot;&gt;
	&lt;OCD description=&quot;Example Managed Service&quot; name=&quot;Managed Service&quot; id=&quot;ocd&quot;&gt;
		&lt;AD name=&quot;Example Choice Attribute&quot; id=&quot;choice&quot; required=&quot;true&quot; type=&quot;String&quot; default=&quot;normal&quot;&gt;
			&lt;Option label=&quot;Normal&quot; value=&quot;normal&quot; /&gt;
			&lt;Option label=&quot;Priority&quot; value=&quot;priority&quot; /&gt;
		&lt;/AD&gt;
	&lt;/OCD&gt;
	&lt;Designate pid=&quot;org.eclipselabs.metatype.examples.managedService&quot;&gt; &lt;Object ocdref=&quot;ocd&quot;/&gt;
	&lt;/Designate&gt;
&lt;/MetaData&gt;
</pre></p>
<p><strong>managed_service_factory.xml</strong></p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;MetaData xmlns=&quot;http://www.osgi.org/xmlns/metatype/v1.0.0&quot;&gt;
	&lt;OCD description=&quot;Example Managed Service&quot; name=&quot;Managed Service Factory&quot; id=&quot;ocd&quot;&gt;
		&lt;AD name=&quot;Example Choice Attribute&quot; id=&quot;choice&quot; required=&quot;true&quot; type=&quot;String&quot; default=&quot;normal&quot;&gt;
			&lt;Option label=&quot;Normal&quot; value=&quot;normal&quot; /&gt;
			&lt;Option label=&quot;Priority&quot; value=&quot;priority&quot; /&gt;
		&lt;/AD&gt;
	&lt;/OCD&gt;
	&lt;Designate factoryPid=&quot;org.eclipselabs.metatype.examples.managedServiceFactory&quot; pid=&quot;org.eclipselabs.metatype.examples.managedServiceFactory&quot; bundle=&quot;*&quot;&gt;
		&lt;Object ocdref=&quot;ocd&quot;/&gt;
	&lt;/Designate&gt;
&lt;/MetaData&gt;
</pre></p>
<p>Note that for the factory case, you must specify both the <strong>pid</strong> and <strong>factoryPid</strong> in the metatype XML.</p>
<h2>Run the Examples</h2>
<p>Let&#8217;s set up a launch configuration and run the examples you&#8217;ve created so far.</p>
<ol>
<li>Select <strong>Run -&gt; Run Configurations&#8230;</strong></li>
<li>Select<strong> OSGi Framework</strong></li>
<li>Click <strong>New launch configuration</strong> on the toolbar</li>
<li>In the <strong>Bundles</strong> tab, click <strong>Deselect All</strong></li>
<li>Uncheck <strong>Include optional dependencies when computing required bundles</strong></li>
<li>Check your examples bundle</li>
<li>Check the following bundles from the <strong>Target Platform</strong>
<ol>
<li><strong>org.eclipse.equinox.metatype</strong></li>
<li><strong>org.eclipselabs.metatype</strong></li>
<li><strong>org.eclipse.equinox.cm</strong></li>
<li><strong>org.ecliplse.equinox.http.jetty</strong></li>
<li><strong>org.mortbay.jetty.server</strong></li>
<li><strong>org.mortbay.jetty.util</strong></li>
<li><strong>org.apache.felix.webconsole</strong></li>
</ol>
</li>
<li>Click <strong>Add Required Bundles</strong></li>
<li>On the <strong>Arguments</strong> tab, add the <strong>VM arguments:</strong> -Dorg.osgi.service.http.port=8080</li>
</ol>
<p>Your launch configuration should look like:</p>
<p><a href="http://bryanhunt.files.wordpress.com/2010/07/run-configurations.png"><img class="aligncenter size-full wp-image-402" title="Run Configurations" src="http://bryanhunt.files.wordpress.com/2010/07/run-configurations.png" alt="" width="1024" height="883" /></a>Click <strong>Run</strong> and after the application starts, open your web browser on the URL: <a href="http://localhost:8080/system/console/configMgr" target="_blank">http://localhost:8080/system/console/configMgr</a>.  When prompted for login, use <strong>admin</strong> for both the id and password.  You should now see the Apache Felix Web Console with your services listed for configuration.  Your services will probably appear twice, and if you click to edit them you will see different results.  One will display an empty text box, and the other will display a proper form with a combo allowing you to select between Normal and Priority.  Ignore the one with the empty text box &#8211; I assume it&#8217;s a bug in the web console.  For your managed service, you can click the edit button to change it&#8217;s configuration.  For your managed service factory, you can add and remove configurations.</p>
<p><a href="http://bryanhunt.files.wordpress.com/2010/07/safari.png"><img class="aligncenter size-full wp-image-405" title="Safari" src="http://bryanhunt.files.wordpress.com/2010/07/safari.png" alt="" width="875" height="675" /></a></p>
<p>Try changing the the setting on your managed service from Normal to Priority.  You should see the following in the Console view:</p>
<p><a href="http://bryanhunt.files.wordpress.com/2010/07/eclipse.png"><img class="aligncenter size-full wp-image-404" title="Eclipse" src="http://bryanhunt.files.wordpress.com/2010/07/eclipse.png" alt="" width="684" height="259" /></a></p>
<h2>Declarative Services</h2>
<p>As I mentioned above, the metatype service does not &#8211; yet &#8211; work with declarative services.  With some help from Tom Watson, I proposed a change to the OSGi specification to allow the metatype service to work with declarative services.  Here are the important parts of the proposal:</p>
<blockquote><p>I would propose changing the MetaType spec to allow for MetaTypeProvider<br />
services to be registered without a ManagedService or ManagedServiceFactory,<br />
and with the following two service properties: metatype.target.pid, and<br />
metatype.factory.  The value of metatype.target.pid would be set to the pid of<br />
the declarative service for which the meta type applies, and the<br />
metatype.factory would be set to boolean true if the pid is a factory pid, and<br />
false otherwise.</p>
<p>The meta type service would be changed to include a service tracker for<br />
MetaTypeProvider and the existence of the two properties defined above.  The<br />
meta type service would continue to look for ManagedService and<br />
ManagedServiceFactory and simply add any MetaTypeProvider services with those<br />
properties to the list.</p></blockquote>
<p>Tom suggested that we use metatype.provider.pid and metatype.provider.type = &#8220;normal&#8221; | &#8220;factory&#8221; instead of metatype.target.pid and metatype.factory.  The net of this is that you can register a metatype provider with the metatype.provider.pid and metatype.provider.type properties set, and you will get metatype data for declarative services.  This proposal appears to be moving forward into the OSGi specification.</p>
<p>I have provided a patch to the Equinox metatype implementation at <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=311128" target="_blank">https://bugs.eclipse.org/bugs/show_bug.cgi?id=311128</a> with these proposed changes.  With this patch, you can experiment with metatype and declarative services.  Note that this work is not final and still subject to change until it is in the actual OSGi specification.  To try this out, you first need the Equinox metatype source from CVS.</p>
<ol>
<li>Switch to the <strong>CVS Repository Exploring</strong> perspective</li>
<li>Click <strong>Add CVS Repository</strong> in the toolbar</li>
<li>Host: <strong>dev.eclipse.org</strong></li>
<li>Repository path: <strong>/cvsroot/rt</strong></li>
<li>User: <strong>anonymous</strong></li>
<li>Connection type: <strong>pserver</strong></li>
<li>Click <strong>Finish</strong></li>
<li>In the CVS Repositories view, expand:
<ol>
<li>/cvsroot/rt</li>
<li>HEAD</li>
<li>org.eclipse.equinox</li>
<li>compendium</li>
<li>bundles</li>
</ol>
</li>
<li>Select <strong>org.eclipse.equinox.metatype</strong>, right-click and choose <strong>Check Out</strong></li>
</ol>
<p>You should now have the metatype source in your workspace ready to be patched.  To apply my patch:</p>
<ol>
<li>Switch back to the <strong>Plug-in Development</strong> perspective</li>
<li>Right-click on the <strong>org.eclipse.equinox.metatype</strong> project</li>
<li>Choose <strong>Team -&gt; Apply Patch&#8230;</strong></li>
<li>Choose <strong>URL https://bugs.eclipse.org/bugs/attachment.cgi?id=166704</strong></li>
<li>Click <strong>Finish</strong></li>
</ol>
<p>Let&#8217;s create a declarative service and try this out.  You need to create a new bundle for your declarative services.  If you add your declarative service metatype provider to a bundle that contains metatype XML files, the registered metatype providers are ignored.  This might be a bug in the metatype implementation.</p>
<p>Here is the code for the declarative service:</p>
<p><pre class="brush: java;">
package org.eclipselabs.metatype.examples.ds;

import java.util.Dictionary;
import java.util.Enumeration;

import org.osgi.service.component.ComponentContext;

public class ExampleDeclarativeService
{
	@SuppressWarnings({ &quot;rawtypes&quot;, &quot;unchecked&quot; })
	protected void activate(ComponentContext context)
	{
		System.out.println(&quot;Activating ExampleDeclarativeService&quot;);

		Dictionary properties = context.getProperties();

		if (properties != null)
		{
			Enumeration&lt;String&gt; keys = properties.keys();

			while (keys.hasMoreElements())
			{
				String key = keys.nextElement();
				System.out.println(key + &quot; : &quot; + properties.get(key));
			}
		}
	}

	protected void deactivate()
	{
		System.out.println(&quot;Deactivating ExampleDeclarativeService&quot;);
	}
}
</pre></p>
<p>Here is the code for the declarative service metatype:</p>
<p><pre class="brush: java;">
package org.eclipselabs.metatype.examples.ds;

import org.eclipselabs.metatype.AttributeDefinitionImpl;
import org.eclipselabs.metatype.MetatypeFactory;
import org.eclipselabs.metatype.ObjectClassDefinitionImpl;
import org.osgi.service.metatype.AttributeDefinition;
import org.osgi.service.metatype.MetaTypeProvider;
import org.osgi.service.metatype.ObjectClassDefinition;

public class ExampleDeclarativeServiceMetatype implements MetaTypeProvider
{
	@Override
	public ObjectClassDefinition getObjectClassDefinition(String id, String locale)
	{
		ObjectClassDefinitionImpl ocd = MetatypeFactory.eINSTANCE.createObjectClassDefinitionImpl();
		ocd.setID(&quot;org.eclipselabs.metatype.examples.service&quot;);
		ocd.setName(&quot;Declarative Service&quot;);
		ocd.setDescription(&quot;Example Description&quot;);

		AttributeDefinitionImpl ad = MetatypeFactory.eINSTANCE.createAttributeDefinitionImpl();
		ad.setName(&quot;Exampel Chioce Attribute&quot;);
		ad.setDescription(&quot;Attribute Description&quot;);
		ad.setID(&quot;choice&quot;);
		ad.setType(AttributeDefinition.STRING);
		ad.setOptionLabels(new String[] {&quot;Normal&quot;, &quot;Priority&quot;});
		ad.setOptionValues(new String[] {&quot;normal&quot;, &quot;priority&quot;});
		ad.setDefaultValue(new String[] {&quot;normal&quot;});

		ocd.getAttributeDefinitions().add(ad);
		return ocd;
	}

	@Override
	public String[] getLocales()
	{
		return null;
	}
}
</pre></p>
<p>Here is the code for the declarative service factory metatype:</p>
<p><pre class="brush: java;">
package org.eclipselabs.metatype.examples.ds;

import java.util.UUID;

import org.eclipselabs.metatype.AttributeDefinitionImpl;
import org.eclipselabs.metatype.MetatypeFactory;
import org.eclipselabs.metatype.ObjectClassDefinitionImpl;
import org.osgi.service.metatype.AttributeDefinition;
import org.osgi.service.metatype.MetaTypeProvider;
import org.osgi.service.metatype.ObjectClassDefinition;

public class ExampleDeclarativeServiceFactoryMetatype implements MetaTypeProvider
{
	@Override
	public ObjectClassDefinition getObjectClassDefinition(String id, String locale)
	{
		ObjectClassDefinitionImpl ocd = MetatypeFactory.eINSTANCE.createObjectClassDefinitionImpl();
		ocd.setID(&quot;org.eclipselabs.metatype.examples.service.factory&quot;);
		ocd.setName(&quot;Declarative Service Factory&quot;);
		ocd.setDescription(&quot;Example Description&quot;);

		AttributeDefinitionImpl ad = MetatypeFactory.eINSTANCE.createAttributeDefinitionImpl();
		ad.setName(&quot;Exampel Chioce Attribute&quot;);
		ad.setDescription(&quot;Attribute Description&quot;);
		ad.setID(&quot;choice&quot;);
		UUID normal = UUID.randomUUID();
		UUID priority = UUID.randomUUID();
		ad.setType(AttributeDefinition.STRING);
		ad.setOptionLabels(new String[] {&quot;Normal&quot;, &quot;Priority&quot;});
		ad.setOptionValues(new String[] {normal.toString(), priority.toString()});
		ad.setDefaultValue(new String[] {normal.toString()});

		ocd.getAttributeDefinitions().add(ad);
		return ocd;
	}

	@Override
	public String[] getLocales()
	{
		return null;
	}
}
</pre></p>
<p>The metatype providers can be registered as declarative services.  When you register them, you must set the <strong>metatype.provider.pid</strong> and <strong>metatype.provider.type</strong> properties.  First, register the declarative service as a factory and non-factory configurable service.</p>
<p>Here is the non-factory registration:</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.metatype.examples.service&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.metatype.examples.ds.ExampleDeclarativeService&quot;/&gt;
&lt;/scr:component&gt;
</pre></p>
<p>Here is the factory configurable service:</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; configuration-policy=&quot;require&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.metatype.examples.service.factory&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.metatype.examples.ds.ExampleDeclarativeService&quot;/&gt;
&lt;/scr:component&gt;
</pre></p>
<p>Here is the metatype provider registration:</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.metatype.examples.service.metatype&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.metatype.examples.ds.ExampleDeclarativeServiceMetatype&quot;/&gt;
   &lt;service&gt;
      &lt;provide interface=&quot;org.osgi.service.metatype.MetaTypeProvider&quot;/&gt;
   &lt;/service&gt;
   &lt;property name=&quot;metatype.provider.pid&quot; type=&quot;String&quot; value=&quot;org.eclipselabs.metatype.examples.service&quot;/&gt;
   &lt;property name=&quot;metatype.provider.type&quot; type=&quot;String&quot; value=&quot;normal&quot;/&gt;
&lt;/scr:component&gt;
</pre></p>
<p>Here is the metatype factory provider registration:</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;scr:component xmlns:scr=&quot;http://www.osgi.org/xmlns/scr/v1.1.0&quot; immediate=&quot;true&quot; name=&quot;org.eclipselabs.metatype.examples.service.factory.metatype&quot;&gt;
   &lt;implementation class=&quot;org.eclipselabs.metatype.examples.ds.ExampleDeclarativeServiceFactoryMetatype&quot;/&gt;
   &lt;service&gt;
      &lt;provide interface=&quot;org.osgi.service.metatype.MetaTypeProvider&quot;/&gt;
   &lt;/service&gt;
   &lt;property name=&quot;metatype.provider.pid&quot; type=&quot;String&quot; value=&quot;org.eclipselabs.metatype.examples.service.factory&quot;/&gt;
   &lt;property name=&quot;metatype.provider.type&quot; type=&quot;String&quot; value=&quot;factory&quot;/&gt;
&lt;/scr:component&gt;
</pre></p>
<p>That&#8217;s all the code we need, so let&#8217;s modify our launch configuration and try it out.</p>
<h2>Run the Examples</h2>
<p>Bring up the launch configuration you created to run the first example.</p>
<ol>
<li>Add your new bundle containing your declarative services</li>
<li>Add the <strong>org.eclipse.equinox.metatype</strong> bundle from your <strong>Workspace</strong></li>
<li>Add the <strong>org.eclilpse.equinox.ds</strong> bundle</li>
<li>Remove the <strong>org.eclipse.equinox.metatype</strong> bundle from the <strong>Target Platform</strong></li>
<li>Click <strong>Add Required Bundles</strong></li>
</ol>
<p>Your launch configuration should look like:</p>
<p><a href="http://bryanhunt.files.wordpress.com/2010/07/run-configurations-3.png"><img class="aligncenter size-full wp-image-415" title="Run Configurations 3" src="http://bryanhunt.files.wordpress.com/2010/07/run-configurations-3.png" alt="" width="1024" height="926" /></a></p>
<p>Click Run and point your web browser to <a href="http://localhost:8080/system/console/configMgr" target="_blank">http://localhost:8080/system/console/configMgr</a>.  You should see your declarative services in addition to your managed services.  Try creating a configuration for your factory service and you will see it display the value of the UUID that was dynamically chosen for a configuration value.  This is where the real power of this technology shines &#8211; the ability to programatically create values for declarative service configuration and have those values available as choices on an administrative UI.</p>
<p>If you don&#8217;t feel like setting up the bundles and typing in the code, you can get the example source code from <a href="http://code.google.com/a/eclipselabs.org/p/metatype-emf-model/" target="_blank">Eclipse Labs</a>.</p>
<h2>References</h2>
<ol>
<li><a href="http://www.osgi.org/Specifications/HomePage" target="_blank">OSGi Specifications</a></li>
<li><a href="http://www.osgi.org/javadoc/r4v42/org/osgi/service/metatype/package-summary.html" target="_blank">Metatype API</a></li>
<li><a href="http://dz.prosyst.com/pdoc/mbs_prof_6.1/um/framework/bundles/osgi/metatype/osgi.html" target="_blank">OSGi Metatype Service</a></li>
<li><a href="http://www.osgi.org/javadoc/r4v42/org/osgi/service/cm/package-summary.html" target="_blank">Configuration Admin API</a></li>
<li><a href="http://bryanhunt.wordpress.com/2009/04/30/dynamically-configured-declarative-osgi-services/" target="_blank">Dynamically configured declarative OSGi services</a></li>
<li><a href="http://www.dynamicjava.org/articles/osgi-compendium/configuration-admin-service" target="_blank">Configuration Admin Service specification explained by Example</a></li>
<li><a href="http://www.osgi.org/blog/2010/06/how-to-use-config-admin.html" target="_blank">How to use Config Admin</a></li>
<li><a href="https://bryanhunt.wordpress.com/2010/05/14/osgi-as-a-web-application-server/" target="_blank">OSGi as a Web Application Server</a></li>
<li><a href="http://code.google.com/a/eclipselabs.org/hosting/" target="_blank">Eclipse Labs</a></li>
</ol>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/bryanhunt.wordpress.com/352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/bryanhunt.wordpress.com/352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/bryanhunt.wordpress.com/352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/bryanhunt.wordpress.com/352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/352/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&amp;blog=7500940&amp;post=352&amp;subd=bryanhunt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2010/07/07/configuring-osgi-services-with-apache-web-console-and-metatype/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2010/07/apache-felix-web-console-configuration.png" medium="image">
			<media:title type="html">Apache Felix Web Console - Configuration</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2010/07/edit-target-definition-2.png" medium="image">
			<media:title type="html">Edit Target Definition 2</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2010/07/run-configurations.png" medium="image">
			<media:title type="html">Run Configurations</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2010/07/safari.png" medium="image">
			<media:title type="html">Safari</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2010/07/eclipse.png" medium="image">
			<media:title type="html">Eclipse</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2010/07/run-configurations-3.png" medium="image">
			<media:title type="html">Run Configurations 3</media:title>
		</media:content>
	</item>
	</channel>
</rss>
