You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ws.apache.org by Apache Wiki <wi...@apache.org> on 2006/04/16 00:57:13 UTC

[Ws Wiki] Update of "Tuscany/Extending/StAXLoading" by JeremyBoynes

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.