Package com.sun.tools.ws.processor.generator

Source Code of com.sun.tools.ws.processor.generator.JwsImplGenerator$ImplFile

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License.  You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

package com.sun.tools.ws.processor.generator;

import com.sun.codemodel.*;
import com.sun.tools.ws.processor.model.*;
import com.sun.tools.ws.processor.model.java.JavaInterface;
import com.sun.tools.ws.processor.model.java.JavaMethod;
import com.sun.tools.ws.processor.model.java.JavaParameter;
import com.sun.tools.ws.processor.model.jaxb.JAXBTypeAndAnnotation;
import com.sun.tools.ws.wsdl.document.Definitions;
import com.sun.tools.ws.wsdl.document.Binding;
import com.sun.tools.ws.wsdl.document.soap.SOAP12Binding;
import com.sun.tools.ws.wsdl.document.soap.SOAPBinding;
import com.sun.tools.ws.wsdl.document.soap.SOAPConstants;
import com.sun.tools.ws.api.wsdl.TWSDLExtension;
import com.sun.tools.ws.wscompile.ErrorReceiver;
import com.sun.tools.ws.processor.model.ModelProperties;
import com.sun.tools.ws.wscompile.WsimportOptions;
import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.xml.ws.api.SOAPVersion;

import com.sun.xml.ws.util.ServiceFinder;

import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.xml.namespace.QName;
import javax.xml.ws.Holder;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Iterator;
import java.util.Map;

/**
* Generator for placeholder JWS implementations
*
* @since 2.2.6
*/
public final class JwsImplGenerator extends GeneratorBase {
  private static final Map<String, String> TRANSLATION_MAP = new HashMap<String, String>(
      1);
  static
  {
    TRANSLATION_MAP.put(SOAPConstants.URI_SOAP_TRANSPORT_HTTP,
        javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING);
  }
  // save the generated impl files' info
  private final List<String> implFiles = new ArrayList<String>();

  public static List<String> generate(Model model, WsimportOptions options,
      ErrorReceiver receiver) {
    // options check

    // Generate it according the implDestDir option
    if (options.implDestDir == null)
      return null;

    JwsImplGenerator jwsImplGenerator = new JwsImplGenerator();
    jwsImplGenerator.init(model, options, receiver);
    jwsImplGenerator.doGeneration();
    // print a warning message while implFiles.size() is zero
    if (jwsImplGenerator.implFiles.isEmpty()) {
      StringBuilder msg = new StringBuilder();
      if (options.implServiceName != null)
        msg.append("serviceName=[").append(options.implServiceName).append("] ");
      if (options.implPortName != null)
        msg.append("portName=[").append(options.implPortName).append("] ");

      if (msg.length() > 0)
        msg.append(", Not found in wsdl file.\n");

      msg.append("No impl files generated!");
      receiver.warning(null, msg.toString());
    }

    return jwsImplGenerator.implFiles;
  }

  /**
   * Move impl files to implDestDir
   */
  public static boolean moveToImplDestDir(List<String> gImplFiles,
      WsimportOptions options, ErrorReceiver receiver) {
    if (options.implDestDir == null || gImplFiles == null
        || gImplFiles.isEmpty())
      return true;

    List<ImplFile> generatedImplFiles = ImplFile.toImplFiles(gImplFiles);

    try {
      File implDestDir = makePackageDir(options);

      File movedF;
      File f;
      for (ImplFile implF : generatedImplFiles) {
        movedF = findFile(options, implF.qualifiedName);
        if (movedF == null) {
          // should never happen
          receiver.warning(null, "Class " + implF.qualifiedName
              + " is not generated. Not moving.");
          return false;
        }
       
        f = new File(implDestDir, implF.name);
          if (!movedF.equals(f)) {    //bug 10102169
         
                    if (f.exists())
                    {
                        if (!f.delete()){
                            receiver.error("Class " + implF.qualifiedName
                                    + " has existed in destImplDir, and it "
                                    + "can not be written!", null);
                        }
                    }
                    if(!movedF.renameTo(f))
                    {
                        throw new Exception();
                    }
                }
      }
    } catch (Exception e) {
      receiver.error("Moving WebService Impl files failed!", e);
      return false;
    }
    return true;
  }

  private JwsImplGenerator() {
    donotOverride = true;
  }

