src/share/jaxws_classes/com/sun/xml/internal/ws/model/RuntimeModeler.java

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
child 368
0989ad8c0860
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

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

mercurial