13 Replies Latest reply on Dec 25, 2004 12:29 PM by starksm64

    Managing the JBossXB/JAXB namespace object factories

    starksm64

      So Alexey has resolved the coupling between namespaces and their type discussed here:
      http://www.jboss.org/index.html?module=bb&op=viewtopic&t=57861

      Now there is an issue with user of the JBossXB framework needing to know all of the namespace to object factory mappings. The current example of this issue is the JAAS login configuration parser needing to know all of the possible namespace to object factory mappings for the module-option injection point in the schema. Here is an example document that illustrates how the policy/application-policy/authentication/login-module/module-option element can have a model that is a function of the login-module code:

      <?xml version="1.0" encoding="UTF-8"?>
      <!-- A login-config.xml example that uses the extended schema and jbossxb
      to marshall non-trival module-options.
      -->
      <policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.jboss.org/j2ee/schema/jaas"
       targetNamespace="http://www.jboss.org/j2ee/schema/jaas"
       >
      
       <application-policy name="testXMLLoginModule">
       <authentication>
       <login-module code="org.jboss.security.auth.spi.XMLLoginModule" flag="required">
       <module-option name="userInfo">
       <lm:users xmlns:lm="http://www.jboss.org/j2ee/schemas/XMLLoginModule">
       <lm:user name="jduke" password="theduke">
       <lm:role name="Role1"/>
       <lm:role name="Role2"/>
       <lm:role name="Echo"/>
       <lm:role name="callerJduke" group="CallerPrincipal" />
       </lm:user>
       <lm:user name="scott" password="echoman">
       <lm:role name="Echo"/>
       <lm:role name="ProjectUser"/>
       <lm:role name="callerScott" group="CallerPrincipal" />
       </lm:user>
       <lm:user name="stark" password="javaman">
       <lm:role name="Java"/>
       <lm:role name="Coder"/>
       <lm:role name="callerStark" group="CallerPrincipal" />
       </lm:user>
       <lm:user name="jdukeman" password="anotherduke">
       <lm:role name="Role2"/>
       <lm:role name="Role3"/>
       <lm:role name="callerJdukeman" group="CallerPrincipal" />
       </lm:user>
       <lm:user name="invoker" password="invoker">
       <lm:role name="HttpInvoker"/>
       </lm:user>
       <lm:user name="admin" password="admin">
       <lm:role name="JBossAdmin"/>
       </lm:user>
       </lm:users>
       </module-option>
       <module-option name="unauthenticatedIdentity">guest</module-option>
       </login-module>
       </authentication>
       </application-policy>
      </policy>
      


      The schema for the module-option element uses a mixed content model with a schema wildcard component:
       <xs:element name="module-option">
       <xs:annotation>
       <xs:documentation>A module option defines a name, value pair that are
       passed to a LoginModule when it is initialized during the login proceedure.
       The name attribute defines the option name while the element value is the
       option value. The type of the value can be anything from a string obtained
       from the module-option body, to arbitary objects unmarshalled based on
       the namespace associated with the module-option child element.</xs:documentation>
       </xs:annotation>
       <xs:complexType mixed="true">
       <xs:sequence>
       <xs:any namespace="##any"/>
       </xs:sequence>
       <xs:attribute name="name" use="required" type="xs:NCName">
       <xs:annotation>
       <xs:documentation>The module option name. This is the key used to store
       the module value in the LoginModule initalize options Map.</xs:documentation>
       </xs:annotation>
       </xs:attribute>
       </xs:complexType>
       </xs:element>
      


      Since the new namespace requiring the custom object factory is showing up at the document instance level, its here that namespace object factory should be defined. I could add an attribute for the object factory to the login-module element, but this would couple the login module parser configuration too tightly to the marshalling implementation.

      JAXB 1.0 punted on this issue. Is JAXB 2.0 suggesting a way to deal with wildcard schema? It seems that the inline <xs:annotation><xs:appinfo>...</xs:appinfo></xs:annotation> approach used by JAXB 1.0 would be a comprimise way to let the binding framework know how to deal with the content.

      Does this same problem manifest in the web services marshalling layer or are wildcards disallowed?


        • 1. Re: Managing the JBossXB/JAXB namespace object factories
          aloubyansky

          I don't know whether support for any type changed in JAXB2.0.
          Of course, we could use xsd:annotation to map namespaces to object model factories.
          Although, there is no default namespace to object model factory mapping at the moment, I could add it based converting namespace to Java package and then following some naming rule for ObjectModelFactory implementation load its class.

          • 2. Re: Managing the JBossXB/JAXB namespace object factories
            starksm64

            To do this I think there would have to be some type of namespace registry service, and that's probably a good thing to add.

            I was thinking more along the lines of mixing binding instruction with the document. for example, consider the following custom ejb container configuration which introduces two custom interceptors each with their own non-trivial configuration:

            <?xml version="1.0" encoding="UTF-8"?>
            <jboss:jboss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:jboss="http://www.jboss.org/j2ee/schema/jboss"
             xmlns:jbossxb="http://www.jboss.org/j2ee/schema/jbossxb"
             xmlns:acme="http://acme.com/schema/jboss"
             xmlns:gizmo="http://gizmo/schema/jboss"
             >
             <!-- Tell JBossXB about the namespace to factory mappings in this doc -->
             <jbossxb:object-factory namespace="http://acme.com/schema/jboss" factory="com.amce.Factory" />
             <jbossxb:object-factory namespace="http://gizmo/schema/jboss" factory="com.gizmo.Factory" />
            
             <container-configurations>
             <container-configuration>
             <container-name>Test Container</container-name>
             <container-interceptors>
             <interceptor>org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor</interceptor>
             <interceptor>
             <acme:interceptor code="com.acme.ejb.interceptors.CustomInterceptor">
             <acme:inteceptor-config>
             ...
             </acme:inteceptor-config>
             </acme:interceptor>
             </interceptor>
             <interceptor>
             <gizmo:interceptor code="com.gizmo.ejb.interceptors.CustomInterceptor">
             <gizmo:inteceptor-config>
             ...
             </gizmo:inteceptor-config>
             </gizmo:interceptor>
             </interceptor>
             ...
             </container-interceptors>
            
             </container-configuration>
            
             </container-configurations>
            </jboss:jboss>
            
            


            This will allow use to put a bullet in the evil XmlLoadable interface once and for all. Would something like this be usable in the webservices layer as part of our jaxb customization as well?



            • 3. Re: Managing the JBossXB/JAXB namespace object factories
              aloubyansky

               

              "scott.stark@jboss.org" wrote:
              To do this I think there would have to be some type of namespace registry service, and that's probably a good thing to add.


              Sorry, I lost you. This is about what?
              There is a standard algorithm to convert XML namespace to Java package name. I already use it for default bindings. So I could also use it by default searching for a new ObjectModelFactory implementation.

              "scott.stark@jboss.org" wrote:
              Would something like this be usable in the webservices layer as part of our jaxb customization as well?


              I think we have already raised this question in another thread. The problem is the schema should allow jbossxb elements in the XML contents if you want to validate the document. Alternatively, we could use processing instructions for in-XML customized binding. And, otherwise, annotations in XSD.

              • 4. Re: Managing the JBossXB/JAXB namespace object factories
                starksm64

                The namespace to factory service applies to this thread. The issue is externalization of the object factory from the jbossxb user (the code parsing the top level document).

                I find it doubtful that namespaces can be converted to expected package names in the absence of an upfront code centric naming policy. So I suppose the package name for 'http://acme.com/schema/jboss' is 'com.acme.sechma.jboss'? As far as I'm concerned these are generally disconnected.

                So in the absence of defining wild card integration points, isn't there way to have a validatable composite document? Are multiple roots allowed? I don't think it should be an absolute requirement to have a schema in order to parse an xml fragment into an object graph.

                • 5. Re: Managing the JBossXB/JAXB namespace object factories
                  aloubyansky

                  I agree that package and namespaces might be disconnected. But still there is a standard convertion described in the JAXB spec ('C.5.1 Mapping from a Namespace URI') and maybe some other specs. Which is ok as the default. This is implemented in

                  package org.jboss.xml.binding;
                  public final class Util
                   public static String xmlNamespaceToJavaPackage(String namespace)
                  


                  Tests are here (at the bottom) http://cvs.sourceforge.net/viewcvs.py/jboss/jbosstest/src/main/org/jboss/test/xml/XMLNameToJavaIdentifierUnitTestCase.java?rev=1.3&view=markup

                  XML documents are always validated against a schema. The schema defines what elements from what namespaces are allowed/required at specific positions (the structure). So, I think you have to define an integration schema for the target document if you want to add other elements (modify the structure).

                  Schema is not required for unmarshalling. It's optional.

                  • 6. Re: Managing the JBossXB/JAXB namespace object factories
                    starksm64

                    Ok, so if I want to take our ejb container schema which would have integration points for the plugins like the interceptors, cache, pool, etc, but would not have integration points for the jbossxb marshalling elements, I would have to create a new schema that used the xsd:import? Would this allow for a validation of the following document:

                    <?xml version="1.0" encoding="UTF-8"?>
                    
                    <!-- Tell JBossXB about the namespace to factory mappings in this doc -->
                    <jbossxb:metadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xmlns:jbossxb="http://www.jboss.org/j2ee/schema/jbossxb"
                     >
                     <jbossxb:object-factory namespace="http://acme.com/schema/jboss" factory="com.amce.Factory" />
                     <jbossxb:object-factory namespace="http://gizmo/schema/jboss" factory="com.gizmo.Factory" />
                    </jbossxb:metadata>
                    
                    <jboss:jboss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xmlns:jboss="http://www.jboss.org/j2ee/schema/jboss"
                     xmlns:acme="http://acme.com/schema/jboss"
                     xmlns:gizmo="http://gizmo/schema/jboss"
                     >
                    
                     <container-configurations>
                     <container-configuration>
                     <container-name>Test Container</container-name>
                     <container-interceptors>
                     <interceptor>org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor</interceptor>
                     <interceptor>
                     <acme:interceptor code="com.acme.ejb.interceptors.CustomInterceptor">
                     <acme:inteceptor-config>
                     ...
                     </acme:inteceptor-config>
                     </acme:interceptor>
                     </interceptor>
                     <interceptor>
                     <gizmo:interceptor code="com.gizmo.ejb.interceptors.CustomInterceptor">
                     <gizmo:inteceptor-config>
                     ...
                     </gizmo:inteceptor-config>
                     </gizmo:interceptor>
                     </interceptor>
                     ...
                     </container-interceptors>
                    
                     </container-configuration>
                    
                     </container-configurations>
                    </jboss:jboss>
                    



                    • 7. Re: Managing the JBossXB/JAXB namespace object factories
                      aloubyansky

                      In case of XSD, there must be one unique root element.

                      Also, it looks like incolusion of a file with customized bindings into the document.

                      • 8. Re: Managing the JBossXB/JAXB namespace object factories
                        starksm64

                        So the alternative is to put the jbossxb directives into another document. This is just a pointless legacy file centric view.

                        • 9. Re: Managing the JBossXB/JAXB namespace object factories
                          aloubyansky

                          To pass info from XML content to applications you can use processing instructions. Otherwise, do not use validation. It's XML spec.

                          • 10. Re: Managing the JBossXB/JAXB namespace object factories
                            starksm64

                            Man, your bringing me down on xmas. I'm going to have to start calling you the Ukrainian Grinch. :)

                            So, can I get the binding metadata passed to jbossxb via PIs or are you going to make me use the schema/jbossxb.xml? Don't PIs require customization of the xml parser?

                            • 11. Re: Managing the JBossXB/JAXB namespace object factories
                              aloubyansky

                              He-e-ello-o-o Scott!!! Have you been a good boy this year? Mmmmmm? Ok, if so, I am going to implement customized binding using processing instructions for you that don't require any special XML parser customizations.

                              But... using annotations in XSD would probably still be a recommended way to customize bindings.

                              All your Christmas are belong to us.

                              xxxxxxxxxxxxxxxxx
                              Grinch/Consultant
                              JBoss, Inc
                              xxxxxxxxxxxxxxxxx

                              • 12. Re: Managing the JBossXB/JAXB namespace object factories
                                aloubyansky

                                Done. Now you can do

                                <?xml version="1.0" encoding="UTF-8"?>
                                
                                <!-- Tell JBossXB about the namespace to factory mappings in this doc -->
                                <?jbossxb ns="http://acme.com/schema/jboss" factory="com.amce.Factory"?>
                                <?jbossxb ns="http://gizmo/schema/jboss" factory="com.gizmo.Factory"?>
                                
                                <jboss:jboss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                 xmlns:jboss="http://www.jboss.org/j2ee/schema/jboss"
                                 xmlns:acme="http://acme.com/schema/jboss"
                                 xmlns:gizmo="http://gizmo/schema/jboss"
                                 >
                                
                                 <container-configurations>
                                 <container-configuration>
                                 <container-name>Test Container</container-name>
                                 <container-interceptors>
                                 <interceptor>org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor</interceptor>
                                 <interceptor>
                                 <acme:interceptor code="com.acme.ejb.interceptors.CustomInterceptor">
                                 <acme:inteceptor-config>
                                 ...
                                 </acme:inteceptor-config>
                                 </acme:interceptor>
                                 </interceptor>
                                 <interceptor>
                                 <gizmo:interceptor code="com.gizmo.ejb.interceptors.CustomInterceptor">
                                 <gizmo:inteceptor-config>
                                 ...
                                 </gizmo:inteceptor-config>
                                 </gizmo:interceptor>
                                 </interceptor>
                                 ...
                                 </container-interceptors>
                                
                                 </container-configuration>
                                
                                 </container-configurations>
                                </jboss:jboss>
                                


                                Merry Christmas!

                                • 13. Re: Managing the JBossXB/JAXB namespace object factories
                                  starksm64

                                  Excellent. Now I have to call you the Ukrainian Santa!
                                  Thanks for the xmas present.