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