  @Override
  public void visit(Service service) {
    QName serviceName = service.getName();
    // process the ordered service only if it is defined
    if (options.implServiceName != null
        && !equalsNSOptional(options.implServiceName, serviceName))
      return;

    for (Port port : service.getPorts()) {
      if (port.isProvider()) {
        continue; // Not generating for Provider based endpoint
      }

      // Generate the impl class name according to
      // Xpath(/definitions/service/port[@name]);
      QName portName = port.getName();

      // process the ordered port only if it is defined
      if (options.implPortName != null
          && !equalsNSOptional(options.implPortName, portName))
        continue;

      String simpleClassName = serviceName.getLocalPart() + "_"
          + portName.getLocalPart() + "Impl";
      String className = makePackageQualified(simpleClassName);
      implFiles.add(className);

      if (donotOverride && GeneratorUtil.classExists(options, className)) {
        log("Class " + className + " exists. Not overriding.");
        return;
      }

      JDefinedClass cls = null;
      try {
        cls = getClass(className, ClassType.CLASS);
      } catch (JClassAlreadyExistsException e) {
        log("Class " + className
            + " generates failed. JClassAlreadyExistsException[" + className
            + "].");
        return;
      }

      // Each serviceImpl will implements one port interface
      JavaInterface portIntf = port.getJavaInterface();
      String portClassName = Names.customJavaTypeClassName(portIntf);
      JDefinedClass portCls = null;
      try {
        portCls = getClass(portClassName, ClassType.INTERFACE);
      } catch (JClassAlreadyExistsException e) {
        log("Class " + className
            + " generates failed. JClassAlreadyExistsException["
            + portClassName + "].");
        return;
      }
      cls._implements(portCls);

      // create a default constructor
      cls.constructor(JMod.PUBLIC);

      // write class comment - JAXWS warning
      JDocComment comment = cls.javadoc();

      if (service.getJavaDoc() != null) {
        comment.add(service.getJavaDoc());
        comment.add("\n\n");
      }

      for (String doc : getJAXWSClassComment()) {
        comment.add(doc);
      }

      // @WebService
      JAnnotationUse webServiceAnn = cls.annotate(cm.ref(WebService.class));
      writeWebServiceAnnotation(service, port, webServiceAnn);

      // @BindingType
      JAnnotationUse bindingTypeAnn = cls.annotate(cm.ref(BindingType.class));
      writeBindingTypeAnnotation(port, bindingTypeAnn);

                        // extra annotation                 
                        for( GeneratorExtension f : ServiceFinder.find(GeneratorExtension.class) ) {
                f.writeWebServiceAnnotation(model, cm, cls, port);
            }

      // WebMethods
      for (Operation operation : port.getOperations()) {
        JavaMethod method = operation.getJavaMethod();

        // @WebMethod
        JMethod m;
        JDocComment methodDoc;
        String methodJavaDoc = operation.getJavaDoc();
        if (method.getReturnType().getName().equals("void")) {
          m = cls.method(JMod.PUBLIC, void.class, method.getName());
          methodDoc = m.javadoc();
        } else {
          JAXBTypeAndAnnotation retType = method.getReturnType().getType();
          m = cls.method(JMod.PUBLIC, retType.getType(), method.getName());
          retType.annotate(m);
          methodDoc = m.javadoc();
          JCommentPart ret = methodDoc.addReturn();
          ret.add("returns " + retType.getName());
        }

        if (methodJavaDoc != null)
          methodDoc.add(methodJavaDoc);

        JClass holder = cm.ref(Holder.class);
        for (JavaParameter parameter : method.getParametersList()) {
          JVar var;
          JAXBTypeAndAnnotation paramType = parameter.getType().getType();
          if (parameter.isHolder()) {
            var = m.param(holder.narrow(paramType.getType().boxify()),
                parameter.getName());
          } else {
            var = m.param(paramType.getType(), parameter.getName());
          }
          methodDoc.addParam(var);
        }

        com.sun.tools.ws.wsdl.document.Operation wsdlOp = operation
            .getWSDLPortTypeOperation();
        for (Fault fault : operation.getFaultsSet()) {
          m._throws(fault.getExceptionClass());
          methodDoc.addThrows(fault.getExceptionClass());
          wsdlOp.putFault(fault.getWsdlFaultName(), fault.getExceptionClass());
        }
        m.body().block().directStatement("//replace with your impl here");
        m.body().block().directStatement(
            getReturnString(method.getReturnType().getName()));
      }
    }
  }

