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 }