1 package org.codehaus.xfire.aegis.type;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Iterator;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Set;
9
10 import ognl.Ognl;
11 import ognl.OgnlException;
12
13 import org.codehaus.xfire.XFireRuntimeException;
14 import org.codehaus.xfire.aegis.AegisService;
15 import org.codehaus.xfire.aegis.mapping.TypeRegistry;
16 import org.codehaus.xfire.fault.XFireFault;
17 import org.dom4j.Element;
18 import org.dom4j.QName;
19
20 /***
21 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse </a>
22 */
23 public class FlatArrayType
24 extends Type
25 {
26 private String key;
27
28 private String arrayClass;
29
30 private Type childType;
31
32 /***
33 * Uses an OGNL expression to find an array. It then puts each
34 * array object in as the key (see <code>getKey()</code> for retrieval
35 * when write()'ing in the child type.
36 *
37 * @see org.codehaus.xfire.aegis.type.Type#write(org.dom4j.Element, java.util.Map)
38 */
39 public void write(Element element, Map context) throws XFireFault
40 {
41 try
42 {
43 Object value = Ognl.getValue(getOgnl(), context, (Object) null);
44
45 if ( value == null )
46 {
47 return;
48 }
49
50 if ( value instanceof Object[] )
51 {
52 Object[] children = (Object[]) value;
53
54 for (int i = 0; i < children.length; i++)
55 {
56 context.put( getKey(), children[i] );
57
58 Type type = getChildType();
59 type.write(element, context);
60 }
61 }
62 else if ( value instanceof Collection )
63 {
64 Collection children = (Collection) value;
65 for ( Iterator itr = children.iterator(); itr.hasNext(); )
66 {
67 context.put( getKey(), itr.next());
68
69 Type type = getChildType();
70 type.write(element, context);
71 }
72 }
73
74 context.put( getKey(), null );
75 }
76 catch (OgnlException e)
77 {
78 throw new XFireFault("Couldn't process message.", e, XFireFault.SENDER);
79 }
80 }
81
82 public void read( Element element, Map context )
83 throws XFireFault
84 {
85 read( element, 0, context );
86 }
87
88
89 public void read(Element element, int occurrence, Map context) throws XFireFault
90 {
91 List array = new ArrayList();
92 List elements = element.elements();
93
94 context.put( getKey() + ".length", new Integer(elements.size()) );
95
96 int i = 0;
97 for (Iterator itr = elements.iterator(); itr.hasNext();)
98 {
99 context.put( getKey() + ".index", new Integer(i) );
100 Element arrayEl = (Element) itr.next();
101
102 getChildType().read(arrayEl, context);
103
104 try
105 {
106 Object value = Ognl.getValue(getOgnl(), context, (Object) null);
107
108 array.add(value);
109 }
110 catch (OgnlException e)
111 {
112 throw new XFireFault("Couldn't process message.", e, XFireFault.SENDER);
113 }
114
115 i++;
116 }
117
118 context.put( getKey(), array );
119 }
120
121 public boolean isComplex()
122 {
123 return getChildType().isComplex();
124 }
125
126 public Set getDependencies()
127 {
128 return getChildType().getDependencies();
129 }
130
131 public Type getChildType()
132 {
133 return childType;
134 }
135
136 public void setChildType(Type childType)
137 {
138 this.childType = childType;
139 }
140
141 public String getKey()
142 {
143 return key;
144 }
145
146 public void setKey(String key)
147 {
148 this.key = key;
149 }
150
151 /***
152 * @see org.codehaus.xfire.aegis.type.Type#writeSchema(org.dom4j.Element)
153 */
154 public void writeSchema(Element root)
155 {
156 getChildType().writeSchema(root);
157 }
158
159
160 public String getMaxOccurs()
161 {
162 return getChildType().getMaxOccurs();
163 }
164
165 public String getMinOccurs()
166 {
167 return getChildType().getMinOccurs();
168 }
169
170 public String getName()
171 {
172 return getChildType().getName();
173 }
174
175 public QName getQName()
176 {
177 return getChildType().getQName();
178 }
179
180
181 public QName getSchemaType()
182 {
183 return getChildType().getSchemaType();
184 }
185
186 /***
187 * @see org.codehaus.xfire.aegis.type.Type#configure(org.dom4j.Element)
188 */
189 public void configure(Element configuration,
190 AegisService service,
191 TypeRegistry reg)
192 {
193 setOgnl(configuration.attributeValue("ognl"));
194 setKey(configuration.attributeValue("key"));
195 setDocumentation( configuration.getTextTrim() );
196
197 if ( configuration.elements().size() > 1 )
198 {
199 throw new XFireRuntimeException("Only one array child type allowed.");
200 }
201
202 Element childTypeEl = (Element) configuration.elements().get(0);
203 QName typeQ = QName.get(childTypeEl.getName(), service.getSoapVersion());
204
205 Type type = reg.createType(typeQ);
206 type.configure(childTypeEl, service, reg);
207
208 setChildType(type);
209 }
210
211 }