View Javadoc

    1   package org.codehaus.xfire.aegis.type;
    2
    3   import java.beans.PropertyDescriptor;
    4   import java.lang.reflect.Field;
    5   import java.lang.reflect.Method;
    6   import java.util.Collection;
    7   import java.util.Map;
    8
    9   import javax.xml.namespace.QName;
    10
    11  import org.codehaus.xfire.XFireRuntimeException;
    12  import org.codehaus.xfire.aegis.type.basic.ArrayType;
    13  import org.codehaus.xfire.aegis.type.collection.CollectionType;
    14  import org.codehaus.xfire.aegis.type.collection.MapType;
    15  import org.codehaus.xfire.util.NamespaceHelper;
    16  import org.codehaus.xfire.util.ServiceUtils;
    17
    18  /***
    19   * @author Hani Suleiman
    20   *         Date: Jun 14, 2005
    21   *         Time: 11:59:57 PM
    22   */
    23  public abstract class AbstractTypeCreator implements TypeCreator
    24  {
    25      protected TypeMapping tm;
    26      protected AbstractTypeCreator nextCreator;
    27
    28      public TypeMapping getTypeMapping()
    29      {
    30          return tm;
    31      }
    32
    33      public void setTypeMapping(TypeMapping typeMapping)
    34      {
    35          this.tm = typeMapping;
    36      }
    37
    38      public void setNextCreator(AbstractTypeCreator creator)
    39      {
    40          this.nextCreator = creator;
    41      }
    42
    43      protected TypeClassInfo createClassInfo(Field f)
    44      {
    45          return createBasicClassInfo(f.getType());
    46      }
    47
    48      protected TypeClassInfo createBasicClassInfo(Class typeClass)
    49      {
    50          TypeClassInfo info = new TypeClassInfo();
    51
    52          info.setTypeClass(typeClass);
    53
    54          return info;
    55      }
    56
    57      protected Type createTypeForClass(TypeClassInfo info)
    58      {
    59          Class javaType = info.getTypeClass();
    60
    61          if(javaType.isArray())
    62          {
    63              return createArrayType(info);
    64          }
    65          else if(isMap(javaType))
    66          {
    67              return createMapType(info);
    68          }
    69          else if(isCollection(javaType))
    70          {
    71              return createCollectionType(info);
    72          }
    73          else if(isEnum(javaType))
    74          {
    75              return createEnumType(info);
    76          }
    77          else
    78          {
    79              Type type = getTypeMapping().getType(javaType);
    80              if (type == null)
    81              {
    82                  type = createDefaultType(info);
    83              }
    84
    85              return type;
    86          }
    87      }
    88
    89      protected QName createArrayQName(Class javaType)
    90      {
    91          return createCollectionQName(javaType, javaType.getComponentType());
    92      }
    93
    94      protected Type createArrayType(TypeClassInfo info)
    95      {
    96          ArrayType type = new ArrayType();
    97          type.setSchemaType(createArrayQName(info.getTypeClass()));
    98          type.setTypeClass(info.getTypeClass());
    99
    100         return type;
    101     }
    102
    103     protected QName createQName(Class javaType)
    104     {
    105         String clsName = javaType.getName();
    106
    107         String ns = NamespaceHelper.makeNamespaceFromClassName(clsName, "http");
    108         String localName = ServiceUtils.makeServiceNameFromClassName(javaType);
    109
    110         return new QName(ns, localName);
    111     }
    112
    113     protected boolean isCollection(Class javaType)
    114     {
    115         return Collection.class.isAssignableFrom(javaType);
    116     }
    117
    118     protected Type createCollectionType(TypeClassInfo info, Class component)
    119     {
    120         CollectionType type = new CollectionType(component);
    121         type.setTypeMapping(getTypeMapping());
    122
    123         QName name = info.getName();
    124         if (name == null) name = createCollectionQName(info.getTypeClass(), component);
    125         type.setSchemaType(name);
    126
    127         type.setTypeClass(info.getTypeClass());
    128
    129         return type;
    130     }
    131
    132     protected Type createMapType(TypeClassInfo info)
    133     {
    134         QName schemaType = new QName(getTypeMapping().getEncodingStyleURI(), "map");
    135         MapType type = new MapType(schemaType,
    136                                    (Class) info.getKeyType(),
    137                                    (Class) info.getGenericType());
    138         type.setTypeMapping(getTypeMapping());
    139         type.setTypeClass(info.getTypeClass());
    140
    141         return type;
    142     }
    143
    144     protected boolean isMap(Class javaType)
    145     {
    146         return Map.class.isAssignableFrom(javaType);
    147     }
    148
    149     public abstract TypeClassInfo createClassInfo(PropertyDescriptor pd);
    150
    151     protected boolean isEnum(Class javaType)
    152     {
    153         return false;
    154     }
    155
    156     public Type createEnumType(TypeClassInfo info)
    157     {
    158         return null;
    159     }
    160
    161     public abstract Type createCollectionType(TypeClassInfo info);
    162
    163     public abstract Type createDefaultType(TypeClassInfo info);
    164
    165     protected QName createCollectionQName(Class javaType, Class componentType)
    166     {
    167         if(componentType == null)
    168         {
    169             throw new XFireRuntimeException("Cannot create mapping for " + javaType.getName() + ", unspecified component type");
    170         }
    171         Type type = tm.getType(componentType);
    172         if(type == null)
    173         {
    174             type = createType(componentType);
    175             getTypeMapping().register(type);
    176         }
    177         String ns;
    178
    179         if(type.isComplex())
    180         {
    181             ns = type.getSchemaType().getNamespaceURI();
    182         }
    183         else
    184         {
    185             ns = tm.getEncodingStyleURI();
    186         }
    187
    188         String first = type.getSchemaType().getLocalPart().substring(0, 1);
    189         String last = type.getSchemaType().getLocalPart().substring(1);
    190         String localName = "ArrayOf" + first.toUpperCase() + last;
    191
    192         return new QName(ns, localName);
    193     }
    194
    195     public abstract TypeClassInfo createClassInfo(Method m, int index);
    196
    197     /***
    198      * Create a Type for a Method parameter.
    199      *
    200      * @param m the method to create a type for
    201      * @param index The parameter index. If the index is less than zero, the return type is used.
    202      */
    203     public Type createType(Method m, int index)
    204     {
    205         TypeClassInfo info = createClassInfo(m, index);
    206
    207         return createTypeForClass(info);
    208     }
    209
    210     /***
    211      * Create type information for a PropertyDescriptor.
    212      *
    213      * @param pd the propertydescriptor
    214      */
    215     public Type createType(PropertyDescriptor pd)
    216     {
    217         TypeClassInfo info = createClassInfo(pd);
    218
    219         return createTypeForClass(info);
    220     }
    221
    222     /***
    223      * Create type information for a <code>Field</code>.
    224      *
    225      * @param f the field to create a type from
    226      */
    227     public Type createType(Field f)
    228     {
    229         TypeClassInfo info = createClassInfo(f);
    230
    231         return createTypeForClass(info);
    232     }
    233
    234     public Type createType(Class clazz)
    235     {
    236         TypeClassInfo info = createBasicClassInfo(clazz);
    237
    238         return createTypeForClass(info);
    239     }
    240
    241     public static class TypeClassInfo
    242     {
    243         Class typeClass;
    244         Object[] annotations;
    245         Object genericType;
    246         Object keyType;
    247         QName name;
    248
    249         public Object[] getAnnotations()
    250         {
    251             return annotations;
    252         }
    253
    254         public void setAnnotations(Object[] annotations)
    255         {
    256             this.annotations = annotations;
    257         }
    258
    259         public Object getGenericType()
    260         {
    261             return genericType;
    262         }
    263
    264         public void setGenericType(Object genericType)
    265         {
    266             this.genericType = genericType;
    267         }
    268
    269         public Object getKeyType()
    270         {
    271             return keyType;
    272         }
    273
    274         public void setKeyType(Object keyType)
    275         {
    276             this.keyType = keyType;
    277         }
    278
    279         public Class getTypeClass()
    280         {
    281             return typeClass;
    282         }
    283
    284         public void setTypeClass(Class typeClass)
    285         {
    286             this.typeClass = typeClass;
    287         }
    288
    289         public QName getName()
    290         {
    291             return name;
    292         }
    293
    294         public void setName(QName name)
    295         {
    296             this.name = name;
    297         }
    298     }
    299 }