Author: buildbot
Date: Tue Mar 10 19:19:01 2015
New Revision: 943225
Log:
Staging update by buildbot for felix
Added:
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/diagrams/resources.png
(with props)
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/diagrams/resources.uxf
(with props)
Modified:
websites/staging/felix/trunk/content/ (props changed)
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/resources.html
Propchange: websites/staging/felix/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Tue Mar 10 19:19:01 2015
@@ -1 +1 @@
-1665537
+1665651
Added:
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/diagrams/resources.png
==============================================================================
Binary file - no diff available.
Propchange:
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/diagrams/resources.png
------------------------------------------------------------------------------
svn:mime-type = image/png
Added:
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/diagrams/resources.uxf
==============================================================================
Binary file - no diff available.
Propchange:
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/diagrams/resources.uxf
------------------------------------------------------------------------------
svn:mime-type = application/xml
Modified:
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/resources.html
==============================================================================
---
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/resources.html
(original)
+++
websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/resources.html
Tue Mar 10 19:19:01 2015
@@ -18,7 +18,7 @@
limitations under the License.
-->
<head>
- <title>Apache Felix - Apache Felix Dependency Manager - Resources</title>
+ <title>Apache Felix - Resources</title>
<link rel="icon" href="/res/favicon.ico">
<link rel="stylesheet" href="/res/site.css" type="text/css" media="all">
<link rel="stylesheet" href="/res/codehilite.css" type="text/css"
media="all">
@@ -67,10 +67,86 @@
- <h1>Apache Felix Dependency Manager - Resources</h1>
- <p>...</p>
+ <h1>Resources</h1>
+ <p>Resource adapters are a special type of adapters which can adapt a
resource into an OSGi service. These resources can be all kinds of resources,
e.g. bundle resources, files, database records, anything as long as it can be
resolved though a URL.</p>
+<p>The diagram below illustrates the classes involved in the resource adapter
pattern:</p>
+<p><img src="./diagrams/resources.png" alt="Resource adapters" style="width:
780px"/>
+The yellow elements have to be implemented in order to use the pattern.</p>
+<p>A resource adapter is configured as follows:</p>
+<p><code>manager.add(createResourceAdapter("*.MF", true, null, "changed")
+ .setImplementation(ManifestAdapter.class));</code></p>
+<p>The filter semantics depend on the resource repository. In this example the
resource repository will be serving bundle resources, so we're using a standard
file wildcard filter. As the filter specifies in this case the resource of
interest is the bundle manifest. For each MANIFEST.MF found a new instance of
ManifestAdapter will be created and registered. Each instance gets access to
the resource by injecting the URL of the resource into the implementation
object.</p>
+<p>```
+public class ManifestAdapter {</p>
+<div class="codehilite"><pre><span class="n">private</span> <span
class="n">volatile</span> <span class="n">URL</span> <span
class="n">url</span><span class="p">;</span>
+
+<span class="n">void</span> <span class="n">start</span><span
class="p">()</span> <span class="p">{</span>
+ <span class="n">System</span><span class="p">.</span><span
class="n">out</span><span class="p">.</span><span class="n">println</span><span
class="p">(</span>"<span class="n">started</span><span class="p">:</span>
" <span class="o">+</span> <span class="n">url</span><span
class="p">);</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>}
+```</p>
+<p>But how does DM know where to go looking for manifest files? We'll it does
not automatically. It requires you to implement a resource repository
component. For each resource adapter service DM launches a ResourceHandler
service tracking the resources the resource adapter is interested in. A
resource repository is responsible for tracking resources and notifying adding
/ changing and removal of the resources from the repository. Notifying these
resource 'events' is done by invoking the corresponding method on the
ResourceHandler service.</p>
+<p>We'll explain how to implement a resource repository by an example. The
example resource repository is a bundle resource repository which as it's name
says, is capable of serving bundle resources.</p>
+<p>A simplified bundle resource repository looks as follows:</p>
+<p>```
+public class BundleResourceRepositoryImpl {</p>
+<div class="codehilite"><pre><span class="n">private</span> <span
class="n">Map</span><span class="o"><</span><span
class="n">ServiceReference</span><span class="p">,</span> <span
class="n">ResourceHandler</span><span class="o">></span> <span
class="n">handlers</span> <span class="p">=</span> <span class="n">new</span>
<span class="n">ConcurrentHashMap</span><span class="o"><></span><span
class="p">();</span>
+<span class="n">private</span> <span class="n">volatile</span> <span
class="n">BundleContext</span> <span class="n">context</span><span
class="p">;</span>
+
+<span class="n">void</span> <span class="n">addHandler</span><span
class="p">(</span><span class="n">ServiceReference</span> <span
class="n">ref</span><span class="p">,</span> <span
class="n">ResourceHandler</span> <span class="n">handler</span><span
class="p">)</span> <span class="p">{</span>
+ <span class="n">handlers</span><span class="p">.</span><span
class="n">put</span><span class="p">(</span><span class="n">ref</span><span
class="p">,</span> <span class="n">handler</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span
class="n">ref</span><span class="p">.</span><span
class="n">getProperty</span><span class="p">(</span><span
class="n">ResourceHandler</span><span class="p">.</span><span
class="n">URL</span><span class="p">)</span> !<span class="p">=</span> <span
class="n">null</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">URL</span> <span class="n">url</span> <span
class="p">=</span> <span class="p">(</span><span class="n">URL</span><span
class="p">)</span> <span class="n">ref</span><span class="p">.</span><span
class="n">getProperty</span><span class="p">(</span><span
class="n">ResourceHandler</span><span class="p">.</span><span
class="n">URL</span><span class="p">);</span>
+ <span class="n">notifyMatchingInitialResource</span><span
class="p">(</span><span class="n">url</span><span class="p">,</span> <span
class="n">handler</span><span class="p">);</span>
+ <span class="p">}</span> <span class="k">else</span> <span
class="p">{</span>
+ <span class="n">String</span> <span class="n">filter</span> <span
class="p">=</span> <span class="p">(</span><span class="n">String</span><span
class="p">)</span> <span class="n">ref</span><span class="p">.</span><span
class="n">getProperty</span><span class="p">(</span><span
class="n">ResourceHandler</span><span class="p">.</span><span
class="n">FILTER</span><span class="p">);</span>
+ <span class="n">notifyMatchingInitialResources</span><span
class="p">(</span><span class="n">filter</span><span class="p">,</span> <span
class="n">handler</span><span class="p">);</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="n">void</span> <span class="n">removeHandler</span><span
class="p">(</span><span class="n">ServiceReference</span> <span
class="n">ref</span><span class="p">,</span> <span
class="n">ResourceHandler</span> <span class="n">handler</span><span
class="p">)</span> <span class="p">{</span>
+ <span class="n">handlers</span><span class="p">.</span><span
class="n">remove</span><span class="p">(</span><span class="n">ref</span><span
class="p">);</span>
+<span class="p">}</span>
+
+<span class="n">private</span> <span class="n">void</span> <span
class="n">notifyMatchingInitialResource</span><span class="p">(</span><span
class="n">URL</span> <span class="n">url</span><span class="p">,</span> <span
class="n">ResourceHandler</span> <span class="n">handler</span><span
class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span
class="n">bundleContainsResource</span><span class="p">(</span><span
class="n">url</span><span class="p">))</span> <span class="p">{</span>
+ <span class="n">handler</span><span class="p">.</span><span
class="n">added</span><span class="p">(</span><span class="n">url</span><span
class="p">,</span> <span class="n">new</span> <span
class="n">Hashtable</span><span class="o"><</span><span
class="n">String</span><span class="p">,</span> <span
class="n">String</span><span class="o">></span><span class="p">());</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="p">@</span><span class="n">SuppressWarnings</span><span
class="p">(</span>"<span class="n">unchecked</span>"<span
class="p">)</span>
+<span class="n">void</span> <span
class="n">notifyMatchingInitialResources</span><span class="p">(</span><span
class="n">String</span> <span class="n">filter</span><span class="p">,</span>
<span class="n">ResourceHandler</span> <span class="n">handler</span><span
class="p">)</span> <span class="p">{</span>
+ <span class="n">Enumeration</span><span class="o"><</span><span
class="n">URL</span><span class="o">></span> <span class="n">entries</span>
<span class="p">=</span> <span class="n">context</span><span
class="p">.</span><span class="n">getBundle</span><span
class="p">().</span><span class="n">findEntries</span><span
class="p">(</span>"<span class="o">/</span>"<span class="p">,</span>
<span class="n">filter</span><span class="p">,</span> <span
class="n">true</span><span class="p">);</span>
+ <span class="k">while</span> <span class="p">(</span><span
class="n">entries</span><span class="p">.</span><span
class="n">hasMoreElements</span><span class="p">())</span> <span
class="p">{</span>
+ <span class="n">URL</span> <span class="n">entry</span> <span
class="p">=</span> <span class="n">entries</span><span class="p">.</span><span
class="n">nextElement</span><span class="p">();</span>
+ <span class="n">handler</span><span class="p">.</span><span
class="n">added</span><span class="p">(</span><span class="n">entry</span><span
class="p">,</span> <span class="n">new</span> <span
class="n">Hashtable</span><span class="o"><</span><span
class="n">String</span><span class="p">,</span> <span
class="n">String</span><span class="o">></span><span class="p">());</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="n">private</span> <span class="n">boolean</span> <span
class="n">bundleContainsResource</span><span class="p">(</span><span
class="n">URL</span> <span class="n">url</span><span class="p">)</span> <span
class="p">{</span>
+ <span class="k">return</span> <span class="n">true</span><span
class="p">;</span> <span class="o">//</span> <span class="n">more</span> <span
class="n">specific</span> <span class="n">checks</span> <span
class="n">required</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>}
+``` </p>
+<p>The resource repository is registered in the bundle activator as
follows:</p>
+<p><code>manager.add(createComponent().setImplementation(BundleResourceRepositoryImpl.class)
+
.add(createServiceDependency().setService(ResourceHandler.class).setCallbacks("addHandler",
"removeHandler")));</code></p>
+<p>A resource repository implementation must have a dependency on resource
handlers. The ResourceHandler service has two important service properties:</p>
+<ul>
+<li>"filter" (<code>ResourceHandler.FILTER</code>)</li>
+<li>"url" (<code>ResourceHandler.URL</code>)</li>
+</ul>
+<p>A resource handler service has either one of these properties, not both! A
resource handler with a filter can match multiple resources whereas a resource
handler with a url only matches a single resource. It's important the resource
repository handles both situations.</p>
+<p>When a new handler is being added, the resource repository should inform
the resource handler on the resources it has that match the handler's filter or
url. This is done by invoking the <code>added(url, properties)</code> method on
the ResourceHandler. This callback results in the ResourceAdapter's
ResourceDependency being satisfied, the url being injected into the resource
adapter implementation object and the resource adapter implementation component
being started.</p>
+<p>Besides the added() callback the resource repository is also responsible
for handling the changed() and removed() methods on change or removal of the
resource from the resource repository. For a bundle resource repository that's
not likely to happen, but for a filesystem resource repository this can very
well be the case.</p>
<div class="timestamp" style="margin-top: 30px; font-size: 80%;
text-align: right;">
- Rev. 1664040 by marrs on Wed, 4 Mar 2015 15:21:58 +0000
+ Rev. 1665651 by uiterlix on Tue, 10 Mar 2015 19:18:28 +0000
</div>
<div class="trademarkFooter">
Apache Felix, Felix, Apache, the Apache feather logo, and the Apache
Felix project