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 [] getMethods(Class implClass) { 786 if (implClass.isInterface()){ 787 return implClass.getMethods(); 789 } else { 790 return implClass.getDeclaredMethods(); 791 } 792 } 793 794 private int checkMessageMethod(Method method) { 795 Class [] params = method.getParameterTypes(); 798 799 if (params.length == 1) { 800 if ((params[0] == Element[].class) && 801 (method.getReturnType() == Element[].class)) { 802 return OperationDesc.MSG_METHOD_ELEMENTARRAY; 803 } 804 805 if ((params[0] == SOAPBodyElement[].class) && 806 (method.getReturnType() == SOAPBodyElement[].class)) { 807 return OperationDesc.MSG_METHOD_BODYARRAY; 808 } 809 810 if ((params[0] == Document .class) && 811 (method.getReturnType() == Document .class)) { 812 return OperationDesc.MSG_METHOD_DOCUMENT; 813 } 814 } else if (params.length == 2) { 815 if (((params[0] == SOAPEnvelope.class) && 816 (params[1] == SOAPEnvelope.class)) || 817 ((params[0] == javax.xml.soap.SOAPEnvelope .class) && 818 (params[1] == javax.xml.soap.SOAPEnvelope .class)) && 819 (method.getReturnType() == void.class)){ 820 return OperationDesc.MSG_METHOD_SOAPENVELOPE; 821 } 822 } 823 if( null != allowedMethods && !allowedMethods.isEmpty() ) 824 throw new InternalException (Messages.getMessage("badMsgMethodParams", 825 method.getName())); 826 return OperationDesc.MSG_METHOD_NONCONFORMING; 827 } 828 829 833 public void loadServiceDescByIntrospection() 834 { 835 loadServiceDescByIntrospection(implClass); 836 837 completedNames = null; 840 } 841 842 846 public void loadServiceDescByIntrospection(Class implClass) { 847 if (introspectionComplete || implClass == null) { 848 return; 849 } 850 851 this.implClass = implClass; 853 if (Skeleton.class.isAssignableFrom(implClass)) { 854 isSkeletonClass = true; 855 loadSkeletonOperations(); 856 } 857 858 861 AxisServiceConfig axisConfig = null; 862 try { 863 Method method = implClass.getDeclaredMethod( 864 "getAxisServiceConfig", new Class [] {}); 865 if (method != null && Modifier.isStatic(method.getModifiers())) { 866 axisConfig = (AxisServiceConfig)method.invoke(null, null); 867 } 868 } catch (Exception e) { 869 } 871 872 if (axisConfig != null) { 873 String allowedMethodsStr = axisConfig.getAllowedMethods(); 874 if (allowedMethodsStr != null && !"*".equals(allowedMethodsStr)) { 875 ArrayList methodList = new ArrayList (); 876 StringTokenizer tokenizer = 877 new StringTokenizer (allowedMethodsStr, " ,"); 878 while (tokenizer.hasMoreTokens()) { 879 methodList.add(tokenizer.nextToken()); 880 } 881 setAllowedMethods(methodList); 882 } 883 } 884 885 loadServiceDescByIntrospectionRecursive(implClass); 886 887 for (Iterator iterator = operations.iterator(); iterator.hasNext();) { 889 OperationDesc operation = (OperationDesc) iterator.next(); 890 if (operation.getMethod() == null) { 891 throw new InternalException( 892 Messages.getMessage("badWSDDOperation", 893 operation.getName(), 894 "" + operation.getNumParams())); 895 } 896 } 897 898 if ((style == Style.MESSAGE) && operations.size() == 1) { 899 messageServiceDefaultOp = (OperationDesc)operations.get(0); 900 } 901 902 introspectionComplete = true; 903 } 904 905 910 private boolean isServiceLifeCycleMethod(Class implClass, Method m) { 911 if(javax.xml.rpc.server.ServiceLifecycle .class.isAssignableFrom(implClass)) { 912 String methodName = m.getName(); 913 914 if(methodName.equals("init")) { 915 Class [] classes = m.getParameterTypes(); 918 if(classes != null && 919 classes.length == 1 && 920 classes[0] == Object .class && 921 m.getReturnType() == Void.TYPE) { 922 return true; 923 } 924 } else if (methodName.equals("destroy")){ 925 Class [] classes = m.getParameterTypes(); 928 if(classes != null && 929 classes.length == 0 && 930 m.getReturnType() == Void.TYPE) { 931 return true; 932 } 933 } 934 } 935 return false; 936 } 937 938 941 private void loadServiceDescByIntrospectionRecursive(Class implClass) 942 { 943 if (Skeleton.class.equals(implClass)) { 944 return; 945 } 946 947 Method [] methods = getMethods(implClass); 948 949 for (int i = 0; i < methods.length; i++) { 950 if (Modifier.isPublic(methods[i].getModifiers()) && !isServiceLifeCycleMethod(implClass, methods[i])) { 951 getSyncedOperationsForName(implClass, methods[i].getName()); 952 } 953 } 954 955 if (implClass.isInterface()) { 956 Class [] superClasses = implClass.getInterfaces(); 957 for (int i = 0; i < superClasses.length; i++) { 958 Class superClass = superClasses[i]; 959 if (!superClass.getName().startsWith("java.") && 960 !superClass.getName().startsWith("javax.") && 961 (stopClasses == null || 962 !stopClasses.contains(superClass.getName()))) { 963 loadServiceDescByIntrospectionRecursive(superClass); 964 } 965 } 966 } else { 967 Class superClass = implClass.getSuperclass(); 968 if (superClass != null && 969 !superClass.getName().startsWith("java.") && 970 !superClass.getName().startsWith("javax.") && 971 (stopClasses == null || 972 !stopClasses.contains(superClass.getName()))) { 973 loadServiceDescByIntrospectionRecursive(superClass); 974 } 975 } 976 } 977 978 983 public void loadServiceDescByIntrospection(Class cls, TypeMapping tm) 984 { 985 implClass = cls; 987 this.tm = tm; 988 989 if (Skeleton.class.isAssignableFrom(implClass)) { 990 isSkeletonClass = true; 991 loadSkeletonOperations(); 992 } 993 994 loadServiceDescByIntrospection(); 995 } 996 997 1001 private void getSyncedOperationsForName(Class implClass, String methodName) 1002 { 1003 if (isSkeletonClass) { 1005 if (methodName.equals("getOperationDescByName") || 1006 methodName.equals("getOperationDescs")) 1007 return; 1008 } 1009 1010 if (implClass == null) 1013 return; 1014 1015 if (completedNames == null || completedNames.contains(methodName)) 1017 return; 1018 1019 if ((allowedMethods != null) && 1021 !allowedMethods.contains(methodName)) 1022 return; 1023 1024 if ((disallowedMethods != null) && 1025 disallowedMethods.contains(methodName)) 1026 return; 1027 1028 if (isSkeletonClass && !haveAllSkeletonMethods) { 1032 1034 if (skelMethod == null) { 1035 try { 1037 skelMethod = implClass.getDeclaredMethod( 1038 "getOperationDescByName", 1039 new Class [] { String .class }); 1040 } catch (NoSuchMethodException e) { 1041 } catch (SecurityException e) { 1042 } 1043 if (skelMethod == null) { 1044 return; 1046 } 1047 } 1048 try { 1049 List skelList = 1050 (List )skelMethod.invoke(implClass, 1051 new Object [] { methodName }); 1052 if (skelList != null) { 1053 Iterator i = skelList.iterator(); 1054 while (i.hasNext()) { 1055 addOperationDesc((OperationDesc)i.next()); 1056 } 1057 } 1058 } catch (IllegalAccessException e) { 1059 if(log.isDebugEnabled()) { 1060 log.debug(Messages.getMessage("exception00"), e); 1061 } 1062 return; 1063 } catch (IllegalArgumentException e) { 1064 if(log.isDebugEnabled()) { 1065 log.debug(Messages.getMessage("exception00"), e); 1066 } 1067 return; 1068 } catch (InvocationTargetException e) { 1069 if(log.isDebugEnabled()) { 1070 log.debug(Messages.getMessage("exception00"), e); 1071 } 1072 return; 1073 } 1074 } 1075 1076 if (name2OperationsMap != null) { 1079 ArrayList currentOverloads = 1080 (ArrayList )name2OperationsMap.get(methodName); 1081 if (currentOverloads != null) { 1082 for (Iterator i = currentOverloads.iterator(); i.hasNext();) { 1084 OperationDesc oper = (OperationDesc) i.next(); 1085 if (oper.getMethod() == null) { 1086 syncOperationToClass(oper, implClass); 1087 } 1088 } 1089 } 1090 } 1091 1092 1101 createOperationsForName(implClass, methodName); 1102 1103 completedNames.add(methodName); 1105 } 1106 1107 private String getUniqueOperationName(String name) { 1108 int i = 1; 1109 String candidate; 1110 do { 1111 candidate = name + i++; 1112 } while (name2OperationsMap.get(candidate) != null); 1113 1114 return candidate; 1115 } 1116 1117 1123 private void createOperationsForName(Class implClass, String methodName) 1124 { 1125 if (isSkeletonClass) { 1127 if (methodName.equals("getOperationDescByName") || 1128 methodName.equals("getOperationDescs")) 1129 return; 1130 } 1131 1132 Method [] methods = getMethods(implClass); 1133 1134 for (int i = 0; i < methods.length; i++) { 1135 Method method = methods[i]; 1136 if (Modifier.isPublic(method.getModifiers()) && 1137 method.getName().equals(methodName) && 1138 !isServiceLifeCycleMethod(implClass, method)) { 1139 createOperationForMethod(method); 1140 } 1141 } 1142 1143 Class superClass = implClass.getSuperclass(); 1144 if (superClass != null && 1145 !superClass.getName().startsWith("java.") && 1146 !superClass.getName().startsWith("javax.") && 1147 (stopClasses == null || 1148 !stopClasses.contains(superClass.getName()))) { 1149 createOperationsForName(superClass, methodName); 1150 } 1151 } 1152 1153 1163 private void createOperationForMethod(Method method) { 1164 if (method2OperationMap.get(method) != null) { 1166 return; 1167 } 1168 1169 Class [] paramTypes = method.getParameterTypes(); 1170 1171 1174 ArrayList overloads = name2OperationsMap == null ? null : 1175 (ArrayList )name2OperationsMap.get(method.getName()); 1176 if (overloads != null && !overloads.isEmpty()) { 1177 for (int i = 0; i < overloads.size(); i++) { 1180 OperationDesc op = (OperationDesc)overloads.get(i); 1181 Method checkMethod = op.getMethod(); 1182 if (checkMethod != null) { 1183 Class [] others = checkMethod.getParameterTypes(); 1184 if (paramTypes.length == others.length) { 1185 int j = 0; 1186 for (; j < others.length; j++) { 1187 if (!others[j].equals(paramTypes[j])) 1188 break; 1189 } 1190 if (j == others.length) 1192 return; 1193 } 1194 } 1195 } 1196 } 1197 1198 boolean isWSICompliant = JavaUtils.isTrue( 1199 AxisProperties.getProperty(Constants.WSIBP11_COMPAT_PROPERTY)); 1200 1201 OperationDesc operation = new OperationDesc(); 1203 1204 String name = method.getName(); 1208 if (isWSICompliant && name2OperationsMap != null) { 1209 Collection methodNames = name2OperationsMap.keySet(); 1210 name = JavaUtils.getUniqueValue(methodNames, name); 1211 } 1212 operation.setName(name); 1213 String defaultNS = ""; 1214 if (namespaceMappings != null && !namespaceMappings.isEmpty()) { 1215 defaultNS = (String )namespaceMappings.get(0); 1218 } 1219 if(defaultNS.length() == 0) { 1220 defaultNS = Namespaces.makeNamespace(method.getDeclaringClass().getName()); 1221 } 1222 operation.setElementQName(new QName (defaultNS, name)); 1223 operation.setMethod(method); 1224 1225 if (style == Style.MESSAGE) { 1228 int messageOperType = checkMessageMethod(method); 1229 if(messageOperType == OperationDesc.MSG_METHOD_NONCONFORMING) return; 1230 if (messageOperType == -1) { 1231 throw new InternalException("Couldn't match method to any of the allowable message-style patterns!"); 1232 } 1233 operation.setMessageOperationStyle(messageOperType); 1234 operation.setReturnClass(Object .class); 1235 operation.setReturnType(Constants.XSD_ANYTYPE); 1236 } else { 1237 Class retClass = method.getReturnType(); 1239 operation.setReturnClass(retClass); 1240 QName typeQName = getTypeQName(retClass); 1241 operation.setReturnType(typeQName); 1242 1243 String [] paramNames = getParamNames(method); 1244 1245 for (int k = 0; k < paramTypes.length; k++) { 1246 Class type = paramTypes[k]; 1247 ParameterDesc paramDesc = new ParameterDesc(); 1248 String paramNamespace = (this.style == Style.RPC ? "" : operation.getElementQName().getNamespaceURI()); 1251 1252 if (paramNames != null && paramNames[k] != null && 1255 paramNames[k].length()>0) { 1256 paramDesc.setQName(new QName (paramNamespace, paramNames[k])); 1257 } else { 1258 paramDesc.setQName(new QName (paramNamespace, "in" + k)); 1259 } 1260 1261 1264 Class heldClass = JavaUtils.getHolderValueType(type); 1265 if (heldClass != null) { 1266 paramDesc.setMode(ParameterDesc.INOUT); 1267 paramDesc.setTypeQName(getTypeQName(heldClass)); 1268 } else { 1269 paramDesc.setMode(ParameterDesc.IN); 1270 paramDesc.setTypeQName(getTypeQName(type)); 1271 } 1272 paramDesc.setJavaType(type); 1273 operation.addParameter(paramDesc); 1274 } 1275 } 1276 1277 createFaultMetadata(method, operation); 1278 1279 addOperationDesc(operation); 1280 method2OperationMap.put(method, operation); 1281 } 1282 1283 private QName getTypeQName(Class javaClass) { 1284 QName typeQName; 1285 TypeMapping tm = getTypeMapping(); 1286 if (style == Style.RPC) { 1287 typeQName = tm.getTypeQName(javaClass); 1288 } else { 1289 typeQName = tm.getTypeQNameExact(javaClass); 1290 if (typeQName == null && javaClass.isArray()) { 1291 typeQName = tm.getTypeQName(javaClass.getComponentType()); 1292 } else { 1293 typeQName = tm.getTypeQName(javaClass); 1294 } 1295 } 1296 return typeQName; 1297 } 1298 1299 private void createFaultMetadata(Method method, OperationDesc operation) { 1300 Class [] exceptionTypes = method.getExceptionTypes(); 1302 1303 for (int i=0; i < exceptionTypes.length; i++) { 1304 Class ex = exceptionTypes[i]; 1308 if (ex != java.rmi.RemoteException .class && 1309 ex != org.apache.axis.AxisFault.class && 1310 !ex.getName().startsWith("java.") && 1311 !ex.getName().startsWith("javax.")) { 1312 1313 1325 1326 1348 1349 FaultDesc fault = operation.getFaultByClass(ex, false); 1350 boolean isNew; 1351 1352 if (fault == null) { 1354 fault = new FaultDesc(); 1355 isNew = true; 1356 } else { 1357 isNew = false; 1358 } 1359 1360 1362 QName xmlType = fault.getXmlType(); 1364 if (xmlType == null) { 1365 fault.setXmlType(getTypeMapping().getTypeQName(ex)); 1366 } 1367 1368 String pkgAndClsName = ex.getName(); 1370 if (fault.getClassName() == null) { 1371 fault.setClassName(pkgAndClsName); 1372 } 1373 if (fault.getName() == null) { 1374 String name = pkgAndClsName.substring( 1375 pkgAndClsName.lastIndexOf('.') + 1, 1376 pkgAndClsName.length()); 1377 fault.setName(name); 1378 } 1379 1380 if (fault.getParameters() == null) { 1383 if (xmlType == null) { 1384 xmlType = getTypeMapping().getTypeQName(ex); 1385 } 1386 QName qname = fault.getQName(); 1387 if (qname == null) { 1388 qname = new QName ("", "fault"); 1389 } 1390 ParameterDesc param = new ParameterDesc( 1391 qname, 1392 ParameterDesc.IN, 1393 xmlType); 1394 param.setJavaType(ex); 1395 ArrayList exceptionParams = new ArrayList (); 1396 exceptionParams.add(param); 1397 fault.setParameters(exceptionParams); 1398 } 1399 1400 if (fault.getQName() == null) { 1402 fault.setQName(new QName (pkgAndClsName)); 1403 } 1404 1405 if (isNew) { 1406 operation.addFault(fault); 1408 } 1409 } 1410 } 1411 } 1412 1413 private String [] getParamNames(Method method) { 1414 synchronized (method2ParamsMap) { 1415 String [] paramNames = (String []) method2ParamsMap.get(method); 1416 if(paramNames != null) 1417 return paramNames; 1418 paramNames = ParamNameExtractor.getParameterNamesFromDebugInfo(method); 1419 method2ParamsMap.put(method, paramNames); 1420 return paramNames; 1421 } 1422 } 1423 1424 public void setNamespaceMappings(List namespaces) { 1425 namespaceMappings = namespaces; 1426 } 1427 1428 public String getDefaultNamespace() { 1429 if (namespaceMappings == null || namespaceMappings.isEmpty()) 1430 return null; 1431 return (String )namespaceMappings.get(0); 1432 } 1433 1434 public void setDefaultNamespace(String namespace) { 1435 if (namespaceMappings == null) 1436 namespaceMappings = new ArrayList (); 1437 namespaceMappings.add(0, namespace); 1438 } 1439 1440 public void setProperty(String name, Object value) { 1441 if (properties == null) { 1442 properties = new HashMap (); 1443 } 1444 properties.put(name, value); 1445 } 1446 1447 public Object getProperty(String name) { 1448 if (properties == null) 1449 return null; 1450 1451 return properties.get(name); 1452 } 1453 1454 public String getEndpointURL() { 1455 return endpointURL; 1456 } 1457 1458 public void setEndpointURL(String endpointURL) { 1459 this.endpointURL = endpointURL; 1460 } 1461 1462 public TypeMappingRegistry getTypeMappingRegistry() { 1463 if (tmr == null) { 1464 tmr = new TypeMappingRegistryImpl(false); 1465 } 1466 return tmr; 1467 } 1468 1469 public void setTypeMappingRegistry(TypeMappingRegistry tmr) { 1470 this.tmr = tmr; 1471 } 1472 1473 public boolean isInitialized() { 1474 return implClass != null; 1475 } 1476} 1477 | Popular Tags |