View Javadoc

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