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