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
For the location just modify the org.jboss.util.xml.JBossEntityResolver
For the initializer modify
org.jboss.util.xml.SingletonSchemaResolverFactory
/**
* 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
Comments