11 Replies Latest reply on Apr 6, 2006 8:05 AM by aloubyansky

    Schema Imports

      Here's another test, this time imports. :-)

      See: org.jboss.test.xml.ExtendedByImportUnitTestCase

      I want to extend a type from another schema.
      I understand that I need to rebind the type in my schema
      that I want to extend, but do I really need to rebind all the other
      artifacts from the schema I imported?

      <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
       targetNamespace="urn:jboss:test-extended:1.0"
       xmlns="urn:jboss:test-extended:1.0"
       xmlns:mc="urn:jboss:bean-deployer:2.0"
       elementFormDefault="qualified"
       attributeFormDefault="unqualified"
       version="1.0"
      >
      
       <xsd:import namespace="urn:jboss:bean-deployer:2.0"/>
      
       <xsd:element name="extended" type="extendedType"/>
      
       <xsd:complexType name="extendedType">
       <xsd:complexContent>
       <xsd:extension base="mc:beanType"/>
       </xsd:complexContent>
       </xsd:complexType>
      
      </xsd:schema>
      


      <extended xmlns="urn:jboss:test-extended:1.0"
       xmlns:mc="urn:jboss:bean-deployer:2.0"
       name="TestAspect" class="TestClass">
       <mc:property name="testProperty">testString</mc:property>
      </extended>
      


      If I add the binding for the property to my schema
      (the commented code) it works,
      but shouldn't it be using the schema bindings from the imported
      schema? Rather than forcing me to rebind everything in mine?

      public class ExtendedSchemaInitializer implements SchemaBindingInitializer
      {
       /** The namespace */
       public static final String EXTENDED_NS = "urn:jboss:test-extended:1.0";
      
       /** The extended binding */
       private static final QName extendedTypeQName = new QName(EXTENDED_NS, "extendedType");
      
       public SchemaBinding init(SchemaBinding schema)
       {
       // extended binding
       TypeBinding extendedType = schema.getType(extendedTypeQName);
       BeanSchemaBindingHelper.initBeanHandlers(extendedType);
       extendedType.setHandler(new BeanHandler()
       {
       public Object startElement(Object parent, QName name, ElementBinding element)
       {
       return new Extended();
       }
       });
      
       /*
       TypeBinding propertyType = schema.getType(BeanSchemaBinding20.propertyTypeQName);
       BeanSchemaBindingHelper.initPropertyHandlers(propertyType);
       */
      
       return schema;
       }
      }
      


        • 1. Re: Schema Imports

          Actually, even the commented out code doesn't work properly.
          It is invoking the endElement() of the interceptor rather than the add()

          • 2. Re: Schema Imports

            Ignore that last comment. It was my test that was broken :-)

            • 3. Re: Schema Imports
              aloubyansky

              The way it currently works, schema import/include are handled by Xerces. When Xerces parses an XSD it creates an instance of XSModel (Xerces' schema API) and imports/includes other XSDs into the XSModel instance. JBossXB/XsdBinder works with the resulting XSModel instance. So, it's not like we import/include one JBossXB SchemaBinding into another one as you would expect.

              But I agree with your expection. There is an initializer registered for the imported schema that should be run before the initializer of the importing schema.

              • 4. Re: Schema Imports
                aloubyansky

                But actually it still would not be the same as importing one SchemaBinding into another one since imported schemas are re-parsed/re-bound.

                • 5. Re: Schema Imports

                  Why doesn't it just resolve the schema binding based on the namespace?

                  In this case, when it hits mc:property it delegates to the schema binding
                  for "urn:jboss:bean-deployer:2.0"

                  This is the way I had it working in my prototype:

                  
                   public ElementBinding AbstractSchemaBinding::resolveElement(QName name)
                   {
                   if (name == null)
                   throw new IllegalArgumentException("Null name");
                  
                   ParticleBinding binding = (ParticleBinding) elementsByName.get(name);
                   // Not a local name
                   if (binding == null)
                   {
                  ...
                   // Use the resolver to get the element if it is not the current namespace
                   String uri = name.getNamespaceURI();
                   if (uri.equals(targetNamespace) == false)
                   {
                   String schemaLocation = null; // @todo schemaLocation 4
                   SchemaBinding schema = AbstractSchemaBindingResolver.resolveSchemaBinding(true, null, schemaBindingResolver, uri, null, schemaLocation);
                   return schema.resolveElement(name);
                   }
                   // @todo exception element not installed
                   throw new IllegalStateException("Element not installed " + name);
                   }
                   return (ElementBinding) binding.getTerm();
                   }
                  


                  • 6. Re: Schema Imports
                    aloubyansky

                    It does so when it has to resolve a wildcard content element. But import/include are not done by JBossXB.

                    • 7. Re: Schema Imports

                      Yes, but couldn't JBossXB weed out the foreign namespace
                      then do a similar thing as the wildcard process for it?

                      • 8. Re: Schema Imports
                        aloubyansky

                        It's an alternative.

                        What if SchemaBindingResolver is not provided?
                        I guess, one could be created internally.

                        What if schema initializer associated with the importing schema wants to customize bindings for the imported schema?
                        Probably, it would have to clone the component to be customized with all its children and copy into the importing schema. This doesn't look nice.

                        • 9. Re: Schema Imports

                          Wouldn't customising the bindings locally
                          be the exception rather than the rule?

                          Normally, you would do like I did.
                          i.e. extend the base type and initialize it locally
                          but it is still likely to reference particles from the other binding
                          which you don't want to redo yourself.

                          • 10. Re: Schema Imports
                            aloubyansky

                            I don't know what would be an exception at this moment.

                            I am not saying you should redo referenced bindings yourself. To fix this we have at least two alternatives to choose from.

                            An advantage I can see in your suggestion is that if we look at SchemaBindingResolver as a library of SchemaBindings then it probably should not contain multiple versions of the same schemas (in different SchemaBinding instances). Or maybe it's ok... :)

                            • 11. Re: Schema Imports
                              aloubyansky

                              The issue for this

                              xsd:import and schema binding initializer
                              http://jira.jboss.com/jira/browse/JBXB-60