  /**
   * Generate return statement according to return type.
   *
   * @param type
   *          The method's return type
   * @return The whole return statement
   */
  private String getReturnString(String type) {
    final String nullReturnStr = "return null;";
    // complex type or array
    if (type.indexOf('.') > -1 || type.indexOf('[') > -1) {
      return nullReturnStr;
    }

    // primitive type
    if (type.equals("void")) {
      return "return;";
    }
    if (type.equals("boolean")) {
      return "return false;";
    }
    if (type.equals("int") || type.equals("byte") || type.equals("short")
        || type.equals("long") || type.equals("double") || type.equals("float")) {
      return "return 0;";
    }
    if (type.equals("char")) {
      return "return '0';";
    }

    return nullReturnStr;
  }

  /**
   *
   * @param service
   * @param port
   * @param webServiceAnn
   * @param options
   */
  private void writeWebServiceAnnotation(Service service, Port port,
      JAnnotationUse webServiceAnn) {
    webServiceAnn.param("portName", port.getName().getLocalPart());
    webServiceAnn.param("serviceName", service.getName().getLocalPart());
    webServiceAnn.param("targetNamespace", service.getName().getNamespaceURI());
    webServiceAnn.param("wsdlLocation", wsdlLocation);
    webServiceAnn.param("endpointInterface", port.getJavaInterface().getName());
  }
       
        //CR373098 To transform the java class name as validate.
        private String transToValidJavaIdentifier(String s) {
            if (s == null) {
                return null;
            }
            final int len = s.length();
            StringBuilder retSB = new StringBuilder();
            if (len == 0 || !Character.isJavaIdentifierStart(s.charAt(0))) {
                retSB.append("J"); //update to a default start char
            } else {
                retSB.append(s.charAt(0));
            }

            for (int i = 1; i < len; i++) {
                if (!Character.isJavaIdentifierPart(s.charAt(i)))
                  ; //delete it if it is illegal //TODO: It might conflict "a-b" vs. "ab"
                else {
                    retSB.append(s.charAt(i));
                }
            }
            return retSB.toString();
        }

  private String makePackageQualified(String s) {
    s = transToValidJavaIdentifier(s);
    if (options.defaultPackage != null && !options.defaultPackage.equals("")) {
      return options.defaultPackage + "." + s;
    } else {
      return s;
    }
  }
 

  /**
   * TODO
   *
   * @param port
   * @param bindingTypeAnn
   */
  private void writeBindingTypeAnnotation(Port port,
      JAnnotationUse bindingTypeAnn) {
    QName bName = (QName) port
        .getProperty(ModelProperties.PROPERTY_WSDL_BINDING_NAME);
    if (bName == null)
      return;

    String v = getBindingType(bName);

    // TODO: How to decide if it is a mtom?
    if (v != null) {
      // transport = translate(transport);
      bindingTypeAnn.param("value", v);
    }

  }

  private String resolveBindingValue(TWSDLExtension wsdlext) {
    if (wsdlext.getClass().equals(SOAPBinding.class)) {
      SOAPBinding sb = (SOAPBinding) wsdlext;
      if(javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING.equals(sb.getTransport()))
        return javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING;
                        else {
                            for(GeneratorExtension f : ServiceFinder.find(GeneratorExtension.class) ) {
                                String bindingValue = f.getBindingValue(sb.getTransport(), SOAPVersion.SOAP_11);
                                if(bindingValue!=null) {
                                    return bindingValue;
                                }
                            }
                                return javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING;
                        }
    }
    if (wsdlext.getClass().equals(SOAP12Binding.class)) {
      SOAP12Binding sb = (SOAP12Binding) wsdlext;
      if(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING.equals(sb.getTransport()))
        return javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING;
        else {
            for(GeneratorExtension f : ServiceFinder.find(GeneratorExtension.class) ) {
                String bindingValue = f.getBindingValue(sb.getTransport(), SOAPVersion.SOAP_12);
                if(bindingValue!=null) {
                    return bindingValue;
                }
            }
                return javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING;
        }
    }
    return null;
  }

