8 Replies Latest reply on Mar 10, 2010 6:13 PM by aloubyansky

    PropertyInfo creation from private/protected getter/setters

    jaikiran
      Is there a way to instruct JBossXB to scan for protected or private methods while building PropertyInfo for properties? 
      
      For example, for the below code, JBossXB isn't able to find the getter/setter for "methods" since they are marked as private.
      It only works when i change them to public:
      
      {code:java}
      @XmlType(name = "classType", propOrder ={"methods"})
      public class ClassMetaData
      {
      
          private Set methods;
          
          @XmlElement (name="method")
          private void setMethods(Set methods)
          {
              this.methods = methods;
          }
          
          private Set getMethods()
          {
              return this.methods;
          }
      }
      {code}
      
      And if there's a way to instruct JBossXB to look for protected/private getter/setters, then at what granularity can it be specified:
      
      1) Applies to all binding classes?
      2) Or Per binding class?
      3) Or Per property?
      
      
        • 1. Re: PropertyInfo creation from private/protected getter/setters
          aloubyansky
          XB uses whatever is returned from org.jboss.beans.info.spi.BeanInfo.getProperties(). I am not sure whether there is an option to include non-public properties into BeanInfo.getProperties().
          • 2. Re: PropertyInfo creation from private/protected getter/setters
            jaikiran

            Looking at the API, the creation of BeanInfo can be provided a BeanAccessMode:

             

            From JBossXB:

             

            // Create the handler
                  BeanInfo beanInfo = JBossXBBuilder.configuration.getBeanInfo(typeInfo);
            

             

            The Configuration API has a overloaded method which accepts a BeanAccessMode:

             

             /**
                * Get the bean info
                *
                * @param type the type info
                * @param accessMode the bean access mode
                * @return the bean info
                */
               BeanInfo getBeanInfo(TypeInfo type, BeanAccessMode accessMode);
            

             

             

            But none of this is exposed via JBossXB from what i can gather.

            • 3. Re: PropertyInfo creation from private/protected getter/setters
              aloubyansky

              No, it's not. I don't mind exposing it but need to think about the best way. Up until now, the binding configuration would be set using statis methods/variables on JBossXBBuilder. Which all users in the current VM will share the same configuration. I am not sure this is a good idea for property visibility.

              SchemaBinding building is actually done by an instance of JBossXBNoSchemaBuilder which copies config settings from JBossXBBuilder. Perhaps (in addition to adding this to the static configuration) JBossXBNoSchemaBuilder could be exposed as well and get BeanAccessMode property too to make it effective only for specific SchemaBinding.

               

              What do you need this for? For which schema/metadata is this?

              • 4. Re: PropertyInfo creation from private/protected getter/setters
                jaikiran
                I was trying to use it for a EJB3.1 specific metadata (although the usecase could very well be a common one). Here's the details:
                
                I had to map a <concurrent-method> in a session bean to its binding class. A session bean can have multiple concurrent-method elements so ideally i would map it as:
                
                {code:java}
                @XmlType(... propOrder ={... "concurrentMethods"...})
                public class SessionBeanMetaData
                {
                
                
                    private Set<ConcurrentMethodMetaData> concurrentMethods;
                    
                    @XmlElement (name="concurrent-method")
                    public void setConcurrentMethods(Set<ConcurrentMethodMetaData> cms)
                    {
                        ...
                    }
                    
                    public Set<ConcurrentMethodMetaData> getConcurrentMethods()
                    {
                        ...
                    }
                    
                }
                {code}
                
                But i did not want to expose the getConcurrentMethods() public API to return a Collection to users. Instead i wanted to keep that method name and wanted to return a Map<NamedMethodMetaData, ConcurrentMethodMetaData>. Like this:
                
                {code:java}
                public Map<NamedMethodMetaData, ConcurrentMethodMetaData> getConcurrentMethods()
                {
                    ...
                }
                {code}
                So i decide to change the binding class to internally use a private (or even protected) method for marshalling/unmarshalling:
                
                {code:java}
                @XmlType(... propOrder ={... "internalConMethods"...})
                public class SessionBeanMetaData
                {
                
                
                    private Set<ConcurrentMethodMetaData> internalConMethods;
                
                    /**
                     * Internal used for JBossXB
                     */
                    @XmlElement (name="concurrent-method")
                    private void setInternalConMethods(Set<ConcurrentMethodMetaData> cms)
                    {
                        ...
                    }
                    
                    /**
                     * Internal used for JBossXB
                     */
                    private Set<ConcurrentMethodMetaData> getInternalConMethods()
                    {
                        ...
                    }
                    
                    /**
                     * A better view to the public
                     */
                    public Map<NamedMethodMetaData, ConcurrentMethodMetaData> getConcurrentMethods()
                    {
                        ...
                    }
                    
                    
                }
                {code}
                
                So i created a couple of private methods for JBossXB marshalling/unmarshalling and exposed getConcurrentMethods() to return a better view to users. That didn't work out because of the "private" access. I have now implemented this in a slightly different way by using a XmlJavaAdapter, but the original usecase still seems valid. 
                
                And yes, as you said, having those config properties at a global level won't be very useful. Per binding class would be more useful.
                

                 

                Message was edited by: I totally hate this useless editor

                • 5. Re: PropertyInfo creation from private/protected getter/setters
                  aloubyansky

                  Yes, maps are bound with adapters.

                  Actually, I've already added (not committed yet) BeanAccessMode as a static config option. I'll look into adding a type-level annotation for access mode as well.

                  • 6. Re: PropertyInfo creation from private/protected getter/setters
                    aloubyansky

                    I've changed my mind about the statis config option and added just the annotations for now. This is what currently is in the snapshot

                     

                    The issue, btw, is [url]https://jira.jboss.org/jira/browse/JBXB-241[/url]

                     

                    A new enum has been added org.jboss.xb.annotations.JBossXmlAccessMode:

                    public enum JBossXmlAccessMode
                    {
                        // not specified which means it will inherit the value from somewhere else depending on the context
                        NOT_SPECIFIED,
                        
                        // equivalent to javax.xml.bind.annotation.XmlAccessType.PROPERTY and org.jboss.beans.info.spi.BeanAccessMode.STANDARD
                        PROPERTY,
                        
                        // equivalent to javax.xml.bind.annotation.XmlAccessType.PUBLIC_MEMBER and org.jboss.beans.info.spi.BeanAccessMode.FIELD 
                        PUBLIC_MEMBER,
                        
                        // org.jboss.beans.info.spi.BeanAccessMode.ALL
                        ALL
                    }

                    And a new element has been added to JBossXmlSchema, JBossXmlType and JBossXmlModelGroup:

                        JBossXmlAccessMode accessMode().

                    For JBossXmlSchema the default value is JBossXmlAccessMode.PROPERTY and for JBossXmlType and JBossXmlModelGroup it's JBossXmlAccessMode.NOT_SPECIFIED, which means types and groups will by default inherit the value from the schema.

                    Here are some examples (from the testsuite)

                    @JBossXmlSchema(accessMode = JBossXmlAccessMode.ALL)
                    @XmlRootElement(name="root")
                    public class PropertyAccessModeTypeOverride extends SomeType
                    {
                       @XmlElement
                       public PropertyAccessModeType e;
                      
                       @JBossXmlType(accessMode = JBossXmlAccessMode.PROPERTY)
                       public static class PropertyAccessModeType extends SomeType
                       {     
                       }
                    }

                    @JBossXmlSchema(accessMode = JBossXmlAccessMode.ALL)
                    @XmlRootElement(name="root")
                    public class PublicMemberAccessModeGroupOverride extends SomeType
                    {
                       public PropertyAccessModeGroup e;
                      
                       @JBossXmlModelGroup(name="all", accessMode=JBossXmlAccessMode.PUBLIC_MEMBER, kind=JBossXmlConstants.MODEL_GROUP_ALL)
                       public static class PropertyAccessModeGroup
                       {
                          private String property;
                          public String publicField;
                          private String privateField;
                    ...

                    Unless there are other suggestions I'll close the issue and make a release (MC team needs, asap)
                    • 7. Re: PropertyInfo creation from private/protected getter/setters
                      jaikiran

                      alex.loubyansky@jboss.com wrote:

                       



                      Unless there are other suggestions I'll close the issue and make a release (MC team needs, asap)

                      Alexey, the JBossXmlAccessMode modes look good enough. Thank you for adding this.

                      • 8. Re: PropertyInfo creation from private/protected getter/setters
                        aloubyansky
                        It's been released - 2.0.2.Beta5.