1 54 55 package org.jboss.axis.encoding.ser; 56 57 import org.jboss.axis.Constants; 58 import org.jboss.axis.description.ElementDesc; 59 import org.jboss.axis.description.FieldDesc; 60 import org.jboss.axis.description.TypeDesc; 61 import org.jboss.axis.encoding.DeserializationContext; 62 import org.jboss.axis.encoding.Deserializer; 63 import org.jboss.axis.encoding.DeserializerImpl; 64 import org.jboss.axis.encoding.TypeMapping; 65 import org.jboss.axis.message.SOAPElementAxisImpl; 66 import org.jboss.axis.message.SOAPHandler; 67 import org.jboss.axis.soap.SOAPConstants; 68 import org.jboss.axis.utils.BeanPropertyDescriptor; 69 import org.jboss.axis.utils.JavaUtils; 70 import org.jboss.axis.utils.Messages; 71 import org.jboss.logging.Logger; 72 import org.xml.sax.Attributes ; 73 import org.xml.sax.SAXException ; 74 75 import javax.xml.namespace.QName ; 76 import java.lang.reflect.Constructor ; 77 import java.util.ArrayList ; 78 import java.util.Iterator ; 79 import java.util.Map ; 80 81 88 public class BeanDeserializer extends DeserializerImpl 89 { 90 private static Logger log = Logger.getLogger(BeanDeserializer.class.getName()); 91 92 QName xmlType; 93 Class javaType; 94 protected Map propertyMap; 95 protected QName prevQName; 96 97 100 protected TypeDesc typeDesc = null; 101 102 protected int collectionIndex = -1; 104 105 protected SimpleDeserializer cacheStringDSer = null; 106 protected QName cacheXMLType = null; 107 protected String lastFieldName = null; 108 109 protected DeferredBeanConstruction deferedConstruction; 112 113 public BeanDeserializer(Class javaType, QName xmlType) 115 { 116 this(javaType, xmlType, TypeDesc.getTypeDescForClass(javaType)); 117 } 118 119 public BeanDeserializer(Class javaType, QName xmlType, TypeDesc typeDesc) 121 { 122 this(javaType, xmlType, typeDesc, BeanDeserializerFactory.getProperties(javaType, typeDesc)); 123 } 124 125 public BeanDeserializer(Class javaType, QName xmlType, TypeDesc typeDesc, Map propertyMap) 127 { 128 this.xmlType = xmlType; 129 this.javaType = javaType; 130 this.typeDesc = typeDesc; 131 this.propertyMap = propertyMap; 132 133 try 135 { 136 value = javaType.newInstance(); 137 } 138 catch (Exception e) 139 { 140 } 144 } 145 146 160 public void onStartElement(String namespace, String localName, 161 String prefix, Attributes attributes, 162 DeserializationContext context) 163 throws SAXException 164 { 165 lastFieldName = null; 167 168 if (value == null) 171 { 172 try 173 { 174 value = javaType.newInstance(); 175 } 176 catch (Exception e) 177 { 178 179 ArrayList propTypes = new ArrayList (); 181 Iterator it = propertyMap.values().iterator(); 182 while (it.hasNext()) 183 { 184 BeanPropertyDescriptor bpd = (BeanPropertyDescriptor)it.next(); 185 propTypes.add(bpd.getType()); 186 } 187 188 Constructor [] ctors = javaType.getConstructors(); 190 191 deferedConstruction = null; 194 195 for (int i = 0; deferedConstruction == null && i < ctors.length; i++) 197 { 198 Constructor ctor = ctors[i]; 199 Class [] ctorArgs = ctor.getParameterTypes(); 200 if (ctorArgs.length > 0) 201 { 202 boolean allFound = true; 203 for (int j = 0; j < ctorArgs.length; j++) 204 { 205 allFound &= propTypes.contains(ctorArgs[j]); 206 } 207 208 if (allFound) 209 { 210 deferedConstruction = new DeferredBeanConstruction(ctor); 211 } 212 } 213 } 214 215 if (value == null && deferedConstruction == null) 217 { 218 throw new SAXException (Messages.getMessage("cantCreateBean00", 220 javaType.getName(), 221 e.toString())); 222 } 223 } 224 } 225 226 if (typeDesc == null) 229 return; 230 231 SOAPConstants soapConstants = context.getMessageContext().getSOAPConstants(); 233 String soapenvURI = soapConstants.getEnvelopeURI(); 234 235 for (int i = 0; i < attributes.getLength(); i++) 238 { 239 QName attrQName = null; 242 if (soapenvURI.equals(attributes.getURI(i))) 243 attrQName = new QName (attributes.getLocalName(i)); 244 else 245 attrQName = new QName (attributes.getURI(i), attributes.getLocalName(i)); 246 247 String fieldName = typeDesc.getFieldNameForAttribute(attrQName); 248 if (fieldName != null) 249 { 250 BeanPropertyDescriptor bpd = (BeanPropertyDescriptor)propertyMap.get(fieldName); 252 if (bpd != null) 253 { 254 if (!bpd.isIndexed()) 255 { 256 Deserializer dSer = getDeserializer(null, bpd.getType(), null, context); 258 if (dSer == null) 259 throw new SAXException (Messages.getMessage("unregistered00", bpd.getType().toString())); 260 261 if (!(dSer instanceof SimpleDeserializer)) 262 throw new SAXException (Messages.getMessage("AttrNotSimpleType00", bpd.getName(), bpd.getType().toString())); 263 264 try 267 { 268 dSer.onStartElement(namespace, localName, prefix, attributes, context); 269 Object val = ((SimpleDeserializer)dSer).makeValue(attributes.getValue(i)); 270 if (value != null) 271 { 272 bpd.set(value, val); 273 } 274 else if (deferedConstruction != null) 275 { 276 value = deferedConstruction.newBeanInstance(val); 277 } 278 } 279 catch (Exception e) 280 { 281 throw new SAXException (e); 282 } 283 } 284 } 285 } 286 } } 288 289 302 public SOAPHandler onStartChild(String namespace, 303 String localName, 304 String prefix, 305 Attributes attributes, 306 DeserializationContext context) 307 throws SAXException 308 { 309 log.debug("onStartChild: " + new QName (namespace, localName)); 310 311 BeanPropertyDescriptor propDesc = null; 312 FieldDesc fieldDesc = null; 313 314 SOAPConstants soapConstants = context.getMessageContext().getSOAPConstants(); 315 String encodingStyle = context.getMessageContext().getEncodingStyle(); 316 boolean isEncoded = Constants.isSOAP_ENC(encodingStyle); 317 318 QName elemQName = new QName (namespace, localName); 319 if ((prevQName == null) || (!prevQName.equals(elemQName))) 321 { 322 collectionIndex = -1; 323 } 324 prevQName = elemQName; 325 326 334 if (typeDesc != null) 335 { 336 String fieldName = typeDesc.getFieldNameForElement(elemQName); 339 if (fieldName != null) 340 { 341 propDesc = (BeanPropertyDescriptor)propertyMap.get(fieldName); 342 if (propDesc == null) 343 { 344 String lowerName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1); 345 propDesc = (BeanPropertyDescriptor)propertyMap.get(lowerName); 346 } 347 348 fieldDesc = typeDesc.getFieldByName(fieldName); 349 if (fieldDesc == null) 350 { 351 String lowerName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1); 352 fieldDesc = typeDesc.getFieldByName(lowerName); 353 } 354 } 355 356 lastFieldName = fieldName; 358 } 359 else 360 { 361 lastFieldName = null; 362 } 363 364 if (propDesc == null) 365 { 366 propDesc = (BeanPropertyDescriptor)propertyMap.get(localName); 368 } 369 370 if (propDesc == null) 373 { 374 propDesc = getAnyPropertyDesc(); 377 if (propDesc != null) 378 { 379 try 380 { 381 SOAPElementAxisImpl[] curElements = (SOAPElementAxisImpl[])propDesc.get(value); 382 int length = 0; 383 if (curElements != null) 384 { 385 length = curElements.length; 386 } 387 SOAPElementAxisImpl[] newElements = new SOAPElementAxisImpl[length + 1]; 388 if (curElements != null) 389 { 390 System.arraycopy(curElements, 0, 391 newElements, 0, length); 392 } 393 SOAPElementAxisImpl thisEl = context.getCurElement(); 394 395 newElements[length] = thisEl; 396 propDesc.set(value, newElements); 397 if (!localName.equals(thisEl.getName())) 403 { 404 return new SOAPHandler(newElements, length); 405 } 406 return new SOAPHandler(); 407 } 408 catch (Exception e) 409 { 410 throw new SAXException (e); 411 } 412 } 413 } 414 415 416 if (propDesc == null) 417 { 418 throw new SAXException (Messages.getMessage("badElem00", javaType.getName(), 420 localName)); 421 } 422 423 QName childXMLType = context.getTypeFromXSITypeAttr(namespace, localName, attributes); 425 426 String href = attributes.getValue(soapConstants.getAttrHref()); 427 428 if (childXMLType == null && fieldDesc != null && href == null) 430 { 431 childXMLType = fieldDesc.getXmlType(); 432 } 433 434 Class propType = propDesc.getType(); 436 TypeMapping tm = context.getTypeMapping(); 437 Class childType = tm.getClassForQName(childXMLType); 438 if (childType != null && propType.isAssignableFrom(childType)) 439 propType = childType; 440 441 Deserializer dSer = getDeserializer(childXMLType, propType, href, context); 443 444 if (dSer == null) 449 { 450 451 460 dSer = new DeserializerImpl(); 461 return (SOAPHandler)dSer; 462 } 463 464 if (propDesc.isWriteable() || deferedConstruction != null) 466 { 467 if (propDesc.isIndexed() && !(dSer instanceof ArrayDeserializer)) 477 { 478 collectionIndex++; 479 dSer.registerValueTarget(getBeanPropertyTarget(propDesc)); 480 } 481 else if (!isEncoded && JavaUtils.isArrayClass(propDesc.getType()) && 487 !(dSer instanceof Base64Deserializer) && !(dSer instanceof HexDeserializer)) 488 { 489 collectionIndex++; 490 dSer.registerValueTarget(getBeanPropertyTarget(propDesc)); 491 } 492 else 493 { 494 collectionIndex = -1; 498 dSer.registerValueTarget(getBeanPropertyTarget(propDesc)); 499 } 500 } 501 502 addChildDeserializer(dSer); 505 506 return (SOAPHandler)dSer; 507 } 508 509 511 public void onEndElement(String namespace, String localName, DeserializationContext context) throws SAXException 512 { 513 super.onEndElement(namespace, localName, context); 514 515 if (value == null && deferedConstruction != null) 516 throw new SAXException ("Could not construct bean using: " + deferedConstruction); 517 } 518 519 522 private BeanPropertyTarget getBeanPropertyTarget(BeanPropertyDescriptor propDesc) 523 { 524 BeanPropertyTarget target = null; 525 526 if (value != null) 527 target = new BeanPropertyTarget(value, propDesc, collectionIndex); 528 else if (deferedConstruction != null) 529 target = new BeanPropertyTarget(this, deferedConstruction, propDesc); 530 else 531 throw new IllegalStateException ("Cannot get a valid property target"); 532 533 return target; 534 } 535 536 543 public BeanPropertyDescriptor getAnyPropertyDesc() 544 { 545 if (typeDesc == null) 546 return null; 547 548 return typeDesc.getAnyDesc(); 549 } 550 551 562 protected Deserializer getDeserializer(QName xmlType, Class javaType, String href, DeserializationContext context) 563 { 564 565 String encodingStyle = context.getMessageContext().getEncodingStyle(); 566 boolean isEncoded = Constants.isSOAP_ENC(encodingStyle); 567 568 if (cacheStringDSer != null) 570 { 571 if (String .class.equals(javaType) && 572 href == null && 573 (cacheXMLType == null && xmlType == null || 574 cacheXMLType != null && cacheXMLType.equals(xmlType))) 575 { 576 cacheStringDSer.reset(); 577 return cacheStringDSer; 578 } 579 } 580 581 Deserializer dSer = null; 582 TypeMapping tm = context.getTypeMapping(); 583 584 if (xmlType != null && href == null) 585 { 586 dSer = context.getDeserializerForType(xmlType); 588 } 589 590 if (dSer == null) 591 { 592 593 QName defaultXMLType = tm.getTypeQName(javaType); 595 596 if (href == null) 603 { 604 dSer = context.getDeserializer(javaType, defaultXMLType); 605 } 606 else 607 { 608 dSer = new DeserializerImpl(); 609 dSer.setDefaultType(defaultXMLType); 610 } 611 } 612 613 if (javaType.equals(String .class) && 614 dSer instanceof SimpleDeserializer) 615 { 616 cacheStringDSer = (SimpleDeserializer)dSer; 617 cacheXMLType = xmlType; 618 } 619 620 if (dSer == null && !isEncoded && JavaUtils.isArrayClass(javaType) && javaType != Byte [].class && javaType != byte[].class) 626 { 627 628 FieldDesc fieldDesc = (lastFieldName != null) ? typeDesc.getFieldByName(lastFieldName) : null; 629 Class compType = javaType.getComponentType(); 630 QName itemXmlType = null; 631 632 if (fieldDesc != null && fieldDesc instanceof ElementDesc) 633 { 634 itemXmlType = ((ElementDesc)fieldDesc).getItemXmlType(); 635 } 636 637 if (itemXmlType == null) 640 { 641 itemXmlType = tm.getTypeQName(compType); 642 } 643 644 log.debug("Using itemXmlType = " + itemXmlType); 645 646 dSer = context.getDeserializer(compType, itemXmlType); 647 } 648 649 return dSer; 650 } 651 652 657 public void characters(char[] p1, int p2, int p3) throws SAXException 658 { 659 super.characters(p1, p2, p3); 660 661 if (typeDesc != null) 662 { 663 Iterator it = propertyMap.values().iterator(); 664 while (it.hasNext()) 665 { 666 BeanPropertyDescriptor bpDesc = (BeanPropertyDescriptor)it.next(); 667 if (bpDesc.isWriteable()) 668 { 669 String name = bpDesc.getName(); 670 FieldDesc fieldDesc = typeDesc.getFieldByName(name); 671 if (fieldDesc instanceof ElementDesc && ((ElementDesc)fieldDesc).isAsContent()) 672 { 673 String strContent = new String (p1, p2, p3); 674 try 675 { 676 log.debug("Setting content property: " + name + "=" + strContent); 677 bpDesc.set(value, strContent); 678 } 679 catch (Exception e) 680 { 681 log.warn("Cannot set content property", e); 682 } 683 } 684 } 685 } 686 } 687 } 688 } 689 | Popular Tags |