1 2 Previous Next 23 Replies Latest reply on Dec 13, 2005 3:04 PM by starksm64

    Annotations and holders

      Sorry, I've temporarily broken some of the JBossXB tests (the annotation pojo tests).

      This is part of this work: http://jira.jboss.com/jira/browse/JBMICROCONT-32

      I've converted the tests to be more like the real parsing (I fixed the schema bindings version).

      Now I've got to figure out how to do the values. This is the stuff that we discussed
      before where it is polymorphic and there is a long form/short form version for plain strings.

      I don't see it dealing with the XXXValueMetaData in the
      annotation-bean-deploy_1_0.old (I kept a copy in cvs),
      instead this is handled in code?
      I've currently got that code commented out.

        • 1. Re: Annotations and holders
          aloubyansky

          Most of the bindings for these are in the XSDs. Bindings that I couldn't figure out how to do with annotations (this is mainly about JAXB annotations) are coded.

          Since it's troublesome, why are you spending your time on this? We agreed earlier that it doesn't make sense to keep these tests in sync with your model but create finer-grained tests for specfic use-cases. I haven't had time for this task yet. But I run MC and WS tests anyway before I commit XB code.

          • 2. Re: Annotations and holders

             

            "alex.loubyansky@jboss.com" wrote:

            Since it's troublesome, why are you spending your time on this?


            I told Bill to stop work on his AOP/MC integration (or at least the xml deployment)
            until we finalized the xml processing.
            We've already been through 3 iterations and I don't want him to go through another. :-)

            Additionally, the use of annotated schema allows for other features:
            http://sourceforge.net/mailarchive/forum.php?thread_id=8500217&forum_id=7101

            P.S. I updated the JBossXB tests because I didn't want to break the real version until
            I knew it worked - your tests don't matter to me :-P

            • 3. Re: Annotations and holders
              aloubyansky

               

              "adrian@jboss.org" wrote:
              I updated the JBossXB tests because I didn't want to break the real version until
              I knew it worked


              That's ok assuming you are going to fix them. Otherwise, you should not have committed them. Let me know if you need help (I haven't actually looked into details of what's wrong).

              "adrian@jboss.org" wrote:
              your tests don't matter to me :-P


              That's fine but breaking them just for fun is different :)

              • 4. Re: Annotations and holders

                Ok. I'm back to the original problem.

                For the "manual" parsing, I deal with the ValueType polymorphism
                by assuming I'm going to get a String Value.

                If it turns out I get something else, the StringValueMetaData is overridden
                by the ValueMetaDataElementInterceptor which also deals with the same issue
                for collections.

                The valueType is an AbstractValueMetaData holder with an
                embedded StringValueMetaData. Direct manipulation of the value
                delegates to the underlying StringValueMetaData
                
                 TypeBinding valueType = schemaBinding.getType(valueTypeQName);
                 configureValueBindings(valueType);
                 valueType.setHandler(new DefaultElementHandler()
                 {
                 public Object startElement(Object parent, QName name, ElementBinding element)
                 {
                 return new AbstractValueMetaData(new StringValueMetaData());
                 }
                
                 public void attributes(Object o, QName elementName, ElementBinding element, Attributes attrs, NamespaceContext nsCtx)
                 {
                 AbstractValueMetaData value = (AbstractValueMetaData) o;
                 StringValueMetaData string = (StringValueMetaData) value.getValue();
                 for (int i = 0; i < attrs.getLength(); ++i)
                 {
                 String localName = attrs.getLocalName(i);
                 if ("class".equals(localName))
                 string.setType(attrs.getValue(i));
                 }
                 }
                 });
                
                 // value can take a value
                 valueType.setSimpleType(new CharactersHandler()
                 {
                 public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx, org.jboss.xb.binding.metadata.ValueMetaData valueMetaData, String value)
                 {
                 return value;
                 }
                
                 public void setValue(QName qName, ElementBinding element, Object owner, Object value)
                 {
                 AbstractValueMetaData valueMetaData = (AbstractValueMetaData) owner;
                 StringValueMetaData string = (StringValueMetaData) valueMetaData.getValue();
                 string.setValue(value);
                 }
                 });
                
                Override all places where I expect polymorphism to use the interceptor
                
                 private static void configureValueBindings(TypeBinding typeBinding)
                 {
                 // type has values
                 typeBinding.pushInterceptor(valueQName, VALUES);
                
                 // type has injections
                 typeBinding.pushInterceptor(injectQName, VALUES);
                etc.
                
                The interceptor:
                
                 private static class ValueMetaDataElementInterceptor extends DefaultElementInterceptor
                 {
                 public void add(Object parent, Object child, QName name)
                 {
                 if (parent instanceof AbstractCollectionMetaData)
                 {
                 AbstractCollectionMetaData collection = (AbstractCollectionMetaData) parent;
                 ValueMetaData value = (ValueMetaData) child;
                 collection.add(value);
                 }
                 else if (parent instanceof AbstractParameterMetaData)
                 {
                 AbstractParameterMetaData valueMetaData = (AbstractParameterMetaData) parent;
                 ValueMetaData value = (ValueMetaData) child;
                 valueMetaData.setValue(value);
                 }
                 else if (parent instanceof AbstractPropertyMetaData)
                 {
                 AbstractPropertyMetaData valueMetaData = (AbstractPropertyMetaData) parent;
                 ValueMetaData value = (ValueMetaData) child;
                 valueMetaData.setValue(value);
                 }
                 else
                 {
                 AbstractValueMetaData valueMetaData = (AbstractValueMetaData) parent;
                 ValueMetaData value = (ValueMetaData) child;
                 valueMetaData.setValue(value);
                 }
                 }
                 }
                
                


                • 5. Re: Annotations and holders

                  More generally there is the issue of holders.

                  e.g. If I want to do something like the -ds.xml of jboss jca

                  <local-tx-datasource>
                   <connection-url>blah</connection-url> <!-- MCF property with key connectionURL -->
                   <max-pool-size>10</max-pool-size> <!-- pool-->
                  </local-tx-datasource>
                  


                  This should map using annotations into different parts of the metadata:

                  public class LocalTxDataSourceMetaData
                  {
                   ManagedConnectionFactoryMetaData mcfMD;
                   PoolMetaData poolMD;
                  }
                  
                  public class ManagedConnectionFactoryMetaData
                  {
                   Properties props;
                  }
                  
                  public class PoolMetaData
                  {
                   int maxPoolSize;
                  }
                  


                  • 6. Re: Annotations and holders

                    Or going further, it should create the equivalent of

                    <bean class="JDBCMCF">
                     <property name="connectionURL">blah</property>
                    </bean>
                    
                    <bean class="Pool">
                     <property name="maxPoolSize>10</property>
                    </bean>
                    


                    With the implementation details of AbstractBean/PropertyMetaData, the exact property
                    names and the class names defined in the schema.

                    i.e. we create more complicated metadata from simple xml using holders and schema
                    mapping with some parts of the schema hard-wired or containing defaults.

                    • 7. Re: Annotations and holders
                      aloubyansky

                      About the valueType case. I see that jbxb:property metadata doesn't work when element's value should be added to its parent in the way specific to its parent's type. What else am I missing here?

                      • 8. Re: Annotations and holders

                         

                        "alex.loubyansky@jboss.com" wrote:
                        I see that jbxb:property metadata doesn't work when element's value should be added to its parent in the way specific to its parent's type.

                        That might be part of it? I haven't really looked at the set/add stuff.
                        I thought you already had code in place that was "clever" about this?

                        What else am I missing here?

                        The issue is how do I reproduce what I did before with annotations?
                        See the jbxb collection test which is failing because it is passed the wrong type.
                        It should be getting a StringValueMetaData.

                        But it actually gets a can't load class "org.jboss.test.xml.pojoserver.metadata.ValueType"
                        It shouldn't really try to instantiate something here because the type is going to
                        come from the contained valueGroup (polymorphically).

                        Maybe the XSD/annotations doesn't model the metadata objects correctly?

                        I think I might be able to make it work by combining the ValueMetaData/TypeMetaData
                        abstractions such that all values have types. But that isn't really correct
                        and I'd rather not morph the metadata model because of mapping problems.
                        I'd be happy if it just requires a change to the xsd. :-)

                        • 9. Re: Annotations and holders

                          I managed to work around this problem for now.
                          But it is still not working as I would expect.

                          I have a "valueType" that is supposed to define one of the "valueGroup".
                          But I have to make the "valueType" extend "plainValueType"
                          (even though "plainValueType" is part of "valueGroup").

                          I've tried a number of variations to try to restructure the xsd, but can't get it to work.
                          (so many I've forgotten what they all are :-)

                          And I still have to wrap/unwrap AbstractValueMetaData to make the maps work
                          correctly?
                          See the AbstractMapMetaDataEntry class that does an unwrap in response to the getXXX().

                          I have no idea how I am going to do the beanfactory :-)

                          But I can at least fix up and augment the tests as they stand to make sure
                          it is parsing everything correctly.

                          • 10. Re: Annotations and holders
                            aloubyansky

                            I'll review and let you know. Last days I've been busy with WS issues.

                            • 11. Re: Annotations and holders

                              I'm going to have a look at how this annotated parser is put together,
                              maybe fork a prototype (in the testsuite) in the process so I don't break JBossWS? :-)

                              I want to re-implement it on top of this anyway:
                              http://docs.jboss.org/nightly/microkernel/docs/reference/en/html/reflection.html

                              But I also want to experiment with a richer object model injection using "holders"
                              where there isn't a simple correspondance between the xml structure and the
                              object model structure. e.g. the "flattened" xml example I posted before.

                              I was thinking of something like this?

                               <xsd:complexType name="datasourceType">
                               <xsd:appinfo>
                               <!-- new DataSourceConfig() -->
                               <jbxb:class impl="org.jboss.xxx.DataSourceConfig">
                               <!-- DataSourceConfig.setPoolConfig(new PoolConfig()) -->
                               <jbxb:holder name="pool" property="poolConfig" impl="org.jboss.xxx.PoolConfg"/>
                               </jbxb:class>
                               </xsd:appinfo>
                               </xsd:annotation>
                               <xsd:choice>
                               <xsd:element name="maxsize">
                               <xsd:annotation>
                               <xsd:appinfo>
                               <!-- poolConfig.setMaxSize(...) -->
                               <jbxb:property holder="pool" name="maxSize"/>
                               </xsd:appinfo>
                               </xsd:annotation>
                               </xsd:element>
                               </xsd:choice>
                               </xsd:complexType>
                              


                              Where the holder name is in the current context and could change instance during
                              iteration (e.g. for collections).

                              • 12. Re: Annotations and holders

                                Another form of holder would be a generalization of the MapEntry processing,
                                something like:

                                 <xsd:complexType name="mapType">
                                 <xsd:annotation>
                                 <xsd:appinfo>
                                 <jbxb:class impl="org.jboss.test.xml.pojoserver.metadata.AbstractMapMetaData"/>
                                 <jbxb:holder name="map"/>
                                 </xsd:appinfo>
                                 </xsd:annotation>
                                 <xsd:sequence>
                                 <xsd:element name="entry" type="entryType" minOccurs="0" maxOccurs="unbounded">
                                 <xsd:annotation>
                                 <xsd:appinfo>
                                 <jbxb:end-element holder="map" method="put">
                                 <jbxb:param property="entry.key"/>
                                 <jbxb:param property="entry.value"/>
                                 </jbxb:end-element>
                                 </xsd:appinfo>
                                 </xsd:annotation>
                                 </xsd:element>
                                 </xsd:sequence>
                                 </xsd:complexType>
                                
                                 <xsd:complexType name="entryType">
                                 <xsd:annotation>
                                 <xsd:appinfo>
                                 <jbxb:holder name="entry"/>
                                 </xsd:appinfo>
                                 </xsd:annotation>
                                 <xsd:sequence>
                                 <xsd:element name="key" type="valueType" minOccurs="0">
                                 <xsd:annotation>
                                 <xsd:appinfo>
                                 <jbxb:property name="key" />
                                 </xsd:appinfo>
                                 </xsd:annotation>
                                 </xsd:element>
                                 <xsd:element name="value" type="valueType" minOccurs="0">
                                 <xsd:annotation>
                                 <xsd:appinfo>
                                 <jbxb:property name="value" />
                                 </xsd:appinfo>
                                 </xsd:annotation>
                                 </xsd:element>
                                 </xsd:sequence>
                                 </xsd:complexType>
                                


                                • 13. Re: Annotations and holders
                                  aloubyansky

                                   

                                  "adrian@jboss.org" wrote:
                                  But it actually gets a can't load class "org.jboss.test.xml.pojoserver.metadata.ValueType"
                                  It shouldn't really try to instantiate something here because the type is going to
                                  come from the contained valueGroup (polymorphically).


                                  I've been blind... That's the main problem. It's not supported but doable. I'll work on that.

                                  Here is an example of how something like you want to achieve could be done currently based on the simple collection test using anyType instead of valueType.

                                  1. declare 'inject' and 'null' as global elements and reference them from the valueGroup choice.
                                  2. modify entryType like this
                                   <xsd:complexType name="entryType">
                                   <xsd:annotation>
                                   <xsd:appinfo>
                                  <!--
                                   <jbxb:mapEntry impl="org.jboss.test.xml.pojoserver.metadata.AbstractMapMetaDataEntry" getKeyMethod="getKey"
                                  
                                  setKeyMethod="setKey" getValueMethod="getValue" setValueMethod="setValue"/>
                                  -->
                                   <jbxb:mapEntry/>
                                   </xsd:appinfo>
                                   </xsd:annotation>
                                   <xsd:sequence>
                                  <!--
                                   <xsd:element name="key" type="valueType" minOccurs="0" maxOccurs="unbounded">
                                  -->
                                   <xsd:element name="key" type="xsd:anyType">
                                   <xsd:annotation>
                                   <xsd:appinfo>
                                   <jbxb:mapEntryKey/>
                                   <jbxb:value unmarshalMethod="org.jboss.test.xml.pojoserver.metadata.DataTypeConverter.unmarshalStringValue"/>
                                   </xsd:appinfo>
                                   </xsd:annotation>
                                   </xsd:element>
                                  <!--
                                   <xsd:element name="value" type="valueType" minOccurs="0" maxOccurs="unbounded">
                                  -->
                                   <xsd:element name="value" type="xsd:anyType">
                                   <xsd:annotation>
                                   <xsd:appinfo>
                                   <jbxb:mapEntryValue/>
                                   <jbxb:value unmarshalMethod="org.jboss.test.xml.pojoserver.metadata.DataTypeConverter.unmarshalStringValue"/>
                                   </xsd:appinfo>
                                   </xsd:annotation>
                                   </xsd:element>
                                   </xsd:sequence>
                                   </xsd:complexType>
                                  


                                  This way it'll avoid AbstractValueTypeMetaData and map entry holder.

                                  • 14. Re: Annotations and holders
                                    aloubyansky

                                    Also some schema issues. You define entry type as a sequence of key and value elements each of which is unbounded. That doesn't make sense, e.g.

                                    <entry>
                                     <key>key1</key>
                                     <key>key2</key>
                                     <value>valuex</value>
                                    </entry>
                                    


                                    They should have min and max occurs 1. If you wanted to bind sequence like the following to a map
                                     <key>key_1</key><value>value_1</value>
                                     <key>key_2</key><value>value_2</value>
                                    

                                    have a look at maps.xsd/maps.xml in the testsuite how it can be done.

                                    1 2 Previous Next