1 16 17 package org.apache.axis.encoding.ser; 18 19 import java.io.IOException ; 20 import java.lang.reflect.Array ; 21 import java.util.Collection ; 22 import java.util.Iterator ; 23 import javax.xml.namespace.QName ; 24 import org.w3c.dom.Element ; 25 import org.xml.sax.Attributes ; 26 import org.xml.sax.helpers.AttributesImpl ; 27 import org.apache.axis.AxisEngine; 28 import org.apache.axis.Constants; 29 import org.apache.axis.MessageContext; 30 import org.apache.axis.components.logger.LogFactory; 31 import org.apache.axis.constants.Use; 32 import org.apache.axis.encoding.SerializationContext; 33 import org.apache.axis.encoding.Serializer; 34 import org.apache.axis.encoding.SerializerFactory; 35 import org.apache.axis.encoding.TypeMapping; 36 import org.apache.axis.schema.SchemaVersion; 37 import org.apache.axis.soap.SOAPConstants; 38 import org.apache.axis.utils.JavaUtils; 39 import org.apache.axis.utils.Messages; 40 import org.apache.axis.wsdl.fromJava.Types; 41 import org.apache.commons.logging.Log; 42 43 53 public class ArraySerializer implements Serializer 54 { 55 QName xmlType = null; 56 Class javaType = null; 57 QName componentType = null; 58 QName componentQName = null; 59 60 64 public ArraySerializer(Class javaType, QName xmlType) { 65 this.javaType = javaType; 66 this.xmlType = xmlType; 67 } 68 69 73 public ArraySerializer(Class javaType, QName xmlType, QName componentType) { 74 this(javaType, xmlType); 75 this.componentType = componentType; 76 } 77 78 82 public ArraySerializer(Class javaType, QName xmlType, QName componentType, QName componentQName) { 83 this(javaType, xmlType, componentType); 84 this.componentQName = componentQName; 85 } 86 87 protected static Log log = 88 LogFactory.getLog(ArraySerializer.class.getName()); 89 90 97 public void serialize(QName name, Attributes attributes, 98 Object value, SerializationContext context) 99 throws IOException 100 { 101 if (value == null) 102 throw new IOException (Messages.getMessage("cantDoNullArray00")); 103 104 MessageContext msgContext = context.getMessageContext(); 105 SchemaVersion schema = SchemaVersion.SCHEMA_2001; 106 SOAPConstants soap = SOAPConstants.SOAP11_CONSTANTS; 107 boolean encoded = context.isEncoded(); 108 109 if (msgContext != null) { 110 schema = msgContext.getSchemaVersion(); 111 soap = msgContext.getSOAPConstants(); 112 } 113 114 Class cls = value.getClass(); 115 Collection list = null; 116 117 if (!cls.isArray()) { 118 if (!(value instanceof Collection )) { 119 throw new IOException ( 120 Messages.getMessage("cantSerialize00", cls.getName())); 121 } 122 list = (Collection )value; 123 } 124 125 Class componentClass; 127 if (list == null) { 128 componentClass = cls.getComponentType(); 129 } else { 130 componentClass = Object .class; 131 } 132 133 QName componentTypeQName = this.componentType; 136 137 String dims = ""; 145 146 if (componentTypeQName != null) { 147 TypeMapping tm = context.getTypeMapping(); 150 SerializerFactory factory = (SerializerFactory) tm.getSerializer( 151 componentClass, componentTypeQName); 152 while (componentClass.isArray() 153 && factory instanceof ArraySerializerFactory) { 154 ArraySerializerFactory asf = (ArraySerializerFactory) factory; 155 componentClass = componentClass.getComponentType(); 156 QName componentType = null; 157 if (asf.getComponentType() != null) { 158 componentType = asf.getComponentType(); 159 if(encoded) { 160 componentTypeQName = componentType; 161 } 162 } 163 factory = (SerializerFactory) tm.getSerializer(componentClass, 165 componentType); 166 if (soap == SOAPConstants.SOAP12_CONSTANTS) 167 dims += "* "; 168 else 169 dims += "[]"; 170 } 171 } else { 172 while (componentClass.isArray()) { 174 componentClass = componentClass.getComponentType(); 175 if (soap == SOAPConstants.SOAP12_CONSTANTS) 176 dims += "* "; 177 else 178 dims += "[]"; 179 } 180 } 181 182 if (componentTypeQName == null) { 184 componentTypeQName = context.getCurrentXMLType(); 185 if (componentTypeQName != null) { 186 if ((componentTypeQName.equals(xmlType) || 187 componentTypeQName.equals(Constants.XSD_ANYTYPE) || 188 componentTypeQName.equals(soap.getArrayType()))) { 189 componentTypeQName = null; 190 } 191 } 192 } 193 194 if (componentTypeQName == null) { 195 componentTypeQName = context.getItemType(); 196 } 197 198 if (componentTypeQName == null) { 200 componentTypeQName = context.getQNameForClass(componentClass); 201 } 202 203 if (componentTypeQName == null) { 205 Class searchCls = componentClass; 206 while(searchCls != null && componentTypeQName == null) { 207 searchCls = searchCls.getSuperclass(); 208 componentTypeQName = context.getQNameForClass(searchCls); 209 } 210 if (componentTypeQName != null) { 211 componentClass = searchCls; 212 } 213 } 214 215 if (componentTypeQName == null) { 217 throw new IOException ( 218 Messages.getMessage("noType00", componentClass.getName())); 219 } 220 221 int len = (list == null) ? Array.getLength(value) : list.size(); 222 String arrayType = ""; 223 int dim2Len = -1; 224 if (encoded) { 225 if (soap == SOAPConstants.SOAP12_CONSTANTS) { 226 arrayType = dims + len; 227 } else { 228 arrayType = dims + "[" + len + "]"; 229 } 230 231 258 boolean enable2Dim = false; 261 262 if( msgContext != null ) { 264 enable2Dim = JavaUtils.isTrueExplicitly(msgContext.getProperty( 265 AxisEngine.PROP_TWOD_ARRAY_ENCODING)); 266 } 267 268 if (enable2Dim && !dims.equals("")) { 269 if (cls.isArray() && len > 0) { 270 boolean okay = true; 271 for (int i=0; i < len && okay; i++) { 273 274 Object elementValue = Array.get(value, i); 275 if (elementValue == null) 276 okay = false; 277 else if (dim2Len < 0) { 278 dim2Len = Array.getLength(elementValue); 279 if (dim2Len <= 0) { 280 okay = false; 281 } 282 } else if (dim2Len != Array.getLength(elementValue)) { 283 okay = false; 284 } 285 } 286 if (okay) { 288 dims = dims.substring(0, dims.length()-2); 289 if (soap == SOAPConstants.SOAP12_CONSTANTS) 290 arrayType = dims + len + " " + dim2Len; 291 else 292 arrayType = dims + "[" + len + "," + dim2Len + "]"; 293 } else { 294 dim2Len = -1; 295 } 296 } 297 } 298 } 299 300 QName itemQName = context.getItemQName(); 305 boolean maxOccursUsage = !encoded && itemQName == null && 306 componentTypeQName.equals(context.getCurrentXMLType()); 307 308 if (encoded) { 309 AttributesImpl attrs; 310 if (attributes == null) { 311 attrs = new AttributesImpl (); 312 } else if (attributes instanceof AttributesImpl ) { 313 attrs = (AttributesImpl )attributes; 314 } else { 315 attrs = new AttributesImpl (attributes); 316 } 317 318 String compType = context.attributeQName2String(componentTypeQName); 319 320 if (attrs.getIndex(soap.getEncodingURI(), soap.getAttrItemType()) == -1) { 321 String encprefix = 322 context.getPrefixForURI(soap.getEncodingURI()); 323 324 if (soap != SOAPConstants.SOAP12_CONSTANTS) { 325 compType = compType + arrayType; 326 327 attrs.addAttribute(soap.getEncodingURI(), 328 soap.getAttrItemType(), 329 encprefix + ":arrayType", 330 "CDATA", 331 compType); 332 333 } else { 334 attrs.addAttribute(soap.getEncodingURI(), 335 soap.getAttrItemType(), 336 encprefix + ":itemType", 337 "CDATA", 338 compType); 339 340 attrs.addAttribute(soap.getEncodingURI(), 341 "arraySize", 342 encprefix + ":arraySize", 343 "CDATA", 344 arrayType); 345 } 346 } 347 348 String qname = 363 context.getPrefixForURI(schema.getXsiURI(), 364 "xsi") + ":type"; 365 QName soapArray; 366 if (soap == SOAPConstants.SOAP12_CONSTANTS) { 367 soapArray = Constants.SOAP_ARRAY12; 368 } else { 369 soapArray = Constants.SOAP_ARRAY; 370 } 371 372 int typeI = attrs.getIndex(schema.getXsiURI(), 373 "type"); 374 if (typeI != -1) { 375 attrs.setAttribute(typeI, 376 schema.getXsiURI(), 377 "type", 378 qname, 379 "CDATA", 380 context.qName2String(soapArray)); 381 } else { 382 attrs.addAttribute(schema.getXsiURI(), 383 "type", 384 qname, 385 "CDATA", 386 context.qName2String(soapArray)); 387 } 388 389 attributes = attrs; 390 } 391 392 QName elementName = name; 396 Attributes serializeAttr = attributes; 397 if (!maxOccursUsage) { 398 serializeAttr = null; context.startElement(name, attributes); 400 if (itemQName != null) 401 elementName = itemQName; 402 else if(componentQName != null) 403 elementName = componentQName; 404 } 405 406 407 if (dim2Len < 0) { 408 if (list == null) { 410 for (int index = 0; index < len; index++) { 411 Object aValue = Array.get(value, index); 412 413 context.serialize(elementName, 415 (serializeAttr == null ? 416 serializeAttr : new AttributesImpl (serializeAttr)), 417 aValue, 418 componentTypeQName); } 420 } else { 421 for (Iterator iterator = list.iterator(); iterator.hasNext();) { 422 Object aValue = iterator.next(); 423 424 context.serialize(elementName, 426 (serializeAttr == null ? 427 serializeAttr : new AttributesImpl (serializeAttr)), 428 aValue, 429 componentTypeQName); } 431 } 432 } else { 433 for (int index = 0; index < len; index++) { 435 for (int index2 = 0; index2 < dim2Len; index2++) { 436 Object aValue = Array.get(Array.get(value, index), index2); 437 context.serialize(elementName, null, aValue, componentTypeQName); 438 } 439 } 440 } 441 442 if (!maxOccursUsage) 443 context.endElement(); 444 } 445 446 public String getMechanismType() { return Constants.AXIS_SAX; } 447 448 private static boolean isArray(Class clazz) 449 { 450 return clazz.isArray() || java.util.Collection .class.isAssignableFrom(clazz); 451 } 452 453 private static Class getComponentType(Class clazz) 454 { 455 if (clazz.isArray()) 456 { 457 return clazz.getComponentType(); 458 } 459 else if (java.util.Collection .class.isAssignableFrom(clazz)) 460 { 461 return Object .class; 462 } 463 else 464 { 465 return null; 466 } 467 } 468 469 470 481 public Element writeSchema(Class javaType, Types types) throws Exception { 482 boolean encoded = true; 483 MessageContext mc = MessageContext.getCurrentContext(); 484 if (mc != null) { 485 encoded = mc.isEncoded(); 486 } else { 487 encoded = types.getServiceDesc().getUse() == Use.ENCODED; 488 } 489 490 if (!encoded) { 491 Class cType = Object .class; 492 if (javaType.isArray()) { 493 cType = javaType.getComponentType(); 494 } 495 496 String typeName = types.writeType(cType); 497 return types.createLiteralArrayElement(typeName, null); 498 } 499 500 String componentTypeName = null; 502 Class componentType = null; 503 if (isArray(javaType)) { 504 String dimString = "[]"; 505 componentType = getComponentType(javaType); 506 while (isArray(componentType)) { 507 dimString += "[]"; 508 componentType = getComponentType(componentType); 509 } 510 types.writeType(componentType,null); 511 512 componentTypeName = 513 types.getQNameString(types.getTypeQName(componentType)) + 514 dimString; 515 } 516 517 return types.createArrayElement(componentTypeName); 519 } 520 } 521 | Popular Tags |