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.ArrayList;
8   import java.util.HashSet;
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      public Object readObject(MessageReader reader)
31          throws XFireRuntimeException
32      {
33          try
34          {
35              Type compType = getComponentType();
36              
37              List values = new ArrayList();
38              
39              while ( reader.hasMoreChildReaders() )
40              {
41                  Type type = getTypeMapping().getType( compType.getTypeClass() );
42                  
43                  values.add( type.readObject(reader.getNextChildReader()) );
44              }
45              
46              return values.toArray( (Object[]) Array.newInstance( compType.getTypeClass(), values.size()) );
47          }
48          catch (IllegalArgumentException e)
49          {
50              throw new XFireRuntimeException("Illegal argument.", e);
51          }
52      }
53  
54      public void writeObject(Object object, MessageWriter writer)
55          throws XFireRuntimeException
56      {
57          try
58          {
59          	Object[] array = (Object[]) object;
60              
61              Type type = getComponentType();
62              
63              if ( type == null )
64                  throw new XFireRuntimeException( "Couldn't find type for " + type.getTypeClass() + "." );
65              
66              for ( int i = 0; i < array.length; i++ )
67              {
68                  BeanInfo info = Introspector.getBeanInfo( type.getTypeClass(), Object.class );
69  
70                  MessageWriter cwriter = writer.getChildWriter(type.getSchemaType().getName());
71                  type.writeObject( array[i], writer );
72                  cwriter.close();
73              }
74          }
75          catch (IntrospectionException e)
76          {
77              throw new XFireRuntimeException("Couldn't introspect.", e);
78          }
79          catch (IllegalArgumentException e)
80          {
81              throw new XFireRuntimeException("Illegal argument.", e);
82          }
83      }
84  
85      public void writeSchema( Element root )
86      {
87          try
88          {        
89              Namespace xsdNs = root.getNamespaceForURI( SOAPConstants.XSD );
90              org.dom4j.QName complexQ = new org.dom4j.QName("complexType", xsdNs);   
91  
92              Element complex = root.addElement( complexQ );
93  
94              complex.addAttribute( "name", getSchemaType().getName() );
95  
96              org.dom4j.QName seqQ = new org.dom4j.QName("sequence", xsdNs); 
97              Element seq = complex.addElement( seqQ );
98  
99              org.dom4j.QName elementQ = new org.dom4j.QName("element", xsdNs); 
100             Element element = seq.addElement( elementQ );
101             
102             Type componentType = getComponentType();
103             Namespace ns = NamespaceHelper.getNamespace( root, componentType.getSchemaType().getNamespaceURI() );
104 
105             QName typeDom4j = DocumentFactory.getInstance().createQName( componentType.getSchemaType().getName(),
106                                                                          ns );
107             
108             String typeName = typeDom4j.getNamespacePrefix() + ":" + componentType.getSchemaType().getName();
109             
110             element.addAttribute("name", componentType.getSchemaType().getName());
111             element.addAttribute("type", typeName);
112             // TODO: Add config support for nillable
113             element.addAttribute("nillable", "true");
114  
115             element.addAttribute("minOccurs", "0");
116             element.addAttribute("maxOccurs", "unbounded");
117             
118         }
119         catch (IllegalArgumentException e)
120         {
121             throw new XFireRuntimeException("Illegal argument.", e);
122         }
123     }
124     
125     /***
126      * We need to write a complex type schema for Beans, so return true.
127      * 
128      * @see org.codehaus.xfire.java.type.Type#isComplex()
129      */
130     public boolean isComplex()
131     {
132         return true;
133     }
134     
135     /***
136      * @see org.codehaus.xfire.java.type.Type#getDependencies()
137      */
138     public Set getDependencies()
139     {
140         Set deps = new HashSet();
141         
142         deps.add( getTypeMapping().getType( getTypeClass().getComponentType() ) );
143         
144         return deps;
145     }
146     
147     protected Type getComponentType()
148     {
149         Class compType = getTypeClass().getComponentType();
150         
151         return getTypeMapping().getType( compType );
152     }
153 }