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 }