View Javadoc

1   package org.codehaus.xfire.java.type;
2   
3   import java.beans.BeanInfo;
4   import java.beans.IntrospectionException;
5   import java.beans.Introspector;
6   import java.lang.reflect.Array;
7   import java.util.HashSet;
8   import java.util.Iterator;
9   import java.util.List;
10  import java.util.Set;
11  
12  import org.codehaus.xfire.SOAPConstants;
13  import org.codehaus.xfire.XFireRuntimeException;
14  import org.codehaus.xfire.java.message.MessageReader;
15  import org.codehaus.xfire.java.message.MessageWriter;
16  import org.codehaus.xfire.util.NamespaceHelper;
17  import org.dom4j.DocumentFactory;
18  import org.dom4j.Element;
19  import org.dom4j.Namespace;
20  import org.dom4j.QName;
21  
22  /***
23   * An ArrayType.
24   * 
25   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
26   */
27  public class ArrayType
28      extends Type
29  {
30  
31  	/***
32       * @see org.codehaus.xfire.java.type.Type#readObject(org.dom4j.Element)
33       */
34      public Object readObject(MessageReader reader)
35          throws XFireRuntimeException
36      {
37          try
38          {
39              Type compType = getComponentType();
40              
41              List readers = reader.getReaders( compType.getSchemaType().getName() );
42              
43              Object[] array = (Object[]) Array.newInstance( compType.getTypeClass(), readers.size() );
44              
45              int i = 0;
46              for ( Iterator itr = readers.iterator(); itr.hasNext(); )
47              {
48                  Type type = getTypeMapping().getType( compType.getTypeClass() );
49                  
50                  array[i] = type.readObject( (MessageReader) itr.next() );
51                  i++;
52              }
53              
54              return array;
55          }
56          catch (IllegalArgumentException e)
57          {
58              throw new XFireRuntimeException("Illegal argument.", e);
59          }
60      }
61  
62      /***
63       * @see org.codehaus.xfire.java.type.Type#writeObject(java.lang.Object)
64       */
65      public void writeObject(Object object, MessageWriter writer)
66          throws XFireRuntimeException
67      {
68          try
69          {
70          	Object[] array = (Object[]) object;
71              
72              Type type = getComponentType();
73              
74              if ( type == null )
75                  throw new XFireRuntimeException( "Couldn't find type for " + type.getTypeClass() + "." );
76              
77              List writers = writer.getWriters();
78              
79              for ( int i = 0; i < array.length; i++ )
80              {
81                  BeanInfo info = Introspector.getBeanInfo( type.getTypeClass(), Object.class );
82  
83                  type.writeObject( array[i], 
84                                    writer.getWriter( info.getBeanDescriptor().getDisplayName() ) );
85                  i++;
86              }
87          }
88          catch (IntrospectionException e)
89          {
90              throw new XFireRuntimeException("Couldn't introspect.", e);
91          }
92          catch (IllegalArgumentException e)
93          {
94              throw new XFireRuntimeException("Illegal argument.", e);
95          } 
96      }
97  
98      /***
99       * @see org.codehaus.xfire.java.type.Type#writeSchema()
100      */
101     public void writeSchema( Element root )
102     {
103         try
104         {        
105             Namespace xsdNs = root.getNamespaceForURI( SOAPConstants.XSD );
106             org.dom4j.QName complexQ = new org.dom4j.QName("complexType", xsdNs);   
107 
108             Element complex = root.addElement( complexQ );
109 
110             complex.addAttribute( "name", getSchemaType().getName() );
111 
112             org.dom4j.QName seqQ = new org.dom4j.QName("sequence", xsdNs); 
113             Element seq = complex.addElement( seqQ );
114 
115             org.dom4j.QName elementQ = new org.dom4j.QName("element", xsdNs); 
116             Element element = seq.addElement( elementQ );
117             
118             Type componentType = getComponentType();
119             Namespace ns = NamespaceHelper.getNamespace( root, componentType.getSchemaType().getNamespaceURI() );
120 
121             QName typeDom4j = DocumentFactory.getInstance().createQName( componentType.getSchemaType().getName(),
122                                                                          ns );
123             
124             String typeName = typeDom4j.getNamespacePrefix() + ":" + componentType.getSchemaType().getName();
125             
126             element.addAttribute("name", componentType.getSchemaType().getName());
127             element.addAttribute("type", typeName);
128             // TODO: Add config support for nillable
129             element.addAttribute("nillable", "true");
130  
131             element.addAttribute("minOccurs", "0");
132             element.addAttribute("maxOccurs", "unbounded");
133             
134         }
135         catch (IllegalArgumentException e)
136         {
137             throw new XFireRuntimeException("Illegal argument.", e);
138         }
139     }
140     
141     /***
142      * We need to write a complex type schema for Beans, so return true.
143      * 
144      * @see org.codehaus.xfire.java.type.Type#isComplex()
145      */
146     public boolean isComplex()
147     {
148         return true;
149     }
150     
151     /***
152      * @see org.codehaus.xfire.java.type.Type#getDependencies()
153      */
154     public Set getDependencies()
155     {
156         Set deps = new HashSet();
157         
158         deps.add( getTypeMapping().getType( getTypeClass().getComponentType() ) );
159         
160         return deps;
161     }
162     
163     protected Type getComponentType()
164     {
165         Class compType = getTypeClass().getComponentType();
166         
167         return getTypeMapping().getType( compType );
168     }
169 }