2.4 The Chaupal JP2P Factories
Every factory is responsible for a single JP2P component. In fact, one
could say that the JP2P XML file represents the factories that are
needed, rather than the components. When a JP2P project is launched, the
builder:
- parses the jp2p-1.0.0.xml file globally to see if all the required
factories are available
- parses the file in more detail, in order to fill the factories
with the required data
- completes the builder with factories that are needed by others
- Runs the factories in order to build the JP2P container.
If a container is not built, it usually means that a builder is not
registered as a declarative service. You will see this in the console,
through a message that complains that the builder is waiting for a
certain factory (e.g: NetworkManagerFactory if the JXTA TM platform
bundle is not activated).
A factory not only creates a corresponding JP2P component, but it
actually starts by creating a property source. The property
source actually contains the values that are depicted in the XML file,
and come in two flavours:
- net.jp2p.container.properties.IJp2pDirectives (the XML attributes)
- net.jp2p.container.properties.IJp2pProperties (XML properties)
Although the distinction between these is not rigid, one could say
that, in general, a directive provides information for the factory,
while the properties are needed to configure the JP2P component.
If we look at the configuration file we made in the previous section:
<?xml version='1.0' encoding='UTF-8'?>
<jp2p-container id="org.chaupal.rdv" name="RDV" auto-start="true">
<properties>
<home-folder>${user.home}/.jxta/${bundle-id}</home-folder>
</properties>
<persistence-service context="chaupal"/>
</jp2p-container>
we can see that the builder gets a directive to
auto-start the container, and that one of the properties of the
container itself is the location of the home folder.
2.4.1: The Build Sequence of a JP2P
Component Factory
When the builder is ready to run a factory, it follows a certain
procedure:
- It creates the property source and adds it to a tree of property
sources
- it adds property sources that are needed to successfully build a
component
- When the tree of property sources is complete, it starts to build
the components
- Depending on the type and the provided directives, the services
are started
The build process of the components does not follow the tree
structure of the property sources. Instead, every factory is notified
of the various states that other factories are in, and they can
proceed when the correct conditions are met. For instance, the net.jp2p.chaupal.jxta.platform;NetworkManagerFactory
should not start if the net.jp2p.chaupal.jxta.platform.configurator.NetworkConfiguratorFactory
is not ready. Therefore the construction of the NetworkManager
component is delayed until all the configuration properties have been
set.
The builder therefore dispatches a number of net.jp2p.container.builder.ICompositeBuilderListener.BuilderEvents
to all the factories:
- PROPERTY_SOURCE_PREPARED
- PROPERTY_SOURCE_CREATED
- COMPONENT_PREPARED
- COMPONENT_CREATED
- COMPONENT_STARTED
- FACTORY_COMPLETED
There are two types of factories, which implement a corresponding
interface:
- net.jp2p.container.factory.IPropertySourceFactory
- net.jp2p.container.factory.IComponentFactory
Obviously the latter is derived from the former. As may be expected, a
propertysource factory does not create a JP2P component, but just
properties. The net.jp2p.container.startup.StartupServiceFactory
is a good example of this type of factory, as it little more than follow
the BuilderEvents, and start a service if these happen
to be created. The net.jp2p.container.log.LoggerFactory
is another fine example, as it displays information on the build
process, and is no longer needed once the container is complete.
A special type of propertysource factories have been implemented for net.jp2p.chaupal.jxta.platform.configurator.NetworkConfiguratorFactory.
If we take a closer look at the jp2p-1.0.0.xml file:
<?xml version='1.0' encoding='UTF-8'?>
<jp2p-container id="org.chaupal.rdv" name="RDV" auto-start="true">
...
<network-configurator>
<properties></properties>
<tcp>
<properties>
<port>9715</port>
<incoming-status>true</incoming-status>
<outgoing-status>true</outgoing-status>
</properties>
</tcp>
<http>
<properties>
<port>8081</port>
<incoming-status>true</incoming-status>
<outgoing-status>true</outgoing-status>
</properties>
</http>
<multicast enabled="true"/>
</network-configurator>
...
</jp2p-container>
we see that the properties of the NetworkConfigurator have been grouped
together in logical units, such as http tcp, multicast and so on.
Internally, the NetworkConfiguratorFactory is
completed by a number of property source factories that complete
the platform settings.
A property source factory implements the net.jp2p.container.builder.ICompositeBuilderListener
interface, which contains one method:
public void notifyChange(
ComponentBuilderEvent<T> event );
Every factory must override this method in order to determine when a
next state of the factory should start.
The component factories provide a getComponent() method
that is used to fill the container. After the build process has
completed, only these components are therefore available in the
container, as the factories and builders are cleaned up and removed from
the VM.
A consequences of this approach is that a lot of services can be
positioned anywhere in the XML file;
<?xml version='1.0' encoding='UTF-8'?>
<jp2p-container id="org.chaupal.rdv" name="RDV" auto-start="true">
<network-manager clear-config="true">
<network-configurator>
<tcp>...</tcp>
<http>...</http>
<multicast enabled="true"/>
</network-configurator>
</network-manager>
</jp2p-container>
The parent-child structure of the above XML file is more a matter of
convention than that the parser requires this; as long as the
factories start the creation of JP2P components at the correct moment,
the container should be built in the cortrect fashion. The structure does
have consequences for the way the components are stored in the
container (and displayed in the UI). As a result, a JP2P container
tends to be flatter than than the corresponding JXTATM
application.
Licensing...
JXTA is a registered trademark of Sun Microsystems/Oracle.
JXSE is still governed
by the JXTA license, which cannot be
changed. New code by Chaupal that extends/modifies JXSE is governed by
the Apache License, version 2.0, and must be committed to the JP2P
GitHub repository.