  private String getBindingType(QName bName) {

    String value = null;
    // process the bindings in definitions of model.entity
    if (model.getEntity() instanceof Definitions) {
      Definitions definitions = (Definitions) model.getEntity();
      if (definitions != null) {
        Iterator bindings = definitions.bindings();
        if (bindings != null) {
          while (bindings.hasNext()) {
            Binding binding = (Binding) bindings.next();
            if (bName.getLocalPart().equals(binding.getName())
                && bName.getNamespaceURI().equals(binding.getNamespaceURI())) {
              List<TWSDLExtension> bindextends = (List<TWSDLExtension>) binding
                  .extensions();
              for (TWSDLExtension wsdlext : bindextends) {
                value = resolveBindingValue(wsdlext);
                if (value != null)
                  break;
              }
              break;
            }
          }
        }
      }
    }

    // process the bindings in whole document
    if (value == null) {
      if (model.getEntity() instanceof Definitions) {
          Definitions definitions = (Definitions) model.getEntity();
          Binding b = (Binding) definitions.resolveBindings().get(bName);
          if (b != null) {
        List<TWSDLExtension> bindextends = (List<TWSDLExtension>) b
            .extensions();
        for (TWSDLExtension wsdlext : bindextends) {
            value = resolveBindingValue(wsdlext);
            if (value != null)
            break;
        }
                      }
      }
    }

    return value;
  }
 
  /**
   * Since the SOAP 1.1 binding transport URI defined in WSDL 1.1 specification
   * is different with the SOAPBinding URI defined by JAX-WS 2.0 specification.
   * We must translate the wsdl version into JAX-WS version. If the given
   * transport URI is NOT one of the predefined transport URIs, it is returned
   * as is.
   *
   * @param transportURI
   *          retrieved from WSDL
   * @return Standard BindingType URI defined by JAX-WS 2.0 specification.
   */
//  private String translate(String transportURI)
//  {
//    String translatedBindingId = TRANSLATION_MAP.get(transportURI);
//    if (translatedBindingId == null)
//      translatedBindingId = transportURI;
//
//    return translatedBindingId;
//  }

  /*****************************************************************************
   * Inner classes definition
   */
  static final class ImplFile {
    public String qualifiedName; // package+"."+simpleClassName + ".java"

    public String name; // simpleClassName + ".java"

    private ImplFile(String qualifiedClassName) {
      this.qualifiedName = qualifiedClassName + ".java";

      String simpleClassName = qualifiedClassName;
      int i = qualifiedClassName.lastIndexOf(".");
      if (i != -1)
        simpleClassName = qualifiedClassName.substring(i + 1);

      this.name = simpleClassName + ".java";
    }

    public static List<ImplFile> toImplFiles(List<String> qualifiedClassNames) {
      List<ImplFile> ret = new ArrayList<ImplFile>();

      for (String qualifiedClassName : qualifiedClassNames)
        ret.add(new ImplFile(qualifiedClassName));

      return ret;
    }
  }

  /*****************************************************************************
   * Other utility methods
   */

  private static File makePackageDir(WsimportOptions options) {
    File ret = null;
    if (options.defaultPackage != null && !options.defaultPackage.equals("")) {
      String subDir = options.defaultPackage.replace('.', '/');
      ret = new File(options.implDestDir, subDir);
    } else {
      ret = options.implDestDir;
    }

    boolean created = ret.mkdirs();
                if (options.verbose && !created) {
                    System.out.println(MessageFormat.format("Directory not created: {0}", ret));
                }
    return ret;
  }

  private static String getQualifiedFileName(String canonicalBaseDir, File f)
      throws java.io.IOException {
    String fp = f.getCanonicalPath();
    if (fp == null)
      return null;
    fp = fp.replace(canonicalBaseDir, "");
    fp = fp.replace('\\', '.');
    fp = fp.replace('/', '.');
    if (fp.startsWith("."))
      fp = fp.substring(1);

    return fp;
  }

  private static File findFile(WsimportOptions options, String qualifiedFileName)
      throws java.io.IOException {
    String baseDir = options.sourceDir.getCanonicalPath();
    String fp = null;
    for (File f : options.getGeneratedFiles()) {
      fp = getQualifiedFileName(baseDir, f);
      if (qualifiedFileName.equals(fp))
        return f;
    }

    return null;
  }

  private static boolean equalsNSOptional(String strQName, QName checkQN) {
    if (strQName == null)
      return false;
    strQName = strQName.trim();
    QName reqQN = QName.valueOf(strQName);

    if (reqQN.getNamespaceURI() == null || reqQN.getNamespaceURI().equals(""))
      return reqQN.getLocalPart().equals(checkQN.getLocalPart());

    return reqQN.equals(checkQN);
  }
}
TOP

Related Classes of com.sun.tools.ws.processor.generator.JwsImplGenerator$ImplFile

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.