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
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 }