2 Replies Latest reply on Jul 28, 2005 10:52 AM by starksm64

    Unmarshalling without specifying the top schema

    starksm64

      One last issue with integrating the jbxb framework into the legacy SARDeployer is having to know the schema of the document root passed to the jbxb Unmarshaller. Since the SARDeployer does not use the jbxb Unmarshaller for the jboss-service.xml document (in the future it will), it ends up having to parse the content of an attribute of serialDataType="jbxb" without any knowledge of the associated schema. For example, the Bindings attribute in this example jboss-service.xml:

      <server>
       <!-- A self-contained dynamic login configuration deployment
       -->
       <mbean code="org.jboss.naming.JNDIBindingService"
       name="jboss.tests:service=JNDIBindingService">
       <attribute name="Bindings" serialDataType="jbxb">
       <jndi:bindings
       xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jndi="urn:jboss:jndi-binding-service"
       xs:schemaLocation="urn:jboss:jndi-binding-service jndi-binding-service_1_0.xsd"
       >
       <jndi:binding name="ctx1/key1">
       <jndi:value>value1</jndi:value>
       </jndi:binding>
       <jndi:binding name="ctx1/user.home">
       <jndi:value replace="false" >${user.home}</jndi:value>
       </jndi:binding>
       <jndi:binding name="ctx1/key2">
       <jndi:value type="java.net.URL">http://www.jboss.org</jndi:value>
       </jndi:binding>
       <jndi:binding name="ctx2/key1">
       <custom:properties xmlns:custom="urn:jboss:custom-object-binding"
       xs:schemaLocation="urn:jboss:custom-object-binding custom-object-binding.xsd">
       <custom:property>
       <custom:key>key1</custom:key>
       <custom:value>value1</custom:value>
       </custom:property>
       <custom:property>
       <custom:key>key2</custom:key>
       <custom:value>value2</custom:value>
       </custom:property>
       </custom:properties>
       </jndi:binding>
      
       <jndi:binding name="hosts/localhost">
       <jndi:value editor="org.jboss.util.propertyeditor.InetAddressEditor">
       127.0.0.1
       </jndi:value>
       </jndi:binding>
      
       </jndi:bindings>
       </attribute>
       </mbean>
      
      </server>
      


      I added support for this by doing a query to the schema resolver following a failure to find a root element current binding to the SundayContentHandler.startElement:

       public void startElement(String namespaceURI,
       String localName,
       String qName,
       Attributes atts,
       XSTypeDefinition type)
       {
       QName startName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
       ElementBinding binding = null;
      
       ElementBinding parentBinding = null;
       if(elementStack.isEmpty())
       {
       binding = schema.getElement(startName);
       if( binding == null )
       {
       /* This can happen when an empty SchemaBinding was used to kick
       start the unmarshalling. The actual document schema needs to be
       obtained based on the first element's namespace.
       */
       String schemaLocation = atts.getValue(
       XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
       "schemaLocation");
       SchemaBinding nextSchema = schema.resolve(namespaceURI, localName,
       schema.getBaseURI(), schemaLocation);
       if( nextSchema != null )
       binding = nextSchema.getElement(startName);
       }
       }
      


      Using this I can start with an empty SchemaBinding with a SchemaResolver to parse the jndi:bindings content:
       InputStream is2 = xml content of jndi-bindings element;
      
       SchemaBinding schemaBinding = new SchemaBinding();
       DefaultSchemaResolver resolver = new DefaultSchemaResolver(new JBossEntityResolver());
       schemaBinding.setSchemaResolver(resolver);
       URL url = Thread.currentThread().getContextClassLoader().getResource("xml/naming/");
       schemaBinding.setBaseURI(url.toString());
       Unmarshaller unmarshaller = UnmarshallerFactory.newInstance().newUnmarshaller();
       JNDIBindings bindings = (JNDIBindings) unmarshaller.unmarshal(is2, schemaBinding);