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 [EMAIL PROTECTED](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.

Reply via email to