Policies provide a bridge through which components can interact
with their run-time environment. This effectively decouples a
component from its environment so that the component can be deployed
in different environments without modification to the component.
XML
Policy files are in the form of XML and XSD files so it’s advantageous
to know something about XML and XSD. XML (Extensible Markup Language)
provides a way to make data portable by using HTML-like tags.
Briefly, XML separates data, content and the presentation of how
text is to be displayed. XSD (Extensible Structure Definition)
provides the schema for the data content outlined in XML files.
Additional information about XML and XSD can be found
here.
The use XML and XSD files is a tool Openwings uses to make the
development and execution of software platform independent.
Policies
Either a Systems Engineer or a Component Developer defines a
policy for a particular application domain. This individual will
define the policy, generate the policy and edit the policy.
The Policy Generator tool is used to generate policies from interface
definitions. Given a compiled interface, the generator uses introspection
to create Java source code for classes that implement the policy,
the XML policy definition (in schema or DTD form), and a sample
XML data file that complies with the implementation. This includes
parsing code that can be modified, compiled, and executed to generate
actual XML files.
There are three issues to consider before generating a policy.
If your interface is in net.openwings, then a policy has already
been generated so you probably don’t need to generate another
one. If you have created a user defined interface, then you will
need to follow the instructions in steps 1 and 2 to generate your
policy. Step 1 (Generating a Policy) is something that will be
done once. Step 2 (Create Policy Objects) is what will need to
be done every time values in the policy attributes are changed.
Make sure the user defined interface has been compiled before
you start to generate your policy in step 2.
Finally, if your component is an executable component to be run
on Container Services, you can generate your policy by using the
Installable Component Descriptor Editor. The editor creates an
InstallableComponentDescriptorPolicy.xml
file (also referred to as a policy ) and this policy is
very complete for an executable component. Details of the editors
reside in the Packaging
section of this trail. Note: The InstallableComponentDescriptorPolicy
file is a very important piece to Openwings. You'll be seeing
references to it in the next few trails.
For now, we’ll address the use of a user defined interface.
Generating a Policy for a User defined Interface
Step 1: Policy Generation. There may be instances when
a user-defined interface will be necessary. Consider a case where
one might want to create a video streaming server policy so that
components interested in a particular video streaming service
can request one via some identifier. The policy for this service
is shown below:
|
/*
* Copyright 2002, General Dynamics Decision Systems, Inc.
* All rights reserved.
*/
package com.gd.sample.gok.video;
import net.openwings.policy.Policy;
public interface VideoStreamingServerPolicy extends Policy
{
public void setIdentifier (String videoSourceIdentifier);
public String getIdentifier ();
}
|
After the user defined interface is created, it must be generated.
We use Ant make files when generating policies. We discuss the
details of Ant code elsewhere in this trail. For now, to generate
a policy for your component, simply use the command line to change
directory to where your build.xml file resides and type:
ant imagepolicy
This assumes a target "imagepolicy" resides in the
build.xml file and that this target performs steps to generate
policies. Generating a policy for your service produces the following:
|
File
|
Filename example
|
|
Policy Implementation File
|
<componentName>PolicyImpl.java
|
|
Policy Schema
|
<componentName>Policy.xsd
|
|
Policy Sample XML File
|
<componentName>PolicySample.xml
|
|
Policy Saver
|
<componentName>PolicySaver.java
|
- Policy Implementation File - is auto generated by the policy
builder and should not be modified.
- Policy Schema – this is your XSD file, sometimes referred
to as the policy definition file. It is used in conjunction
with your xml file.
- Policy Sample – is a sample XML file that will be used to
generate a final XML file.
- Policy Saver – is a Java program that can be modified and
will be used to generate the policy XML file.
The Policy Implementation file that was created by the policy
builder is shown below. This code is autogenerated and should
not be modified. It is displayed for information purposes.
|
// This code was autogenerated by com.gd.openwings.PolicyBuilder
on <date>
package com.gd.sample.gok.video;
import com.gd.sample.gok.video.VideoStreamingServerPolicy;
import com.gd.openwings.policy.core.Sax2ParsingPolicy;
// XML imports
import org.xml.sax.*;
public class VideoStreamingServerPolicyImpl extends
com.gd.openwings.policy.core.Sax2ParsingPolicy
implements
VideoStreamingServerPolicy
{
private static final String NAME = "VideoStreamingServerPolicy";
private static final String [] ATTRIBUTES = {"identifier"};
private java.lang.String identifier;
public final java.lang.String getIdentifier()
{
return identifier;
}
public final void setIdentifier(java.lang.String
identifier)
{
this.identifier = identifier;
setPolicyUpdated(true);
}
// inherit comment from interface
public String getName()
{
return NAME;
}
/**
* Returns an array of strings that contains the
* attributes for the policy
* in the order defined in the schema.
*
* @return array of strings containing attributes
*/
public String [] getPolicyAttributes ()
{
return ATTRIBUTES;
}
public void parseElement(String tag, Attributes
attrs)
throws SAXException
{
try
{
if (tag.equals("VideoStreamingServerPolicy")
&& attrs != null)
{
identifier = net.openwings.identity.PropertyInitializer.translate(
attrs.getValue("identifier"));
}
}
//catch any exception, if already a SAXException,
//rethrow, otherwise, embed in a SAXException
catch(Exception e)
{
if (e instanceof SAXException)
{
throw (SAXException) e;
}
else
{
throw new SAXException("Parsing
error in :parseElement.", e);
}
}
}
}
|
The XSD file generated by the policy builder is
shown here:
|
<?xml version="1.0" encoding="UTF-8"?>
<!-- This code was autogenerated by com.gd.openwings.PolicyBuilder
on -->
<!-- Do not change it manually unless you know what
you are doing. -->
<schema>
<element name="VideoStreamingServerPolicy">
<complexType content="empty">
<attribute name="identifier" type="string"/>
</complexType>
</element>
<simpleType name="char" base="string">
<minLength value='0'/>
<maxLength value='1'/>
</simpleType>
</schema>
|
The code generator (or policy builder) also created
a policy saver file. Modifications to this file are discussed
next.
Step 2: Create Policy Objects. If a <componentName>PolicySaver.java
file was created, then it may be compiled to populate the XML
file generated in step 1. Before compiling this source file,
however, it must be edited to include the values that
will be used in the final policy xml file. This is done because
the <componentName>PolicySaver.java
serializes the non-primitive, non-String, non-Class objects
into human-readable form that can be placed into an XML file.
Below is policy saver code for our example VideoStreamingServerPolicy.
Notice a value had been assigned (H1800SampleVideo) to the identifier
attribute.
|
package com.gd.sample.gok.video;
import net.openwings.policy.PolicyException;
import java.io.File;
public class VideoStreamingServerPolicySaver
{
private static final int ARGUMENT_LENGTH = 1;
public static void main (String [] args)throws
PolicyException
{
if (args.length != ARGUMENT_LENGTH)
{
System.err.println ("usage:
VideoStreamingServerPolicySaver savePolicyFileName");
System.exit (-1);
}
com.gd.sample.gok.video.VideoStreamingServerPolicyImpl
policy = new
com.gd.sample.gok.video.VideoStreamingServerPolicyImpl
();
java.lang.String identifier = H1800SampleVideo;
policy.setIdentifier (identifier);
policy.savePolicy (new File (args[0]));
}
}
|
After making these data additions, the <componentName>PolicySaver.java
can be compiled using the ANT command:
ant providepolicy
It is assumed a target "providepolicy"
resides in the build.xml file and this target performs a step
to create the final policy.xml file. The resultant policy file
will be used by Component Services to execute your component.
The figure below depicts the policy generation process.

Click for full size image
Note: Be sure that the <componentName>.class
and <componentName>Impl.class are
in a directory structure that matches the package hierarchy.
Also, make sure that the <componentName>.xsd
and <componentName>Sample.xml
are in the "policies" directory. (see the Packaging
section of the Getting Started trail for more details about
directory structure).
Another Example Using Image Demo
The Image demo provides you with an opportunity
to experiment with the policy builder and observe results on
your own. We will also use the Image demo to demonstrate what
Ant build code you will need so that you can generate policies.
The complete build code can be found in the build.xml file for
the Image_im (provider) component. It is assumed you have already
reviewed the Component
Compilation section of this tutorial and have been introduced
to Ant.
Consider component Image_im, part of the demo
applications. This component is responsible for providing the
image service and one of the ways this is done is through the
use of a user defined policy. Specifically, the policy provides
the location of playlists, a series of gif images that are used
by Image Service. The policy interface is shown:
|
/*
* Copyright 1999, General Dynamics Decision Systems,
Inc.
* All rights reserved.
*/
package com.gd.openwings.demo.image.provider;
import net.openwings.policy.*;
/**
* This interface is used to configure the Image Service
*
* @version 0.1
*/
public interface ImagePolicy extends Policy
{
/**
* This method is used to set playlist directory.
*
* @param projectName is the directory of the playlist.
*/
public void setPlaylistDirectory(String mapFile);
/**
* This method is used to get the playlist directory.
*
* @return a string representing the directory of the
playlist.
*/
public String getPlaylistDirectory();
}
|
The ANT code shown below performs the policy generation (Step
1):
|
<!-- This target will generate and create the image
policy -->
<target name="imagepolicy">
<!-- generate the ImagePolicy -->
<java classname="com.gd.openwings.policy.core.PolicyBuilder"
fork="yes">
<sysproperty key="com.gd.openwings.policy.core.ParserBuilder"
value="com.gd.openwings.policy.core.SaxParserBuilder"/>
<classpath>
<pathelement location="${classes}"/>
<pathelement location="${targetClassDir}"/>
<pathelement location="${sunXmlHome}/lib/xml.jar"/>
<pathelement location="${xercesHome}/lib/xerces.jar"/>
<pathelement location="${libDir}/ow_policy.jar"/>
<pathelement location="${libDir}/gd_policy_core.jar"/>
<pathelement location="${libDir}/gd_identity.jar"/>
</classpath>
<arg value="${package}.ImagePolicy"/>
<arg value="${package}"/>
</java>
<!-- the policy gets generated under a sub-directory
-->
<copy todir=".">
<fileset dir="${relativeSrcDir}" includes="ImagePolicyImpl.java"/>
</copy>
<copy todir="policies">
<fileset dir="${relativeSrcDir}" includes="*.xml"/>
</copy>
<copy todir="policies">
<fileset dir="${relativeSrcDir}" includes="*.xsd"/>
</copy>
<javac srcdir="."
destdir="${srcDir}"
debug="on"
includes="ImagePolicyImpl.java" >
<classpath>
<pathelement location="${classes}"/>
<pathelement location="${targetClassDir}"/>
<pathelement location="${sunXmlHome}/lib/xml.jar"/>
<pathelement location="${xercesHome}/lib/xerces.jar"/>
<pathelement location="${libDir}/ow_policy.jar"/>
<pathelement location="${libDir}/gd_policy_core.jar"/>
<pathelement location="${libDir}/gd_identity.jar"/>
<pathelement location="${libDir}/ow_identity.jar"/>
</classpath>
</javac>
<!-- save the ImagePolicy -->
<java classname="com.gd.openwings.demo.image.ImagePolicySaver"
fork="yes">
<classpath>
<pathelement location="${classes}"/>
<pathelement location="${targetClassDir}"/>
<pathelement location="${sunXmlHome}/lib/xml.jar"/>
<pathelement location="${xercesHome}/lib/xerces.jar"/>
<pathelement location="${libDir}/ow_policy.jar"/>
<pathelement location="${libDir}/gd_policy_core.jar"/>
<pathelement location="${libDir}/gd_identity.jar"/>
<pathelement location="${libDir}/ow_identity.jar"/>
</classpath>
<arg value="${targetSrcDir}/policies/ImagePolicy.xml"/>
</java>
</target>
|
Change directory to where you have installed this component and
execute the command:
ant imagepolicy
Notice "imagepolicy" is the ANT target name. This snippet
of code generates three files:
- ImagePolicyImpl
- ImagePolicySaver
- ImagePolicy.xml
The ImagePolicyImple file is autogenerated by the policy builder
and does not need to be modified. The ImagePolicySaver code is
shown below. The last file generated, is the final policy xml
file that is needed in reference to the interface described earlier.
In this case, the final policy xml file does not need to be modified.
|
package com.gd.openwings.demo.image.provider;
import net.openwings.policy.PolicyException;
import java.io.File;
public class ImagePolicySaver
{
private static final int ARGUMENT_LENGTH = 1;
public static void main (String [] args)throws
PolicyException
{
if (args.length != ARGUMENT_LENGTH)
{
System.err.println ("usage:
ImagePolicySaver savePolicyFileName");
System.exit (-1);
}
com.gd.openwings.demo.image.provider.ImagePolicyImpl
policy = new
com.gd.openwings.demo.image.provider.ImagePolicyImpl
();
// TO DO Create object that is to be written
to XML file
java.lang.String playlistDirectory;
policy.setPlaylistDirectory (playlistDirectory);
policy.savePolicy (new File (args[0]));
}
}
|
At this point we have a policy that describes from where playlists
can be retrieved but what we need now is a policy that tells Component
Services how to provide this service. This is done through
the Policy Saver code. When the Policy Saver code was generated
(in this case) it was originally generated as an empty file. We
can use this to specify the needed details required.
To make things easier, we have already provided the code so that
a policy xml file will be properly created. Specifically, we chose
to use the UseServiceParameters object to describe the policy
for this service. The policy shown below sets parameters for the
Image Service by assigning values to attributes (see the UseServiceParameters
and ProvideServiceParameters API’s in Openwings Javadocs for
more details). Recall, parameters associated with a service is
one way a Component Services can identify and provide a service.
The code below shows how we have modified policy details:
|
package com.gd.openwings.demo.image.provider;
import net.openwings.policy.PolicyException;
import java.io.File;
import net.openwings.component.ProvideServiceParameters;
public class ProvideServicePolicySaver
{
private static final int ARGUMENT_LENGTH = 1;
public static void main (String [] args)throws
PolicyException
{
if (args.length != ARGUMENT_LENGTH)
{
System.err.println ("usage: ProvideServicePolicySaver
savePolicyFileName");
System.exit (-1);
}
com.gd.openwings.component.policy.ProvideServicePolicyImpl
policy = new
com.gd.openwings.component.policy.ProvideServicePolicyImpl
();
ProvideServiceParameters parameters = new ProvideServiceParameters();
java.lang.String serviceDescription =
"This service implements the ImageService
interface";
parameters.setServiceDescription (serviceDescription);
java.lang.String iconResource =
"com/gd/openwings/demo/image/ui/image.jpg";
parameters.setIconResource (iconResource);
java.lang.String serialNumber = "";
parameters.setSerialNumber (serialNumber);
java.lang.String comment = "";
parameters.setComment (comment);
java.lang.String serviceName = "ImageService";
parameters.setServiceName (serviceName);
java.lang.String displayName = "ImageService";
parameters.setDisplayName (displayName);
net.openwings.ui.UserInterfaceFactory []
userInterfaceFactories =
{ new com.gd.openwings.demo.image.ui.ImageUIFactory()
};
parameters.setUserInterfaceFactories (userInterfaceFactories);
policy.setParameters(parameters);
policy.savePolicy (new File (args[0]));
}
}
|
Finally, we can generate the final policy.xml file. This is the
portion of the build file that performs this final step:
|
<!-- This target will create the provide service
policy -->
<target name="providepolicy">
<!-- save the provideServicePolicy -->
<java classname="com.gd.openwings.demo.image.ProvideServicePolicySaver"
fork="yes">
<classpath>
<pathelement location="${classes}"/>
<pathelement location="${targetClassDir}"/>
<pathelement location="${sunXmlHome}/lib/xml.jar"/>
<pathelement location="${xercesHome}/lib/xerces.jar"/>
<pathelement location="${libDir}/ow_policy.jar"/>
<pathelement location="${libDir}/gd_policy_core.jar"/>
<pathelement location="${libDir}/gd_component_policy.jar"/>
</classpath>
<arg value="${targetSrcDir}/policies/ProvideServicePolicyImageService.xml"/>
</java>
</target>
|
The final policy generated can be found in the policies directory
of the Image_im component. You can view it here.
Note: You can easily generate the policy for this component
by typing
ant policy
The ANT code in the build.xml file:
<target name="policy" depends="imagepolicy,providepolicy">
</target>
automatically executes the policy generation step and object
creation steps for you. We did it in steps, however, to help demonstrate
what is needed should a user defined policy be required. In most
cases the the Installable Component Descriptor should be all that
is needed for your policy requirements. Details on how to create
these can be found in the Packaging
section of this trail.
Next: Using
Properties