| 1 16 package org.apache.axis.description; 17 18 import org.apache.axis.AxisServiceConfig; 19 import org.apache.axis.Constants; 20 import org.apache.axis.InternalException; 21 import org.apache.axis.AxisProperties; 22 import org.apache.axis.components.logger.LogFactory; 23 import org.apache.axis.encoding.*; 24 import org.apache.axis.constants.Style; 25 import org.apache.axis.constants.Use; 26 import org.apache.axis.message.SOAPBodyElement; 27 import org.apache.axis.message.SOAPEnvelope; 28 import org.apache.axis.utils.JavaUtils; 29 import org.apache.axis.utils.Messages; 30 import org.apache.axis.utils.bytecode.ParamNameExtractor; 31 import org.apache.axis.wsdl.Skeleton; 32 import org.apache.axis.wsdl.fromJava.Namespaces; 33 import org.apache.commons.logging.Log; 34 import org.w3c.dom.Document ; 35 import org.w3c.dom.Element ; 36 37 import javax.xml.namespace.QName ; 38 import javax.xml.rpc.holders.Holder ; 39 import java.lang.reflect.InvocationTargetException ; 40 import java.lang.reflect.Method ; 41 import java.lang.reflect.Modifier ; 42 import java.util.ArrayList ; 43 import java.util.Collection ; 44 import java.util.Collections ; 45 import java.util.Comparator ; 46 import java.util.HashMap ; 47 import java.util.Iterator ; 48 import java.util.List ; 49 import java.util.StringTokenizer ; 50 51 52 61 public class JavaServiceDesc implements ServiceDesc { 62 protected static Log log = 63 LogFactory.getLog(JavaServiceDesc.class.getName()); 64 65 66 private String name = null; 67 68 69 private String documentation = null; 70 71 72 private Style style = Style.RPC; 73 private Use use = Use.ENCODED; 74 75 private boolean useSet = false; 79 80 81 private ArrayList operations = new ArrayList (); 82 83 84 private List namespaceMappings = null; 85 86 92 private String wsdlFileName = null; 93 94 99 private String endpointURL = null; 100 101 102 private HashMap properties = null; 103 104 105 private HashMap name2OperationsMap = null; 106 private HashMap qname2OperationsMap = null; 107 private transient HashMap method2OperationMap = new HashMap (); 108 109 112 113 114 private List allowedMethods = null; 115 116 117 private List disallowedMethods = null; 118 119 120 private Class implClass = null; 121 122 126 private boolean isSkeletonClass = false; 127 128 129 private transient Method skelMethod = null; 130 131 134 private ArrayList stopClasses = null; 135 136 137 private transient HashMap method2ParamsMap = new HashMap (); 138 private OperationDesc messageServiceDefaultOp = null; 139 140 141 private ArrayList completedNames = new ArrayList (); 142 143 144 private TypeMapping tm = null; 145 private TypeMappingRegistry tmr = null; 146 147 private boolean haveAllSkeletonMethods = false; 148 private boolean introspectionComplete = false; 149 150 153 public JavaServiceDesc() { 154 } 155 156 160 public Style getStyle() { 161 return style; 162 } 163 164 public void setStyle(Style style) { 165 this.style = style; 166 if (!useSet) { 167 use = style == Style.RPC ? Use.ENCODED : Use.LITERAL; 169 } 170 } 171 172 173 177 public Use getUse() { 178 return use; 179 } 180 181 public void setUse(Use use) { 182 useSet = true; 183 this.use = use; 184 } 185 186 195 public boolean isWrapped() 196 { 197 return ((style == Style.RPC) || 198 (style == Style.WRAPPED)); 199 } 200 201 206 public String getWSDLFile() { 207 return wsdlFileName; 208 } 209 210 216 public void setWSDLFile(String wsdlFileName) { 217 this.wsdlFileName = wsdlFileName; 218 } 219 220 public List getAllowedMethods() { 221 return allowedMethods; 222 } 223 224 public void setAllowedMethods(List allowedMethods) { 225 this.allowedMethods = allowedMethods; 226 } 227 228 public Class getImplClass() { 229 return implClass; 230 } 231 232 242 public void setImplClass(Class implClass) { 243 if (this.implClass != null) 244 throw new IllegalArgumentException ( 245 Messages.getMessage("implAlreadySet")); 246 247 this.implClass = implClass; 248 if (Skeleton.class.isAssignableFrom(implClass)) { 249 isSkeletonClass = true; 250 loadSkeletonOperations(); 251 } 252 } 253 254 private void loadSkeletonOperations() { 255 Method method = null; 256 try { 257 method = implClass.getDeclaredMethod("getOperationDescs", 258 new Class [] {}); 259 } catch (NoSuchMethodException e) { 260 } catch (SecurityException e) { 261 } 262 if (method == null) { 263 return; 265 } 266 267 try { 268 Collection opers = (Collection )method.invoke(implClass, null); 269 for (Iterator i = opers.iterator(); i.hasNext();) { 270 OperationDesc skelDesc = (OperationDesc)i.next(); 271 addOperationDesc(skelDesc); 272 } 273 } catch (IllegalAccessException e) { 274 if(log.isDebugEnabled()) { 275 log.debug(Messages.getMessage("exception00"), e); 276 } 277 return; 278 } catch (IllegalArgumentException e) { 279 if(log.isDebugEnabled()) { 280 log.debug(Messages.getMessage("exception00"), e); 281 } 282 return; 283 } catch (InvocationTargetException e) { 284 if(log.isDebugEnabled()) { 285 log.debug(Messages.getMessage("exception00"), e); 286 } 287 return; 288 } 289 haveAllSkeletonMethods = true; 290 } 291 292 public TypeMapping getTypeMapping() { 293 if(tm == null) { 294 return DefaultTypeMappingImpl.getSingletonDelegate(); 295 } 297 return tm; 298 } 299 300 public void setTypeMapping(TypeMapping tm) { 301 this.tm = tm; 302 } 303 304 307 public String getName() { 308 return name; 309 } 310 311 315 public void setName(String name) { 316 this.name = name; 317 } 318 319 322 public String getDocumentation() { 323 return documentation; 324 } 325 326 329 public void setDocumentation(String documentation) { 330 this.documentation = documentation; 331 } 332 333 public ArrayList getStopClasses() { 334 return stopClasses; 335 } 336 337 public void setStopClasses(ArrayList stopClasses) { 338 this.stopClasses = stopClasses; 339 } 340 341 public List getDisallowedMethods() { 342 return disallowedMethods; 343 } 344 345 public void setDisallowedMethods(List disallowedMethods) { 346 this.disallowedMethods = disallowedMethods; 347 } 348 349 public void removeOperationDesc(OperationDesc operation) { 350 operations.remove(operation); 351 operation.setParent(null); 352 353 if (name2OperationsMap != null) { 354 String name = operation.getName(); 355 ArrayList overloads = (ArrayList )name2OperationsMap.get(name); 356 if (overloads != null) { 357 overloads.remove(operation); 358 if (overloads.size() == 0) { 359 name2OperationsMap.remove(name); 360 } 361 } 362 } 363 364 if (qname2OperationsMap != null) { 365 QName qname = operation.getElementQName(); 366 ArrayList list = (ArrayList )qname2OperationsMap.get(qname); 367 if (list != null) { 368 list.remove(operation); 369 } 370 } 371 372 if (method2OperationMap != null) { 373 Method method = operation.getMethod(); 374 if (method != null) { 375 method2OperationMap.remove(method); 376 } 377 } 378 } 379 380 public void addOperationDesc(OperationDesc operation) 381 { 382 operations.add(operation); 383 operation.setParent(this); 384 if (name2OperationsMap == null) { 385 name2OperationsMap = new HashMap (); 386 } 387 388 String name = operation.getName(); 390 ArrayList overloads = (ArrayList )name2OperationsMap.get(name); 391 if (overloads == null) { 392 overloads = new ArrayList (); 393 name2OperationsMap.put(name, overloads); 394 } else if (JavaUtils.isTrue( 395 AxisProperties.getProperty(Constants.WSIBP11_COMPAT_PROPERTY)) && 396 overloads.size() > 0) { 397 throw new RuntimeException (Messages.getMessage("noOverloadedOperations", name)); 398 } 399 overloads.add(operation); 400 } 401 402 408 public ArrayList getOperations() 409 { 410 loadServiceDescByIntrospection(); return operations; 412 } 413 414 419 public OperationDesc [] getOperationsByName(String methodName) 420 { 421 getSyncedOperationsForName(implClass, methodName); 422 423 if (name2OperationsMap == null) 424 return null; 425 426 ArrayList overloads = (ArrayList )name2OperationsMap.get(methodName); 427 if (overloads == null) { 428 return null; 429 } 430 431 OperationDesc [] array = new OperationDesc [overloads.size()]; 432 return (OperationDesc[])overloads.toArray(array); 433 } 434 435 440 public OperationDesc getOperationByName(String methodName) 441 { 442 getSyncedOperationsForName(implClass, methodName); 446 447 if (name2OperationsMap == null) 448 return null; 449 450 ArrayList overloads = (ArrayList )name2OperationsMap.get(methodName); 451 if (overloads == null) { 452 return null; 453 } 454 455 return (OperationDesc)overloads.get(0); 456 } 457 458 463 public OperationDesc getOperationByElementQName(QName qname) 464 { 465 OperationDesc [] overloads = getOperationsByQName(qname); 466 467 if ((overloads != null) && overloads.length > 0) 469 return overloads[0]; 470 471 return null; 472 } 473 474 479 public OperationDesc [] getOperationsByQName(QName qname) 480 { 481 483 initQNameMap(); 485 486 ArrayList overloads = (ArrayList )qname2OperationsMap.get(qname); 487 if (overloads == null) { 488 if (name2OperationsMap != null) { 490 if ((isWrapped() || 491 ((style == Style.MESSAGE) && 492 (getDefaultNamespace() == null)))) { 493 overloads = (ArrayList ) name2OperationsMap.get(qname.getLocalPart()); 495 } else { 496 Object ops = name2OperationsMap.get(qname.getLocalPart()); 500 if (ops != null) { 501 overloads = new ArrayList ((Collection ) ops); 502 for (Iterator iter = overloads.iterator(); iter.hasNext();) { 503 OperationDesc operationDesc = (OperationDesc) iter.next(); 504 if (Style.WRAPPED != operationDesc.getStyle()) { 505 iter.remove(); 506 } 507 } 508 } 509 } 510 } 511 if ((style == Style.MESSAGE) && (messageServiceDefaultOp != null)) 514 return new OperationDesc [] { messageServiceDefaultOp }; 515 516 if (overloads == null) 517 return null; 518 } 519 520 getSyncedOperationsForName(implClass, 521 ((OperationDesc)overloads.get(0)).getName()); 522 523 Collections.sort(overloads, 528 new Comparator () { 529 public int compare(Object o1, Object o2) 530 { 531 Method meth1 = ((OperationDesc)o1).getMethod(); 532 Method meth2 = ((OperationDesc)o2).getMethod(); 533 return (meth1.getParameterTypes().length - 534 meth2.getParameterTypes().length); 535 } 536 }); 537 538 OperationDesc [] array = new OperationDesc [overloads.size()]; 539 return (OperationDesc[])overloads.toArray(array); 540 } 541 542 private synchronized void initQNameMap() { 543 if (qname2OperationsMap == null) { 544 loadServiceDescByIntrospection(); 545 546 qname2OperationsMap = new HashMap (); 547 for (Iterator i = operations.iterator(); i.hasNext();) { 548 OperationDesc operationDesc = (OperationDesc) i.next(); 549 QName qname = operationDesc.getElementQName(); 550 ArrayList list = (ArrayList )qname2OperationsMap.get(qname); 551 if (list == null) { 552 list = new ArrayList (); 553 qname2OperationsMap.put(qname, list); 554 } 555 list.add(operationDesc); 556 } 557 } 558 } 559 560 569 private void syncOperationToClass(OperationDesc oper, Class implClass) 570 { 571 636 if (oper.getMethod() != null) 638 return; 639 640 642 Method [] methods = getMethods(implClass); 643 Method possibleMatch = null; 645 646 for (int i = 0; i < methods.length; i++) { 647 Method method = methods[i]; 648 if (Modifier.isPublic(method.getModifiers()) && 649 method.getName().equals(oper.getName()) && 650 method2OperationMap.get(method) == null) { 651 652 if (style == Style.MESSAGE) { 653 int messageOperType = checkMessageMethod(method); 654 if(messageOperType == OperationDesc.MSG_METHOD_NONCONFORMING) continue; 655 if (messageOperType == -1) { 656 throw new InternalException("Couldn't match method to any of the allowable message-style patterns!"); 657 } 658 oper.setMessageOperationStyle(messageOperType); 659 660 possibleMatch = method; 662 break; 663 } 664 665 Class [] paramTypes = method.getParameterTypes(); 667 if (paramTypes.length != oper.getNumParams()) 668 continue; 669 670 int j; 671 boolean conversionNecessary = false; 672 for (j = 0; j < paramTypes.length; j++) { 673 Class type = paramTypes[j]; 674 Class actualType = type; 675 if (Holder .class.isAssignableFrom(type)) { 676 actualType = JavaUtils.getHolderValueType(type); 677 } 678 ParameterDesc param = oper.getParameter(j); 679 QName typeQName = param.getTypeQName(); 680 if (typeQName == null) { 681 typeQName = getTypeMapping().getTypeQName(actualType); 689 param.setTypeQName(typeQName); 690 } else { 691 Class paramClass = param.getJavaType(); 698 if (paramClass != null && 699 JavaUtils.getHolderValueType(paramClass) != null) { 700 paramClass = JavaUtils.getHolderValueType(paramClass); 701 } 702 if (paramClass == null) { 703 paramClass = getTypeMapping().getClassForQName(param.getTypeQName(), 704 type); 705 } 706 707 if (paramClass != null) { 708 if (!JavaUtils.isConvertable(paramClass, actualType)) { 712 break; 713 } 714 715 if (!actualType.isAssignableFrom(paramClass)) { 716 conversionNecessary = true; 718 } 719 } 720 } 721 param.setJavaType(type); 725 } 726 727 if (j != paramTypes.length) { 728 continue; 730 } 731 732 possibleMatch = method; 734 735 if (!conversionNecessary) { 738 break; 739 } 740 741 } 742 } 743 744 if (possibleMatch != null) { 749 Class returnClass = possibleMatch.getReturnType(); 750 oper.setReturnClass(returnClass); 751 752 QName returnType = oper.getReturnType(); 753 if (returnType == null) { 754 oper.setReturnType(getTypeMapping().getTypeQName(returnClass)); 755 } 756 757 createFaultMetadata(possibleMatch, oper); 759 760 oper.setMethod(possibleMatch); 761 method2OperationMap.put(possibleMatch, oper); 762 return; 763 } 764 765 Class superClass = implClass.getSuperclass(); 767 if (superClass != null && 768 !superClass.getName().startsWith("java.") && 769 !superClass.getName().startsWith("javax.") && 770 (stopClasses == null || 771 !stopClasses.contains(superClass.getName()))) { 772 syncOperationToClass(oper, superClass); 773 } 774 775 if (oper.getMethod() == null) { 777 InternalException ie = 778 new InternalException(Messages.getMessage("serviceDescOperSync00", 779 oper.getName(), 780 implClass.getName())); 781 throw ie; 782 } 783 } 784 785 private Method
|