A document has been updated:
http://cocoon.zones.apache.org/daisy/documentation/1151.html
Document ID: 1151
Branch: main
Language: default
Name: The OSGi fundament (unchanged)
Document Type: Cocoon Document (unchanged)
Updated on: 5/23/06 9:43:05 AM
Updated by: Reinhard Pötz
A new version has been created, state: publish
Parts
=====
Content
-------
This part has been updated.
Mime type: text/xml (unchanged)
File name: (unchanged)
Size: 14023 bytes (previous version: 14316 bytes)
Content diff:
(18 equal lines skipped)
inheritance so that one sitemap (or servlet) can extend another one.</li>
<li><strong>Dynamic deployment and configuration </strong>- the blocks can
be
installed, updated, reconfigured and removed dynamically while the rest of
the
--- framework is executing.</li>
+++ framework is executed.</li>
</ul>
--- <p><img src="daisy:1160"/></p>
+++ <p><img daisy-caption="UML 2 component diagram" src="daisy:1160"/></p>
<p class="warn">Not everything implemented yet!</p>
(3 equal lines skipped)
<h1>Declarative Services</h1>
--- <p>The declarative services simplify service (component) handling in OSGi by
--- making it possible to declare services and their dependencies in an XML file
--- (before service management wasn't configuration file based in OSGi). The DS
--- supports setter injection. Compared to Spring it is rather small and
primitive.
--- The cool thing about it is that it support dynamic dependencies. A dynamic
--- dependency can have both a setter and an un-setter. The framework also takes
--- care of stopping and starting non-dynamic components when their dependencies
--- comes and goes.</p>
+++ <p>Declarative services simplify service (component) handling in OSGi by
making
+++ it possible to declare services and their dependencies in an XML file
(before
+++ service management wasn't configuration file based in OSGi). DS support
setter
+++ injection. Compared to Spring it is rather small and primitive. The cool
thing
+++ about it is, that it supports dynamic dependencies. A dynamic dependency can
+++ have both a setter and an un-setter. The framework also takes care of
stopping
+++ and starting non-dynamic components when their dependencies come and go.</p>
<p>The DS can be used together with a configuration service that can
override
the default configurations in the DS XML file. The configuration service can
(6 equal lines skipped)
<p>The role of the dispatcher (ServletRegistrationActivator) is that the
blocks
(servlets) are mounted in it based together with their URI prefixes. The
--- dispatcher then call the blocks based on the incoming URIs. This is already
+++ dispatcher then calls the blocks based on the incoming URIs. This is already
handled by the OSGi HTTP service which provides a service that a servlet can
--- lookup and register it self in. <br/>
+++ lookup and register itself in. <br/>
A HTTP service implementation normally contains a HTTP server. But an
alternative for embedding OSGi managed servlets in a servlet container is
to use
a HTTP service that acts as a bridge to the embedding servlet container. [3]
(5 equal lines skipped)
of servlet services, and register and unregister them in the HTTP service
respectively.</p>
--- <p>Using DS a declaration (which is referred to by the Service-Component
--- property in the manifest file) for a "whiteboard" adapter can look like [5]:
--- </p>
+++ <p>Using DS a declaration (which is referred to by the <tt>Service-Component
+++ </tt>property in the manifest file) for a "whiteboard" adapter can look like
+++ [5]:</p>
<pre> <scr:component name="cocoon.activator">
<scr:implementation
class="org.apache.cocoon.blocks.osgi.Activator"/>
(13 equal lines skipped)
</pre>
<p>which activates the class <tt>o.a.c.blocks.osgi.Activator</tt> [6] by
calling
--- its <tt>void activate(ComponentContext)</tt>"method if there is one. We can
--- also see that the declaration refers to other services. It will not be
activated
--- until all its references are fulfilled. In this case it require a log
service
+++ its <tt>void activate(ComponentContext)</tt>method if there is one. We can
also
+++ see that the declaration refers to other services. It will not be activated
+++ until all its references are fulfilled. In this case it requires a log
service
and an HTTP service to be present, and will insert these into the Activator
--- instance by using its setLog and setHttpService methods.</p>
+++ instance by using its <tt>setLog </tt>and <tt>setHttpService
</tt>methods.</p>
<p>The servlet reference is more interesting, it is dynamic an it has
--- cardinality 0..n. This means that the activator can be connected to many
--- servlets and that they can come and go dynamically. Each time a servlet
service
--- appears the setServlet method is called with it and each time one disappear
the
--- unsetServlet method is called.</p>
+++ cardinality <tt>0..n</tt>. This means that the activator can be connected to
+++ many servlets and that they can come and go dynamically. Each time a servlet
+++ service appears, the <tt>setServlet </tt>method is called with it and each
time
+++ one disappear the <tt>unsetServlet </tt>method is called.</p>
<p>The name attribute for the references are used for allowing service
manager
style lookup using the name, within the component. The service manager can
be
--- get through the ComponentContext.</p>
+++ get through the <tt>ComponentContext</tt>.</p>
<h1>A Servlet Service</h1>
<p>A bundle that provides a servlet, can register it as a service with a
--- declaration like [5]:</p>
+++ declaration like this: [5]</p>
<pre> <scr:component name="cocoon.servlet3">
<scr:implementation
class="org.apache.cocoon.blocks.osgi.TestServlet"/>
(4 equal lines skipped)
</scr:component>
</pre>
--- <p>compared to the whiteboard adapter we can see some new things, here we
+++ <p>compared to the whiteboard adapter we can see some new things. Here we
provide a service to the framework and it can be refered to by the name
--- "cocoon.servlet3" (we should use a better naming scheme, I just adapted some
--- examples from the specification while implementing the above).</p>
+++ <tt>cocoon.servlet3</tt>. The declaration also contains a property:
+++ <tt>path=/test3</tt>, that is looked up by the whiteboard adapter and used
for
+++ mounting the servlet at that URI context.</p>
--- <p>The declaration also contains a property: <tt>path=/test3</tt>, that is
--- looked up by the whiteboard adapter and used for mounting the servlet at
that
--- URI context.</p>
+++ <p>This far we can see that by using what OSGi implementations already
provide
+++ and enhanced by some minimal glue code [6], we get the possiblity to
dynamically
+++ register (and unregister) servlets within a webapp. In the next step we
will see
+++ how these servlets can share (dynamic) components.</p>
--- <p>This far we can see that by using what OSGi implementations already
contain
--- and some minimal glue code [6], we get the possiblity to dynamically
register
--- (and unregister) servlets within a webapp.</p>
---
--- <p>In the next step we will see how these servlets can share (dynamic)
--- components.</p>
---
<h1>Component Management</h1>
<p>Actually we already have inter block component management from OSGi. A
bundle
(block) can provide components by declaring them as services and it can
depend
on other components, possibly from other bundles by declaring them as
references.</p>
--- <p>More specifically, for a servlet to depend on some components, we can
add a
--- number of set (and unset if we want dynamism) methods to it, and add the
--- corresponding references in its declaration.</p>
+++ <p>More specifically, for a servlet that should depend on some components,
we
+++ can add a number of set (and unset if we want dynamism) methods to it, and
add
+++ the corresponding references in its declaration.</p>
<p>So, by just using OSGi, we get much of what the block architecture is
--- intended for: dynamic component handling, packaging of servlets (sitemaps),
--- sharing of components between blocks.</p>
+++ intended for:</p>
+++ <ul>
+++ <li>dynamic component handling</li>
+++ <li>packaging of servlets (sitemaps)</li>
+++ <li>sharing of components between blocks.</li>
+++ </ul>
+++
<h1>Component Manager Bridges</h1>
<p>While DS is neat, it is not as flexible and powerful as Spring and we
still
--- have our legacy of Avalon components to take care of.</p>
+++ have our legacy of components to take care of.</p>
<p>To create a bridge between OSGi services and Spring or Avalon component
--- management we need two kind of adapters:</p>
+++ management we need an adapter:</p>
<ul>
--- <li>An OSGi service to ServiceManager (or BeanFactory) adapter. This adapter
--- just implement ServiceManager (or BeanFactory) and lookup the components
OSGi
--- services. It could be registered as an OSGi service it self and refered to
by
--- other components that needs a ServiceManager. We can even get dynamism by
--- creating the adapter with DS and explicitly list the services that it
should be
--- able to provide, as references.</li>
--- <li>A Spring component manager to OSGi services adapter. This adapter
register
--- all the components that is created by the Spring container as services. By
--- letting the Spring container have a OSGi service to BeanFactory adapter as
+++ <li>A Spring component manager to OSGi services adapter (see
+++ <tt>OSGiSpringECMFactory </tt>in the diagram above). This adapter registers
all
+++ the components that is created by the Spring container as services. By
letting
+++ the Spring container have a OSGi service to <tt>BeanFactory </tt>adapter as
parent component manager, the Spring component manager can use components
from
other blocks as well, while creating new components.</li>
</ul>
--- <p>We have already implemented this kind of bridge for ECM++ [7]. Now we
need to
--- implement it for the new Spring based container.</p>
---
<h1>Inter Block Communication</h1>
<p>The servlets (sitemaps) in the different blocks need to be able to call
each
other. Also it simplifies reuse of blocks if one block can extend another
one
(or rather that a servlets in one block can extend a servlet in another
one).
--- This is achieved with the block protocol.</p>
+++ This is achieved with the <tt>block </tt>protocol.</p>
<p>One way of thinking about the inter block communication is to consider
the
--- servlet in the block to be embedded in an own container where the the
servlets
--- of the other blocks are available through the servlet context. This is the
way I
--- have implemented it, so other servlets can be called through the
--- getNamedDispatcher method of the servlet context, with the block name as
--- argument.</p>
+++ servlet in the block to be embedded in an own container where the servlets
of
+++ the other blocks are available through the servlet context. This is the way
it
+++ is implemented, so that other servlets can be called through the
+++ <tt>getNamedDispatcher</tt> method of the servlet context, with the block
name
+++ as argument.</p>
<p>The implementation of calls to super blocks and polymorphism requires
the use
of a call stack, see [8] for details.</p>
<p>Block properties are accessed as servlet config (and context) init
parameters.</p>
--- <p>In the OSGi implementation there is a BlockServlet that sets up the the
--- communication with other blocks and creates the context that the servlet of
the
--- own block is executed within. A declaration of a BlockServlet might look
like:
--- </p>
+++ <p>In the OSGi implementation there is a <tt>BlockServlet</tt> that sets up
the
+++ the communication with other blocks and creates the context that the
servlet of
+++ the own block is executed within. A declaration of a BlockServlet might look
+++ like:</p>
<pre> <scr:component name="cocoon.blockServlet2">
<scr:implementation
class="org.apache.cocoon.blocks.osgi.BlockServlet"/>
(12 equal lines skipped)
</pre>
<p>Here we can see that we provide a service with the identifier
--- "cocoon.blockServlet2" that is implemented by the mentioned BlockServlet and
--- implements Servlet, it is mounted on the path "/test2". So the "whiteboard"
part
--- of the dispatcher described above, will take care of installing this block
--- servlet in the HttpService of the framework.</p>
+++ <tt>cocoon.blockServlet2 </tt>that is implemented by the mentioned
BlockServlet
+++ and implements <tt>javax.servlet.Servlet</tt>, it is mounted on the path
+++ <tt>/test2</tt>. So the <em>whiteboard</em> part of the dispatcher described
+++ above, will take care of installing this block servlet in the
+++ <tt>HttpService</tt> of the framework.</p>
--- <p>The servlet reference with the special name "blockServlet" (should find a
--- less confusing name) refer to the servlet that is embedded by the
BlockServlet.
--- The embeded servlet could e.g. be a sitemap servlet, and it could get the
--- components it needs through the mechanism described in the sections about
--- component management above.</p>
+++ <p>The servlet reference with the special name "<tt>blockServlet</tt>"
refesr to
+++ the servlet that is embedded by the <tt>BlockServlet</tt>. The embeded
servlet
+++ could e.g. be a <tt>SitemapServlet</tt> (= a servlet that uses the Cocoon
+++ sitemap processor), and it could get the components it needs through the
+++ mechanism described in the sections about component management above.</p>
--- <p>The "target" attribute in a reference can contain constraints on what
service
--- that is refered to. The constraint "(component.name=cocoon.servlet2)" means
that
--- we want the particular servlet that is registered under the name
--- "cocoon.servlet2". The constraint lanuage is the same as is used in LDAP,
and it
--- is possible to create rather complex constraints if needed.</p>
+++ <p>The <tt>target</tt> attribute in a reference can contain constraints on
what
+++ service that is refered to. The constraint
+++ <tt>(component.name=cocoon.servlet2)</tt> means that we want the particular
+++ servlet that is registered under the name "cocoon.servlet2". The constraint
+++ lanuage is the same as is used in LDAP, and it is possible to create rather
+++ complex constraints if needed.</p>
<p>We can also see that there is a reference to a block servlet with the
--- identifier "cocoon.blockServlet1", it will be made available through the
--- servlet context for "cocoon.servlet2" with the getNamedDispatcher method
using
--- the name "block1".</p>
+++ identifier <tt>cocoon.blockServlet1</tt>, it will be made available through
the
+++ servlet context for <tt>cocoon.servlet2</tt> with the
+++ <tt>getNamedDispatcher</tt> method using the name <tt>block1</tt>.</p>
--- <p>All the properties (path and attr) are made available as init parameters
in
--- the servlet context for "cocoon.servlet2".</p>
+++ <p>All the properties (<tt>path</tt> and <tt>attr</tt>) are made available
as
+++ init parameters in the servlet context for <tt>cocoon.servlet2</tt>.</p>
--- <p>As we can see, the above DS configuration of a block servlet take care of
--- most of what is configured in block.xml in the current block
architecture.</p>
+++ <p class="note">As we can see, the above DS configuration of a block servlet
+++ takes care nearly everything that was configured in the former block.xml,
which
+++ got obsolete.</p>
<h1>The Block Protocol</h1>
--- <p>OSGi have an URL service that make it possible to dynamically add
protocols
--- that are available through java.net.URL, much like the Excalibur sources. I
have
--- reimplemented the block source as an URLConnection that is registered as a
--- protocol and can be used like in [9] (still buggy code).</p>
+++ <p>OSGi has a URL service that make it possible to dynamically add protocols
+++ that are available through <tt>java.net.URL</tt>, much like the Excalibur
+++ sources. The block source was reimplemented as an URLConnection that is
+++ registered as a protocol and can be used like in [9].</p>
<h1>Links</h1>
(31 equal lines skipped)
Fields
======
no changes
Links
=====
no changes
Custom Fields
=============
no changes
Collections
===========
no changes