felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Felix > Apache Felix Dependency Manager - Getting Started
Date Tue, 22 Dec 2009 15:41:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=FELIX&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/FELIX/Apache+Felix+Dependency+Manager+-+Getting+Started">Apache
Felix Dependency Manager - Getting Started</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~marrs">Marcel
Offermans</a>
    </h4>
     
          <br/>
     <div class="notificationGreySide">
         <h2><a name="ApacheFelixDependencyManager-GettingStarted-GettingStarted"></a>Getting
Started</h2>

<p>When developing an OSGi bundle that has dependencies and possibly registers services,
there are two classes in particular we need to implement:</p>
<ol>
	<li>The bundle activator which controls the life-cycle of the bundle.</li>
	<li>The actual service implementation, which can be a POJO.</li>
</ol>


<p>When using the dependency manager, your bundle activator is a subclass of DependencyActivatorBase.
It needs to implement two life cycle methods: init and destroy. Both methods take two arguments:
BundleContext and DependencyManager. The latter is your interface to the declarative API you
can use to define your services and dependencies.</p>

<p>The following paragraphs will show various examples that explain how to do this.
Subsequently, some more advanced scenarios will be covered that involve listening to dependency
and service state changes and interacting with the OSGi framework from within your service
implementation.</p>

<h3><a name="ApacheFelixDependencyManager-GettingStarted-Registeringaservice"></a>Registering
a service</h3>

<p>The first example is about registering a service. We extend DependencyActivatorBase
and in the init method we use the reference to the DependencyManager to create and add a service.
For this service we subsequently set its interface and implementation. In this case the interface
is the Store interface, the second parameter, null, allows you to provide properties along
with the service registration. For the implementation, we only mention the Class of the implementation,
which means the dependency manager will lazily instantiate it. In this case, there is not
much point in doing that because the service has no dependencies, but if it had, the instantiation
would only happen when those dependencies were resolved.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Activator <span class="code-keyword">extends</span>
DependencyActivatorBase {
    <span class="code-keyword">public</span> void init(BundleContext context,
DependencyManager manager) <span class="code-keyword">throws</span> Exception
{
        manager.add(createService()
            .setInterface(Store.class.getName(), <span class="code-keyword">null</span>)
            .setImplementation(MemoryStore.class)
        );
    }
    
    <span class="code-keyword">public</span> void destroy(BundleContext context,
DependencyManager manager) <span class="code-keyword">throws</span> Exception
{}
}
</pre>
</div></div>

<p>This is the service interface. Nothing special here.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> <span class="code-keyword">interface</span>
Store {
    <span class="code-keyword">public</span> void put(<span class="code-object">String</span>
key, <span class="code-object">Object</span> value);
    <span class="code-keyword">public</span> <span class="code-object">Object</span>
get(<span class="code-object">String</span> key);
}
</pre>
</div></div>

<p>And finally the implementation. Again, this is just a POJO, there is no reference
here to any OSGi or dependency manager specific class or annotation.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class MemoryStore <span class="code-keyword">implements</span>
Store {
    <span class="code-keyword">private</span> Map m_map = <span class="code-keyword">new</span>
HashMap();

    <span class="code-keyword">public</span> <span class="code-object">Object</span>
get(<span class="code-object">String</span> key) {
        <span class="code-keyword">return</span> m_map.get(key);
    }

    <span class="code-keyword">public</span> void put(<span class="code-object">String</span>
key, <span class="code-object">Object</span> value) {
        m_map.put(key, value);
    }
}
</pre>
</div></div>

<h3><a name="ApacheFelixDependencyManager-GettingStarted-Dependingonaservice"></a>Depending
on a service</h3>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Activator <span class="code-keyword">extends</span>
DependencyActivatorBase {
    <span class="code-keyword">public</span> void init(BundleContext context,
DependencyManager manager) <span class="code-keyword">throws</span> Exception
{
        manager.add(createService()
            .setImplementation(DataGenerator.class)
            .add(createServiceDependency()
                .setService(Store.class)
                .setRequired(<span class="code-keyword">true</span>)
            )
            .add(createServiceDependency()
                .setService(LogService.class)
                .setRequired(<span class="code-keyword">false</span>)
            )
        );
    }
    
    <span class="code-keyword">public</span> void destroy(BundleContext context,
DependencyManager manager) <span class="code-keyword">throws</span> Exception
{}
}
</pre>
</div></div>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class DataGenerator {
    <span class="code-keyword">private</span> <span class="code-keyword">volatile</span>
Store m_store;
    <span class="code-keyword">private</span> <span class="code-keyword">volatile</span>
LogService m_log;
    
    <span class="code-keyword">public</span> void generate() {
        <span class="code-keyword">for</span> (<span class="code-object">int</span>
i = 0; i &lt; 10; i++) {
            m_store.put(<span class="code-quote">"#"</span> + i, <span class="code-quote">"value_"</span>
+ i);
        }
        m_log.log(LogService.LOG_INFO, <span class="code-quote">"Data generated."</span>);
    }
}
</pre>
</div></div>

