src/share/jaxws_classes/com/sun/tools/internal/ws/wscompile/WsgenTool.java

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

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 408
b0610cd08440
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.wscompile;
    28 import com.oracle.webservices.internal.api.databinding.WSDLResolver;
    29 import com.sun.istack.internal.tools.ParallelWorldClassLoader;
    30 import com.sun.tools.internal.ws.ToolVersion;
    31 import com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceAp;
    32 import com.sun.tools.internal.ws.processor.modeler.wsdl.ConsoleErrorReporter;
    33 import com.sun.tools.internal.ws.resources.WscompileMessages;
    34 import com.sun.tools.internal.xjc.util.NullStream;
    35 import com.sun.xml.internal.txw2.TXW;
    36 import com.sun.xml.internal.txw2.TypedXmlWriter;
    37 import com.sun.xml.internal.txw2.annotation.XmlAttribute;
    38 import com.sun.xml.internal.txw2.annotation.XmlElement;
    39 import com.sun.xml.internal.txw2.output.StreamSerializer;
    40 import com.sun.xml.internal.ws.api.BindingID;
    41 import com.sun.xml.internal.ws.api.databinding.DatabindingConfig;
    42 import com.sun.xml.internal.ws.api.databinding.DatabindingFactory;
    43 import com.sun.xml.internal.ws.api.databinding.WSDLGenInfo;
    44 import com.sun.xml.internal.ws.api.server.Container;
    45 import com.sun.xml.internal.ws.api.wsdl.writer.WSDLGeneratorExtension;
    46 import com.sun.xml.internal.ws.binding.WebServiceFeatureList;
    47 import com.sun.xml.internal.ws.model.ExternalMetadataReader;
    48 import com.sun.xml.internal.ws.model.AbstractSEIModelImpl;
    49 import com.sun.xml.internal.ws.util.ServiceFinder;
    50 import org.xml.sax.SAXParseException;
    52 import javax.tools.DiagnosticCollector;
    53 import javax.tools.JavaCompiler;
    54 import javax.tools.JavaFileObject;
    55 import javax.tools.StandardJavaFileManager;
    56 import javax.tools.ToolProvider;
    57 import javax.xml.bind.annotation.XmlSeeAlso;
    58 import javax.xml.namespace.QName;
    59 import javax.xml.transform.Result;
    60 import javax.xml.transform.stream.StreamResult;
    61 import javax.xml.ws.EndpointReference;
    62 import javax.xml.ws.Holder;
    63 import java.io.BufferedOutputStream;
    64 import java.io.File;
    65 import java.io.FileNotFoundException;
    66 import java.io.FileOutputStream;
    67 import java.io.IOException;
    68 import java.io.OutputStream;
    69 import java.io.PrintStream;
    70 import java.net.URLClassLoader;
    71 import java.util.ArrayList;
    72 import java.util.Collection;
    73 import java.util.Collections;
    74 import java.util.HashMap;
    75 import java.util.List;
    76 import java.util.Map;
    78 /**
    79  * @author Vivek Pandey
    80  */
    82 /*
    83  * All annotation types are supported.
    84  */
    85 public class WsgenTool {
    86     private final PrintStream out;
    87     private final WsgenOptions options = new WsgenOptions();
    90     public WsgenTool(OutputStream out, Container container) {
    91         this.out = (out instanceof PrintStream) ? (PrintStream) out : new PrintStream(out);
    92         this.container = container;
    93     }
    96     public WsgenTool(OutputStream out) {
    97         this(out, null);
    98     }
   100     public boolean run(String[] args) {
   101         final Listener listener = new Listener();
   102         for (String arg : args) {
   103             if (arg.equals("-version")) {
   104                 listener.message(
   105                         WscompileMessages.WSGEN_VERSION(ToolVersion.VERSION.MAJOR_VERSION));
   106                 return true;
   107             }
   108             if (arg.equals("-fullversion")) {
   109                 listener.message(
   110                         WscompileMessages.WSGEN_FULLVERSION(ToolVersion.VERSION.toString()));
   111                 return true;
   112             }
   113         }
   114         try {
   115             options.parseArguments(args);
   116             options.validate();
   117             if (!buildModel(options.endpoint.getName(), listener)) {
   118                 return false;
   119             }
   120         } catch (Options.WeAreDone done) {
   121             usage(done.getOptions());
   122         } catch (BadCommandLineException e) {
   123             if (e.getMessage() != null) {
   124                 System.out.println(e.getMessage());
   125                 System.out.println();
   126             }
   127             usage(e.getOptions());
   128             return false;
   129         } catch (AbortException e) {
   130             //error might have been reported
   131         } finally {
   132             if (!options.keep) {
   133                 options.removeGeneratedFiles();
   134             }
   135         }
   136         return true;
   137     }
   139     private final Container container;
   141     /*
   142      * To take care of JDK6-JDK6u3, where 2.1 API classes are not there
   143      */
   144     private static boolean useBootClasspath(Class clazz) {
   145         try {
   146             ParallelWorldClassLoader.toJarUrl(clazz.getResource('/' + clazz.getName().replace('.', '/') + ".class"));
   147             return true;
   148         } catch (Exception e) {
   149             return false;
   150         }
   151     }
   153     /**
   154      *
   155      * @param endpoint
   156      * @param listener
   157      * @return
   158      * @throws BadCommandLineException
   159      */
   160     public boolean buildModel(String endpoint, Listener listener) throws BadCommandLineException {
   161         final ErrorReceiverFilter errReceiver = new ErrorReceiverFilter(listener);
   163         boolean bootCP = useBootClasspath(EndpointReference.class) || useBootClasspath(XmlSeeAlso.class);
   164         List<String> args = new ArrayList<String>(6 + (bootCP ? 1 : 0) + (options.nocompile ? 1 : 0)
   165                 + (options.encoding != null ? 2 : 0));
   166         args.add("-d");
   167         args.add(options.destDir.getAbsolutePath());
   168         args.add("-classpath");
   169         args.add(options.classpath);
   170         args.add("-s");
   171         args.add(options.sourceDir.getAbsolutePath());
   172         if (options.nocompile) {
   173             args.add("-proc:only");
   174         }
   175         if (options.encoding != null) {
   176             args.add("-encoding");
   177             args.add(options.encoding);
   178         }
   179         if (bootCP) {
   180             args.add(new StringBuilder()
   181                     .append("-Xbootclasspath/p:")
   182                     .append(JavaCompilerHelper.getJarFile(EndpointReference.class))
   183                     .append(File.pathSeparator)
   184                     .append(JavaCompilerHelper.getJarFile(XmlSeeAlso.class)).toString());
   185         }
   186         if (options.javacOptions != null) {
   187             args.addAll(options.getJavacOptions(args, listener));
   188         }
   190         JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();//        compiler = JavacTool.create();
   191         DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
   192         StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
   193         JavaCompiler.CompilationTask task = compiler.getTask(
   194                 null,
   195                 fileManager,
   196                 diagnostics,
   197                 args,
   198                 Collections.singleton(endpoint.replaceAll("\\$", ".")),
   199                 null);
   200         task.setProcessors(Collections.singleton(new WebServiceAp(options, out)));
   201         boolean result = task.call();
   203         if (!result) {
   204             out.println(WscompileMessages.WSCOMPILE_ERROR(WscompileMessages.WSCOMPILE_COMPILATION_FAILED()));
   205             return false;
   206         }
   207         if (options.genWsdl) {
   208             DatabindingConfig config = new DatabindingConfig();
   210             List<String> externalMetadataFileNames = options.externalMetadataFiles;
   211             boolean disableXmlSecurity = options.disableXmlSecurity;
   212             if (externalMetadataFileNames != null && externalMetadataFileNames.size() > 0) {
   213                 config.setMetadataReader(new ExternalMetadataReader(getExternalFiles(externalMetadataFileNames), null, null, true, disableXmlSecurity));
   214             }
   216             String tmpPath = options.destDir.getAbsolutePath() + File.pathSeparator + options.classpath;
   217             ClassLoader classLoader = new URLClassLoader(Options.pathToURLs(tmpPath),
   218                     this.getClass().getClassLoader());
   219             Class<?> endpointClass;
   220             try {
   221                 endpointClass = classLoader.loadClass(endpoint);
   222             } catch (ClassNotFoundException e) {
   223                 throw new BadCommandLineException(WscompileMessages.WSGEN_CLASS_NOT_FOUND(endpoint));
   224             }
   226             BindingID bindingID = options.getBindingID(options.protocol);
   227             if (!options.protocolSet) {
   228                 bindingID = BindingID.parse(endpointClass);
   229             }
   230             WebServiceFeatureList wsfeatures = new WebServiceFeatureList(endpointClass);
   231 //            RuntimeModeler rtModeler = new RuntimeModeler(endpointClass, options.serviceName, bindingID, wsfeatures.toArray());
   232 //            rtModeler.setClassLoader(classLoader);
   233             if (options.portName != null)
   234                 config.getMappingInfo().setPortName(options.portName);//rtModeler.setPortName(options.portName);
   235 //            AbstractSEIModelImpl rtModel = rtModeler.buildRuntimeModel();
   237             DatabindingFactory fac = DatabindingFactory.newInstance();
   238             config.setEndpointClass(endpointClass);
   239             config.getMappingInfo().setServiceName(options.serviceName);
   240             config.setFeatures(wsfeatures.toArray());
   241             config.setClassLoader(classLoader);
   242             config.getMappingInfo().setBindingID(bindingID);
   243             com.sun.xml.internal.ws.db.DatabindingImpl rt = (com.sun.xml.internal.ws.db.DatabindingImpl) fac.createRuntime(config);
   245             final File[] wsdlFileName = new File[1]; // used to capture the generated WSDL file.
   246             final Map<String, File> schemaFiles = new HashMap<String, File>();
   248             WSDLGenInfo wsdlGenInfo = new WSDLGenInfo();
   249             wsdlGenInfo.setSecureXmlProcessingDisabled(disableXmlSecurity);
   251             wsdlGenInfo.setWsdlResolver(
   252                     new WSDLResolver() {
   253                         private File toFile(String suggestedFilename) {
   254                             return new File(options.nonclassDestDir, suggestedFilename);
   255                         }
   257                         private Result toResult(File file) {
   258                             Result result;
   259                             try {
   260                                 result = new StreamResult(new FileOutputStream(file));
   261                                 result.setSystemId(file.getPath().replace('\\', '/'));
   262                             } catch (FileNotFoundException e) {
   263                                 errReceiver.error(e);
   264                                 return null;
   265                             }
   266                             return result;
   267                         }
   269                         @Override
   270                         public Result getWSDL(String suggestedFilename) {
   271                             File f = toFile(suggestedFilename);
   272                             wsdlFileName[0] = f;
   273                             return toResult(f);
   274                         }
   276                         public Result getSchemaOutput(String namespace, String suggestedFilename) {
   277                             if (namespace == null)
   278                                 return null;
   279                             File f = toFile(suggestedFilename);
   280                             schemaFiles.put(namespace, f);
   281                             return toResult(f);
   282                         }
   284                         @Override
   285                         public Result getAbstractWSDL(Holder<String> filename) {
   286                             return toResult(toFile(filename.value));
   287                         }
   289                         @Override
   290                         public Result getSchemaOutput(String namespace, Holder<String> filename) {
   291                             return getSchemaOutput(namespace, filename.value);
   292                         }
   293                         // TODO pass correct impl's class name
   294                     });
   296             wsdlGenInfo.setContainer(container);
   297             wsdlGenInfo.setExtensions(ServiceFinder.find(WSDLGeneratorExtension.class).toArray());
   298             wsdlGenInfo.setInlineSchemas(options.inlineSchemas);
   299             rt.generateWSDL(wsdlGenInfo);
   302             if (options.wsgenReport != null)
   303                 generateWsgenReport(endpointClass, (AbstractSEIModelImpl) rt.getModel(), wsdlFileName[0], schemaFiles);
   304         }
   305         return true;
   306     }
   308     private List<File> getExternalFiles(List<String> exts) {
   309         List<File> files = new ArrayList<File>();
   310         for (String ext : exts) {
   311             // first try absolute path ...
   312             File file = new File(ext);
   313             if (!file.exists()) {
   314                 // then relative path ...
   315                 file = new File(options.sourceDir.getAbsolutePath() + File.separator + ext);
   316             }
   317             files.add(file);
   318         }
   319         return files;
   320     }
   322     /**
   323      * Generates a small XML file that captures the key activity of wsgen,
   324      * so that test harness can pick up artifacts.
   325      */
   326     private void generateWsgenReport(Class<?> endpointClass, AbstractSEIModelImpl rtModel, File wsdlFile, Map<String, File> schemaFiles) {
   327         try {
   328             ReportOutput.Report report = TXW.create(ReportOutput.Report.class,
   329                     new StreamSerializer(new BufferedOutputStream(new FileOutputStream(options.wsgenReport))));
   331             report.wsdl(wsdlFile.getAbsolutePath());
   332             ReportOutput.writeQName(rtModel.getServiceQName(), report.service());
   333             ReportOutput.writeQName(rtModel.getPortName(), report.port());
   334             ReportOutput.writeQName(rtModel.getPortTypeName(), report.portType());
   336             report.implClass(endpointClass.getName());
   338             for (Map.Entry<String, File> e : schemaFiles.entrySet()) {
   339                 ReportOutput.Schema s = report.schema();
   340                 s.ns(e.getKey());
   341                 s.location(e.getValue().getAbsolutePath());
   342             }
   344             report.commit();
   345         } catch (IOException e) {
   346             // this is code for the test, so we can be lousy in the error handling
   347             throw new Error(e);
   348         }
   349     }
   351     /**
   352      * "Namespace" for code needed to generate the report file.
   353      */
   354     static class ReportOutput {
   355         @XmlElement("report")
   356         interface Report extends TypedXmlWriter {
   357             @XmlElement
   358             void wsdl(String file); // location of WSDL
   360             @XmlElement
   361             QualifiedName portType();
   363             @XmlElement
   364             QualifiedName service();
   366             @XmlElement
   367             QualifiedName port();
   369             /**
   370              * Name of the class that has {@link javax.jws.WebService}.
   371              */
   372             @XmlElement
   373             void implClass(String name);
   375             @XmlElement
   376             Schema schema();
   377         }
   379         interface QualifiedName extends TypedXmlWriter {
   380             @XmlAttribute
   381             void uri(String ns);
   383             @XmlAttribute
   384             void localName(String localName);
   385         }
   387         interface Schema extends TypedXmlWriter {
   388             @XmlAttribute
   389             void ns(String ns);
   391             @XmlAttribute
   392             void location(String filePath);
   393         }
   395         private static void writeQName(QName n, QualifiedName w) {
   396             w.uri(n.getNamespaceURI());
   397             w.localName(n.getLocalPart());
   398         }
   399     }
   401     protected void usage(Options options) {
   402         // Just don't see any point in passing WsgenOptions
   403         // BadCommandLineException also shouldn't have options
   404         if (options == null)
   405             options = this.options;
   406         if (options instanceof WsgenOptions) {
   407             System.out.println(WscompileMessages.WSGEN_HELP("WSGEN",
   408                     ((WsgenOptions)options).protocols,
   409                     ((WsgenOptions)options).nonstdProtocols.keySet()));
   410             System.out.println(WscompileMessages.WSGEN_USAGE_EXTENSIONS());
   411             System.out.println(WscompileMessages.WSGEN_USAGE_EXAMPLES());
   412         }
   413     }
   415     class Listener extends WsimportListener {
   416         ConsoleErrorReporter cer = new ConsoleErrorReporter(out == null ? new PrintStream(new NullStream()) : out);
   418         @Override
   419         public void generatedFile(String fileName) {
   420             message(fileName);
   421         }
   423         @Override
   424         public void message(String msg) {
   425             out.println(msg);
   426         }
   428         @Override
   429         public void error(SAXParseException exception) {
   430             cer.error(exception);
   431         }
   433         @Override
   434         public void fatalError(SAXParseException exception) {
   435             cer.fatalError(exception);
   436         }
   438         @Override
   439         public void warning(SAXParseException exception) {
   440             cer.warning(exception);
   441         }
   443         @Override
   444         public void info(SAXParseException exception) {
   445             cer.info(exception);
   446         }
   447     }
   448 }

mercurial