View Javadoc

    1   package org.codehaus.xfire.aegis.type.basic;
    2
    3   import java.beans.BeanInfo;
    4   import java.beans.IntrospectionException;
    5   import java.beans.Introspector;
    6   import java.beans.PropertyDescriptor;
    7   import java.util.ArrayList;
    8   import java.util.Collection;
    9   import java.util.HashMap;
    10  import java.util.Iterator;
    11  import java.util.List;
    12  import java.util.Map;
    13
    14  import javax.xml.namespace.QName;
    15
    16  import org.codehaus.xfire.XFireRuntimeException;
    17  import org.codehaus.xfire.aegis.type.Type;
    18  import org.codehaus.xfire.aegis.type.TypeMapping;
    19
    20  public class BeanTypeInfo
    21  {
    22      private Map qname2name = new HashMap();
    23      private Class typeClass;
    24      private List attributes = new ArrayList();
    25      private List elements = new ArrayList();
    26      private String defaultNamespace;
    27      private PropertyDescriptor[] descriptors;
    28      private TypeMapping typeMapping;
    29      private boolean initialized;
    30
    31      public BeanTypeInfo(Class typeClass, String defaultNamespace)
    32      {
    33          this.typeClass = typeClass;
    34          this.defaultNamespace = defaultNamespace;
    35
    36          initializeProperties();
    37      }
    38
    39      /***
    40       * Create a BeanTypeInfo class.
    41       *
    42       * @param typeClass
    43       * @param defaultNamespace
    44       * @param initiallize If true attempt default property/xml mappings.
    45       */
    46      public BeanTypeInfo(Class typeClass, String defaultNamespace, boolean initialize)
    47      {
    48          this.typeClass = typeClass;
    49          this.defaultNamespace = defaultNamespace;
    50
    51          initializeProperties();
    52          setInitialized(!initialize);
    53      }
    54
    55      protected BeanTypeInfo(Class typeClass)
    56      {
    57          this.typeClass = typeClass;
    58
    59          initializeProperties();
    60      }
    61
    62      public void initialize()
    63      {
    64          try
    65          {
    66              for (int i = 0; i < descriptors.length; i++)
    67              {
    68                  // Don't map the property unless there is both a read and write property
    69                  if (descriptors[i].getReadMethod() != null &&
    70                          descriptors[i].getWriteMethod() != null)
    71                  {
    72                      mapProperty(descriptors[i]);
    73                  }
    74              }
    75          }
    76          catch (Exception e)
    77          {
    78              if(e instanceof XFireRuntimeException) throw (XFireRuntimeException)e;
    79              throw new XFireRuntimeException("Couldn't create TypeInfo.", e);
    80          }
    81
    82          setInitialized(true);
    83      }
    84
    85      public boolean isInitialized()
    86      {
    87          return initialized;
    88      }
    89
    90      private void setInitialized(boolean initialized)
    91      {
    92          this.initialized = initialized;
    93      }
    94
    95      protected void mapProperty(PropertyDescriptor pd)
    96      {
    97          String name = pd.getName();
    98
    99          if (isAttribute(pd))
    100         {
    101             mapAttribute(name, createQName(pd));
    102         }
    103         else if (isElement(pd))
    104         {
    105             mapElement(name, createQName(pd));
    106         }
    107     }
    108
    109     protected PropertyDescriptor[] getPropertyDescriptors()
    110     {
    111         return descriptors;
    112     }
    113
    114     protected PropertyDescriptor getPropertyDescriptor(String name)
    115     {
    116         for (int i = 0; i < descriptors.length; i++)
    117         {
    118             if (descriptors[i].getName().equals(name))
    119                 return descriptors[i];
    120         }
    121
    122         return null;
    123     }
    124
    125     /***
    126      * Get the type class for the field with the specified QName.
    127      */
    128     public Type getType(QName name)
    129     {
    130         Type type = getTypeMapping().getType(name);
    131
    132         if (type == null)
    133         {
    134             PropertyDescriptor desc;
    135             try
    136             {
    137                 desc = getPropertyDescriptor(name);
    138             }
    139             catch (Exception e)
    140             {
    141                 if(e instanceof XFireRuntimeException) throw (XFireRuntimeException)e;
    142                 throw new XFireRuntimeException("Couldn't get properties.", e);
    143             }
    144
    145             if (desc == null)
    146             {
    147                 return null;
    148             }
    149
    150             if (getTypeMapping().isRegistered(desc.getPropertyType())
    151                     && !Collection.class.isAssignableFrom(desc.getPropertyType()))
    152             {
    153                 type = getTypeMapping().getType(desc.getPropertyType());
    154             }
    155             else
    156             {
    157                 try
    158                 {
    159                     type = getTypeMapping().getTypeCreator().createType(desc);
    160                 }
    161                 catch(XFireRuntimeException e)
    162                 {
    163                     e.prepend("Couldn't create type for property " + desc.getName()
    164                               + " on " + getTypeClass());
    165
    166                     throw e;
    167                 }
    168
    169                 getTypeMapping().register(type);
    170             }
    171         }
    172
    173         if ( type == null )
    174             throw new XFireRuntimeException( "Couldn't find type for property " + name );
    175
    176         return type;
    177     }
    178
    179     public TypeMapping getTypeMapping()
    180     {
    181         return typeMapping;
    182     }
    183
    184     public void setTypeMapping(TypeMapping typeMapping)
    185     {
    186         this.typeMapping = typeMapping;
    187     }
    188
    189     protected QName createQName(PropertyDescriptor desc)
    190     {
    191         return new QName(defaultNamespace, desc.getName());
    192     }
    193
    194     public void mapAttribute(String property, QName type)
    195     {
    196         qname2name.put(type, property);
    197         attributes.add(type);
    198     }
    199
    200     public void mapElement(String property, QName type)
    201     {
    202         qname2name.put(type, property);
    203         elements.add(type);
    204     }
    205
    206     private void initializeProperties()
    207     {
    208         BeanInfo beanInfo = null;
    209         try
    210         {
    211             if (typeClass.isInterface() || typeClass.isPrimitive())
    212             {
    213                 beanInfo = Introspector.getBeanInfo(typeClass);
    214             }
    215             else if (typeClass == Object.class)
    216             {
    217             }
    218             else
    219             {
    220                 beanInfo = Introspector.getBeanInfo(typeClass, Object.class);
    221             }
    222         }
    223         catch (IntrospectionException e)
    224         {
    225             throw new XFireRuntimeException("Couldn't introspect interface.", e);
    226         }
    227
    228         if (beanInfo != null)
    229             descriptors = beanInfo.getPropertyDescriptors();
    230
    231         if (descriptors == null)
    232         {
    233             descriptors = new PropertyDescriptor[0];
    234         }
    235     }
    236
    237     public PropertyDescriptor getPropertyDescriptor(QName name)
    238     {
    239         return getPropertyDescriptor( getPropertyName(name) );
    240     }
    241
    242     protected boolean isAttribute(PropertyDescriptor desc)
    243     {
    244         return false;
    245     }
    246
    247     protected boolean isElement(PropertyDescriptor desc)
    248     {
    249         return true;
    250     }
    251
    252     protected boolean isSerializable(PropertyDescriptor desc)
    253     {
    254         return true;
    255     }
    256
    257     protected Class getTypeClass()
    258     {
    259         return typeClass;
    260     }
    261
    262     public boolean isNillable(QName name)
    263     {
    264         return true;
    265     }
    266
    267     private String getPropertyName(QName name)
    268     {
    269         return (String) qname2name.get(name);
    270     }
    271
    272     public Iterator getAttributes()
    273     {
    274         return attributes.iterator();
    275     }
    276
    277     public Iterator getElements()
    278     {
    279         return elements.iterator();
    280     }
    281 }