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