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