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

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
child 368
0989ad8c0860
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

     1 /*
     2  * Copyright (c) 1997, 2012, 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.sun.istack.internal.tools.ParallelWorldClassLoader;
    29 import com.sun.tools.internal.ws.ToolVersion;
    30 import com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceAp;
    31 import com.sun.tools.internal.ws.processor.modeler.wsdl.ConsoleErrorReporter;
    32 import com.sun.tools.internal.ws.resources.WscompileMessages;
    33 import com.sun.tools.internal.xjc.util.NullStream;
    34 import com.sun.xml.internal.txw2.TXW;
    35 import com.sun.xml.internal.txw2.TypedXmlWriter;
    36 import com.sun.xml.internal.txw2.annotation.XmlAttribute;
    37 import com.sun.xml.internal.txw2.annotation.XmlElement;
    38 import com.sun.xml.internal.txw2.output.StreamSerializer;
    39 import com.sun.xml.internal.ws.api.BindingID;
    40 import com.sun.xml.internal.ws.api.databinding.DatabindingConfig;
    41 import com.sun.xml.internal.ws.api.databinding.DatabindingFactory;
    42 import com.sun.xml.internal.ws.api.databinding.WSDLGenInfo;
    43 import com.sun.xml.internal.ws.api.server.Container;
    44 import com.sun.xml.internal.ws.api.wsdl.writer.WSDLGeneratorExtension;
    45 import com.sun.xml.internal.ws.binding.WebServiceFeatureList;
    46 import com.sun.xml.internal.ws.model.AbstractSEIModelImpl;
    47 import com.sun.xml.internal.ws.util.ServiceFinder;
    48 import com.sun.xml.internal.ws.wsdl.writer.WSDLResolver;
    49 import org.xml.sax.SAXParseException;
    51 import javax.tools.DiagnosticCollector;
    52 import javax.tools.JavaCompiler;
    53 import javax.tools.JavaFileObject;
    54 import javax.tools.StandardJavaFileManager;
    55 import javax.tools.ToolProvider;
    56 import javax.xml.bind.annotation.XmlSeeAlso;
    57 import javax.xml.namespace.QName;
    58 import javax.xml.transform.Result;
    59 import javax.xml.transform.stream.StreamResult;
    60 import javax.xml.ws.EndpointReference;
    61 import javax.xml.ws.Holder;
    62 import java.io.BufferedOutputStream;
    63 import java.io.File;
    64 import java.io.FileNotFoundException;
    65 import java.io.FileOutputStream;
    66 import java.io.IOException;
    67 import java.io.OutputStream;
    68 import java.io.PrintStream;
    69 import java.net.URLClassLoader;
    70 import java.util.ArrayList;
    71 import java.util.Collection;
    72 import java.util.Collections;
    73 import java.util.HashMap;
    74 import java.util.Map;
    76 /**
    77  * @author Vivek Pandey
    78  */
    80 /*
    81  * All annotation types are supported.
    82  */
    83 public class WsgenTool {
    84     private final PrintStream out;
    85     private final WsgenOptions options = new WsgenOptions();
    88     public WsgenTool(OutputStream out, Container container) {
    89         this.out = (out instanceof PrintStream)?(PrintStream)out:new PrintStream(out);
    90         this.container = container;
    91     }
    94     public WsgenTool(OutputStream out) {
    95         this(out, null);
    96     }
    98     public boolean run(String[] args){
    99         final Listener listener = new Listener();
   100         for (String arg : args) {
   101             if (arg.equals("-version")) {
   102                 listener.message(
   103                         WscompileMessages.WSGEN_VERSION(ToolVersion.VERSION.MAJOR_VERSION));
   104                 return true;
   105             }
   106             if (arg.equals("-fullversion")) {
   107                 listener.message(
   108                         WscompileMessages.WSGEN_FULLVERSION(ToolVersion.VERSION.toString()));
   109                 return true;
   110             }
   111         }
   112         try {
   113             options.parseArguments(args);
   114             options.validate();
   115             if(!buildModel(options.endpoint.getName(), listener)){
   116                 return false;
   117             }
   118         }catch (Options.WeAreDone done){
   119             usage((WsgenOptions)done.getOptions());
   120         }catch (BadCommandLineException e) {
   121             if(e.getMessage()!=null) {
   122                 System.out.println(e.getMessage());
   123                 System.out.println();
   124             }
   125             usage((WsgenOptions)e.getOptions());
   126             return false;
   127         }catch(AbortException e){
   128             //error might have been reported
   129         }finally{
   130             if(!options.keep){
   131                 options.removeGeneratedFiles();
   132             }
   133         }
   134         return true;
   135     }
   137     private final Container container;
   139     private int round = 0;
   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     }
   154     public boolean buildModel(String endpoint, Listener listener) throws BadCommandLineException {
   155         final ErrorReceiverFilter errReceiver = new ErrorReceiverFilter(listener);
   157         boolean bootCP = useBootClasspath(EndpointReference.class) || useBootClasspath(XmlSeeAlso.class);
   158         Collection<String> args = new ArrayList<String>(6 + (bootCP ? 1 : 0) + (options.nocompile ? 1 : 0)
   159                 + (options.encoding != null ? 2 : 0));
   160         args.add("-d");
   161         args.add(options.destDir.getAbsolutePath());
   162         args.add("-classpath");
   163         args.add(options.classpath);
   164         args.add("-s");
   165         args.add(options.sourceDir.getAbsolutePath());
   166         if (options.nocompile) {
   167             args.add("-proc:only");
   168         }
   169         if (options.encoding != null) {
   170             args.add("-encoding");
   171             args.add(options.encoding);
   172         }
   173         if (bootCP) {
   174             args.add(new StringBuilder()
   175                     .append("-Xbootclasspath/p:")
   176                     .append(JavaCompilerHelper.getJarFile(EndpointReference.class))
   177                     .append(File.pathSeparator)
   178                     .append(JavaCompilerHelper.getJarFile(XmlSeeAlso.class)).toString());
   179         }
   181         JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
   182         DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
   183         StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
   184         JavaCompiler.CompilationTask task = compiler.getTask(
   185                 null,
   186                 fileManager,
   187                 diagnostics,
   188                 args,
   189                 Collections.singleton(endpoint.replaceAll("\\$", ".")),
   190                 null);
   191         task.setProcessors(Collections.singleton(new WebServiceAp(options, out)));
   192         boolean result = task.call();
   194         if (!result) {
   195             out.println(WscompileMessages.WSCOMPILE_ERROR(WscompileMessages.WSCOMPILE_COMPILATION_FAILED()));
   196             return false;
   197         }
   198         if (options.genWsdl) {
   199                 DatabindingConfig config = new DatabindingConfig();
   200             String tmpPath = options.destDir.getAbsolutePath()+ File.pathSeparator+options.classpath;
   201             ClassLoader classLoader = new URLClassLoader(Options.pathToURLs(tmpPath),
   202                     this.getClass().getClassLoader());
   203             Class<?> endpointClass;
   204             try {
   205                 endpointClass = classLoader.loadClass(endpoint);
   206             } catch (ClassNotFoundException e) {
   207                 throw new BadCommandLineException(WscompileMessages.WSGEN_CLASS_NOT_FOUND(endpoint));
   208             }
   210             BindingID bindingID = options.getBindingID(options.protocol);
   211             if (!options.protocolSet) {
   212                 bindingID = BindingID.parse(endpointClass);
   213             }
   214             WebServiceFeatureList wsfeatures = new WebServiceFeatureList(endpointClass);
   215 //            RuntimeModeler rtModeler = new RuntimeModeler(endpointClass, options.serviceName, bindingID, wsfeatures.toArray());
   216 //            rtModeler.setClassLoader(classLoader);
   217             if (options.portName != null)
   218                 config.getMappingInfo().setPortName(options.portName);//rtModeler.setPortName(options.portName);
   219 //            AbstractSEIModelImpl rtModel = rtModeler.buildRuntimeModel();
   221                 DatabindingFactory fac = DatabindingFactory.newInstance();
   222                 config.setEndpointClass(endpointClass);
   223                 config.getMappingInfo().setServiceName(options.serviceName);
   224                 config.setFeatures(wsfeatures.toArray());
   225                 config.setClassLoader(classLoader);
   226                 config.getMappingInfo().setBindingID(bindingID);
   227                 com.sun.xml.internal.ws.db.DatabindingImpl rt = (com.sun.xml.internal.ws.db.DatabindingImpl)fac.createRuntime(config);
   229             final File[] wsdlFileName = new File[1]; // used to capture the generated WSDL file.
   230             final Map<String,File> schemaFiles = new HashMap<String,File>();
   232             WSDLGenInfo wsdlGenInfo = new WSDLGenInfo();
   233             wsdlGenInfo.setWsdlResolver(
   234                     new WSDLResolver() {
   235                         private File toFile(String suggestedFilename) {
   236                             return new File(options.nonclassDestDir, suggestedFilename);
   237                         }
   238                         private Result toResult(File file) {
   239                             Result result;
   240                             try {
   241                                 result = new StreamResult(new FileOutputStream(file));
   242                                 result.setSystemId(file.getPath().replace('\\', '/'));
   243                             } catch (FileNotFoundException e) {
   244                                 errReceiver.error(e);
   245                                 return null;
   246                             }
   247                             return result;
   248                         }
   250                         public Result getWSDL(String suggestedFilename) {
   251                             File f = toFile(suggestedFilename);
   252                             wsdlFileName[0] = f;
   253                             return toResult(f);
   254                         }
   255                         public Result getSchemaOutput(String namespace, String suggestedFilename) {
   256                             if (namespace == null)
   257                                 return null;
   258                             File f = toFile(suggestedFilename);
   259                             schemaFiles.put(namespace,f);
   260                             return toResult(f);
   261                         }
   262                         public Result getAbstractWSDL(Holder<String> filename) {
   263                             return toResult(toFile(filename.value));
   264                         }
   265                         public Result getSchemaOutput(String namespace, Holder<String> filename) {
   266                             return getSchemaOutput(namespace, filename.value);
   267                         }
   268                         // TODO pass correct impl's class name
   269                     });
   271             wsdlGenInfo.setContainer(container);
   272             wsdlGenInfo.setExtensions(ServiceFinder.find(WSDLGeneratorExtension.class).toArray());
   273             wsdlGenInfo.setInlineSchemas(options.inlineSchemas);
   274             rt.generateWSDL(wsdlGenInfo);
   277             if(options.wsgenReport!=null)
   278                 generateWsgenReport(endpointClass,(AbstractSEIModelImpl)rt.getModel(),wsdlFileName[0],schemaFiles);
   279         }
   280         return true;
   281     }
   283     /**
   284      * Generates a small XML file that captures the key activity of wsgen,
   285      * so that test harness can pick up artifacts.
   286      */
   287     private void generateWsgenReport(Class<?> endpointClass, AbstractSEIModelImpl rtModel, File wsdlFile, Map<String,File> schemaFiles) {
   288         try {
   289             ReportOutput.Report report = TXW.create(ReportOutput.Report.class,
   290                 new StreamSerializer(new BufferedOutputStream(new FileOutputStream(options.wsgenReport))));
   292             report.wsdl(wsdlFile.getAbsolutePath());
   293             ReportOutput.writeQName(rtModel.getServiceQName(), report.service());
   294             ReportOutput.writeQName(rtModel.getPortName(), report.port());
   295             ReportOutput.writeQName(rtModel.getPortTypeName(), report.portType());
   297             report.implClass(endpointClass.getName());
   299             for (Map.Entry<String,File> e : schemaFiles.entrySet()) {
   300                 ReportOutput.Schema s = report.schema();
   301                 s.ns(e.getKey());
   302                 s.location(e.getValue().getAbsolutePath());
   303             }
   305             report.commit();
   306         } catch (IOException e) {
   307             // this is code for the test, so we can be lousy in the error handling
   308             throw new Error(e);
   309         }
   310     }
   312     /**
   313      * "Namespace" for code needed to generate the report file.
   314      */
   315     static class ReportOutput {
   316         @XmlElement("report")
   317         interface Report extends TypedXmlWriter {
   318             @XmlElement
   319             void wsdl(String file); // location of WSDL
   320             @XmlElement
   321             QualifiedName portType();
   322             @XmlElement
   323             QualifiedName service();
   324             @XmlElement
   325             QualifiedName port();
   327             /**
   328              * Name of the class that has {@link javax.jws.WebService}.
   329              */
   330             @XmlElement
   331             void implClass(String name);
   333             @XmlElement
   334             Schema schema();
   335         }
   337         interface QualifiedName extends TypedXmlWriter {
   338             @XmlAttribute
   339             void uri(String ns);
   340             @XmlAttribute
   341             void localName(String localName);
   342         }
   344         interface Schema extends TypedXmlWriter {
   345             @XmlAttribute
   346             void ns(String ns);
   347             @XmlAttribute
   348             void location(String filePath);
   349         }
   351         private static void writeQName( QName n, QualifiedName w ) {
   352             w.uri(n.getNamespaceURI());
   353             w.localName(n.getLocalPart());
   354         }
   355     }
   357     protected void usage(WsgenOptions options) {
   358         // Just don't see any point in passing WsgenOptions
   359         // BadCommandLineException also shouldn't have options
   360         if (options == null)
   361             options = this.options;
   362         System.out.println(WscompileMessages.WSGEN_HELP("WSGEN", options.protocols, options.nonstdProtocols.keySet()));
   363         System.out.println(WscompileMessages.WSGEN_USAGE_EXAMPLES());
   364     }
   366     class Listener extends WsimportListener {
   367         ConsoleErrorReporter cer = new ConsoleErrorReporter(out == null ? new PrintStream(new NullStream()) : out);
   369         @Override
   370         public void generatedFile(String fileName) {
   371             message(fileName);
   372         }
   374         @Override
   375         public void message(String msg) {
   376             out.println(msg);
   377         }
   379         @Override
   380         public void error(SAXParseException exception) {
   381             cer.error(exception);
   382         }
   384         @Override
   385         public void fatalError(SAXParseException exception) {
   386             cer.fatalError(exception);
   387         }
   389         @Override
   390         public void warning(SAXParseException exception) {
   391             cer.warning(exception);
   392         }
   394         @Override
   395         public void info(SAXParseException exception) {
   396             cer.info(exception);
   397         }
   398     }
   399 }

mercurial