1 /* 2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.ws.model; 27 28 import com.sun.istack.internal.NotNull; 29 import com.sun.istack.internal.localization.Localizable; 30 import com.sun.xml.internal.ws.api.BindingID; 31 import com.sun.xml.internal.ws.api.SOAPVersion; 32 import com.sun.xml.internal.ws.api.WSBinding; 33 import com.sun.xml.internal.ws.api.databinding.DatabindingConfig; 34 import com.sun.xml.internal.ws.api.databinding.MetadataReader; 35 import com.sun.xml.internal.ws.api.model.ExceptionType; 36 import com.sun.xml.internal.ws.api.model.MEP; 37 import com.sun.xml.internal.ws.api.model.Parameter; 38 import com.sun.xml.internal.ws.api.model.ParameterBinding; 39 import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation; 40 import com.sun.xml.internal.ws.api.model.wsdl.WSDLInput; 41 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPart; 42 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort; 43 import com.sun.xml.internal.ws.binding.WebServiceFeatureList; 44 import com.sun.xml.internal.ws.model.soap.SOAPBindingImpl; 45 import com.sun.xml.internal.ws.resources.ModelerMessages; 46 import com.sun.xml.internal.ws.resources.ServerMessages; 47 import com.sun.xml.internal.ws.spi.db.BindingContext; 48 import com.sun.xml.internal.ws.spi.db.TypeInfo; 49 import com.sun.xml.internal.ws.spi.db.WrapperComposite; 50 51 import static com.sun.xml.internal.ws.binding.WebServiceFeatureList.getSoapVersion; 52 import static com.sun.xml.internal.ws.model.Utils.REFLECTION_NAVIGATOR; 53 54 import javax.jws.*; 55 import javax.jws.WebParam.Mode; 56 import javax.jws.soap.SOAPBinding; 57 import javax.jws.soap.SOAPBinding.Style; 58 import javax.xml.bind.annotation.XmlElement; 59 import javax.xml.bind.annotation.XmlSeeAlso; 60 import javax.xml.namespace.QName; 61 import javax.xml.ws.*; 62 import javax.xml.ws.soap.MTOM; 63 import javax.xml.ws.soap.MTOMFeature; 64 import java.lang.annotation.Annotation; 65 import java.lang.reflect.Method; 66 import java.lang.reflect.Modifier; 67 import java.lang.reflect.ParameterizedType; 68 import java.lang.reflect.Type; 69 import java.security.AccessController; 70 import java.util.HashSet; 71 import java.util.Map; 72 import java.util.Set; 73 import java.util.StringTokenizer; 74 import java.util.TreeMap; 75 import java.util.concurrent.Future; 76 import java.util.logging.Logger; 77 78 import static javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED; 79 80 /** 81 * Creates a runtime model of a SEI (portClass). 82 * 83 * @author WS Developement Team 84 */ 85 public class RuntimeModeler { 86 private final WebServiceFeatureList features; 87 private BindingID bindingId; 88 private WSBinding wsBinding; 89 private final Class portClass; 90 private AbstractSEIModelImpl model; 91 private SOAPBindingImpl defaultBinding; 92 // can be empty but never null 93 private String packageName; 94 private String targetNamespace; 95 private boolean isWrapped = true; 96 private ClassLoader classLoader; 97 private final WSDLPort binding; 98 private QName serviceName; 99 private QName portName; 100 private Set<Class> classUsesWebMethod; 101 private DatabindingConfig config; 102 private MetadataReader metadataReader; 103 /** 104 * 105 */ 106 public static final String PD_JAXWS_PACKAGE_PD = ".jaxws."; 107 /** 108 * 109 */ 110 public static final String JAXWS_PACKAGE_PD = "jaxws."; 111 public static final String RESPONSE = "Response"; 112 public static final String RETURN = "return"; 113 public static final String BEAN = "Bean"; 114 public static final String SERVICE = "Service"; 115 public static final String PORT = "Port"; 116 public static final Class HOLDER_CLASS = Holder.class; 117 public static final String REMOTE_EXCEPTION_CLASS = "java.rmi.RemoteException"; 118 public static final Class<RuntimeException> RUNTIME_EXCEPTION_CLASS = RuntimeException.class; 119 public static final Class<Exception> EXCEPTION_CLASS = Exception.class; 120 public static final String DecapitalizeExceptionBeanProperties = "com.sun.xml.internal.ws.api.model.DecapitalizeExceptionBeanProperties"; 121 public static final String SuppressDocLitWrapperGeneration = "com.sun.xml.internal.ws.api.model.SuppressDocLitWrapperGeneration"; 122 public static final String DocWrappeeNamespapceQualified = "com.sun.xml.internal.ws.api.model.DocWrappeeNamespapceQualified"; 123 124 /*public RuntimeModeler(@NotNull Class portClass, @NotNull QName serviceName, @NotNull BindingID bindingId, @NotNull WebServiceFeature... features) { 125 this(portClass, serviceName, null, bindingId, features); 126 }*/ 127 128 /** 129 * 130 * creates an instance of RunTimeModeler given a <code>sei</code> and <code>binding</code> 131 * @param portClass The SEI class to be modeled. 132 * @param serviceName The ServiceName to use instead of one calculated from the implementation class 133 * @param wsdlPort {@link com.sun.xml.internal.ws.api.model.wsdl.WSDLPort} 134 * @param features web service features 135 */ 136 /*public RuntimeModeler(@NotNull Class portClass, @NotNull QName serviceName, @NotNull WSDLPortImpl wsdlPort, @NotNull WebServiceFeature... features){ 137 this(portClass, serviceName, wsdlPort, wsdlPort.getBinding().getBindingId(), features); 138 }*/ 139 140 /*private RuntimeModeler(@NotNull Class portClass, @NotNull QName serviceName, WSDLPortImpl binding, BindingID bindingId, @NotNull WebServiceFeature... features) { 141 this.portClass = portClass; 142 this.serviceName = serviceName; 143 this.binding = binding; 144 this.bindingId = bindingId; 145 this.features = features; 146 }*/ 147 148 public RuntimeModeler(@NotNull DatabindingConfig config){ 149 this.portClass = (config.getEndpointClass() != null)? config.getEndpointClass() : config.getContractClass(); 150 this.serviceName = config.getMappingInfo().getServiceName(); 151 this.binding = config.getWsdlPort(); 152 this.classLoader = config.getClassLoader(); 153 this.portName = config.getMappingInfo().getPortName(); 154 this.config = config; 155 this.wsBinding = config.getWSBinding(); 156 metadataReader = config.getMetadataReader(); 157 targetNamespace = config.getMappingInfo().getTargetNamespace(); 158 if (metadataReader == null) metadataReader = new ReflectAnnotationReader(); 159 if (wsBinding != null) { 160 this.bindingId = wsBinding.getBindingId(); 161 if (config.getFeatures() != null) wsBinding.getFeatures().mergeFeatures(config.getFeatures(), false); 162 if (binding != null) wsBinding.getFeatures().mergeFeatures(binding.getFeatures(), false); 163 this.features = WebServiceFeatureList.toList(wsBinding.getFeatures()); 164 } else { 165 this.bindingId = config.getMappingInfo().getBindingID(); 166 this.features = WebServiceFeatureList.toList(config.getFeatures()); 167 if (binding != null) bindingId = binding.getBinding().getBindingId(); 168 if (bindingId == null) bindingId = getDefaultBindingID(); 169 if (!features.contains(MTOMFeature.class)) { 170 MTOM mtomAn = getAnnotation(portClass, MTOM.class); 171 if (mtomAn != null) features.add(WebServiceFeatureList.getFeature(mtomAn)); 172 } 173 if (!features.contains(com.oracle.webservices.internal.api.EnvelopeStyleFeature.class)) { 174 com.oracle.webservices.internal.api.EnvelopeStyle es = getAnnotation(portClass, com.oracle.webservices.internal.api.EnvelopeStyle.class); 175 if (es != null) features.add(WebServiceFeatureList.getFeature(es)); 176 } 177 this.wsBinding = bindingId.createBinding(features); 178 } 179 } 180 181 private BindingID getDefaultBindingID() { 182 BindingType bt = getAnnotation(portClass, BindingType.class); 183 if (bt != null) return BindingID.parse(bt.value()); 184 SOAPVersion ver = getSoapVersion(features); 185 boolean mtomEnabled = features.isEnabled(MTOMFeature.class); 186 if (SOAPVersion.SOAP_12.equals(ver)) { 187 return (mtomEnabled) ? BindingID.SOAP12_HTTP_MTOM : BindingID.SOAP12_HTTP; 188 } else { 189 return (mtomEnabled) ? BindingID.SOAP11_HTTP_MTOM : BindingID.SOAP11_HTTP; 190 } 191 } 192 193 /** 194 * sets the classloader to be used when loading classes by the <code>RuntimeModeler</code>. 195 * @param classLoader ClassLoader used to load classes 196 */ 197 public void setClassLoader(ClassLoader classLoader) { 198 this.classLoader = classLoader; 199 } 200 201 /** 202 * sets the PortName to be used by the <code>RuntimeModeler</code>. 203 * @param portName The PortName to be used instead of the PortName 204 * retrieved via annotations 205 */ 206 public void setPortName(QName portName) { 207 this.portName = portName; 208 } 209 210 private <T extends Annotation> T getAnnotation(final Class<?> clazz, final Class<T> T) { 211 return metadataReader.getAnnotation(T, clazz); 212 } 213 214 private <T extends Annotation> T getAnnotation(final Method method, final Class<T> T) { 215 return metadataReader.getAnnotation(T, method); 216 } 217 218 private Annotation[] getAnnotations(final Method method) { 219 return metadataReader.getAnnotations(method); 220 } 221 222 private Annotation[] getAnnotations(final Class<?> c) { 223 return metadataReader.getAnnotations(c); 224 } 225 private Annotation[][] getParamAnnotations(final Method method) { 226 return metadataReader.getParameterAnnotations(method); 227 } 228 229 private static final Logger logger = 230 Logger.getLogger( 231 com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server"); 232 233 //currently has many local vars which will be eliminated after debugging issues 234 //first draft 235 /** 236 * builds the runtime model from the <code>portClass</code> using the binding ID <code>bindingId</code>. 237 * @return the runtime model for the <code>portClass</code>. 238 */ 239 public AbstractSEIModelImpl buildRuntimeModel() { 240 model = new SOAPSEIModel(features); 241 model.contractClass = config.getContractClass(); 242 model.endpointClass = config.getEndpointClass(); 243 model.classLoader = this.classLoader; 244 model.wsBinding = wsBinding; 245 model.databindingInfo.setWsdlURL(config.getWsdlURL()); 246 model.databindingInfo.properties().putAll(config.properties()); 247 if (model.contractClass == null) model.contractClass = portClass; 248 if (model.endpointClass == null && !portClass.isInterface()) model.endpointClass = portClass; 249 Class<?> seiClass = portClass; 250 metadataReader.getProperties(model.databindingInfo.properties(), portClass); 251 WebService webService = getAnnotation(portClass, WebService.class); 252 if (webService == null) { 253 throw new RuntimeModelerException("runtime.modeler.no.webservice.annotation", 254 portClass.getCanonicalName()); 255 } 256 Class<?> seiFromConfig = configEndpointInterface(); 257 if (webService.endpointInterface().length() > 0 || seiFromConfig != null) { 258 if (seiFromConfig != null) { 259 seiClass = seiFromConfig; 260 } else { 261 seiClass = getClass(webService.endpointInterface(), ModelerMessages.localizableRUNTIME_MODELER_CLASS_NOT_FOUND(webService.endpointInterface())); 262 } 263 model.contractClass = seiClass; 264 model.endpointClass = portClass; 265 WebService seiService = getAnnotation(seiClass, WebService.class); 266 if (seiService == null) { 267 throw new RuntimeModelerException("runtime.modeler.endpoint.interface.no.webservice", 268 webService.endpointInterface()); 269 } 270 271 //check if @SOAPBinding is defined on the impl class 272 SOAPBinding sbPortClass = getAnnotation(portClass, SOAPBinding.class); 273 SOAPBinding sbSei = getAnnotation(seiClass, SOAPBinding.class); 274 if(sbPortClass != null){ 275 if(sbSei == null || sbSei.style() != sbPortClass.style()|| sbSei.use() != sbPortClass.use()){ 276 logger.warning(ServerMessages.RUNTIMEMODELER_INVALIDANNOTATION_ON_IMPL("@SOAPBinding", portClass.getName(), seiClass.getName())); 277 } 278 } 279 } 280 if (serviceName == null) 281 serviceName = getServiceName(portClass, metadataReader); 282 model.setServiceQName(serviceName); 283 284 // String portLocalName = portClass.getSimpleName()+PORT; 285 // if (webService.portName().length() >0) { 286 // portLocalName = webService.portName(); 287 // } else if (webService.name().length() >0) { 288 // portLocalName = webService.name()+PORT; 289 // } 290 // 291 // if (portName == null) 292 // portName = new QName(serviceName.getNamespaceURI(), portLocalName); 293 // if (!portName.getNamespaceURI().equals(serviceName.getNamespaceURI())) { 294 // throw new RuntimeModelerException("runtime.modeler.portname.servicename.namespace.mismatch", 295 // serviceName, portName); 296 // } 297 298 if (portName == null) portName = getPortName(portClass, metadataReader, serviceName.getNamespaceURI()); 299 model.setPortName(portName); 300 301 // Check if databinding is overridden in annotation. 302 com.oracle.webservices.internal.api.databinding.DatabindingMode dbm2 = getAnnotation(portClass, com.oracle.webservices.internal.api.databinding.DatabindingMode.class); 303 if (dbm2 != null) model.databindingInfo.setDatabindingMode(dbm2.value()); 304 305 processClass(seiClass); 306 if (model.getJavaMethods().size() == 0) 307 throw new RuntimeModelerException("runtime.modeler.no.operations", 308 portClass.getName()); 309 model.postProcess(); 310 311 // Make the configured databinding mode available to the 312 // DatabindingConfig. 313 config.properties().put(BindingContext.class.getName(), 314 model.bindingContext); 315 316 // TODO: this needs to be fixed properly -- 317 // when we are building RuntimeModel first before building WSDLModel, 318 // we still need to do this correctly 319 if(binding!=null) 320 model.freeze(binding); 321 return model; 322 } 323 324 private Class configEndpointInterface() { 325 if (config.getEndpointClass() == null || 326 config.getEndpointClass().isInterface() ) return null; //client proxy Interface 327 return config.getContractClass(); 328 } 329 330 /** 331 * utility method to load classes 332 * @param className the name of the class to load 333 * @param errorMessage 334 * Error message to use when the resolution fails. 335 * @return the class specified by <code>className</code> 336 */ 337 private Class getClass(String className, Localizable errorMessage) { 338 try { 339 if (classLoader == null) 340 return Thread.currentThread().getContextClassLoader().loadClass(className); 341 else 342 return classLoader.loadClass(className); 343 } catch (ClassNotFoundException e) { 344 throw new RuntimeModelerException(errorMessage); 345 } 346 } 347 348 private boolean noWrapperGen() { 349 Object o = config.properties().get(SuppressDocLitWrapperGeneration); 350 return (o!= null && o instanceof Boolean) ? ((Boolean) o) : false; 351 } 352 353 private Class getRequestWrapperClass(String className, Method method, QName reqElemName) { 354 ClassLoader loader = (classLoader == null) ? Thread.currentThread().getContextClassLoader() : classLoader; 355 try { 356 return loader.loadClass(className); 357 } catch (ClassNotFoundException e) { 358 if (noWrapperGen()) return WrapperComposite.class; 359 logger.fine("Dynamically creating request wrapper Class " + className); 360 return WrapperBeanGenerator.createRequestWrapperBean(className, method, reqElemName, loader); 361 } 362 } 363 364 private Class getResponseWrapperClass(String className, Method method, QName resElemName) { 365 ClassLoader loader = (classLoader == null) ? Thread.currentThread().getContextClassLoader() : classLoader; 366 try { 367 return loader.loadClass(className); 368 } catch (ClassNotFoundException e) { 369 if (noWrapperGen()) return WrapperComposite.class; 370 logger.fine("Dynamically creating response wrapper bean Class " + className); 371 return WrapperBeanGenerator.createResponseWrapperBean(className, method, resElemName, loader); 372 } 373 } 374 375 376 private Class getExceptionBeanClass(String className, Class exception, String name, String namespace) { 377 boolean decapitalizeExceptionBeanProperties = true; 378 Object o = config.properties().get(DecapitalizeExceptionBeanProperties); 379 if (o!= null && o instanceof Boolean) decapitalizeExceptionBeanProperties = (Boolean) o; 380 ClassLoader loader = (classLoader == null) ? Thread.currentThread().getContextClassLoader() : classLoader; 381 try { 382 return loader.loadClass(className); 383 } catch (ClassNotFoundException e) { 384 if (noWrapperGen()) return exception; 385 logger.fine("Dynamically creating exception bean Class " + className); 386 return WrapperBeanGenerator.createExceptionBean(className, exception, targetNamespace, name, namespace, loader, decapitalizeExceptionBeanProperties); 387 } 388 } 389 390 protected void determineWebMethodUse(Class clazz) { 391 if (clazz == null) 392 return; 393 if (!clazz.isInterface()) { 394 if (clazz == Object.class) 395 return; 396 WebMethod webMethod; 397 for (Method method : clazz.getMethods()) { 398 if (method.getDeclaringClass()!=clazz) 399 continue; 400 webMethod = getAnnotation(method, WebMethod.class); 401 if (webMethod != null && !webMethod.exclude()) { 402 classUsesWebMethod.add(clazz); 403 break; 404 } 405 } 406 } 407 determineWebMethodUse(clazz.getSuperclass()); 408 } 409 410 void processClass(Class clazz) { 411 classUsesWebMethod = new HashSet<Class>(); 412 determineWebMethodUse(clazz); 413 WebService webService = getAnnotation(clazz, WebService.class); 414 QName portTypeName = getPortTypeName(clazz, targetNamespace, metadataReader); 415 // String portTypeLocalName = clazz.getSimpleName(); 416 // if (webService.name().length() >0) 417 // portTypeLocalName = webService.name(); 418 // 419 // targetNamespace = webService.targetNamespace(); 420 packageName = ""; 421 if (clazz.getPackage() != null) 422 packageName = clazz.getPackage().getName(); 423 // if (targetNamespace.length() == 0) { 424 // targetNamespace = getNamespace(packageName); 425 // } 426 // model.setTargetNamespace(targetNamespace); 427 // QName portTypeName = new QName(targetNamespace, portTypeLocalName); 428 targetNamespace = portTypeName.getNamespaceURI(); 429 model.setPortTypeName(portTypeName); 430 model.setTargetNamespace(targetNamespace); 431 model.defaultSchemaNamespaceSuffix = config.getMappingInfo().getDefaultSchemaNamespaceSuffix(); 432 model.setWSDLLocation(webService.wsdlLocation()); 433 434 SOAPBinding soapBinding = getAnnotation(clazz, SOAPBinding.class); 435 if (soapBinding != null) { 436 if (soapBinding.style() == SOAPBinding.Style.RPC && soapBinding.parameterStyle() == SOAPBinding.ParameterStyle.BARE) { 437 throw new RuntimeModelerException("runtime.modeler.invalid.soapbinding.parameterstyle", 438 soapBinding, clazz); 439 440 } 441 isWrapped = soapBinding.parameterStyle()== WRAPPED; 442 } 443 defaultBinding = createBinding(soapBinding); 444 /* 445 * if clazz != portClass then there is an SEI. If there is an 446 * SEI, then all methods should be processed. However, if there is 447 * no SEI, and the implementation class uses at least one 448 * WebMethod annotation, then only methods with this annotation 449 * will be processed. 450 */ 451 /* if (clazz == portClass) { 452 WebMethod webMethod; 453 for (Method method : clazz.getMethods()) { 454 webMethod = getPrivMethodAnnotation(method, WebMethod.class); 455 if (webMethod != null && 456 !webMethod.exclude()) { 457 usesWebMethod = true; 458 break; 459 } 460 } 461 }*/ 462 463 for (Method method : clazz.getMethods()) { 464 if (!clazz.isInterface()) { // if clazz is SEI, then all methods are web methods 465 if (method.getDeclaringClass() == Object.class) continue; 466 if (!getBooleanSystemProperty("com.sun.xml.internal.ws.legacyWebMethod")) { // legacy webMethod computation behaviour to be used 467 if (!isWebMethodBySpec(method, clazz)) 468 continue; 469 } else { 470 if (!isWebMethod(method)) 471 continue; 472 } 473 } 474 // TODO: binding can be null. We need to figure out how to post-process 475 // RuntimeModel to link to WSDLModel 476 processMethod(method); 477 } 478 //Add additional jaxb classes referenced by {@link XmlSeeAlso} 479 XmlSeeAlso xmlSeeAlso = getAnnotation(clazz, XmlSeeAlso.class); 480 if(xmlSeeAlso != null) 481 model.addAdditionalClasses(xmlSeeAlso.value()); 482 } 483 484 /* 485 * Section 3.3 of spec 486 * Otherwise, the class implicitly defines a service endpoint interface (SEI) which 487 * comprises all of the public methods that satisfy one of the following conditions: 488 * 1. They are annotated with the javax.jws.WebMethod annotation with the exclude element set to 489 * false or missing (since false is the default for this annotation element). 490 * 2. They are not annotated with the javax.jws.WebMethod annotation but their declaring class has a 491 * javax.jws.WebService annotation. 492 * 493 * also the method should non-static or non-final 494 */ 495 private boolean isWebMethodBySpec(Method method, Class clazz) { 496 497 int modifiers = method.getModifiers(); 498 boolean staticFinal = Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers); 499 500 assert Modifier.isPublic(modifiers); 501 assert !clazz.isInterface(); 502 503 WebMethod webMethod = getAnnotation(method, WebMethod.class); 504 if (webMethod != null) { 505 if (webMethod.exclude()) { 506 return false; // @WebMethod(exclude="true") 507 } 508 if (staticFinal) { 509 throw new RuntimeModelerException(ModelerMessages.localizableRUNTIME_MODELER_WEBMETHOD_MUST_BE_NONSTATICFINAL(method)); 510 } 511 return true; // @WebMethod 512 } 513 514 if (staticFinal) { 515 return false; 516 } 517 518 Class declClass = method.getDeclaringClass(); 519 return getAnnotation(declClass, WebService.class) != null; 520 } 521 522 private boolean isWebMethod(Method method) { 523 int modifiers = method.getModifiers(); 524 if (Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers)) 525 return false; 526 527 Class clazz = method.getDeclaringClass(); 528 boolean declHasWebService = getAnnotation(clazz, WebService.class) != null; 529 WebMethod webMethod = getAnnotation(method, WebMethod.class); 530 if (webMethod != null && !webMethod.exclude() && declHasWebService) 531 return true; 532 return declHasWebService && !classUsesWebMethod.contains(clazz); 533 } 534 535 /** 536 * creates a runtime model <code>SOAPBinding</code> from a <code>javax.jws.soap.SOAPBinding</code> object 537 * @param soapBinding the <code>javax.jws.soap.SOAPBinding</code> to model 538 * @return returns the runtime model SOAPBinding corresponding to <code>soapBinding</code> 539 */ 540 protected SOAPBindingImpl createBinding(SOAPBinding soapBinding) { 541 SOAPBindingImpl rtSOAPBinding = new SOAPBindingImpl(); 542 Style style = soapBinding!=null ? soapBinding.style() : Style.DOCUMENT; 543 rtSOAPBinding.setStyle(style); 544 assert bindingId != null; 545 model.bindingId = bindingId; 546 SOAPVersion soapVersion = bindingId.getSOAPVersion(); 547 rtSOAPBinding.setSOAPVersion(soapVersion); 548 return rtSOAPBinding; 549 } 550 551 /** 552 * gets the namespace <code>String</code> for a given <code>packageName</code> 553 * @param packageName the name of the package used to find a namespace. 554 * can be empty. 555 * @return the namespace for the specified <code>packageName</code> 556 */ 557 public static String getNamespace(@NotNull String packageName) { 558 if (packageName.length() == 0) 559 return null; 560 561 StringTokenizer tokenizer = new StringTokenizer(packageName, "."); 562 String[] tokens; 563 if (tokenizer.countTokens() == 0) { 564 tokens = new String[0]; 565 } else { 566 tokens = new String[tokenizer.countTokens()]; 567 for (int i=tokenizer.countTokens()-1; i >= 0; i--) { 568 tokens[i] = tokenizer.nextToken(); 569 } 570 } 571 StringBuilder namespace = new StringBuilder("http://"); 572 for (int i=0; i<tokens.length; i++) { 573 if (i!=0) 574 namespace.append('.'); 575 namespace.append(tokens[i]); 576 } 577 namespace.append('/'); 578 return namespace.toString(); 579 } 580 581 /* 582 * Returns true if an exception is service specific exception as per JAX-WS rules. 583 * @param exception 584 * @return 585 */ 586 private boolean isServiceException(Class<?> exception) { 587 return EXCEPTION_CLASS.isAssignableFrom(exception) && 588 !(RUNTIME_EXCEPTION_CLASS.isAssignableFrom(exception) || isRemoteException(exception)); 589 } 590 591 /** 592 * creates the runtime model for a method on the <code>portClass</code> 593 * @param method the method to model 594 */ 595 private void processMethod(Method method) { 596 // int mods = method.getModifiers(); 597 WebMethod webMethod = getAnnotation(method, WebMethod.class); 598 if (webMethod != null && webMethod.exclude()) return; 599 /* 600 validations are already done 601 602 if (!Modifier.isPublic(mods) || Modifier.isStatic(mods)) { 603 if(webMethod != null) { 604 // if the user put @WebMethod on these non-qualifying method, 605 // it's an error 606 if(Modifier.isStatic(mods)) 607 throw new RuntimeModelerException(ModelerMessages.localizableRUNTIME_MODELER_WEBMETHOD_MUST_BE_NONSTATIC(method)); 608 else 609 throw new RuntimeModelerException(ModelerMessages.localizableRUNTIME_MODELER_WEBMETHOD_MUST_BE_PUBLIC(method)); 610 } 611 return; 612 } 613 614 if (webMethod != null && webMethod.exclude()) 615 return; 616 */ 617 618 String methodName = method.getName(); 619 boolean isOneway = (getAnnotation(method, Oneway.class) != null); 620 621 //Check that oneway methods don't thorw any checked exceptions 622 if (isOneway) { 623 for (Class<?> exception : method.getExceptionTypes()) { 624 if(isServiceException(exception)) { 625 throw new RuntimeModelerException("runtime.modeler.oneway.operation.no.checked.exceptions", 626 portClass.getCanonicalName(), methodName, exception.getName()); 627 } 628 } 629 } 630 631 JavaMethodImpl javaMethod; 632 //Class implementorClass = portClass; 633 if (method.getDeclaringClass()==portClass) { 634 javaMethod = new JavaMethodImpl(model,method,method,metadataReader); 635 } else { 636 try { 637 Method tmpMethod = portClass.getMethod(method.getName(), 638 method.getParameterTypes()); 639 javaMethod = new JavaMethodImpl(model,tmpMethod,method,metadataReader); 640 } catch (NoSuchMethodException e) { 641 throw new RuntimeModelerException("runtime.modeler.method.not.found", 642 method.getName(), portClass.getName()); 643 } 644 } 645 646 647 648 //set MEP -oneway, async, req/resp 649 MEP mep = getMEP(method); 650 javaMethod.setMEP(mep); 651 652 String action = null; 653 654 655 String operationName = method.getName(); 656 if (webMethod != null ) { 657 action = webMethod.action(); 658 operationName = webMethod.operationName().length() > 0 ? 659 webMethod.operationName() : 660 operationName; 661 } 662 663 //override the @WebMethod.action value by the one from the WSDL 664 if(binding != null){ 665 WSDLBoundOperation bo = binding.getBinding().get(new QName(targetNamespace, operationName)); 666 if(bo != null){ 667 WSDLInput wsdlInput = bo.getOperation().getInput(); 668 String wsaAction = wsdlInput.getAction(); 669 if(wsaAction != null && !wsdlInput.isDefaultAction()) 670 action = wsaAction; 671 else 672 action = bo.getSOAPAction(); 673 } 674 } 675 676 javaMethod.setOperationQName(new QName(targetNamespace,operationName)); 677 SOAPBinding methodBinding = getAnnotation(method, SOAPBinding.class); 678 if(methodBinding != null && methodBinding.style() == SOAPBinding.Style.RPC) { 679 logger.warning(ModelerMessages.RUNTIMEMODELER_INVALID_SOAPBINDING_ON_METHOD(methodBinding, method.getName(), method.getDeclaringClass().getName())); 680 } else if (methodBinding == null && !method.getDeclaringClass().equals(portClass)) { 681 methodBinding = getAnnotation(method.getDeclaringClass(), SOAPBinding.class); 682 if (methodBinding != null && methodBinding.style() == SOAPBinding.Style.RPC && methodBinding.parameterStyle() == SOAPBinding.ParameterStyle.BARE) { 683 throw new RuntimeModelerException("runtime.modeler.invalid.soapbinding.parameterstyle", 684 methodBinding, method.getDeclaringClass()); 685 } 686 } 687 688 if(methodBinding!= null && defaultBinding.getStyle() != methodBinding.style()) { 689 throw new RuntimeModelerException("runtime.modeler.soapbinding.conflict", 690 methodBinding.style(), method.getName(),defaultBinding.getStyle()); 691 } 692 693 boolean methodIsWrapped = isWrapped; 694 Style style = defaultBinding.getStyle(); 695 if (methodBinding != null) { 696 SOAPBindingImpl mySOAPBinding = createBinding(methodBinding); 697 style = mySOAPBinding.getStyle(); 698 if (action != null) 699 mySOAPBinding.setSOAPAction(action); 700 methodIsWrapped = methodBinding.parameterStyle().equals( 701 WRAPPED); 702 javaMethod.setBinding(mySOAPBinding); 703 } else { 704 SOAPBindingImpl sb = new SOAPBindingImpl(defaultBinding); 705 if (action != null) { 706 sb.setSOAPAction(action); 707 } else { 708 String defaults = SOAPVersion.SOAP_11 == sb.getSOAPVersion() ? "" : null; 709 sb.setSOAPAction(defaults); 710 } 711 javaMethod.setBinding(sb); 712 } 713 if (!methodIsWrapped) { 714 processDocBareMethod(javaMethod, operationName, method); 715 } else if (style.equals(Style.DOCUMENT)) { 716 processDocWrappedMethod(javaMethod, methodName, operationName, 717 method); 718 } else { 719 processRpcMethod(javaMethod, methodName, operationName, method); 720 } 721 model.addJavaMethod(javaMethod); 722 } 723 724 private MEP getMEP(Method m){ 725 if (getAnnotation(m, Oneway.class)!= null) { 726 return MEP.ONE_WAY; 727 } 728 if(Response.class.isAssignableFrom(m.getReturnType())){ 729 return MEP.ASYNC_POLL; 730 }else if(Future.class.isAssignableFrom(m.getReturnType())){ 731 return MEP.ASYNC_CALLBACK; 732 } 733 return MEP.REQUEST_RESPONSE; 734 } 735 736 /** 737 * models a document/literal wrapped method 738 * @param javaMethod the runtime model <code>JavaMethod</code> instance being created 739 * @param methodName the runtime model <code>JavaMethod</code> instance being created 740 * @param operationName the runtime model <code>JavaMethod</code> instance being created 741 * @param method the <code>method</code> to model 742 */ 743 protected void processDocWrappedMethod(JavaMethodImpl javaMethod, String methodName, 744 String operationName, Method method) { 745 boolean methodHasHeaderParams = false; 746 boolean isOneway = getAnnotation(method, Oneway.class)!= null; 747 RequestWrapper reqWrapper = getAnnotation(method,RequestWrapper.class); 748 ResponseWrapper resWrapper = getAnnotation(method,ResponseWrapper.class); 749 String beanPackage = packageName + PD_JAXWS_PACKAGE_PD; 750 if (packageName == null || packageName.length() == 0) { 751 beanPackage = JAXWS_PACKAGE_PD; 752 } 753 String requestClassName; 754 if(reqWrapper != null && reqWrapper.className().length()>0){ 755 requestClassName = reqWrapper.className(); 756 }else{ 757 requestClassName = beanPackage + capitalize(method.getName()); 758 } 759 760 761 String responseClassName; 762 if(resWrapper != null && resWrapper.className().length()>0){ 763 responseClassName = resWrapper.className(); 764 }else{ 765 responseClassName = beanPackage + capitalize(method.getName()) + RESPONSE; 766 } 767 768 String reqName = operationName; 769 String reqNamespace = targetNamespace; 770 String reqPartName = "parameters"; 771 if (reqWrapper != null) { 772 if (reqWrapper.targetNamespace().length() > 0) 773 reqNamespace = reqWrapper.targetNamespace(); 774 if (reqWrapper.localName().length() > 0) 775 reqName = reqWrapper.localName(); 776 try { 777 if (reqWrapper.partName().length() > 0) 778 reqPartName = reqWrapper.partName(); 779 } catch(LinkageError e) { 780 //2.1 API dopes n't have this method 781 //Do nothing, just default to "parameters" 782 } 783 } 784 QName reqElementName = new QName(reqNamespace, reqName); 785 javaMethod.setRequestPayloadName(reqElementName); 786 Class requestClass = getRequestWrapperClass(requestClassName, method, reqElementName); 787 788 Class responseClass = null; 789 String resName = operationName+"Response"; 790 String resNamespace = targetNamespace; 791 QName resElementName = null; 792 String resPartName = "parameters"; 793 if (!isOneway) { 794 if (resWrapper != null) { 795 if (resWrapper.targetNamespace().length() > 0) 796 resNamespace = resWrapper.targetNamespace(); 797 if (resWrapper.localName().length() > 0) 798 resName = resWrapper.localName(); 799 try { 800 if (resWrapper.partName().length() > 0) 801 resPartName = resWrapper.partName(); 802 } catch (LinkageError e) { 803 //2.1 API does n't have this method 804 //Do nothing, just default to "parameters" 805 } 806 } 807 resElementName = new QName(resNamespace, resName); 808 responseClass = getResponseWrapperClass(responseClassName, method, resElementName); 809 } 810 811 TypeInfo typeRef = 812 new TypeInfo(reqElementName, requestClass); 813 typeRef.setNillable(false); 814 WrapperParameter requestWrapper = new WrapperParameter(javaMethod, typeRef, 815 Mode.IN, 0); 816 requestWrapper.setPartName(reqPartName); 817 requestWrapper.setBinding(ParameterBinding.BODY); 818 javaMethod.addParameter(requestWrapper); 819 WrapperParameter responseWrapper = null; 820 if (!isOneway) { 821 typeRef = new TypeInfo(resElementName, responseClass); 822 typeRef.setNillable(false); 823 responseWrapper = new WrapperParameter(javaMethod, typeRef, Mode.OUT, -1); 824 javaMethod.addParameter(responseWrapper); 825 responseWrapper.setBinding(ParameterBinding.BODY); 826 } 827 828 // return value 829 830 831 WebResult webResult = getAnnotation(method, WebResult.class); 832 XmlElement xmlElem = getAnnotation(method, XmlElement.class); 833 QName resultQName = getReturnQName(method, webResult, xmlElem); 834 Class returnType = method.getReturnType(); 835 boolean isResultHeader = false; 836 if (webResult != null) { 837 isResultHeader = webResult.header(); 838 methodHasHeaderParams = isResultHeader || methodHasHeaderParams; 839 if (isResultHeader && xmlElem != null) { 840 throw new RuntimeModelerException("@XmlElement cannot be specified on method "+method+" as the return value is bound to header"); 841 } 842 if (resultQName.getNamespaceURI().length() == 0 && webResult.header()) { 843 // headers must have a namespace 844 resultQName = new QName(targetNamespace, resultQName.getLocalPart()); 845 } 846 } 847 848 if(javaMethod.isAsync()){ 849 returnType = getAsyncReturnType(method, returnType); 850 resultQName = new QName(RETURN); 851 } 852 resultQName = qualifyWrappeeIfNeeded(resultQName, resNamespace); 853 if (!isOneway && (returnType != null) && (!returnType.getName().equals("void"))) { 854 Annotation[] rann = getAnnotations(method); 855 if (resultQName.getLocalPart() != null) { 856 TypeInfo rTypeReference = new TypeInfo(resultQName, returnType, rann); 857 metadataReader.getProperties(rTypeReference.properties(), method); 858 rTypeReference.setGenericType(method.getGenericReturnType()); 859 ParameterImpl returnParameter = new ParameterImpl(javaMethod, rTypeReference, Mode.OUT, -1); 860 if (isResultHeader) { 861 returnParameter.setBinding(ParameterBinding.HEADER); 862 javaMethod.addParameter(returnParameter); 863 } else { 864 returnParameter.setBinding(ParameterBinding.BODY); 865 responseWrapper.addWrapperChild(returnParameter); 866 } 867 } 868 } 869 870 //get WebParam 871 Class<?>[] parameterTypes = method.getParameterTypes(); 872 Type[] genericParameterTypes = method.getGenericParameterTypes(); 873 Annotation[][] pannotations = getParamAnnotations(method); 874 int pos = 0; 875 for (Class clazzType : parameterTypes) { 876 String partName=null; 877 String paramName = "arg"+pos; 878 //String paramNamespace = ""; 879 boolean isHeader = false; 880 881 if(javaMethod.isAsync() && AsyncHandler.class.isAssignableFrom(clazzType)){ 882 continue; 883 } 884 885 boolean isHolder = HOLDER_CLASS.isAssignableFrom(clazzType); 886 //set the actual type argument of Holder in the TypeReference 887 if (isHolder) { 888 if(clazzType==Holder.class){ 889 clazzType = erasure(((ParameterizedType)genericParameterTypes[pos]).getActualTypeArguments()[0]); 890 } 891 } 892 Mode paramMode = isHolder ? Mode.INOUT : Mode.IN; 893 WebParam webParam = null; 894 xmlElem = null; 895 for (Annotation annotation : pannotations[pos]) { 896 if (annotation.annotationType() == WebParam.class) 897 webParam = (WebParam)annotation; 898 else if (annotation.annotationType() == XmlElement.class) 899 xmlElem = (XmlElement)annotation; 900 } 901 902 QName paramQName = getParameterQName(method, webParam, xmlElem, paramName); 903 if (webParam != null) { 904 isHeader = webParam.header(); 905 methodHasHeaderParams = isHeader || methodHasHeaderParams; 906 if (isHeader && xmlElem != null) { 907 throw new RuntimeModelerException("@XmlElement cannot be specified on method "+method+" parameter that is bound to header"); 908 } 909 if(webParam.partName().length() > 0) 910 partName = webParam.partName(); 911 else 912 partName = paramQName.getLocalPart(); 913 if (isHeader && paramQName.getNamespaceURI().equals("")) { // headers cannot be in empty namespace 914 paramQName = new QName(targetNamespace, paramQName.getLocalPart()); 915 } 916 paramMode = webParam.mode(); 917 if (isHolder && paramMode == Mode.IN) 918 paramMode = Mode.INOUT; 919 } 920 paramQName = qualifyWrappeeIfNeeded(paramQName, reqNamespace); 921 typeRef = 922 new TypeInfo(paramQName, clazzType, pannotations[pos]); 923 metadataReader.getProperties(typeRef.properties(), method, pos); 924 typeRef.setGenericType(genericParameterTypes[pos]); 925 ParameterImpl param = new ParameterImpl(javaMethod, typeRef, paramMode, pos++); 926 927 if (isHeader) { 928 param.setBinding(ParameterBinding.HEADER); 929 javaMethod.addParameter(param); 930 param.setPartName(partName); 931 } else { 932 param.setBinding(ParameterBinding.BODY); 933 if (paramMode!=Mode.OUT) { 934 requestWrapper.addWrapperChild(param); 935 } 936 if (paramMode!=Mode.IN) { 937 if (isOneway) { 938 throw new RuntimeModelerException("runtime.modeler.oneway.operation.no.out.parameters", 939 portClass.getCanonicalName(), methodName); 940 } 941 responseWrapper.addWrapperChild(param); 942 } 943 } 944 } 945 946 //If the method has any parameter or return type that is bound to a header, use "result" as part name to avoid 947 // name collison of same input part name and output part name ("parameters") shown up as param names on the 948 // client mapping. 949 if(methodHasHeaderParams) { 950 resPartName = "result"; 951 } 952 if(responseWrapper != null) 953 responseWrapper.setPartName(resPartName); 954 processExceptions(javaMethod, method); 955 } 956 957 private QName qualifyWrappeeIfNeeded(QName resultQName, String ns) { 958 Object o = config.properties().get(DocWrappeeNamespapceQualified); 959 boolean qualified = (o!= null && o instanceof Boolean) ? ((Boolean) o) : false; 960 if (qualified) { 961 if (resultQName.getNamespaceURI() == null || "".equals(resultQName.getNamespaceURI())) { 962 return new QName(ns, resultQName.getLocalPart()); 963 } 964 } 965 return resultQName; 966 } 967 968 /** 969 * models a rpc/literal method 970 * @param javaMethod the runtime model <code>JavaMethod</code> instance being created 971 * @param methodName the name of the <code>method</code> being modeled. 972 * @param operationName the WSDL operation name for this <code>method</code> 973 * @param method the runtime model <code>JavaMethod</code> instance being created 974 */ 975 protected void processRpcMethod(JavaMethodImpl javaMethod, String methodName, 976 String operationName, Method method) { 977 boolean isOneway = getAnnotation(method, Oneway.class) != null; 978 979 // use Map to build parameters in the part order when they are known. 980 // if part is unbound, we just put them at the end, and for that we 981 // use a large index (10000+) to avoid colliding with ordered ones. 982 // this assumes that there's no operation with # of parameters > 10000, 983 // but I think it's a pretty safe assumption - KK. 984 Map<Integer, ParameterImpl> resRpcParams = new TreeMap<Integer, ParameterImpl>(); 985 Map<Integer, ParameterImpl> reqRpcParams = new TreeMap<Integer, ParameterImpl>(); 986 987 //Lets take the service namespace and overwrite it with the one we get it from wsdl 988 String reqNamespace = targetNamespace; 989 String respNamespace = targetNamespace; 990 991 if(binding != null && Style.RPC.equals(binding.getBinding().getStyle())){ 992 QName opQName = new QName(binding.getBinding().getPortTypeName().getNamespaceURI(), operationName); 993 WSDLBoundOperation op = binding.getBinding().get(opQName); 994 if(op != null){ 995 //it cant be null, but lets not fail and try to work with service namespce 996 if(op.getRequestNamespace() != null){ 997 reqNamespace = op.getRequestNamespace(); 998 } 999 1000 //it cant be null, but lets not fail and try to work with service namespce 1001 if(op.getResponseNamespace() != null){ 1002 respNamespace = op.getResponseNamespace(); 1003 } 1004 } 1005 } 1006 1007 QName reqElementName = new QName(reqNamespace, operationName); 1008 javaMethod.setRequestPayloadName(reqElementName); 1009 QName resElementName = null; 1010 if (!isOneway) { 1011 resElementName = new QName(respNamespace, operationName+RESPONSE); 1012 } 1013 1014 Class wrapperType = WrapperComposite.class; 1015 TypeInfo typeRef = new TypeInfo(reqElementName, wrapperType); 1016 WrapperParameter requestWrapper = new WrapperParameter(javaMethod, typeRef, Mode.IN, 0); 1017 requestWrapper.setInBinding(ParameterBinding.BODY); 1018 javaMethod.addParameter(requestWrapper); 1019 WrapperParameter responseWrapper = null; 1020 if (!isOneway) { 1021 typeRef = new TypeInfo(resElementName, wrapperType); 1022 responseWrapper = new WrapperParameter(javaMethod, typeRef, Mode.OUT, -1); 1023 responseWrapper.setOutBinding(ParameterBinding.BODY); 1024 javaMethod.addParameter(responseWrapper); 1025 } 1026 1027 Class returnType = method.getReturnType(); 1028 String resultName = RETURN; 1029 String resultTNS = targetNamespace; 1030 String resultPartName = resultName; 1031 boolean isResultHeader = false; 1032 WebResult webResult = getAnnotation(method, WebResult.class); 1033 1034 if (webResult != null) { 1035 isResultHeader = webResult.header(); 1036 if (webResult.name().length() > 0) 1037 resultName = webResult.name(); 1038 if (webResult.partName().length() > 0) { 1039 resultPartName = webResult.partName(); 1040 if (!isResultHeader) 1041 resultName = resultPartName; 1042 } else 1043 resultPartName = resultName; 1044 if (webResult.targetNamespace().length() > 0) 1045 resultTNS = webResult.targetNamespace(); 1046 isResultHeader = webResult.header(); 1047 } 1048 QName resultQName; 1049 if (isResultHeader) 1050 resultQName = new QName(resultTNS, resultName); 1051 else 1052 resultQName = new QName(resultName); 1053 1054 if(javaMethod.isAsync()){ 1055 returnType = getAsyncReturnType(method, returnType); 1056 } 1057 1058 if (!isOneway && returnType!=null && returnType!=void.class) { 1059 Annotation[] rann = getAnnotations(method); 1060 TypeInfo rTypeReference = new TypeInfo(resultQName, returnType, rann); 1061 metadataReader.getProperties(rTypeReference.properties(), method); 1062 rTypeReference.setGenericType(method.getGenericReturnType()); 1063 ParameterImpl returnParameter = new ParameterImpl(javaMethod, rTypeReference, Mode.OUT, -1); 1064 returnParameter.setPartName(resultPartName); 1065 if(isResultHeader){ 1066 returnParameter.setBinding(ParameterBinding.HEADER); 1067 javaMethod.addParameter(returnParameter); 1068 rTypeReference.setGlobalElement(true); 1069 }else{ 1070 ParameterBinding rb = getBinding(operationName, resultPartName, false, Mode.OUT); 1071 returnParameter.setBinding(rb); 1072 if(rb.isBody()){ 1073 rTypeReference.setGlobalElement(false); 1074 WSDLPart p = getPart(new QName(targetNamespace,operationName), resultPartName, Mode.OUT); 1075 if(p == null) 1076 resRpcParams.put(resRpcParams.size()+10000, returnParameter); 1077 else 1078 resRpcParams.put(p.getIndex(), returnParameter); 1079 }else{ 1080 javaMethod.addParameter(returnParameter); 1081 } 1082 } 1083 } 1084 1085 //get WebParam 1086 Class<?>[] parameterTypes = method.getParameterTypes(); 1087 Type[] genericParameterTypes = method.getGenericParameterTypes(); 1088 Annotation[][] pannotations = getParamAnnotations(method); 1089 int pos = 0; 1090 for (Class clazzType : parameterTypes) { 1091 String paramName = ""; 1092 String paramNamespace = ""; 1093 String partName = ""; 1094 boolean isHeader = false; 1095 1096 if(javaMethod.isAsync() && AsyncHandler.class.isAssignableFrom(clazzType)){ 1097 continue; 1098 } 1099 1100 boolean isHolder = HOLDER_CLASS.isAssignableFrom(clazzType); 1101 //set the actual type argument of Holder in the TypeReference 1102 if (isHolder) { 1103 if (clazzType==Holder.class) 1104 clazzType = erasure(((ParameterizedType)genericParameterTypes[pos]).getActualTypeArguments()[0]); 1105 } 1106 Mode paramMode = isHolder ? Mode.INOUT : Mode.IN; 1107 for (Annotation annotation : pannotations[pos]) { 1108 if (annotation.annotationType() == javax.jws.WebParam.class) { 1109 javax.jws.WebParam webParam = (javax.jws.WebParam) annotation; 1110 paramName = webParam.name(); 1111 partName = webParam.partName(); 1112 isHeader = webParam.header(); 1113 WebParam.Mode mode = webParam.mode(); 1114 paramNamespace = webParam.targetNamespace(); 1115 if (isHolder && mode == Mode.IN) 1116 mode = Mode.INOUT; 1117 paramMode = mode; 1118 break; 1119 } 1120 } 1121 1122 if (paramName.length() == 0) { 1123 paramName = "arg"+pos; 1124 } 1125 if (partName.length() == 0) { 1126 partName = paramName; 1127 } else if (!isHeader) { 1128 paramName = partName; 1129 } 1130 if (partName.length() == 0) { 1131 partName = paramName; 1132 } 1133 1134 QName paramQName; 1135 if (!isHeader) { 1136 //its rpclit body param, set namespace to "" 1137 paramQName = new QName("", paramName); 1138 } else { 1139 if (paramNamespace.length() == 0) 1140 paramNamespace = targetNamespace; 1141 paramQName = new QName(paramNamespace, paramName); 1142 } 1143 typeRef = 1144 new TypeInfo(paramQName, clazzType, pannotations[pos]); 1145 metadataReader.getProperties(typeRef.properties(), method, pos); 1146 typeRef.setGenericType(genericParameterTypes[pos]); 1147 ParameterImpl param = new ParameterImpl(javaMethod, typeRef, paramMode, pos++); 1148 param.setPartName(partName); 1149 1150 if(paramMode == Mode.INOUT){ 1151 ParameterBinding pb = getBinding(operationName, partName, isHeader, Mode.IN); 1152 param.setInBinding(pb); 1153 pb = getBinding(operationName, partName, isHeader, Mode.OUT); 1154 param.setOutBinding(pb); 1155 }else{ 1156 if (isHeader) { 1157 typeRef.setGlobalElement(true); 1158 param.setBinding(ParameterBinding.HEADER); 1159 } else { 1160 ParameterBinding pb = getBinding(operationName, partName, false, paramMode); 1161 param.setBinding(pb); 1162 } 1163 } 1164 if(param.getInBinding().isBody()){ 1165 typeRef.setGlobalElement(false); 1166 if(!param.isOUT()){ 1167 WSDLPart p = getPart(new QName(targetNamespace,operationName), partName, Mode.IN); 1168 if(p == null) 1169 reqRpcParams.put(reqRpcParams.size()+10000, param); 1170 else 1171 reqRpcParams.put(param.getIndex(), param); 1172 } 1173 1174 if(!param.isIN()){ 1175 if (isOneway) { 1176 throw new RuntimeModelerException("runtime.modeler.oneway.operation.no.out.parameters", 1177 portClass.getCanonicalName(), methodName); 1178 } 1179 WSDLPart p = getPart(new QName(targetNamespace,operationName), partName, Mode.OUT); 1180 if(p == null) 1181 resRpcParams.put(resRpcParams.size()+10000, param); 1182 else 1183 resRpcParams.put(param.getIndex(), param); 1184 } 1185 }else{ 1186 javaMethod.addParameter(param); 1187 } 1188 } 1189 for (ParameterImpl p : reqRpcParams.values()) 1190 requestWrapper.addWrapperChild(p); 1191 for (ParameterImpl p : resRpcParams.values()) 1192 responseWrapper.addWrapperChild(p); 1193 processExceptions(javaMethod, method); 1194 } 1195 1196 /** 1197 * models the exceptions thrown by <code>method</code> and adds them to the <code>javaMethod</code> 1198 * runtime model object 1199 * @param javaMethod the runtime model object to add the exception model objects to 1200 * @param method the <code>method</code> from which to find the exceptions to model 1201 */ 1202 protected void processExceptions(JavaMethodImpl javaMethod, Method method) { 1203 Action actionAnn = getAnnotation(method, Action.class); 1204 FaultAction[] faultActions = {}; 1205 if(actionAnn != null) 1206 faultActions = actionAnn.fault(); 1207 for (Class<?> exception : method.getExceptionTypes()) { 1208 1209 //Exclude RuntimeException, RemoteException and Error etc 1210 if (!EXCEPTION_CLASS.isAssignableFrom(exception)) 1211 continue; 1212 if (RUNTIME_EXCEPTION_CLASS.isAssignableFrom(exception) || isRemoteException(exception)) 1213 continue; 1214 if (getAnnotation(exception, javax.xml.bind.annotation.XmlTransient.class) != null) 1215 continue; 1216 Class exceptionBean; 1217 Annotation[] anns; 1218 WebFault webFault = getAnnotation(exception, WebFault.class); 1219 Method faultInfoMethod = getWSDLExceptionFaultInfo(exception); 1220 ExceptionType exceptionType = ExceptionType.WSDLException; 1221 String namespace = targetNamespace; 1222 String name = exception.getSimpleName(); 1223 String beanPackage = packageName + PD_JAXWS_PACKAGE_PD; 1224 if (packageName.length() == 0) 1225 beanPackage = JAXWS_PACKAGE_PD; 1226 String className = beanPackage+ name + BEAN; 1227 String messageName = exception.getSimpleName(); 1228 if (webFault != null) { 1229 if (webFault.faultBean().length()>0) 1230 className = webFault.faultBean(); 1231 if (webFault.name().length()>0) 1232 name = webFault.name(); 1233 if (webFault.targetNamespace().length()>0) 1234 namespace = webFault.targetNamespace(); 1235 if (webFault.messageName().length()>0) 1236 messageName = webFault.messageName(); 1237 } 1238 if (faultInfoMethod == null) { 1239 exceptionBean = getExceptionBeanClass(className, exception, name, namespace); 1240 exceptionType = ExceptionType.UserDefined; 1241 anns = getAnnotations(exceptionBean); 1242 } else { 1243 exceptionBean = faultInfoMethod.getReturnType(); 1244 anns = getAnnotations(faultInfoMethod); 1245 } 1246 QName faultName = new QName(namespace, name); 1247 TypeInfo typeRef = new TypeInfo(faultName, exceptionBean, anns); 1248 CheckedExceptionImpl checkedException = 1249 new CheckedExceptionImpl(javaMethod, exception, typeRef, exceptionType); 1250 checkedException.setMessageName(messageName); 1251 checkedException.setFaultInfoGetter(faultInfoMethod); 1252 for(FaultAction fa: faultActions) { 1253 if(fa.className().equals(exception) && !fa.value().equals("")) { 1254 checkedException.setFaultAction(fa.value()); 1255 break; 1256 } 1257 } 1258 javaMethod.addException(checkedException); 1259 } 1260 } 1261 1262 /** 1263 * returns the method that corresponds to "getFaultInfo". Returns null if this is not an 1264 * exception generated from a WSDL 1265 * @param exception the class to search for the "getFaultInfo" method 1266 * @return the method named "getFaultInfo" if this is an exception generated from WSDL or an 1267 * exception that contains the <code>WebFault</code> annotation. Otherwise it returns null 1268 */ 1269 protected Method getWSDLExceptionFaultInfo(Class exception) { 1270 // if (!exception.isAnnotationPresent(WebFault.class)) 1271 if (getAnnotation(exception, WebFault.class) == null) 1272 return null; 1273 try { 1274 return exception.getMethod("getFaultInfo"); 1275 } catch (NoSuchMethodException e) { 1276 return null; 1277 } 1278 } 1279 1280 /** 1281 * models a document/literal bare method 1282 * @param javaMethod the runtime model <code>JavaMethod</code> instance being created 1283 * @param operationName the runtime model <code>JavaMethod</code> instance being created 1284 * @param method the runtime model <code>JavaMethod</code> instance being created 1285 */ 1286 protected void processDocBareMethod(JavaMethodImpl javaMethod, 1287 String operationName, Method method) { 1288 1289 String resultName = operationName+RESPONSE; 1290 String resultTNS = targetNamespace; 1291 String resultPartName = null; 1292 boolean isResultHeader = false; 1293 WebResult webResult = getAnnotation(method, WebResult.class); 1294 if (webResult != null) { 1295 if (webResult.name().length() > 0) 1296 resultName = webResult.name(); 1297 if (webResult.targetNamespace().length() > 0) 1298 resultTNS = webResult.targetNamespace(); 1299 resultPartName = webResult.partName(); 1300 isResultHeader = webResult.header(); 1301 } 1302 1303 Class returnType = method.getReturnType(); 1304 Type gReturnType = method.getGenericReturnType(); 1305 if(javaMethod.isAsync()){ 1306 returnType = getAsyncReturnType(method, returnType); 1307 } 1308 1309 if ((returnType != null) && (!returnType.getName().equals("void"))) { 1310 Annotation[] rann = getAnnotations(method); 1311 if (resultName != null) { 1312 QName responseQName = new QName(resultTNS, resultName); 1313 TypeInfo rTypeReference = new TypeInfo(responseQName, returnType, rann); 1314 rTypeReference.setGenericType(gReturnType); 1315 metadataReader.getProperties(rTypeReference.properties(), method); 1316 ParameterImpl returnParameter = new ParameterImpl(javaMethod, rTypeReference, Mode.OUT, -1); 1317 1318 if(resultPartName == null || (resultPartName.length() == 0)){ 1319 resultPartName = resultName; 1320 } 1321 returnParameter.setPartName(resultPartName); 1322 if(isResultHeader){ 1323 returnParameter.setBinding(ParameterBinding.HEADER); 1324 }else{ 1325 ParameterBinding rb = getBinding(operationName, resultPartName, false, Mode.OUT); 1326 returnParameter.setBinding(rb); 1327 } 1328 javaMethod.addParameter(returnParameter); 1329 } 1330 } 1331 1332 //get WebParam 1333 Class<?>[] parameterTypes = method.getParameterTypes(); 1334 Type[] genericParameterTypes = method.getGenericParameterTypes(); 1335 Annotation[][] pannotations = getParamAnnotations(method); 1336 int pos = 0; 1337 for (Class clazzType : parameterTypes) { 1338 String paramName = operationName; //method.getName(); 1339 String partName = null; 1340 String requestNamespace = targetNamespace; 1341 boolean isHeader = false; 1342 1343 //async 1344 if(javaMethod.isAsync() && AsyncHandler.class.isAssignableFrom(clazzType)){ 1345 continue; 1346 } 1347 1348 boolean isHolder = HOLDER_CLASS.isAssignableFrom(clazzType); 1349 //set the actual type argument of Holder in the TypeReference 1350 if (isHolder) { 1351 if (clazzType==Holder.class) 1352 clazzType = erasure(((ParameterizedType)genericParameterTypes[pos]).getActualTypeArguments()[0]); 1353 } 1354 1355 Mode paramMode = isHolder ? Mode.INOUT : Mode.IN; 1356 for (Annotation annotation : pannotations[pos]) { 1357 if (annotation.annotationType() == javax.jws.WebParam.class) { 1358 javax.jws.WebParam webParam = (javax.jws.WebParam) annotation; 1359 paramMode = webParam.mode(); 1360 if (isHolder && paramMode == Mode.IN) 1361 paramMode = Mode.INOUT; 1362 isHeader = webParam.header(); 1363 if(isHeader) 1364 paramName = "arg"+pos; 1365 if(paramMode == Mode.OUT && !isHeader) 1366 paramName = operationName+RESPONSE; 1367 if (webParam.name().length() > 0) 1368 paramName = webParam.name(); 1369 partName = webParam.partName(); 1370 if (!webParam.targetNamespace().equals("")) { 1371 requestNamespace = webParam.targetNamespace(); 1372 } 1373 break; 1374 } 1375 } 1376 1377 QName requestQName = new QName(requestNamespace, paramName); 1378 if (!isHeader && paramMode != Mode.OUT) javaMethod.setRequestPayloadName(requestQName); 1379 //doclit/wrapped 1380 TypeInfo typeRef = //operationName with upper 1 char 1381 new TypeInfo(requestQName, clazzType, 1382 pannotations[pos]); 1383 metadataReader.getProperties(typeRef.properties(), method, pos); 1384 typeRef.setGenericType(genericParameterTypes[pos]); 1385 ParameterImpl param = new ParameterImpl(javaMethod, typeRef, paramMode, pos++); 1386 if(partName == null || (partName.length() == 0)){ 1387 partName = paramName; 1388 } 1389 param.setPartName(partName); 1390 if(paramMode == Mode.INOUT){ 1391 ParameterBinding pb = getBinding(operationName, partName, isHeader, Mode.IN); 1392 param.setInBinding(pb); 1393 pb = getBinding(operationName, partName, isHeader, Mode.OUT); 1394 param.setOutBinding(pb); 1395 }else{ 1396 if (isHeader){ 1397 param.setBinding(ParameterBinding.HEADER); 1398 }else{ 1399 ParameterBinding pb = getBinding(operationName, partName, false, paramMode); 1400 param.setBinding(pb); 1401 } 1402 } 1403 javaMethod.addParameter(param); 1404 } 1405 validateDocBare(javaMethod); 1406 processExceptions(javaMethod, method); 1407 } 1408 1409 // Does a conservative check if there is only one BODY part for input 1410 // and output message. We are not considering INOUT parameters at this 1411 // time since binding information is not applied. Also, there isn't 1412 // anyway to represent some cases in SEI. For example, a INOUT parameter 1413 // could be bound to body for input message, header for OUTPUT message 1414 // in wsdl:binding 1415 private void validateDocBare(JavaMethodImpl javaMethod) { 1416 int numInBodyBindings = 0; 1417 for(Parameter param : javaMethod.getRequestParameters()){ 1418 if(param.getBinding().equals(ParameterBinding.BODY) && param.isIN()){ 1419 numInBodyBindings++; 1420 } 1421 if(numInBodyBindings > 1){ 1422 throw new RuntimeModelerException(ModelerMessages.localizableNOT_A_VALID_BARE_METHOD(portClass.getName(), javaMethod.getMethod().getName())); 1423 } 1424 } 1425 1426 int numOutBodyBindings = 0; 1427 for(Parameter param : javaMethod.getResponseParameters()){ 1428 if(param.getBinding().equals(ParameterBinding.BODY) && param.isOUT()){ 1429 numOutBodyBindings++; 1430 } 1431 if(numOutBodyBindings > 1){ 1432 throw new RuntimeModelerException(ModelerMessages.localizableNOT_A_VALID_BARE_METHOD(portClass.getName(), javaMethod.getMethod().getName())); 1433 } 1434 } 1435 } 1436 1437 private Class getAsyncReturnType(Method method, Class returnType) { 1438 if(Response.class.isAssignableFrom(returnType)){ 1439 Type ret = method.getGenericReturnType(); 1440 return erasure(((ParameterizedType)ret).getActualTypeArguments()[0]); 1441 }else{ 1442 Type[] types = method.getGenericParameterTypes(); 1443 Class[] params = method.getParameterTypes(); 1444 int i = 0; 1445 for(Class cls : params){ 1446 if(AsyncHandler.class.isAssignableFrom(cls)){ 1447 return erasure(((ParameterizedType)types[i]).getActualTypeArguments()[0]); 1448 } 1449 i++; 1450 } 1451 } 1452 return returnType; 1453 } 1454 1455 /** 1456 * utility to capitalize the first letter in a string 1457 * @param name the string to capitalize 1458 * @return the capitalized string 1459 */ 1460 public static String capitalize(String name) { 1461 if (name == null || name.length() == 0) { 1462 return name; 1463 } 1464 char chars[] = name.toCharArray(); 1465 chars[0] = Character.toUpperCase(chars[0]); 1466 return new String(chars); 1467 } 1468 1469 /* 1470 * Return service QName 1471 */ 1472 /** 1473 * gets the <code>wsdl:serviceName</code> for a given implementation class 1474 * @param implClass the implementation class 1475 * @return the <code>wsdl:serviceName</code> for the <code>implClass</code> 1476 */ 1477 public static QName getServiceName(Class<?> implClass) { 1478 return getServiceName(implClass, null); 1479 } 1480 1481 public static QName getServiceName(Class<?> implClass, boolean isStandard) { 1482 return getServiceName(implClass, null, isStandard); 1483 } 1484 1485 public static QName getServiceName(Class<?> implClass, MetadataReader reader) { 1486 return getServiceName(implClass, reader, true); 1487 } 1488 1489 public static QName getServiceName(Class<?> implClass, MetadataReader reader, boolean isStandard) { 1490 if (implClass.isInterface()) { 1491 throw new RuntimeModelerException("runtime.modeler.cannot.get.serviceName.from.interface", 1492 implClass.getCanonicalName()); 1493 } 1494 1495 String name = implClass.getSimpleName()+SERVICE; 1496 String packageName = ""; 1497 if (implClass.getPackage() != null) 1498 packageName = implClass.getPackage().getName(); 1499 1500 WebService webService = getAnnotation(WebService.class, implClass, reader); 1501 if (isStandard && webService == null) { 1502 throw new RuntimeModelerException("runtime.modeler.no.webservice.annotation", 1503 implClass.getCanonicalName()); 1504 } 1505 if (webService != null && webService.serviceName().length() > 0) { 1506 name = webService.serviceName(); 1507 } 1508 String targetNamespace = getNamespace(packageName); 1509 if (webService != null && webService.targetNamespace().length() > 0) { 1510 targetNamespace = webService.targetNamespace(); 1511 } else if (targetNamespace == null) { 1512 throw new RuntimeModelerException("runtime.modeler.no.package", 1513 implClass.getName()); 1514 } 1515 return new QName(targetNamespace, name); 1516 } 1517 1518 /** 1519 * gets the <code>wsdl:portName</code> for a given implementation class 1520 * @param implClass the implementation class 1521 * @param targetNamespace Namespace URI for service name 1522 * @return the <code>wsdl:portName</code> for the <code>implClass</code> 1523 */ 1524 public static QName getPortName(Class<?> implClass, String targetNamespace) { 1525 return getPortName(implClass, null, targetNamespace); 1526 } 1527 1528 public static QName getPortName(Class<?> implClass, String targetNamespace, boolean isStandard) { 1529 return getPortName(implClass, null, targetNamespace, isStandard); 1530 } 1531 1532 public static QName getPortName(Class<?> implClass, MetadataReader reader, String targetNamespace) { 1533 return getPortName(implClass, reader, targetNamespace, true); 1534 } 1535 1536 public static QName getPortName(Class<?> implClass, MetadataReader reader, String targetNamespace, boolean isStandard) { 1537 WebService webService = getAnnotation(WebService.class, implClass, reader); 1538 if (isStandard && webService == null) { 1539 throw new RuntimeModelerException("runtime.modeler.no.webservice.annotation", 1540 implClass.getCanonicalName()); 1541 } 1542 String name; 1543 if (webService != null && webService.portName().length() > 0) { 1544 name = webService.portName(); 1545 } else if (webService != null && webService.name().length() > 0) { 1546 name = webService.name()+PORT; 1547 } else { 1548 name = implClass.getSimpleName()+PORT; 1549 } 1550 1551 if (targetNamespace == null) { 1552 if (webService != null && webService.targetNamespace().length() > 0) { 1553 targetNamespace = webService.targetNamespace(); 1554 } else { 1555 String packageName = null; 1556 if (implClass.getPackage() != null) { 1557 packageName = implClass.getPackage().getName(); 1558 } 1559 if (packageName != null) { 1560 targetNamespace = getNamespace(packageName); 1561 } 1562 if (targetNamespace == null) { 1563 throw new RuntimeModelerException("runtime.modeler.no.package", 1564 implClass.getName()); 1565 } 1566 } 1567 1568 } 1569 1570 return new QName(targetNamespace, name); 1571 } 1572 1573 static <A extends Annotation> A getAnnotation(Class<A> t, Class<?> cls, MetadataReader reader) { 1574 return (reader == null)? cls.getAnnotation(t) : reader.getAnnotation(t, cls); 1575 } 1576 1577 /** 1578 * Gives portType QName from implementatorClass or SEI 1579 * @param implOrSeiClass cant be null 1580 * @return <code>wsdl:portType@name</code>, null if it could not find the annotated class. 1581 */ 1582 public static QName getPortTypeName(Class<?> implOrSeiClass){ 1583 return getPortTypeName(implOrSeiClass, null, null); 1584 } 1585 1586 public static QName getPortTypeName(Class<?> implOrSeiClass, MetadataReader metadataReader){ 1587 return getPortTypeName(implOrSeiClass, null, metadataReader); 1588 } 1589 1590 public static QName getPortTypeName(Class<?> implOrSeiClass, String tns, MetadataReader reader){ 1591 assert(implOrSeiClass != null); 1592 WebService webService = getAnnotation(WebService.class, implOrSeiClass, reader); 1593 Class<?> clazz = implOrSeiClass; 1594 if (webService == null) 1595 throw new RuntimeModelerException("runtime.modeler.no.webservice.annotation", 1596 implOrSeiClass.getCanonicalName()); 1597 1598 if (!implOrSeiClass.isInterface()) { 1599 String epi = webService.endpointInterface(); 1600 if (epi.length() > 0) { 1601 try { 1602 clazz = Thread.currentThread().getContextClassLoader().loadClass(epi); 1603 } catch (ClassNotFoundException e) { 1604 throw new RuntimeModelerException("runtime.modeler.class.not.found", epi); 1605 } 1606 WebService ws = getAnnotation(WebService.class, clazz, reader); 1607 if (ws == null) { 1608 throw new RuntimeModelerException("runtime.modeler.endpoint.interface.no.webservice", 1609 webService.endpointInterface()); 1610 } 1611 } 1612 } 1613 1614 webService = getAnnotation(WebService.class, clazz, reader); 1615 String name = webService.name(); 1616 if(name.length() == 0){ 1617 name = clazz.getSimpleName(); 1618 } 1619 if (tns == null || "".equals(tns.trim())) tns = webService.targetNamespace(); 1620 if (tns.length() == 0) 1621 tns = getNamespace(clazz.getPackage().getName()); 1622 if (tns == null) { 1623 throw new RuntimeModelerException("runtime.modeler.no.package", clazz.getName()); 1624 } 1625 return new QName(tns, name); 1626 } 1627 1628 private ParameterBinding getBinding(String operation, String part, boolean isHeader, Mode mode){ 1629 if(binding == null){ 1630 if(isHeader) 1631 return ParameterBinding.HEADER; 1632 else 1633 return ParameterBinding.BODY; 1634 } 1635 QName opName = new QName(binding.getBinding().getPortType().getName().getNamespaceURI(), operation); 1636 return binding.getBinding().getBinding(opName, part, mode); 1637 } 1638 1639 private WSDLPart getPart(QName opName, String partName, Mode mode){ 1640 if(binding != null){ 1641 WSDLBoundOperation bo = binding.getBinding().get(opName); 1642 if(bo != null) 1643 return bo.getPart(partName, mode); 1644 } 1645 return null; 1646 } 1647 1648 /* 1649 * Returns true if an exception is a java.rmi.RemoteException or its subtype. 1650 * 1651 * @param exception 1652 * @return true if an exception is a java.rmi.RemoteException or its subtype, 1653 * false otherwise 1654 */ 1655 private boolean isRemoteException(Class<?> exception) { 1656 Class<?> c = exception; 1657 while (c != null && !REMOTE_EXCEPTION_CLASS.equals(c.getName())) { 1658 c = c.getSuperclass(); 1659 } 1660 return c != null; 1661 } 1662 1663 private static Boolean getBooleanSystemProperty(final String prop) { 1664 return AccessController.doPrivileged( 1665 new java.security.PrivilegedAction<Boolean>() { 1666 public Boolean run() { 1667 String value = System.getProperty(prop); 1668 return value != null ? Boolean.valueOf(value) : Boolean.FALSE; 1669 } 1670 } 1671 ); 1672 } 1673 1674 private static QName getReturnQName(Method method, WebResult webResult, XmlElement xmlElem) { 1675 String webResultName = null; 1676 if (webResult != null && webResult.name().length() > 0) { 1677 webResultName = webResult.name(); 1678 } 1679 String xmlElemName = null; 1680 if (xmlElem != null && !xmlElem.name().equals("##default")) { 1681 xmlElemName = xmlElem.name(); 1682 } 1683 if (xmlElemName != null && webResultName != null && !xmlElemName.equals(webResultName)) { 1684 throw new RuntimeModelerException("@XmlElement(name)="+xmlElemName+" and @WebResult(name)="+webResultName+" are different for method " +method); 1685 } 1686 String localPart = RETURN; 1687 if (webResultName != null) { 1688 localPart = webResultName; 1689 } else if (xmlElemName != null) { 1690 localPart = xmlElemName; 1691 } 1692 1693 String webResultNS = null; 1694 if (webResult != null && webResult.targetNamespace().length() > 0) { 1695 webResultNS = webResult.targetNamespace(); 1696 } 1697 String xmlElemNS = null; 1698 if (xmlElem != null && !xmlElem.namespace().equals("##default")) { 1699 xmlElemNS = xmlElem.namespace(); 1700 } 1701 if (xmlElemNS != null && webResultNS != null && !xmlElemNS.equals(webResultNS)) { 1702 throw new RuntimeModelerException("@XmlElement(namespace)="+xmlElemNS+" and @WebResult(targetNamespace)="+webResultNS+" are different for method " +method); 1703 } 1704 String ns = ""; 1705 if (webResultNS != null) { 1706 ns = webResultNS; 1707 } else if (xmlElemNS != null) { 1708 ns = xmlElemNS; 1709 } 1710 1711 return new QName(ns, localPart); 1712 } 1713 1714 private static QName getParameterQName(Method method, WebParam webParam, XmlElement xmlElem, String paramDefault) { 1715 String webParamName = null; 1716 if (webParam != null && webParam.name().length() > 0) { 1717 webParamName = webParam.name(); 1718 } 1719 String xmlElemName = null; 1720 if (xmlElem != null && !xmlElem.name().equals("##default")) { 1721 xmlElemName = xmlElem.name(); 1722 } 1723 if (xmlElemName != null && webParamName != null && !xmlElemName.equals(webParamName)) { 1724 throw new RuntimeModelerException("@XmlElement(name)="+xmlElemName+" and @WebParam(name)="+webParamName+" are different for method " +method); 1725 } 1726 String localPart = paramDefault; 1727 if (webParamName != null) { 1728 localPart = webParamName; 1729 } else if (xmlElemName != null) { 1730 localPart = xmlElemName; 1731 } 1732 1733 String webParamNS = null; 1734 if (webParam != null && webParam.targetNamespace().length() > 0) { 1735 webParamNS = webParam.targetNamespace(); 1736 } 1737 String xmlElemNS = null; 1738 if (xmlElem != null && !xmlElem.namespace().equals("##default")) { 1739 xmlElemNS = xmlElem.namespace(); 1740 } 1741 if (xmlElemNS != null && webParamNS != null && !xmlElemNS.equals(webParamNS)) { 1742 throw new RuntimeModelerException("@XmlElement(namespace)="+xmlElemNS+" and @WebParam(targetNamespace)="+webParamNS+" are different for method " +method); 1743 } 1744 String ns = ""; 1745 if (webParamNS != null) { 1746 ns = webParamNS; 1747 } else if (xmlElemNS != null) { 1748 ns = xmlElemNS; 1749 } 1750 1751 return new QName(ns, localPart); 1752 } 1753 1754 static public Class erasure(Type type) { 1755 return (Class)REFLECTION_NAVIGATOR.erasure(type); 1756 } 1757 }