src/share/jaxws_classes/com/sun/tools/internal/ws/processor/generator/ServiceGenerator.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 1997, 2013, 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  */
    26 package com.sun.tools.internal.ws.processor.generator;
    28 import com.sun.codemodel.internal.ClassType;
    29 import com.sun.codemodel.internal.JAnnotationUse;
    30 import com.sun.codemodel.internal.JBlock;
    31 import com.sun.codemodel.internal.JCatchBlock;
    32 import com.sun.codemodel.internal.JClass;
    33 import com.sun.codemodel.internal.JClassAlreadyExistsException;
    34 import com.sun.codemodel.internal.JCommentPart;
    35 import com.sun.codemodel.internal.JConditional;
    36 import com.sun.codemodel.internal.JDefinedClass;
    37 import com.sun.codemodel.internal.JDocComment;
    38 import com.sun.codemodel.internal.JExpr;
    39 import com.sun.codemodel.internal.JFieldVar;
    40 import com.sun.codemodel.internal.JInvocation;
    41 import com.sun.codemodel.internal.JMethod;
    42 import com.sun.codemodel.internal.JMod;
    43 import com.sun.codemodel.internal.JTryBlock;
    44 import com.sun.codemodel.internal.JType;
    45 import com.sun.codemodel.internal.JVar;
    46 import com.sun.tools.internal.ws.processor.model.Model;
    47 import com.sun.tools.internal.ws.processor.model.ModelProperties;
    48 import com.sun.tools.internal.ws.processor.model.Port;
    49 import com.sun.tools.internal.ws.processor.model.Service;
    50 import com.sun.tools.internal.ws.processor.model.java.JavaInterface;
    51 import com.sun.tools.internal.ws.resources.GeneratorMessages;
    52 import com.sun.tools.internal.ws.wscompile.ErrorReceiver;
    53 import com.sun.tools.internal.ws.wscompile.Options;
    54 import com.sun.tools.internal.ws.wscompile.WsimportOptions;
    55 import com.sun.tools.internal.ws.wsdl.document.PortType;
    56 import com.sun.xml.internal.ws.spi.db.BindingHelper;
    58 import org.xml.sax.Locator;
    60 import javax.xml.namespace.QName;
    61 import javax.xml.ws.WebEndpoint;
    62 import javax.xml.ws.WebServiceClient;
    63 import javax.xml.ws.WebServiceFeature;
    64 import javax.xml.ws.WebServiceException;
    65 import java.net.MalformedURLException;
    66 import java.net.URL;
    68 import com.sun.xml.internal.ws.util.ServiceFinder;
    69 import java.util.Locale;
    71 /**
    72  * @author WS Development Team
    73  * @author Jitendra Kotamraju
    74  */
    75 public class ServiceGenerator extends GeneratorBase {
    77     public static void generate(Model model, WsimportOptions options, ErrorReceiver receiver) {
    78         ServiceGenerator serviceGenerator = new ServiceGenerator(model, options, receiver);
    79         serviceGenerator.doGeneration();
    80     }
    82     private ServiceGenerator(Model model, WsimportOptions options, ErrorReceiver receiver) {
    83         init(model, options, receiver);
    84     }
    86     @Override
    87     public void visit(Service service) {
    88         JavaInterface intf = service.getJavaInterface();
    89         String className = Names.customJavaTypeClassName(intf);
    90         if (donotOverride && GeneratorUtil.classExists(options, className)) {
    91             log("Class " + className + " exists. Not overriding.");
    92             return;
    93         }
    95         JDefinedClass cls;
    96         try {
    97             cls = getClass(className, ClassType.CLASS);
    98         } catch (JClassAlreadyExistsException e) {
    99             receiver.error(service.getLocator(), GeneratorMessages.GENERATOR_SERVICE_CLASS_ALREADY_EXIST(className, service.getName()));
   100             return;
   101         }
   103         cls._extends(javax.xml.ws.Service.class);
   104         String serviceFieldName = BindingHelper.mangleNameToClassName(service.getName().getLocalPart()).toUpperCase(Locale.ENGLISH);
   105         String wsdlLocationName = serviceFieldName + "_WSDL_LOCATION";
   106         JFieldVar urlField = cls.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, URL.class, wsdlLocationName);
   108         JFieldVar exField = cls.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, WebServiceException.class, serviceFieldName+"_EXCEPTION");
   111         String serviceName = serviceFieldName + "_QNAME";
   112         cls.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, QName.class, serviceName,
   113             JExpr._new(cm.ref(QName.class)).arg(service.getName().getNamespaceURI()).arg(service.getName().getLocalPart()));
   115         JClass qNameCls = cm.ref(QName.class);
   116         JInvocation inv;
   117         inv = JExpr._new(qNameCls);
   118         inv.arg("namespace");
   119         inv.arg("localpart");
   121         if (options.useBaseResourceAndURLToLoadWSDL) {
   122             writeClassLoaderBaseResourceWSDLLocation(className, cls, urlField, exField);
   123         } else if (wsdlLocation.startsWith("http://") || wsdlLocation.startsWith("https://") || wsdlLocation.startsWith("file:/")) {
   124             writeAbsWSDLLocation(cls, urlField, exField);
   125         } else if (wsdlLocation.startsWith("META-INF/")) {
   126             writeClassLoaderResourceWSDLLocation(className, cls, urlField, exField);
   127         } else {
   128             writeResourceWSDLLocation(className, cls, urlField, exField);
   129         }
   131         //write class comment - JAXWS warning
   132         JDocComment comment = cls.javadoc();
   134         if (service.getJavaDoc() != null) {
   135             comment.add(service.getJavaDoc());
   136             comment.add("\n\n");
   137         }
   139         for (String doc : getJAXWSClassComment()) {
   140             comment.add(doc);
   141         }
   143         // Generating constructor
   144         // for e.g:  public ExampleService()
   145         JMethod constructor1 = cls.constructor(JMod.PUBLIC);
   146         String constructor1Str = String.format("super(__getWsdlLocation(), %s);", serviceName);
   147         constructor1.body().directStatement(constructor1Str);
   149         // Generating constructor
   150         // for e.g:  public ExampleService(WebServiceFeature ... features)
   151         if (options.target.isLaterThan(Options.Target.V2_2)) {
   152             JMethod constructor2 = cls.constructor(JMod.PUBLIC);
   153             constructor2.varParam(WebServiceFeature.class, "features");
   154             String constructor2Str = String.format("super(__getWsdlLocation(), %s, features);", serviceName);
   155             constructor2.body().directStatement(constructor2Str);
   156         }
   158         // Generating constructor
   159         // for e.g:  public ExampleService(URL wsdlLocation)
   160         if (options.target.isLaterThan(Options.Target.V2_2)) {
   161             JMethod constructor3 = cls.constructor(JMod.PUBLIC);
   162             constructor3.param(URL.class, "wsdlLocation");
   163             String constructor3Str = String.format("super(wsdlLocation, %s);", serviceName);
   164             constructor3.body().directStatement(constructor3Str);
   165         }
   167         // Generating constructor
   168         // for e.g:  public ExampleService(URL wsdlLocation, WebServiceFeature ... features)
   169         if (options.target.isLaterThan(Options.Target.V2_2)) {
   170             JMethod constructor4 = cls.constructor(JMod.PUBLIC);
   171             constructor4.param(URL.class, "wsdlLocation");
   172             constructor4.varParam(WebServiceFeature.class, "features");
   173             String constructor4Str = String.format("super(wsdlLocation, %s, features);", serviceName);
   174             constructor4.body().directStatement(constructor4Str);
   175         }
   177         // Generating constructor
   178         // for e.g:  public ExampleService(URL wsdlLocation, QName serviceName)
   179         JMethod constructor5 = cls.constructor(JMod.PUBLIC);
   180         constructor5.param(URL.class, "wsdlLocation");
   181         constructor5.param(QName.class, "serviceName");
   182         constructor5.body().directStatement("super(wsdlLocation, serviceName);");
   184         // Generating constructor
   185         // for e.g:  public ExampleService(URL, QName, WebServiceFeature ...)
   186         if (options.target.isLaterThan(Options.Target.V2_2)) {
   187             JMethod constructor6 = cls.constructor(JMod.PUBLIC);
   188             constructor6.param(URL.class, "wsdlLocation");
   189             constructor6.param(QName.class, "serviceName");
   190             constructor6.varParam(WebServiceFeature.class, "features");
   191             constructor6.body().directStatement("super(wsdlLocation, serviceName, features);");
   192         }
   194         //@WebService
   195         JAnnotationUse webServiceClientAnn = cls.annotate(cm.ref(WebServiceClient.class));
   196         writeWebServiceClientAnnotation(service, webServiceClientAnn);
   198         // additional annotations
   199         for (GeneratorExtension f:ServiceFinder.find(GeneratorExtension.class)) {
   200             f.writeWebServiceClientAnnotation(options, cm, cls);
   201         }
   204         //@HandlerChain
   205         writeHandlerConfig(Names.customJavaTypeClassName(service.getJavaInterface()), cls, options);
   207         for (Port port : service.getPorts()) {
   208             if (port.isProvider()) {
   209                 continue;  // No getXYZPort() for porvider based endpoint
   210             }
   212             //Get the SEI class
   213             JType retType;
   214             try {
   215                 retType = getClass(port.getJavaInterface().getName(), ClassType.INTERFACE);
   216             } catch (JClassAlreadyExistsException e) {
   217                 QName portTypeName =
   218                         (QName) port.getProperty(
   219                                 ModelProperties.PROPERTY_WSDL_PORT_TYPE_NAME);
   220                 Locator loc = null;
   221                 if (portTypeName != null) {
   222                     PortType pt = port.portTypes.get(portTypeName);
   223                     if (pt != null) {
   224                         loc = pt.getLocator();
   225                     }
   226                 }
   227                 receiver.error(loc, GeneratorMessages.GENERATOR_SEI_CLASS_ALREADY_EXIST(port.getJavaInterface().getName(), portTypeName));
   228                 return;
   229             }
   231             //write getXyzPort()
   232             writeDefaultGetPort(port, retType, cls);
   234             //write getXyzPort(WebServicesFeature...)
   235             if (options.target.isLaterThan(Options.Target.V2_1)) {
   236                 writeGetPort(port, retType, cls);
   237             }
   238         }
   240         writeGetWsdlLocation(cm.ref(URL.class), cls, urlField, exField);
   241     }
   243     private void writeGetPort(Port port, JType retType, JDefinedClass cls) {
   244         JMethod m = cls.method(JMod.PUBLIC, retType, port.getPortGetter());
   245         JDocComment methodDoc = m.javadoc();
   246         if (port.getJavaDoc() != null) {
   247             methodDoc.add(port.getJavaDoc());
   248         }
   249         JCommentPart ret = methodDoc.addReturn();
   250         JCommentPart paramDoc = methodDoc.addParam("features");
   251         paramDoc.append("A list of ");
   252         paramDoc.append("{@link " + WebServiceFeature.class.getName() + "}");
   253         paramDoc.append("to configure on the proxy.  Supported features not in the <code>features</code> parameter will have their default values.");
   254         ret.add("returns " + retType.name());
   255         m.varParam(WebServiceFeature.class, "features");
   256         JBlock body = m.body();
   257         StringBuilder statement = new StringBuilder("return ");
   258         statement.append("super.getPort(new QName(\"").append(port.getName().getNamespaceURI()).append("\", \"").append(port.getName().getLocalPart()).append("\"), ");
   259         statement.append(retType.name());
   260         statement.append(".class, features);");
   261         body.directStatement(statement.toString());
   262         writeWebEndpoint(port, m);
   263     }
   266     /*
   267        Generates the code to create URL for absolute WSDL location
   269        for e.g.:
   270        static {
   271            URL url = null;
   272            WebServiceException e = null;
   273            try {
   274                 url = new URL("http://ExampleService.wsdl");
   275            } catch (MalformedURLException ex) {
   276                 e = new WebServiceException(ex);
   277            }
   278            EXAMPLESERVICE_WSDL_LOCATION = url;
   279            EXAMPLESERVICE_EXCEPTION = e;
   280        }
   281     */
   282     private void writeAbsWSDLLocation(JDefinedClass cls, JFieldVar urlField, JFieldVar exField) {
   283         JBlock staticBlock = cls.init();
   284         JVar urlVar = staticBlock.decl(cm.ref(URL.class), "url", JExpr._null());
   285         JVar exVar = staticBlock.decl(cm.ref(WebServiceException.class), "e", JExpr._null());
   287         JTryBlock tryBlock = staticBlock._try();
   288         tryBlock.body().assign(urlVar, JExpr._new(cm.ref(URL.class)).arg(wsdlLocation));
   289         JCatchBlock catchBlock = tryBlock._catch(cm.ref(MalformedURLException.class));
   290         catchBlock.param("ex");
   291         catchBlock.body().assign(exVar, JExpr._new(cm.ref(WebServiceException.class)).arg(JExpr.ref("ex")));
   293         staticBlock.assign(urlField, urlVar);
   294         staticBlock.assign(exField, exVar);
   295     }
   297     /*
   298        Generates the code to create URL for WSDL location as resource
   300        for e.g.:
   301        static {
   302            EXAMPLESERVICE_WSDL_LOCATION = ExampleService.class.getResource(...);
   303            Exception e = null;
   304            if (EXAMPLESERVICE_WSDL_LOCATION == null) {
   305                e = new WebServiceException("...");
   306            }
   307            EXAMPLESERVICE_EXCEPTION = e;
   308        }
   309      */
   310     private void writeResourceWSDLLocation(String className, JDefinedClass cls, JFieldVar urlField, JFieldVar exField) {
   311         JBlock staticBlock = cls.init();
   312         staticBlock.assign(urlField, JExpr.dotclass(cm.ref(className)).invoke("getResource").arg(wsdlLocation));
   313         JVar exVar = staticBlock.decl(cm.ref(WebServiceException.class), "e", JExpr._null());
   314         JConditional ifBlock = staticBlock._if(urlField.eq(JExpr._null()));
   315         ifBlock._then().assign(exVar, JExpr._new(cm.ref(WebServiceException.class)).arg(
   316                 "Cannot find "+JExpr.quotify('\'', wsdlLocation)+" wsdl. Place the resource correctly in the classpath."));
   317         staticBlock.assign(exField, exVar);
   318     }
   320     /*
   321        Generates the code to create URL for WSDL location as classloader resource
   323        for e.g.:
   324        static {
   325            EXAMPLESERVICE_WSDL_LOCATION = ExampleService.class.getClassLoader().getResource(...);
   326            Exception e = null;
   327            if (EXAMPLESERVICE_WSDL_LOCATION == null) {
   328                e = new WebServiceException("...");
   329            }
   330            EXAMPLESERVICE_EXCEPTION = e;
   331        }
   332      */
   333     private void writeClassLoaderResourceWSDLLocation(String className, JDefinedClass cls, JFieldVar urlField, JFieldVar exField) {
   334         JBlock staticBlock = cls.init();
   335         staticBlock.assign(urlField, JExpr.dotclass(cm.ref(className)).invoke("getClassLoader").invoke("getResource").arg(wsdlLocation));
   336         JVar exVar = staticBlock.decl(cm.ref(WebServiceException.class), "e", JExpr._null());
   337         JConditional ifBlock = staticBlock._if(urlField.eq(JExpr._null()));
   338         ifBlock._then().assign(exVar, JExpr._new(cm.ref(WebServiceException.class)).arg(
   339                 "Cannot find "+JExpr.quotify('\'', wsdlLocation)+" wsdl. Place the resource correctly in the classpath."));
   340         staticBlock.assign(exField, exVar);
   341     }
   343     /*
   344        Generates the code to create URL for WSDL location from classloader base resource
   346        for e.g.:
   347        static {
   348            Exception e = null;
   349            URL url = null;
   350            try {
   351                url = new URL(ExampleService.class.getClassLoader().getResource("."), ...);
   352            } catch (MalformedURLException murl) {
   353                e = new WebServiceException(murl);
   354            }
   355            EXAMPLESERVICE_WSDL_LOCATION = url;
   356            EXAMPLESERVICE_EXCEPTION = e;
   357        }
   358      */
   359      private void writeClassLoaderBaseResourceWSDLLocation(String className, JDefinedClass cls, JFieldVar urlField, JFieldVar exField) {
   360          JBlock staticBlock = cls.init();
   361          JVar exVar = staticBlock.decl(cm.ref(WebServiceException.class), "e", JExpr._null());
   362          JVar urlVar = staticBlock.decl(cm.ref(URL.class), "url", JExpr._null());
   363          JTryBlock tryBlock = staticBlock._try();
   364          tryBlock.body().assign(urlVar, JExpr._new(cm.ref(URL.class)).arg(JExpr.dotclass(cm.ref(className)).invoke("getResource").arg(".")).arg(wsdlLocation));
   365          JCatchBlock catchBlock = tryBlock._catch(cm.ref(MalformedURLException.class));
   366          JVar murlVar = catchBlock.param("murl");
   367          catchBlock.body().assign(exVar, JExpr._new(cm.ref(WebServiceException.class)).arg(murlVar));
   368          staticBlock.assign(urlField, urlVar);
   369          staticBlock.assign(exField, exVar);
   370      }
   372     /*
   373        Generates code that gives wsdl URL. If there is an exception in
   374        creating the URL, it throws an exception.
   376        for example:
   378        private URL __getWsdlLocation() {
   379            if (EXAMPLESERVICE_EXCEPTION != null) {
   380                throw EXAMPLESERVICE_EXCEPTION;
   381            }
   382            return EXAMPLESERVICE_WSDL_LOCATION;
   383        }
   384      */
   385     private void writeGetWsdlLocation(JType retType, JDefinedClass cls, JFieldVar urlField, JFieldVar exField) {
   386         JMethod m = cls.method(JMod.PRIVATE|JMod.STATIC , retType, "__getWsdlLocation");
   387         JConditional ifBlock = m.body()._if(exField.ne(JExpr._null()));
   388         ifBlock._then()._throw(exField);
   389         m.body()._return(urlField);
   390     }
   392     private void writeDefaultGetPort(Port port, JType retType, JDefinedClass cls) {
   393         String portGetter = port.getPortGetter();
   394         JMethod m = cls.method(JMod.PUBLIC, retType, portGetter);
   395         JDocComment methodDoc = m.javadoc();
   396         if (port.getJavaDoc() != null) {
   397             methodDoc.add(port.getJavaDoc());
   398         }
   399         JCommentPart ret = methodDoc.addReturn();
   400         ret.add("returns " + retType.name());
   401         JBlock body = m.body();
   402         StringBuilder statement = new StringBuilder("return ");
   403         statement.append("super.getPort(new QName(\"").append(port.getName().getNamespaceURI()).append("\", \"").append(port.getName().getLocalPart()).append("\"), ");
   404         statement.append(retType.name());
   405         statement.append(".class);");
   406         body.directStatement(statement.toString());
   407         writeWebEndpoint(port, m);
   408     }
   410     private void writeWebServiceClientAnnotation(Service service, JAnnotationUse wsa) {
   411         String serviceName = service.getName().getLocalPart();
   412         String serviceNS = service.getName().getNamespaceURI();
   413         wsa.param("name", serviceName);
   414         wsa.param("targetNamespace", serviceNS);
   415         wsa.param("wsdlLocation", wsdlLocation);
   416     }
   418     private void writeWebEndpoint(Port port, JMethod m) {
   419         JAnnotationUse webEndpointAnn = m.annotate(cm.ref(WebEndpoint.class));
   420         webEndpointAnn.param("name", port.getName().getLocalPart());
   421     }
   422 }

mercurial