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