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) throws XFireFault
83 {
84 List array = new ArrayList();
85 List elements = element.elements();
86
87 context.put( getKey() + ".length", new Integer(elements.size()) );
88
89 int i = 0;
90 for (Iterator itr = elements.iterator(); itr.hasNext();)
91 {
92 context.put( getKey() + ".index", new Integer(i) );
93 Element arrayEl = (Element) itr.next();
94
95 getChildType().read(arrayEl, context);
96
97 try
98 {
99 Object value = Ognl.getValue(getOgnl(), context, (Object) null);
100
101 array.add(value);
102 }
103 catch (OgnlException e)
104 {
105 throw new XFireFault("Couldn't process message.", e, XFireFault.SENDER);
106 }
107
108 i++;
109 }
110
111 context.put( getKey(), array );
112 }
113
114 public boolean isComplex()
115 {
116 return getChildType().isComplex();
117 }
118
119 public Set getDependencies()
120 {
121 return getChildType().getDependencies();
122 }
123
124 public Type getChildType()
125 {
126 return childType;
127 }
128
129 public void setChildType(Type childType)
130 {
131 this.childType = childType;
132 }
133
134 public String getKey()
135 {
136 return key;
137 }
138
139 public void setKey(String key)
140 {
141 this.key = key;
142 }
143
144 /***
145 * @see org.codehaus.xfire.aegis.type.Type#writeSchema(org.dom4j.Element)
146 */
147 public void writeSchema(Element root)
148 {
149 getChildType().writeSchema(root);
150 }
151
152
153 public String getMaxOccurs()
154 {
155 return getChildType().getMaxOccurs();
156 }
157
158 public String getMinOccurs()
159 {
160 return getChildType().getMinOccurs();
161 }
162
163 public String getName()
164 {
165 return getChildType().getName();
166 }
167
168 public QName getQName()
169 {
170 return getChildType().getQName();
171 }
172
173
174 public QName getSchemaType()
175 {
176 return getChildType().getSchemaType();
177 }
178
179 /***
180 * @see org.codehaus.xfire.aegis.type.Type#configure(org.dom4j.Element)
181 */
182 public void configure(Element configuration,
183 AegisService service,
184 TypeRegistry reg)
185 {
186 setOgnl(configuration.attributeValue("ognl"));
187 setKey(configuration.attributeValue("key"));
188 setDocumentation( configuration.getTextTrim() );
189
190 if ( configuration.elements().size() > 1 )
191 {
192 throw new XFireRuntimeException("Only one array child type allowed.");
193 }
194
195 Element childTypeEl = (Element) configuration.elements().get(0);
196 QName typeQ = QName.get(childTypeEl.getName(), service.getSoapVersion());
197
198 Type type = reg.createType(typeQ);
199 type.configure(childTypeEl, service, reg);
200
201 setChildType(type);
202 }
203
204 }