ws-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Ws Wiki] Update of "Tuscany/Extending/StAXLoading" by JeremyBoynes
Date Sat, 15 Apr 2006 22:57:13 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Ws Wiki" for change notification.

The following page has been changed by JeremyBoynes:
http://wiki.apache.org/ws/Tuscany/Extending/StAXLoading

New page:
The XML used for the SCA Assembly model is structurally quite simple but very extensible;
almost every element support extension elements and the specification itself uses substitution
groups to allow specific types of implementation and binding to replace/extend key elements.
Further, the model itself makes reference to artifacts located outside the XML instance (such
as WSDL definitions, Java classes and other SCA artifacts like componentType sidefiles) that
are needed to build up the complete representation of an application.

To handle this extensibility and the external artifacts, in Tuscany we have chose to use a
streaming approach to parsing based on the Java StAX framework. Rather than load XML artifacts
into objects using a data binding technology such as SDO or JAXB, the loader framework provides
a mechanism for extension to register their willingness to parse any XML element. As the XML
file is read, elements are dispatched to registered loaders who can then handle the stream
in any way they choose. As part of processing the stream, they can also read any associated
artifacts especially those that may be needed later during the configuration loading process
(such as WSDL definitions).

To partipate in the loading process, an extension should provide a component that implements
the [https://svn.apache.org/repos/asf/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXElementLoader.java
StAXElementLoader] interface and should register that component with the framework's [https://svn.apache.org/repos/asf/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/loader/StAXLoaderRegistry.java
StAXLoaderRegistry] during initialization.

Using the [https://svn.apache.org/repos/asf/incubator/tuscany/java/sca/containers/container.js/src/main/java/org/apache/tuscany/container/js/loader/JavaScriptImplementationLoader.java
JavaScript implementation type] as an example, this would be something like:
{{{
public class JavaScriptImplementationLoader implements StAXElementLoader<JavaScriptImplementation>
{
    public static final QName IMPLEMENTATION_JS = new QName("http://org.apache.tuscany/xmlns/js/0.9",
"implementation.js");

    private StAXLoaderRegistry registry;

    @Autowire
    public void setRegistry(StAXLoaderRegistry registry) {
        this.registry = registry;
    }

    @Init(eager = true)
    public void start() {
        registry.registerLoader(IMPLEMENTATION_JS, this);
    }

    @Destroy
    public void stop() {
        registry.unregisterLoader(IMPLEMENTATION_JS, this);
    }
}}}

In this example, an instance of this component would be included with the extension. When
the extension module starts, the component is initialized immediately due to the presence
of the {{{@Init(eager = true)}}} annotation. In its init method, it registers itself with
the loader registry as a loader for elements with the QName {{{<implementation.js>}}}
in the !JavaScript extension's namespace.

As XML configuration files are being parsed, when the loader sees the registered element it
will call this component's load method to handle it. Continuing the !JavaScript example, we
see:

{{{
    public JavaScriptImplementation load(XMLStreamReader reader, ResourceLoader resourceLoader)
throws XMLStreamException, ConfigurationLoadException {
        String scriptFile = reader.getAttributeValue(null, "scriptFile");
        String style = reader.getAttributeValue(null, "style");
        String script = loadScript(scriptFile, resourceLoader);
        ComponentInfo componentType = loadComponentType(scriptFile, resourceLoader);

        JavaScriptImplementation jsImpl = factory.createJavaScriptImplementation();
        jsImpl.setComponentInfo(componentType);
        jsImpl.setScriptFile(scriptFile);
        jsImpl.setStyle(style);
        jsImpl.setScript(script);
        jsImpl.setResourceLoader(resourceLoader);
        return jsImpl;
    }
}}}

The load method is called positioned on the element to be handled ({{{<implementation.js>}}})
so that all attributes and content can be handled. The load method is responsible for parsing
the XML stream and returning an appropriate {{{AssemblyObject}}} (in this case a !JavaScriptImplementation).
In this example, the loader is using the stream directly but it could just as easily use the
data binding library of its choice. When the method returns, the reader should be positioned
on the matching element end event. 

In this case, the !JavaScript implementation needs to access two external resources that are
not part of the XML file. The source code for the script is loaded in the loadScript() method
and stored as a property in the configuration model. Similarly the component definition is
loaded from a {{{.componentType}}} sidefile by the loadComponentType() method and also stored
in the model. The resulting {{{Implementation}} object is thereby complete and the builder
can create the final component without having to load external resources.

To add the loader to the runtime configuration a {{{<component>}}} definition is added
in a SCA Assembly file:
{{{
<moduleFragment 
        xmlns="http://www.osoa.org/xmlns/sca/0.9"
        xmlns:system="http://org.apache.tuscany/xmlns/system/0.9"
        name="org.apache.tuscany.container.js">
...
    <component name="org.apache.tuscany.container.js.loader.JavaScriptImplementationLoader">
        <system:implementation.system class="org.apache.tuscany.container.js.loader.JavaScriptImplementationLoader"/>
    </component>
...
</moduleFragment>
}}}

The extension is added to the system by including this fragment on the classpath as a resource
with the name {{{system.fragment}}}.

== Summary ==

Loaders handle extensions' elements contained in SCA Assembly files. A loader is an implementation
of {{{StAXElementLoader}}} that registers itself with the runtime's {{{StAXLoaderRegistry}}}.
Extensions contribute loaders by including a {{{<component>}}} definition in a {{{system.fragment}}}
file on their classpath.

Mime
View raw message