1 7 8 10 package org.jboss.net.axis.server; 11 12 import org.jboss.axis.MessageContext; 13 import org.jboss.axis.description.TypeDesc; 14 import org.jboss.axis.encoding.DeserializationContext; 15 import org.jboss.axis.encoding.Deserializer; 16 import org.jboss.axis.encoding.DeserializerImpl; 17 import org.jboss.axis.encoding.Target; 18 import org.jboss.axis.encoding.TypeMapping; 19 import org.jboss.axis.encoding.ser.SimpleDeserializer; 20 import org.jboss.axis.message.SOAPHandler; 21 import org.jboss.axis.utils.JavaUtils; 22 import org.jboss.axis.utils.Messages; 23 import org.jboss.net.axis.ParameterizableDeserializer; 24 import org.xml.sax.Attributes ; 25 import org.xml.sax.SAXException ; 26 27 import javax.naming.InitialContext ; 28 import javax.naming.NamingException ; 29 import javax.xml.namespace.QName ; 30 import java.beans.Introspector ; 31 import java.beans.PropertyDescriptor ; 32 import java.lang.reflect.InvocationTargetException ; 33 import java.lang.reflect.Method ; 34 import java.util.Collection ; 35 import java.util.Iterator ; 36 import java.util.List ; 37 import java.util.Map ; 38 import java.util.StringTokenizer ; 39 40 49 50 public class EntityBeanDeserializer 51 extends DeserializerImpl 52 implements ParameterizableDeserializer 53 { 54 55 59 protected Map options; 60 61 protected Object home; 62 protected Method findMethod; 63 protected List findElements = new java.util.ArrayList (1); 64 protected Object [] findObjects; 65 protected TypeDesc typeDesc; 66 protected QName xmlType; 67 protected Class javaType; 68 protected Map propertyMap = new java.util.HashMap (4); 69 protected int collectionIndex = -1; 70 protected Collection fieldSetters = new java.util.ArrayList (4); 71 protected boolean initialized = false; 72 73 78 79 public EntityBeanDeserializer(Class remoteType, QName xmlType) 80 throws Exception 81 { 82 this.xmlType = xmlType; 84 this.javaType = remoteType; 85 } 86 87 88 protected String getStringOption(String key, String def) 89 { 90 String value = (String )options.get(key); 91 if (value == null) 92 { 93 value = def; 94 } 95 return value; 96 } 97 98 101 102 protected void initialize(MessageContext ctx) throws SAXException 103 { 104 if (!initialized) 105 { 106 initialized = true; 107 108 try 109 { 110 this.home = 114 new InitialContext ().lookup(getStringOption("JndiName", javaType.getName() + "Home")); 115 116 120 String findMethodName = getStringOption("FindMethodName", "findByPrimaryKey"); 121 String findMethodSignatureString = 122 getStringOption("FindMethodSignature", "java.lang.String"); 123 List findMethodSignatureClasses = new java.util.ArrayList (1); 124 StringTokenizer tokenizer = new StringTokenizer (findMethodSignatureString, ";"); 125 while (tokenizer.hasMoreTokens()) 126 { 127 findMethodSignatureClasses.add(ctx.getClassLoader().loadClass(tokenizer.nextToken())); 128 } 129 this.findMethod = 130 home.getClass().getMethod(findMethodName, 131 (Class [])findMethodSignatureClasses.toArray(new Class [findMethodSignatureClasses.size()])); 132 133 137 BeanPropertyDescriptor[] pd = getPd(javaType); 139 for (int i = 0; i < pd.length; i++) 141 { 142 BeanPropertyDescriptor descriptor = pd[i]; 143 propertyMap.put(descriptor.getName(), descriptor); 144 propertyMap.put(JavaUtils.xmlNameToJava(descriptor.getName()), descriptor); 145 } 146 typeDesc = TypeDesc.getTypeDescForClass(javaType); 147 148 152 String findMethodElements = getStringOption("FindMethodElements", "name"); 153 tokenizer = new StringTokenizer (findMethodElements, ";"); 154 while (tokenizer.hasMoreElements()) 155 { 156 if (typeDesc != null) 157 { 158 this.findElements.add(typeDesc.getAttributeNameForField(tokenizer.nextToken())); 159 } 160 else 161 { 162 this.findElements.add(new QName ("", tokenizer.nextToken())); 163 } 164 } 165 166 this.findObjects = new Object [findElements.size()]; 167 } 168 catch (NamingException e) 169 { 170 throw new SAXException ("Could not lookup home.", e); 171 } 172 catch (ClassNotFoundException e) 173 { 174 throw new SAXException ("Could not find signature class.", e); 175 } 176 catch (NoSuchMethodException e) 177 { 178 throw new SAXException ("Could not find finder method.", e); 179 } 180 181 } 182 } 183 184 public void setOptions(Map options) 185 { 186 this.options = options; 187 } 188 189 public Map getOptions() 190 { 191 return options; 192 } 193 194 206 public SOAPHandler onStartChild(String namespace, 207 String localName, 208 String prefix, 209 Attributes attributes, 210 DeserializationContext context) 211 throws SAXException 212 { 213 BeanPropertyDescriptor propDesc = null; 214 215 if (typeDesc != null) 216 { 217 QName elemQName = new QName (namespace, localName); 218 String fieldName = typeDesc.getFieldNameForElement(elemQName); 219 propDesc = (BeanPropertyDescriptor)propertyMap.get(fieldName); 220 } 221 222 if (propDesc == null) 223 { 224 propDesc = (BeanPropertyDescriptor)propertyMap.get(localName); 226 } 227 if (propDesc == null) 228 { 229 propDesc = 231 (BeanPropertyDescriptor)propertyMap.get(JavaUtils.xmlNameToJava(localName)); 232 } 233 234 if (propDesc == null) 235 { 236 throw new SAXException (Messages.getMessage("badElem00", javaType.getName(), localName)); 238 } 239 240 QName qn = context.getTypeFromAttributes(namespace, localName, attributes); 244 245 Deserializer dSer = context.getDeserializerForType(qn); 247 248 if (dSer == null) 252 { 253 dSer = new DeserializerImpl(); 254 TypeMapping tm = context.getTypeMapping(); 256 Class type = propDesc.getType(); 257 dSer.setDefaultType(tm.getTypeQName(type)); 258 } 259 260 QName elementQName = new QName (namespace, localName); 261 if (findElements.contains(elementQName)) 262 { 263 dSer.registerValueTarget(new FindPropertyTarget(findElements.indexOf(elementQName))); 264 } 265 else if (propDesc.getWriteMethod().getParameterTypes().length == 1) 266 { 267 collectionIndex = -1; 269 dSer.registerValueTarget(new BeanPropertyTarget(propDesc)); 270 } 271 else 272 { 273 collectionIndex++; 275 dSer.registerValueTarget(new BeanPropertyTarget(propDesc, collectionIndex)); 276 } 277 return (SOAPHandler)dSer; 278 } 279 280 291 public void onStartElement(String namespace, 292 String localName, 293 String qName, 294 Attributes attributes, 295 DeserializationContext context) 296 throws SAXException 297 { 298 299 initialize(context.getMessageContext()); 300 301 if (typeDesc == null) 302 return; 303 304 for (int i = 0; i < attributes.getLength(); i++) 307 { 308 QName attrQName = new QName (attributes.getURI(i), attributes.getLocalName(i)); 309 String fieldName = typeDesc.getFieldNameForAttribute(attrQName); 310 if (fieldName == null) 311 continue; 312 313 BeanPropertyDescriptor bpd = 315 (BeanPropertyDescriptor)propertyMap.get(fieldName); 316 if (bpd != null) 317 { 318 if (bpd.getWriteMethod() == null) 319 continue; 320 321 TypeMapping tm = context.getTypeMapping(); 323 Class type = bpd.getType(); 324 QName qn = tm.getTypeQName(type); 325 if (qn == null) 326 throw new SAXException (Messages.getMessage("unregistered00", type.toString())); 327 328 Deserializer dSer = context.getDeserializerForType(qn); 330 if (dSer == null) 331 throw new SAXException (Messages.getMessage("noDeser00", type.toString())); 332 if (!(dSer instanceof SimpleDeserializer)) 333 throw new SAXException (Messages.getMessage("AttrNotSimpleType00", bpd.getName(), type.toString())); 334 335 if (findElements.contains(attrQName)) 336 { 337 dSer.registerValueTarget(new FindPropertyTarget(findElements.indexOf(attrQName))); 338 } 339 else if (bpd.getWriteMethod().getParameterTypes().length == 1) 340 { 341 try 344 { 345 Object val = ((SimpleDeserializer)dSer).makeValue(attributes.getValue(i)); 346 bpd.getWriteMethod().invoke(value, new Object []{val}); 347 } 348 catch (Exception e) 349 { 350 throw new SAXException (e); 351 } 352 } 353 354 } } } 357 358 public void onEndElement(String namespace, 359 String localName, 360 DeserializationContext context) 361 throws SAXException 362 { 363 try 364 { 365 value = findMethod.invoke(home, findObjects); 366 Iterator allSetters = fieldSetters.iterator(); 367 while (allSetters.hasNext()) 368 { 369 ((BeanPropertyTarget)allSetters.next()).setReal(value); 370 } 371 fieldSetters = null; 372 } 373 catch (InvocationTargetException e) 374 { 375 throw new SAXException ("Encountered exception " + e.getTargetException()); 376 } 377 catch (IllegalAccessException e) 378 { 379 throw new SAXException ("Encountered exception " + e); 380 } 381 super.onEndElement(namespace, localName, context); 382 } 383 384 public class FindPropertyTarget implements Target 385 { 386 int position; 387 388 public FindPropertyTarget(int index) 389 { 390 this.position = index; 391 } 392 393 public void set(Object value) throws SAXException 394 { 395 findObjects[position] = value; 396 } 397 } 398 399 402 public class BeanPropertyTarget implements Target 403 { 404 private BeanPropertyDescriptor pd; 405 private int index = -1; 406 Object value; 407 408 412 public BeanPropertyTarget(BeanPropertyDescriptor pd) 413 { 414 this.pd = pd; 415 this.index = -1; } 417 418 423 public BeanPropertyTarget(BeanPropertyDescriptor pd, int i) 424 { 425 this.pd = pd; 426 this.index = i; 427 } 428 429 public void set(Object value) throws SAXException 430 { 431 this.value = value; 432 if (fieldSetters != null) 433 { 434 fieldSetters.add(this); 435 } 436 else 437 { 438 setReal(EntityBeanDeserializer.this.value); 439 } 440 } 441 442 public void setReal(Object target) throws SAXException 443 { 444 try 445 { 446 if (index < 0) 447 pd.getWriteMethod().invoke(target, new Object []{value}); 448 else 449 pd.getWriteMethod().invoke(target, new Object []{new Integer (index), value}); 450 } 451 catch (Exception e) 452 { 453 Class type = pd.getReadMethod().getReturnType(); 454 value = JavaUtils.convert(value, type); 455 try 456 { 457 if (index < 0) 458 pd.getWriteMethod().invoke(target, new Object []{value}); 459 else 460 pd.getWriteMethod().invoke(target, new Object []{new Integer (index), value}); 461 } 462 catch (Exception ex) 463 { 464 throw new SAXException (ex); 465 } 466 } 467 } 468 } 469 470 static class BeanPropertyDescriptor 471 { 472 private String name; 473 private Method getter; 474 private Method setter; 475 476 public BeanPropertyDescriptor(String _name, Method _getter, Method _setter) 477 { 478 name = _name; 479 getter = _getter; 480 setter = _setter; 481 } 482 483 public Method getReadMethod() 484 { 485 return getter; 486 } 487 488 public Method getWriteMethod() 489 { 490 return setter; 491 } 492 493 public String getName() 494 { 495 return name; 496 } 497 498 public Class getType() 499 { 500 return getter.getReturnType(); 501 } 502 503 517 static BeanPropertyDescriptor[] processPropertyDescriptors(PropertyDescriptor [] rawPd, 518 Class cls) 519 { 520 BeanPropertyDescriptor[] myPd = new BeanPropertyDescriptor[rawPd.length]; 521 522 for (int i = 0; i < rawPd.length; i++) 523 { 524 myPd[i] = 525 new BeanPropertyDescriptor(rawPd[i].getName(), 526 rawPd[i].getReadMethod(), 527 rawPd[i].getWriteMethod()); 528 } 529 530 try 531 { 532 int index = 0; 534 535 BeanPropertyDescriptor[] newPd = new BeanPropertyDescriptor[rawPd.length]; 538 Method [] methods = cls.getMethods(); 539 for (int i = 0; i < methods.length; i++) 540 { 541 Method method = methods[i]; 542 if (method.getName().startsWith("set")) 543 { 544 boolean found = false; 545 for (int j = 0; j < myPd.length && !found; j++) 546 { 547 if (myPd[j].getWriteMethod() != null 548 && myPd[j].getWriteMethod().equals(method)) 549 { 550 found = true; 551 newPd[index] = myPd[j]; 552 index++; 553 } 554 } 555 } 556 } 557 if (index < myPd.length) 559 { 560 for (int m = 0; m < myPd.length && index < myPd.length; m++) 561 { 562 boolean found = false; 563 for (int n = 0; n < index && !found; n++) 564 { 565 found = (myPd[m] == newPd[n]); 566 } 567 if (!found) 568 { 569 newPd[index] = myPd[m]; 570 index++; 571 } 572 } 573 } 574 if (index == myPd.length) 576 { 577 myPd = newPd; 578 } 579 580 for (int i = 0; i < methods.length; i++) 583 { 584 if (methods[i].getName().startsWith("set") 585 && methods[i].getParameterTypes().length == 2) 586 { 587 for (int j = 0; j < methods.length; j++) 588 { 589 if ((methods[j].getName().startsWith("get") 590 || methods[j].getName().startsWith("is")) 591 && methods[j].getParameterTypes().length == 1 592 && methods[j].getReturnType() == methods[i].getParameterTypes()[1] 593 && methods[j].getParameterTypes()[0] == int.class 594 && methods[i].getParameterTypes()[0] == int.class) 595 { 596 for (int k = 0; k < myPd.length; k++) 597 { 598 if (myPd[k].getReadMethod() != null 599 && myPd[k].getWriteMethod() != null 600 && myPd[k].getReadMethod().getName().equals(methods[j].getName()) 601 && myPd[k].getWriteMethod().getName().equals(methods[i].getName())) 602 { 603 myPd[k] = new BeanPropertyDescriptor(myPd[k].getName(), methods[j], methods[i]); 604 } 605 } 606 } 607 } 608 } 609 } 610 } 611 catch (Exception e) 612 { 613 return myPd; 615 } 616 return myPd; 617 } 618 } 619 620 623 public static BeanPropertyDescriptor[] getPd(Class javaType) 624 { 625 BeanPropertyDescriptor[] pd; 626 try 627 { 628 PropertyDescriptor [] rawPd = 629 Introspector.getBeanInfo(javaType).getPropertyDescriptors(); 630 pd = BeanPropertyDescriptor.processPropertyDescriptors(rawPd, javaType); 631 } 632 catch (Exception e) 633 { 634 throw new RuntimeException (e.getMessage()); 636 } 637 return pd; 638 } 639 640 } | Popular Tags |