<h3><a name="ApacheFelixDependencyManager-GettingStarted-Trackingserviceswithcallbacks"></a>Tracking
services with callbacks</h3>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Activator <span class="code-keyword">extends</span>
DependencyActivatorBase {
    <span class="code-keyword">public</span> void init(BundleContext context,
DependencyManager manager) <span class="code-keyword">throws</span> Exception
{
        manager.add(createService()
            .setImplementation(DocumentTranslator.class)
            .add(createServiceDependency()
                .setService(Translator.class)
                .setRequired(<span class="code-keyword">false</span>)
                .setCallbacks(<span class="code-quote">"added"</span>, <span
class="code-quote">"removed"</span>)
            )
        );
    }
    
    <span class="code-keyword">public</span> void destroy(BundleContext context,
DependencyManager manager) <span class="code-keyword">throws</span> Exception
{}
}
</pre>
</div></div>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> <span class="code-keyword">interface</span>
Translator {
    <span class="code-keyword">public</span> <span class="code-object">boolean</span>
canTranslate(<span class="code-object">String</span> from, <span class="code-object">String</span>
to);
    <span class="code-keyword">public</span> Document translate(Document document,
<span class="code-object">String</span> from, <span class="code-object">String</span>
to);
}
</pre>
</div></div>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class DocumentTranslator {
    <span class="code-keyword">private</span> List&lt;Translator&gt; m_translators
= <span class="code-keyword">new</span> ArrayList&lt;Translator&gt;();
    
    <span class="code-keyword">public</span> void added(Translator translator)
{
        m_translators.add(translator);
    }
    
    <span class="code-keyword">public</span> void removed(Translator translator)
{
        m_translators.remove(translator);
    }
    
    <span class="code-keyword">public</span> Document translate(Document document,
<span class="code-object">String</span> from, <span class="code-object">String</span>
to) {
        <span class="code-keyword">for</span> (Translator translator : m_translators)
{
            <span class="code-keyword">if</span> (translator.canTranslate(from,
to)) {
                <span class="code-keyword">return</span> translator.translate(document,
from, to);
            }
        }
        <span class="code-keyword">return</span> <span class="code-keyword">null</span>;
    }
}
</pre>
</div></div>


<h3><a name="ApacheFelixDependencyManager-GettingStarted-Dependingonaconfiguration"></a>Depending
on a configuration</h3>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Activator <span class="code-keyword">extends</span>
DependencyActivatorBase {
    <span class="code-keyword">public</span> void init(BundleContext context,
DependencyManager manager) <span class="code-keyword">throws</span> Exception
{
        manager.add(createService()
            .setImplementation(Task.class)
            .add(createConfigurationDependency()
                .setPid(<span class="code-quote">"config.pid"</span>)
            )
        );
    }
    
    <span class="code-keyword">public</span> void destroy(BundleContext context,
DependencyManager manager) <span class="code-keyword">throws</span> Exception
{}
}
</pre>
</div></div>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class Task <span class="code-keyword">implements</span>
ManagedService {
    <span class="code-keyword">private</span> <span class="code-object">String</span>
m_interval;

    <span class="code-keyword">public</span> void execute() {
        <span class="code-object">System</span>.out.println(<span class="code-quote">"Scheduling
task with interval "</span> + m_interval);
    }

    <span class="code-keyword">public</span> void updated(Dictionary properties)
<span class="code-keyword">throws</span> ConfigurationException {
        <span class="code-keyword">if</span> (properties != <span class="code-keyword">null</span>)
{
            m_interval = (<span class="code-object">String</span>) properties.get(<span
class="code-quote">"interval"</span>);
            <span class="code-keyword">if</span> (m_interval == <span class="code-keyword">null</span>)
{
                <span class="code-keyword">throw</span> <span class="code-keyword">new</span>
ConfigurationException(<span class="code-quote">"interval"</span>, <span class="code-quote">"must
be specified"</span>);
            }
        }
    }
}
</pre>
</div></div>

<h3><a name="ApacheFelixDependencyManager-GettingStarted-..."></a>...</h3>
     </div>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/FELIX/Apache+Felix+Dependency+Manager+-+Getting+Started">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=9374243&revisedVersion=7&originalVersion=6">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/FELIX/Apache+Felix+Dependency+Manager+-+Getting+Started?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message