src/share/jaxws_classes/com/sun/tools/internal/ws/processor/generator/JwsImplGenerator.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.*;
    29 import com.sun.tools.internal.ws.processor.model.*;
    30 import com.sun.tools.internal.ws.processor.model.java.JavaInterface;
    31 import com.sun.tools.internal.ws.processor.model.java.JavaMethod;
    32 import com.sun.tools.internal.ws.processor.model.java.JavaParameter;
    33 import com.sun.tools.internal.ws.processor.model.jaxb.JAXBTypeAndAnnotation;
    34 import com.sun.tools.internal.ws.wsdl.document.Definitions;
    35 import com.sun.tools.internal.ws.wsdl.document.Binding;
    36 import com.sun.tools.internal.ws.wsdl.document.soap.SOAP12Binding;
    37 import com.sun.tools.internal.ws.wsdl.document.soap.SOAPBinding;
    38 import com.sun.tools.internal.ws.wsdl.document.soap.SOAPConstants;
    39 import com.sun.tools.internal.ws.api.wsdl.TWSDLExtension;
    40 import com.sun.tools.internal.ws.wscompile.ErrorReceiver;
    41 import com.sun.tools.internal.ws.processor.model.ModelProperties;
    42 import com.sun.tools.internal.ws.wscompile.WsimportOptions;
    43 import com.sun.codemodel.internal.JClassAlreadyExistsException;
    44 import com.sun.xml.internal.ws.api.SOAPVersion;
    46 import com.sun.xml.internal.ws.util.ServiceFinder;
    48 import javax.jws.WebService;
    49 import javax.xml.ws.BindingType;
    50 import javax.xml.namespace.QName;
    51 import javax.xml.ws.Holder;
    52 import java.io.File;
    53 import java.text.MessageFormat;
    54 import java.util.ArrayList;
    55 import java.util.HashMap;
    56 import java.util.List;
    57 import java.util.Iterator;
    58 import java.util.Map;
    60 /**
    61  * Generator for placeholder JWS implementations
    62  *
    63  * @since 2.2.6
    64  */
    65 public final class JwsImplGenerator extends GeneratorBase {
    66         private static final Map<String, String> TRANSLATION_MAP = new HashMap<String, String>(
    67       1);
    68         static
    69   {
    70     TRANSLATION_MAP.put(SOAPConstants.URI_SOAP_TRANSPORT_HTTP,
    71                 javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING);
    72   }
    73         // save the generated impl files' info
    74         private final List<String> implFiles = new ArrayList<String>();
    76         public static List<String> generate(Model model, WsimportOptions options,
    77             ErrorReceiver receiver) {
    78                 // options check
    80                 // Generate it according the implDestDir option
    81                 if (options.implDestDir == null)
    82                         return null;
    84                 JwsImplGenerator jwsImplGenerator = new JwsImplGenerator();
    85                 jwsImplGenerator.init(model, options, receiver);
    86                 jwsImplGenerator.doGeneration();
    87                 // print a warning message while implFiles.size() is zero
    88                 if (jwsImplGenerator.implFiles.isEmpty()) {
    89                         StringBuilder msg = new StringBuilder();
    90                         if (options.implServiceName != null)
    91                                 msg.append("serviceName=[").append(options.implServiceName).append("] ");
    92                         if (options.implPortName != null)
    93                                 msg.append("portName=[").append(options.implPortName).append("] ");
    95                         if (msg.length() > 0)
    96                                 msg.append(", Not found in wsdl file.\n");
    98                         msg.append("No impl files generated!");
    99                         receiver.warning(null, msg.toString());
   100                 }
   102                 return jwsImplGenerator.implFiles;
   103         }
   105         /**
   106          * Move impl files to implDestDir
   107          */
   108         public static boolean moveToImplDestDir(List<String> gImplFiles,
   109             WsimportOptions options, ErrorReceiver receiver) {
   110                 if (options.implDestDir == null || gImplFiles == null
   111                     || gImplFiles.isEmpty())
   112                         return true;
   114                 List<ImplFile> generatedImplFiles = ImplFile.toImplFiles(gImplFiles);
   116                 try {
   117                         File implDestDir = makePackageDir(options);
   119                         File movedF;
   120                         File f;
   121                         for (ImplFile implF : generatedImplFiles) {
   122                                 movedF = findFile(options, implF.qualifiedName);
   123                                 if (movedF == null) {
   124                                         // should never happen
   125                                         receiver.warning(null, "Class " + implF.qualifiedName
   126                                             + " is not generated. Not moving.");
   127                                         return false;
   128                                 }
   130                                 f = new File(implDestDir, implF.name);
   131                             if (!movedF.equals(f)) {    //bug 10102169
   133                     if (f.exists())
   134                     {
   135                         if (!f.delete()){
   136                             receiver.error("Class " + implF.qualifiedName
   137                                     + " has existed in destImplDir, and it "
   138                                     + "can not be written!", null);
   139                         }
   140                     }
   141                     if(!movedF.renameTo(f))
   142                     {
   143                         throw new Exception();
   144                     }
   145                 }
   146                         }
   147                 } catch (Exception e) {
   148                         receiver.error("Moving WebService Impl files failed!", e);
   149                         return false;
   150                 }
   151                 return true;
   152         }
   154         private JwsImplGenerator() {
   155                 donotOverride = true;
   156         }
   158         @Override
   159         public void visit(Service service) {
   160                 QName serviceName = service.getName();
   161                 // process the ordered service only if it is defined
   162                 if (options.implServiceName != null
   163                     && !equalsNSOptional(options.implServiceName, serviceName))
   164                         return;
   166                 for (Port port : service.getPorts()) {
   167                         if (port.isProvider()) {
   168                                 continue; // Not generating for Provider based endpoint
   169                         }
   171                         // Generate the impl class name according to
   172                         // Xpath(/definitions/service/port[@name]);
   173                         QName portName = port.getName();
   175                         // process the ordered port only if it is defined
   176                         if (options.implPortName != null
   177                             && !equalsNSOptional(options.implPortName, portName))
   178                                 continue;
   180                         String simpleClassName = serviceName.getLocalPart() + "_"
   181                             + portName.getLocalPart() + "Impl";
   182                         String className = makePackageQualified(simpleClassName);
   183                         implFiles.add(className);
   185                         if (donotOverride && GeneratorUtil.classExists(options, className)) {
   186                                 log("Class " + className + " exists. Not overriding.");
   187                                 return;
   188                         }
   190                         JDefinedClass cls = null;
   191                         try {
   192                                 cls = getClass(className, ClassType.CLASS);
   193                         } catch (JClassAlreadyExistsException e) {
   194                                 log("Class " + className
   195                                     + " generates failed. JClassAlreadyExistsException[" + className
   196                                     + "].");
   197                                 return;
   198                         }
   200                         // Each serviceImpl will implements one port interface
   201                         JavaInterface portIntf = port.getJavaInterface();
   202                         String portClassName = Names.customJavaTypeClassName(portIntf);
   203                         JDefinedClass portCls = null;
   204                         try {
   205                                 portCls = getClass(portClassName, ClassType.INTERFACE);
   206                         } catch (JClassAlreadyExistsException e) {
   207                                 log("Class " + className
   208                                     + " generates failed. JClassAlreadyExistsException["
   209                                     + portClassName + "].");
   210                                 return;
   211                         }
   212                         cls._implements(portCls);
   214                         // create a default constructor
   215                         cls.constructor(JMod.PUBLIC);
   217                         // write class comment - JAXWS warning
   218                         JDocComment comment = cls.javadoc();
   220                         if (service.getJavaDoc() != null) {
   221                                 comment.add(service.getJavaDoc());
   222                                 comment.add("\n\n");
   223                         }
   225                         for (String doc : getJAXWSClassComment()) {
   226                                 comment.add(doc);
   227                         }
   229                         // @WebService
   230                         JAnnotationUse webServiceAnn = cls.annotate(cm.ref(WebService.class));
   231                         writeWebServiceAnnotation(service, port, webServiceAnn);
   233                         // @BindingType
   234                         JAnnotationUse bindingTypeAnn = cls.annotate(cm.ref(BindingType.class));
   235                         writeBindingTypeAnnotation(port, bindingTypeAnn);
   237                         // extra annotation
   238                         for( GeneratorExtension f : ServiceFinder.find(GeneratorExtension.class) ) {
   239                             f.writeWebServiceAnnotation(model, cm, cls, port);
   240                         }
   242                         // WebMethods
   243                         for (Operation operation : port.getOperations()) {
   244                                 JavaMethod method = operation.getJavaMethod();
   246                                 // @WebMethod
   247                                 JMethod m;
   248                                 JDocComment methodDoc;
   249                                 String methodJavaDoc = operation.getJavaDoc();
   250                                 if (method.getReturnType().getName().equals("void")) {
   251                                         m = cls.method(JMod.PUBLIC, void.class, method.getName());
   252                                         methodDoc = m.javadoc();
   253                                 } else {
   254                                         JAXBTypeAndAnnotation retType = method.getReturnType().getType();
   255                                         m = cls.method(JMod.PUBLIC, retType.getType(), method.getName());
   256                                         retType.annotate(m);
   257                                         methodDoc = m.javadoc();
   258                                         JCommentPart ret = methodDoc.addReturn();
   259                                         ret.add("returns " + retType.getName());
   260                                 }
   262                                 if (methodJavaDoc != null)
   263                                         methodDoc.add(methodJavaDoc);
   265                                 JClass holder = cm.ref(Holder.class);
   266                                 for (JavaParameter parameter : method.getParametersList()) {
   267                                         JVar var;
   268                                         JAXBTypeAndAnnotation paramType = parameter.getType().getType();
   269                                         if (parameter.isHolder()) {
   270                                                 var = m.param(holder.narrow(paramType.getType().boxify()),
   271                                                     parameter.getName());
   272                                         } else {
   273                                                 var = m.param(paramType.getType(), parameter.getName());
   274                                         }
   275                                         methodDoc.addParam(var);
   276                                 }
   278                                 com.sun.tools.internal.ws.wsdl.document.Operation wsdlOp = operation
   279                                     .getWSDLPortTypeOperation();
   280                                 for (Fault fault : operation.getFaultsSet()) {
   281                                         m._throws(fault.getExceptionClass());
   282                                         methodDoc.addThrows(fault.getExceptionClass());
   283                                         wsdlOp.putFault(fault.getWsdlFaultName(), fault.getExceptionClass());
   284                                 }
   285                                 m.body().block().directStatement("//replace with your impl here");
   286                                 m.body().block().directStatement(
   287                                     getReturnString(method.getReturnType().getName()));
   288                         }
   289                 }
   290         }
   292         /**
   293          * Generate return statement according to return type.
   294          *
   295          * @param type
   296          *          The method's return type
   297          * @return The whole return statement
   298          */
   299         private String getReturnString(String type) {
   300                 final String nullReturnStr = "return null;";
   301                 // complex type or array
   302                 if (type.indexOf('.') > -1 || type.indexOf('[') > -1) {
   303                         return nullReturnStr;
   304                 }
   306                 // primitive type
   307                 if (type.equals("void")) {
   308                         return "return;";
   309                 }
   310                 if (type.equals("boolean")) {
   311                         return "return false;";
   312                 }
   313                 if (type.equals("int") || type.equals("byte") || type.equals("short")
   314                     || type.equals("long") || type.equals("double") || type.equals("float")) {
   315                         return "return 0;";
   316                 }
   317                 if (type.equals("char")) {
   318                         return "return '0';";
   319                 }
   321                 return nullReturnStr;
   322         }
   324         /**
   325          *
   326          * @param service
   327          * @param port
   328          * @param webServiceAnn
   329          * @param options
   330          */
   331         private void writeWebServiceAnnotation(Service service, Port port,
   332             JAnnotationUse webServiceAnn) {
   333                 webServiceAnn.param("portName", port.getName().getLocalPart());
   334                 webServiceAnn.param("serviceName", service.getName().getLocalPart());
   335                 webServiceAnn.param("targetNamespace", service.getName().getNamespaceURI());
   336                 webServiceAnn.param("wsdlLocation", wsdlLocation);
   337                 webServiceAnn.param("endpointInterface", port.getJavaInterface().getName());
   338         }
   340         //CR373098 To transform the java class name as validate.
   341         private String transToValidJavaIdentifier(String s) {
   342             if (s == null) {
   343                 return null;
   344             }
   345             final int len = s.length();
   346             StringBuilder retSB = new StringBuilder();
   347             if (len == 0 || !Character.isJavaIdentifierStart(s.charAt(0))) {
   348                 retSB.append("J"); //update to a default start char
   349             } else {
   350                 retSB.append(s.charAt(0));
   351             }
   353             for (int i = 1; i < len; i++) {
   354                 if (!Character.isJavaIdentifierPart(s.charAt(i)))
   355                   ; //delete it if it is illegal //TODO: It might conflict "a-b" vs. "ab"
   356                 else {
   357                     retSB.append(s.charAt(i));
   358                 }
   359             }
   360             return retSB.toString();
   361         }
   363         private String makePackageQualified(String s) {
   364                 s = transToValidJavaIdentifier(s);
   365                 if (options.defaultPackage != null && !options.defaultPackage.equals("")) {
   366                         return options.defaultPackage + "." + s;
   367                 } else {
   368                         return s;
   369                 }
   370         }
   373         /**
   374          * TODO
   375          *
   376          * @param port
   377          * @param bindingTypeAnn
   378          */
   379         private void writeBindingTypeAnnotation(Port port,
   380             JAnnotationUse bindingTypeAnn) {
   381                 QName bName = (QName) port
   382                     .getProperty(ModelProperties.PROPERTY_WSDL_BINDING_NAME);
   383                 if (bName == null)
   384                         return;
   386                 String v = getBindingType(bName);
   388                 // TODO: How to decide if it is a mtom?
   389                 if (v != null) {
   390                         // transport = translate(transport);
   391                         bindingTypeAnn.param("value", v);
   392                 }
   394         }
   396         private String resolveBindingValue(TWSDLExtension wsdlext) {
   397                 if (wsdlext.getClass().equals(SOAPBinding.class)) {
   398                         SOAPBinding sb = (SOAPBinding) wsdlext;
   399                         if(javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING.equals(sb.getTransport()))
   400                                 return javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING;
   401                         else {
   402                             for(GeneratorExtension f : ServiceFinder.find(GeneratorExtension.class) ) {
   403                                 String bindingValue = f.getBindingValue(sb.getTransport(), SOAPVersion.SOAP_11);
   404                                 if(bindingValue!=null) {
   405                                     return bindingValue;
   406                                 }
   407                             }
   408                                 return javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING;
   409                         }
   410                 }
   411                 if (wsdlext.getClass().equals(SOAP12Binding.class)) {
   412                         SOAP12Binding sb = (SOAP12Binding) wsdlext;
   413                         if(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING.equals(sb.getTransport()))
   414                                 return javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING;
   415                     else {
   416                         for(GeneratorExtension f : ServiceFinder.find(GeneratorExtension.class) ) {
   417                             String bindingValue = f.getBindingValue(sb.getTransport(), SOAPVersion.SOAP_12);
   418                             if(bindingValue!=null) {
   419                                 return bindingValue;
   420                             }
   421                         }
   422                             return javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING;
   423                     }
   424                 }
   425                 return null;
   426         }
   428         private String getBindingType(QName bName) {
   430                 String value = null;
   431                 // process the bindings in definitions of model.entity
   432                 if (model.getEntity() instanceof Definitions) {
   433                         Definitions definitions = (Definitions) model.getEntity();
   434                         if (definitions != null) {
   435                                 Iterator bindings = definitions.bindings();
   436                                 if (bindings != null) {
   437                                         while (bindings.hasNext()) {
   438                                                 Binding binding = (Binding) bindings.next();
   439                                                 if (bName.getLocalPart().equals(binding.getName())
   440                                                     && bName.getNamespaceURI().equals(binding.getNamespaceURI())) {
   441                                                         List<TWSDLExtension> bindextends = (List<TWSDLExtension>) binding
   442                                                             .extensions();
   443                                                         for (TWSDLExtension wsdlext : bindextends) {
   444                                                                 value = resolveBindingValue(wsdlext);
   445                                                                 if (value != null)
   446                                                                         break;
   447                                                         }
   448                                                         break;
   449                                                 }
   450                                         }
   451                                 }
   452                         }
   453                 }
   455                 // process the bindings in whole document
   456                 if (value == null) {
   457                         if (model.getEntity() instanceof Definitions) {
   458                             Definitions definitions = (Definitions) model.getEntity();
   459                             Binding b = (Binding) definitions.resolveBindings().get(bName);
   460                             if (b != null) {
   461                                 List<TWSDLExtension> bindextends = (List<TWSDLExtension>) b
   462                                     .extensions();
   463                                 for (TWSDLExtension wsdlext : bindextends) {
   464                                     value = resolveBindingValue(wsdlext);
   465                                     if (value != null)
   466                                     break;
   467                                 }
   468                             }
   469                         }
   470                 }
   472                 return value;
   473         }
   475   /**
   476    * Since the SOAP 1.1 binding transport URI defined in WSDL 1.1 specification
   477    * is different with the SOAPBinding URI defined by JAX-WS 2.0 specification.
   478    * We must translate the wsdl version into JAX-WS version. If the given
   479    * transport URI is NOT one of the predefined transport URIs, it is returned
   480    * as is.
   481    *
   482    * @param transportURI
   483    *          retrieved from WSDL
   484    * @return Standard BindingType URI defined by JAX-WS 2.0 specification.
   485    */
   486 //  private String translate(String transportURI)
   487 //  {
   488 //    String translatedBindingId = TRANSLATION_MAP.get(transportURI);
   489 //    if (translatedBindingId == null)
   490 //      translatedBindingId = transportURI;
   491 //
   492 //    return translatedBindingId;
   493 //  }
   495         /*****************************************************************************
   496          * Inner classes definition
   497          */
   498         static final class ImplFile {
   499                 public String qualifiedName; // package+"."+simpleClassName + ".java"
   501                 public String name; // simpleClassName + ".java"
   503                 private ImplFile(String qualifiedClassName) {
   504                         this.qualifiedName = qualifiedClassName + ".java";
   506                         String simpleClassName = qualifiedClassName;
   507                         int i = qualifiedClassName.lastIndexOf(".");
   508                         if (i != -1)
   509                                 simpleClassName = qualifiedClassName.substring(i + 1);
   511                         this.name = simpleClassName + ".java";
   512                 }
   514                 public static List<ImplFile> toImplFiles(List<String> qualifiedClassNames) {
   515                         List<ImplFile> ret = new ArrayList<ImplFile>();
   517                         for (String qualifiedClassName : qualifiedClassNames)
   518                                 ret.add(new ImplFile(qualifiedClassName));
   520                         return ret;
   521                 }
   522         }
   524         /*****************************************************************************
   525          * Other utility methods
   526          */
   528         private static File makePackageDir(WsimportOptions options) {
   529                 File ret = null;
   530                 if (options.defaultPackage != null && !options.defaultPackage.equals("")) {
   531                         String subDir = options.defaultPackage.replace('.', '/');
   532                         ret = new File(options.implDestDir, subDir);
   533                 } else {
   534                         ret = options.implDestDir;
   535                 }
   537                 boolean created = ret.mkdirs();
   538                 if (options.verbose && !created) {
   539                     System.out.println(MessageFormat.format("Directory not created: {0}", ret));
   540                 }
   541                 return ret;
   542         }
   544         private static String getQualifiedFileName(String canonicalBaseDir, File f)
   545             throws java.io.IOException {
   546                 String fp = f.getCanonicalPath();
   547                 if (fp == null)
   548                         return null;
   549                 fp = fp.replace(canonicalBaseDir, "");
   550                 fp = fp.replace('\\', '.');
   551                 fp = fp.replace('/', '.');
   552                 if (fp.startsWith("."))
   553                         fp = fp.substring(1);
   555                 return fp;
   556         }
   558         private static File findFile(WsimportOptions options, String qualifiedFileName)
   559             throws java.io.IOException {
   560                 String baseDir = options.sourceDir.getCanonicalPath();
   561                 String fp = null;
   562                 for (File f : options.getGeneratedFiles()) {
   563                         fp = getQualifiedFileName(baseDir, f);
   564                         if (qualifiedFileName.equals(fp))
   565                                 return f;
   566                 }
   568                 return null;
   569         }
   571         private static boolean equalsNSOptional(String strQName, QName checkQN) {
   572                 if (strQName == null)
   573                         return false;
   574                 strQName = strQName.trim();
   575                 QName reqQN = QName.valueOf(strQName);
   577                 if (reqQN.getNamespaceURI() == null || reqQN.getNamespaceURI().equals(""))
   578                         return reqQN.getLocalPart().equals(checkQN.getLocalPart());
   580                 return reqQN.equals(checkQN);
   581         }
   582 }

mercurial