The ComponentComplex
interface extends the Component interface to provide additional
functionality. Some functionality is provided through the use
of special parameters in asynchronous and synchronous connections.
Other functionality is provided through the use of policies. The
following are discussed here:
- Loading a policy
- Providing a synchronous service
- Using a service
- Subscribing to an asynchronous service
- Publishing an asynchronous service
Loading a policy. The LoadPolicy() method
provides a way for a component to instantiate policies. Policies
provide a level of abstraction outlining environmental details
that are used for inter-component communication. For example,
a component providing a service can specify a policy that contains
attributes that describe the service, and user interfaces that
can be built for the service. A component using a service can
specify a policy that requests a service with certain attributes.
Putting these values in a policy allows the details to be isolated
from the application code and be configurable at any time. More
information about policies can be found in the Defining Polices
and Using Policies sections
of this tutorial. For example, in ImageServiceImpl.java
(see Image demo), the following code retrieves a PolicyLoader
and gets the policy.
policyLoader = component.getPolicyLoader();
ImagePolicy policy = (ImagePolicy) policyLoader.getPolicy(ImagePolicy.class,
"");
This example can be also used to demonstrate what a
service attribute defined in a policy could look like. Here
ImageServiceImpl is interested in retrieving images
for display. The policy has an attribute that contains the location
of these images. For clarity, the policy is shown below.
<?xml version="1.0" encoding="UTF-8"?>
<ImagePolicy xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xsi:noNamespaceSchemaLocation='ImagePolicy.xsd'
playlistDirectory="<some path>/Image_im/data/"
/>
We haven't talked about policies
yet (that information is forthcoming) but notice the attribute
"playListDirectory". When the policy is generated, an accessor
method will be created that will allow retrieval of the playList.
Now that ImageServiceImpl has the policy object, all it needs
to do is use
HashMap playListDir = policy.getPlayListDirectory();
to retrieve the required images.
Providing a synchronous service. The provideService()
method is used to make a synchronous (remote method) service available
to other components. A variant of this method includes the use
of a ProvideServiceParameters object which describes how the service
is provided. ProvideServiceParameters allows you to specify configuration
information and behavior relevant to providing services, including:
- Attributes of the service (standard and custom)
- User Interfaces that can be attached to the service
This object can be stored in a ProvideServicePolicy to make
it configurable at deployment time.
The attributes of a service can be easily supplied using the
Openwings Attribute
class. An attribute is a designated key/value pair. An example
of setting attributes for a service would be setting a String
"host" (key) to an ip address (value). A good
example of using parameters can be found in the ServiceUI Development
of this tutorial. Another example shown below is from ImageServiceImpl.java
(see Image demo):
ProvideServiceParameters parameters = new ProvideServiceParameters();
parameters.setDisplayName("ImageService");
parameters.addUserInterfaceFactory(new ImageUIFactory());
parameters.setIconResource("com/gd/openwings/demo/image/ui/image.jpg");
parameters.setServiceDescription("This service
implements the ImageService interface.");
parameters.setServiceName("ImageService");
component.provideService(ImageService.class,
component.distributeObject(ImageService.class,
this), parameters);
Using a service. The useService() method
is overloaded. All variations take a service interface as the
first parameter. This method finds multiple synchronous (remote
method) services provided by another component. Another variant
of this method takes a UseServiceParameters object as one of its
parameters, which can be used to affect how the service is selected
and attached. With this, you can:
- get the first available service
- get all services available. Should the current service go
away, it will be replaced with another available service
- replace the current service with a specified service
An example of a component using useService() can
be seen in HelloWorldUser.java.
Notice HelloWorldUser.java takes the interface object and
a UseServiceListener object (HelloWorldUser implements UserServiceListener)
as parameters.
component.useService(HelloWorldServiceSynchronous.class, this);
Thus, a
UseServiceListener can be used to register ongoing interest in
certain services.
Below is a different example where the Install component takes a UseServiceParameters
object as a parameter.
//
Discovering an installer
Attribute[] a = new Attribute[] { new Attribute("host",
host) };
UseServiceParameters usp = new UseServiceParameters();
usp.setRequiredAttributes(a);
ComponentComplex componentComplex =
ComponentFactory.getComponentComplex();
ServiceResult[] sr = componentComplex.useService(Installer.class,
usp);
Subscribing to an asynchronous service. The subscribeService()
method is used to indicate interest in subscribing to an asynchronous
(event or messaging) service. A variant of the subscribeService()
method adds a EventServiceParameters object which can be used
to determine the event space for this service, even at deployment
time or runtime.
subscribeService(someServiceAsynchronous.class, this, esp);
Publishing an asynchronous service. The publishService()
method is used to provide a service with an EventServiceParameters
object. Here is an example:
ServiceResult result =
component.publishService(someServiceAsynchronous.class);
Next: Failure
Recovery