1 16 17 package org.apache.axis.encoding.ser; 18 19 import org.apache.axis.AxisFault; 20 import org.apache.axis.Constants; 21 import org.apache.axis.components.logger.LogFactory; 22 import org.apache.axis.description.FieldDesc; 23 import org.apache.axis.description.TypeDesc; 24 import org.apache.axis.description.ElementDesc; 25 import org.apache.axis.encoding.SerializationContext; 26 import org.apache.axis.encoding.Serializer; 27 import org.apache.axis.message.MessageElement; 28 import org.apache.axis.utils.BeanPropertyDescriptor; 29 import org.apache.axis.utils.BeanUtils; 30 import org.apache.axis.utils.JavaUtils; 31 import org.apache.axis.utils.Messages; 32 import org.apache.axis.utils.FieldPropertyDescriptor; 33 import org.apache.axis.wsdl.fromJava.Types; 34 import org.apache.axis.wsdl.symbolTable.SchemaUtils; 35 import org.apache.commons.logging.Log; 36 import org.w3c.dom.Element ; 37 import org.xml.sax.Attributes ; 38 import org.xml.sax.helpers.AttributesImpl ; 39 40 import javax.xml.namespace.QName ; 41 import java.io.IOException ; 42 import java.io.Serializable ; 43 import java.lang.reflect.InvocationTargetException ; 44 import java.lang.reflect.Modifier ; 45 import java.lang.reflect.Constructor ; 46 import java.util.List ; 47 48 55 public class BeanSerializer implements Serializer, Serializable { 56 57 protected static Log log = 58 LogFactory.getLog(BeanSerializer.class.getName()); 59 60 private static final QName MUST_UNDERSTAND_QNAME = 61 new QName (Constants.URI_SOAP11_ENV, Constants.ATTR_MUST_UNDERSTAND); 62 private static final Object [] ZERO_ARGS = 63 new Object [] { "0" }; 64 65 QName xmlType; 66 Class javaType; 67 68 protected BeanPropertyDescriptor[] propertyDescriptor = null; 69 protected TypeDesc typeDesc = null; 70 71 public BeanSerializer(Class javaType, QName xmlType) { 73 this(javaType, xmlType, TypeDesc.getTypeDescForClass(javaType)); 74 } 75 76 public BeanSerializer(Class javaType, QName xmlType, TypeDesc typeDesc) { 78 this(javaType, xmlType, typeDesc, null); 79 80 if (typeDesc != null) { 81 propertyDescriptor = typeDesc.getPropertyDescriptors(); 82 } else { 83 propertyDescriptor = BeanUtils.getPd(javaType, null); 84 } 85 } 86 87 public BeanSerializer(Class javaType, QName xmlType, TypeDesc typeDesc, 89 BeanPropertyDescriptor[] propertyDescriptor) { 90 this.xmlType = xmlType; 91 this.javaType = javaType; 92 this.typeDesc = typeDesc; 93 this.propertyDescriptor = propertyDescriptor; 94 } 95 96 103 public void serialize(QName name, Attributes attributes, 104 Object value, SerializationContext context) 105 throws IOException 106 { 107 Attributes beanAttrs = getObjectAttributes(value, attributes, context); 111 112 boolean isEncoded = context.isEncoded(); 114 115 boolean suppressElement = !isEncoded && 117 name.getNamespaceURI().equals("") && 118 name.getLocalPart().equals("any"); 119 120 if (!suppressElement) 121 context.startElement(name, beanAttrs); 122 123 if (value.getClass().isArray()) { 125 Object newVal = JavaUtils.convert(value, javaType); 126 if (newVal != null && javaType.isAssignableFrom(newVal.getClass())) { 127 value = newVal; 128 } 129 } 130 try { 131 for (int i=0; i<propertyDescriptor.length; i++) { 133 String propName = propertyDescriptor[i].getName(); 134 if (propName.equals("class")) 135 continue; 136 QName qname = null; 137 QName xmlType = null; 138 Class javaType = propertyDescriptor[i].getType(); 139 140 boolean isOmittable = false; 141 boolean isNillable = Types.isNullable(javaType); 143 boolean isArray = false; 145 QName itemQName = null; 146 147 if (typeDesc != null) { 152 FieldDesc field = typeDesc.getFieldByName(propName); 153 if (field != null) { 154 if (!field.isElement()) { 155 continue; 156 } 157 158 ElementDesc element = (ElementDesc)field; 159 160 if (isEncoded) { 164 qname = new QName (element.getXmlName().getLocalPart()); 165 } else { 166 qname = element.getXmlName(); 167 } 168 isOmittable = element.isMinOccursZero(); 169 isNillable = element.isNillable(); 170 isArray = element.isMaxOccursUnbounded(); 171 xmlType = element.getXmlType(); 172 itemQName = element.getItemQName(); 173 context.setItemQName(itemQName); 174 } 175 } 176 177 if (qname == null) { 178 qname = new QName (isEncoded ? "" : name.getNamespaceURI(), 179 propName); 180 } 181 182 if (xmlType == null) { 183 xmlType = context.getQNameForClass(javaType); 185 } 186 187 if (propertyDescriptor[i].isReadable()) { 189 if (itemQName != null || 190 (!propertyDescriptor[i].isIndexed() && !isArray)) { 191 Object propValue = 193 propertyDescriptor[i].get(value); 194 195 196 if (propValue == null) { 197 if (!isNillable && !isOmittable) { 200 if (Number .class.isAssignableFrom(javaType)) { 201 try { 205 Constructor constructor = 206 javaType.getConstructor( 207 SimpleDeserializer.STRING_CLASS); 208 propValue = constructor.newInstance(ZERO_ARGS); 209 } catch (Exception e) { 210 } 212 } 213 214 if (propValue == null) { 215 throw new IOException ( 216 Messages.getMessage( 217 "nullNonNillableElement", 218 propName)); 219 } 220 } 221 222 if (isOmittable && !isEncoded) { 226 continue; 227 } 228 } 229 230 context.serialize(qname, 231 null, 232 propValue, 233 xmlType); 234 } else { 235 int j=0; 237 while(j >= 0) { 238 Object propValue = null; 239 try { 240 propValue = 241 propertyDescriptor[i].get(value, j); 242 j++; 243 } catch (Exception e) { 244 j = -1; 245 } 246 if (j >= 0) { 247 context.serialize(qname, null, 248 propValue, xmlType); 249 } 250 } 251 } 252 } 253 } 254 255 BeanPropertyDescriptor anyDesc = typeDesc == null ? null : 256 typeDesc.getAnyDesc(); 257 if (anyDesc != null) { 258 Object anyVal = anyDesc.get(value); 261 if (anyVal != null && anyVal instanceof MessageElement[]) { 262 MessageElement [] anyContent = (MessageElement[])anyVal; 263 for (int i = 0; i < anyContent.length; i++) { 264 MessageElement element = anyContent[i]; 265 element.output(context); 266 } 267 } 268 } 269 } catch (InvocationTargetException ite) { 270 Throwable target = ite.getTargetException(); 271 log.error(Messages.getMessage("exception00"), target); 272 throw new IOException (target.toString()); 273 } catch (Exception e) { 274 log.error(Messages.getMessage("exception00"), e); 275 throw new IOException (e.toString()); 276 } 277 278 if (!suppressElement) 279 context.endElement(); 280 } 281 282 283 284 public String getMechanismType() { return Constants.AXIS_SAX; } 285 286 297 public Element writeSchema(Class javaType, Types types) throws Exception { 298 299 Element complexType = types.createElement("complexType"); 301 302 Element e = null; 304 Class superClass = javaType.getSuperclass(); 305 BeanPropertyDescriptor[] superPd = null; 306 List stopClasses = types.getStopClasses(); 307 if (superClass != null && 308 superClass != java.lang.Object .class && 309 superClass != java.lang.Exception .class && 310 superClass != java.lang.Throwable .class && 311 superClass != java.lang.RuntimeException .class && 312 superClass != java.rmi.RemoteException .class && 313 superClass != org.apache.axis.AxisFault.class && 314 (stopClasses == null || 315 !(stopClasses.contains(superClass.getName()))) ) { 316 String base = types.writeType(superClass); 318 Element complexContent = types.createElement("complexContent"); 319 complexType.appendChild(complexContent); 320 Element extension = types.createElement("extension"); 321 complexContent.appendChild(extension); 322 extension.setAttribute("base", base); 323 e = extension; 324 TypeDesc superTypeDesc = TypeDesc.getTypeDescForClass(superClass); 326 if (superTypeDesc != null) { 327 superPd = superTypeDesc.getPropertyDescriptors(); 328 } else { 329 superPd = BeanUtils.getPd(superClass, null); 330 } 331 } else { 332 e = complexType; 333 } 334 335 Element all = types.createElement("sequence"); 343 e.appendChild(all); 344 345 if (Modifier.isAbstract(javaType.getModifiers())) { 346 complexType.setAttribute("abstract", "true"); 347 } 348 349 for (int i=0; i<propertyDescriptor.length; i++) { 351 String propName = propertyDescriptor[i].getName(); 352 353 boolean writeProperty = true; 355 if (propName.equals("class")) { 356 writeProperty = false; 357 } 358 359 if (superPd != null && writeProperty) { 362 for (int j=0; j<superPd.length && writeProperty; j++) { 363 if (propName.equals(superPd[j].getName())) { 364 writeProperty = false; 365 } 366 } 367 } 368 if (!writeProperty) { 369 continue; 370 } 371 372 377 if (typeDesc != null) { 378 Class fieldType = propertyDescriptor[i].getType(); 379 FieldDesc field = typeDesc.getFieldByName(propName); 380 381 if (field != null) { 382 QName qname = field.getXmlName(); 383 QName fieldXmlType = field.getXmlType(); 384 boolean isAnonymous = fieldXmlType != null && fieldXmlType.getLocalPart().startsWith(">"); 385 386 if (qname != null) { 387 392 propName = qname.getLocalPart(); 394 } 395 if (!field.isElement()) { 396 writeAttribute(types, 397 propName, 398 fieldType, 399 fieldXmlType, 400 complexType); 401 } else { 402 writeField(types, 403 propName, 404 fieldXmlType, 405 fieldType, 406 propertyDescriptor[i].isIndexed(), 407 field.isMinOccursZero(), 408 all, isAnonymous, 409 ((ElementDesc)field).getItemQName()); 410 } 411 } else { 412 writeField(types, 413 propName, 414 null, 415 fieldType, 416 propertyDescriptor[i].isIndexed(), false, all, false, null); 417 } 418 } else { 419 boolean done = false; 420 if (propertyDescriptor[i] instanceof FieldPropertyDescriptor){ 421 FieldPropertyDescriptor fpd = (FieldPropertyDescriptor) propertyDescriptor[i]; 422 Class clazz = fpd.getField().getType(); 423 if(types.getTypeQName(clazz)!=null) { 424 writeField(types, 425 propName, 426 null, 427 clazz, 428 false, false, all, false, null); 429 430 done = true; 431 } 432 } 433 if(!done) { 434 writeField(types, 435 propName, 436 null, 437 propertyDescriptor[i].getType(), 438 propertyDescriptor[i].isIndexed(), false, all, false, null); 439 } 440 441 } 442 } 443 444 return complexType; 446 } 447 448 459 protected void writeField(Types types, 460 String fieldName, 461 QName xmlType, 462 Class fieldType, 463 boolean isUnbounded, 464 boolean isOmittable, 465 Element where, 466 boolean isAnonymous, 467 QName itemQName) throws Exception { 468 Element elem; 469 String elementType = null; 470 471 if (isAnonymous) { 472 elem = types. 473 createElementWithAnonymousType(fieldName, 474 fieldType, 475 isOmittable, 476 where.getOwnerDocument()); 477 } else { 478 if (!SchemaUtils.isSimpleSchemaType(xmlType) && 479 Types.isArray(fieldType)) { 480 xmlType = null; 481 } 482 483 if (itemQName != null && 484 SchemaUtils.isSimpleSchemaType(xmlType) && 485 Types.isArray(fieldType)) { 486 xmlType = null; 487 } 488 489 QName typeQName = types.writeTypeAndSubTypeForPart(fieldType, xmlType); 490 elementType = types.getQNameString(typeQName); 491 492 if (elementType == null) { 493 QName anyQN = Constants.XSD_ANYTYPE; 495 String prefix = types.getNamespaces(). 496 getCreatePrefix(anyQN.getNamespaceURI()); 497 elementType = prefix + ":" + anyQN.getLocalPart(); 498 } 499 500 boolean isNillable = Types.isNullable(fieldType); 502 if (typeDesc != null) { 503 FieldDesc field = typeDesc.getFieldByName(fieldName); 504 if (field != null && field.isElement()) { 505 isNillable = ((ElementDesc)field).isNillable(); 506 } 507 } 508 509 elem = types.createElement(fieldName, 510 elementType, 511 isNillable, 512 isOmittable, 513 where.getOwnerDocument()); 514 } 515 516 if (isUnbounded) { 517 elem.setAttribute("maxOccurs", "unbounded"); 518 } 519 520 where.appendChild(elem); 521 } 522 523 530 protected void writeAttribute(Types types, 531 String fieldName, 532 Class fieldType, 533 QName fieldXmlType, 534 Element where) throws Exception { 535 536 if (!types.isAcceptableAsAttribute(fieldType)) { 538 throw new AxisFault(Messages.getMessage("AttrNotSimpleType00", 539 fieldName, 540 fieldType.getName())); 541 } 542 Element elem = types.createAttributeElement(fieldName, 543 fieldType, fieldXmlType, 544 false, 545 where.getOwnerDocument()); 546 where.appendChild(elem); 547 } 548 549 557 protected Attributes getObjectAttributes(Object value, 558 Attributes attributes, 559 SerializationContext context) { 560 561 if (typeDesc == null || !typeDesc.hasAttributes()) 562 return attributes; 563 564 AttributesImpl attrs; 565 if (attributes == null) { 566 attrs = new AttributesImpl (); 567 } else if (attributes instanceof AttributesImpl ) { 568 attrs = (AttributesImpl )attributes; 569 } else { 570 attrs = new AttributesImpl (attributes); 571 } 572 573 try { 574 for (int i=0; i<propertyDescriptor.length; i++) { 577 String propName = propertyDescriptor[i].getName(); 578 if (propName.equals("class")) 579 continue; 580 581 FieldDesc field = typeDesc.getFieldByName(propName); 582 if (field == null || field.isElement()) 584 continue; 585 586 QName qname = field.getXmlName(); 587 if (qname == null) { 588 qname = new QName ("", propName); 589 } 590 591 if (propertyDescriptor[i].isReadable() && 592 !propertyDescriptor[i].isIndexed()) { 593 Object propValue = propertyDescriptor[i].get(value); 595 if (qname.equals(MUST_UNDERSTAND_QNAME)) { 597 if (propValue.equals(Boolean.TRUE)) { 598 propValue = "1"; 599 } else if (propValue.equals(Boolean.FALSE)) { 600 propValue = "0"; 601 } 602 } 603 if (propValue != null) { 608 setAttributeProperty(propValue, 609 qname, 610 field.getXmlType(), 611 attrs, 612 context); 613 } 614 } 615 } 616 } catch (Exception e) { 617 return attrs; 619 } 620 621 return attrs; 622 } 623 624 private void setAttributeProperty(Object propValue, 625 QName qname, 626 QName xmlType, AttributesImpl attrs, 627 SerializationContext context) throws Exception { 628 629 String namespace = qname.getNamespaceURI(); 630 String localName = qname.getLocalPart(); 631 632 if (attrs.getIndex(namespace, localName) != -1) { 638 return; 639 } 640 641 String propString = context.getValueAsString(propValue, xmlType); 642 643 attrs.addAttribute(namespace, 644 localName, 645 context.attributeQName2String(qname), 646 "CDATA", 647 propString); 648 } 649 } 650 | Popular Tags |