Version 7

    SchemaBindingInitializer

     

    Motivation

     

    As schemas are used together, but evolve independently, there is a strong reason to not have to reference the schema file names and location in your xml or client code.

     

    Example from the AOP testsuite using the Microcontainer to construct aspects:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <aop xmlns="urn:jboss:aop-deployer">
    
       <interceptor name="SimpleInterceptor">
          <class>
             <beanfactory xmlns="urn:jboss:bean-deployer" class="org.jboss.test.kernel.SimpleInterceptor">
                <constructor>
                   <parameter>Hello</parameter>
                </constructor>
                <property name="second">World</property>
             </beanfactory>
          </class>
       </interceptor>
    
       <bind pointcut="execution(* org.jboss.test.kernel.Aspectized->*(..))">
          <interceptor-ref name="SimpleInterceptor"></interceptor-ref>
       </bind>
    
       <introduction class="org.jboss.test.Kernel.Aspectized">
          <mixin>
             <interfaces>org.jboss.Intf1,org.jboss.Intf2</interfaces>
             <class>org.jboss.Mixin</class>
             <construction>new org.jboss.Mixin()</construction>
          </mixin>
       </introduction>
    
    </aop>
    

     

    The client code that deploy this:

    /*
    * JBoss, Home of Professional Open Source
    * Copyright 2006, JBoss Inc., and individual contributors as indicated
    * by the @authors tag. See the copyright.txt in the distribution for a
    * full listing of individual contributors.
    *
    * This is free software; you can redistribute it and/or modify it
    * under the terms of the GNU Lesser General Public License as
    * published by the Free Software Foundation; either version 2.1 of
    * the License, or (at your option) any later version.
    *
    * This software is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    * Lesser General Public License for more details.
    *
    * You should have received a copy of the GNU Lesser General Public
    * License along with this software; if not, write to the Free
    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
    */
    package org.jboss.aspects.kernel.schema;
    
    import java.net.URL;
    
    import org.jboss.aop.AspectManager;
    import org.jboss.kernel.Kernel;
    import org.jboss.xb.binding.Unmarshaller;
    import org.jboss.xb.binding.UnmarshallerFactory;
    import org.jboss.xb.binding.sunday.unmarshalling.SchemaBindingResolver;
    import org.jboss.xb.binding.sunday.unmarshalling.SingletonSchemaResolverFactory;
    
    /**
     * AspectLoader.
     * 
     * @author <a href="adrian@jboss.com">Adrian Brock</a>
     * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
     * @version $Revision: 1.1 $
     */
    public class AspectLoader
    {
       /** The unmarshaller factory */
       private static final UnmarshallerFactory factory = UnmarshallerFactory.newInstance();
       
       /** The resolver */
       private static final SchemaBindingResolver resolver = SingletonSchemaResolverFactory.getInstance().getSchemaBindingResolver();
       
       /**
        * Load an aspect xml
        * 
        * @param url the url
        * @param kernel the kernel
        * @param manager the aspect manager
        * @throws Exception for any error
        */
       public static void loadXml(URL url, Kernel kernel, AspectManager manager) throws Exception
       {
          DeploymentInfo di = new DeploymentInfo(kernel, url.toString(), manager);
          DeploymentInfo.setDeployment(di);
          try
          {
             Unmarshaller unmarshaller = factory.newUnmarshaller();
             unmarshaller.unmarshal(url.toString(), resolver);
          }
          finally
          {
             DeploymentInfo.setDeployment(null);
          }
       }
    }
    

     

    You will notice that none of this references the schema name or its location. So how does it know what these are?

     

    • First, you can register schema binding initializers in a

      SchemaResolverFactory

       

    • Second, it uses the entity resolver to lookup the location of the schema and parse it

    • Third, use the

      SingletonSchemaResolverFactory.getInstance().getSchemaBindingResolver()

      to get a

      SchemaBindingResolver

      and use the versions of

      unmarshal

      that take a resolver.

     

    SchemaBindingInitializer

     

    You implement this interface to add bindings to the raw schema parsed by JBossXB (assuming the schema is not already annotated with bindings).

     

    /*
      * JBoss, Home of Professional Open Source
      * Copyright 2005, JBoss Inc., and individual contributors as indicated
      * by the @authors tag. See the copyright.txt in the distribution for a
      * full listing of individual contributors.
      *
      * This is free software; you can redistribute it and/or modify it
      * under the terms of the GNU Lesser General Public License as
      * published by the Free Software Foundation; either version 2.1 of
      * the License, or (at your option) any later version.
      *
      * This software is distributed in the hope that it will be useful,
      * but WITHOUT ANY WARRANTY; without even the implied warranty of
      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      * Lesser General Public License for more details.
      *
      * You should have received a copy of the GNU Lesser General Public
      * License along with this software; if not, write to the Free
      * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
      * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
      */
    package org.jboss.xb.binding.sunday.unmarshalling;
    
    /**
     * An implementation of this interface is given an instance of SchemaBinding
     * that is returned from XsdBinder.bind() method during schema binding resolution
     * in SchemaBindingResolver.resolve(). In the init(SchemaBinding schema) method an
     * implementation of this interface can correct/adjust bindings programmatically
     * if pure XSD with annotations binding approach was not sufficient.
     *
     * @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a>
     * @version <tt>$Revision: 1.1 $</tt>
     */
    public interface SchemaBindingInitializer
    {
       /**
        * Adjust schema binding programatically if needed.
        *
        * @param schema  just resolved schema binding returned from XsdBinder
        * @return  SchemaBinding instance with complete binding metadata
        */
       SchemaBinding init(SchemaBinding schema);
    }
    

     

    Factory settings population

     

     

       /**
        * Create a new SingletonSchemaResolverFactory.
        */
       private SingletonSchemaResolverFactory()
       {
          addSchema("urn:jboss:bean-deployer", "org.jboss.kernel.plugins.deployment.xml.BeanSchemaInitializer");
          addSchema("urn:jboss:aop-deployer", "org.jboss.aspects.kernel.schema.AspectSchemaBindingInitalizer");
       }
    

     

    Dynamic configuration

     

    A pojo/mbean is available to configure the

    SingletonSchemaResolverFactory

    this takes two property/maps for the schema initializers and locations keyed by the schema namespace.

     

    MBean configuration

    <mbean name="jboss.xb:service=SchemaResolverConfig"
           class="org.jboss.xb.binding.sunday.unmarshalling.SchemaResolverConfig">
    
       <!-- The initializers -->
       <attribute name="SchemaInitializers">
          urn:jboss:aop-deployer=org.jboss.aspects.kernel.schema.AspectSchemaBindingInitalizer
          urn:jboss:bean-deployer=org.jboss.kernel.plugins.deployment.xml.BeanSchemaInitializer
       </attribute>
    
       <!-- The locations (path name on the "classpath") -->
       <attribute name="SchemaLocations">
          urn:jboss:aop-deployer=aop-deployer_1_1.xsd
          urn:jboss:bean-deployer=bean-deployer_1_0.xsd
       </attribute>
    </mbean>
    

     

    Microcontainer configuration

    <bean name="jboss.xb:service=SchemaResolverConfig"
          class="org.jboss.xb.binding.sunday.unmarshalling.SchemaResolverConfig">
    
       <!-- The initializers -->
       <property name="schemaInitializers">
          urn:jboss:aop-deployer=org.jboss.aspects.kernel.schema.AspectSchemaBindingInitalizer
          urn:jboss:bean-deployer=org.jboss.kernel.plugins.deployment.xml.BeanSchemaInitializer
       </property>
    
       <!-- The locations (path name on the "classpath") -->
       <property name="schemaLocations">
          urn:jboss:aop-deployer=aop-deployer_1_1.xsd
          urn:jboss:bean-deployer=bean-deployer_1_0.xsd
       </property>
    </bean>
    

     

    NOTE: The

    schemaLocations

    are actually updated into the

    JBossEntityResolver

    such that the xml parser can find them.

     

    Related

     

    • XMLEntitySchemaResolution - for the

      JBossEntityResolver

      and

      DefaultSchemaResolver

      used by the

      SingletonSchemaResolverFactory

      and

      SchemaResolverConfig