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 }