/*
 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.tools.internal.ws.wscompile;

import com.oracle.webservices.internal.api.databinding.WSDLResolver;
import com.sun.tools.internal.ws.ToolVersion;
import com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceAp;
import com.sun.tools.internal.ws.processor.modeler.wsdl.ConsoleErrorReporter;
import com.sun.tools.internal.ws.resources.WscompileMessages;
import com.sun.tools.internal.xjc.util.NullStream;
import com.sun.xml.internal.txw2.TXW;
import com.sun.xml.internal.txw2.TypedXmlWriter;
import com.sun.xml.internal.txw2.annotation.XmlAttribute;
import com.sun.xml.internal.txw2.annotation.XmlElement;
import com.sun.xml.internal.txw2.output.StreamSerializer;
import com.sun.xml.internal.ws.api.BindingID;
import com.sun.xml.internal.ws.api.databinding.DatabindingConfig;
import com.sun.xml.internal.ws.api.databinding.DatabindingFactory;
import com.sun.xml.internal.ws.api.databinding.WSDLGenInfo;
import com.sun.xml.internal.ws.api.server.Container;
import com.sun.xml.internal.ws.api.wsdl.writer.WSDLGeneratorExtension;
import com.sun.xml.internal.ws.binding.WebServiceFeatureList;
import com.sun.xml.internal.ws.model.ExternalMetadataReader;
import com.sun.xml.internal.ws.model.AbstractSEIModelImpl;
import com.sun.xml.internal.ws.util.ServiceFinder;
import org.xml.sax.SAXParseException;

import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.Holder;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

Author:Vivek Pandey
/** * @author Vivek Pandey */
/* * All annotation types are supported. */ public class WsgenTool { private final PrintStream out; private final WsgenOptions options = new WsgenOptions(); public WsgenTool(OutputStream out, Container container) { this.out = (out instanceof PrintStream) ? (PrintStream) out : new PrintStream(out); this.container = container; } public WsgenTool(OutputStream out) { this(out, null); } public boolean run(String[] args) { final Listener listener = new Listener(); for (String arg : args) { if (arg.equals("-version")) { listener.message( WscompileMessages.WSGEN_VERSION(ToolVersion.VERSION.MAJOR_VERSION)); return true; } if (arg.equals("-fullversion")) { listener.message( WscompileMessages.WSGEN_FULLVERSION(ToolVersion.VERSION.toString())); return true; } } try { options.parseArguments(args); options.validate(); if (!buildModel(options.endpoint.getName(), listener)) { return false; } } catch (Options.WeAreDone done) { usage(done.getOptions()); } catch (BadCommandLineException e) { if (e.getMessage() != null) { System.out.println(e.getMessage()); System.out.println(); } usage(e.getOptions()); return false; } catch (AbortException e) { //error might have been reported } finally { if (!options.keep) { options.removeGeneratedFiles(); } } return true; } private final Container container;
Params:
  • endpoint –
  • listener –
Throws:
Returns:
/** * * @param endpoint * @param listener * @return * @throws BadCommandLineException */
public boolean buildModel(String endpoint, Listener listener) throws BadCommandLineException { final ErrorReceiverFilter errReceiver = new ErrorReceiverFilter(listener); List<String> args = new ArrayList<>(6 + (options.nocompile ? 1 : 0) + (options.encoding != null ? 2 : 0)); args.add("-d"); args.add(options.destDir.getAbsolutePath()); args.add("-classpath"); args.add(options.classpath); args.add("-s"); args.add(options.sourceDir.getAbsolutePath()); if (options.nocompile) { args.add("-proc:only"); } if (options.encoding != null) { args.add("-encoding"); args.add(options.encoding); } boolean addModules = true; if (options.javacOptions != null) { List<String> javacOptions = options.getJavacOptions(args, listener); for (int i = 0; i < javacOptions.size(); i++) { String opt = javacOptions.get(i); if ("-source".equals(opt) && 9 >= getVersion(javacOptions.get(i + 1))) { addModules = false; } if ("-target".equals(opt) && 9 >= getVersion(javacOptions.get(i + 1))) { addModules = false; } if ("--release".equals(opt) && 9 >= getVersion(javacOptions.get(i + 1))) { addModules = false; } args.add(opt); } } if (addModules) { args.add("--add-modules"); args.add("java.xml.ws"); } JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); if (compiler == null) { out.println(WscompileMessages.WSCOMPILE_CANT_GET_COMPILER(property("java.home"), property("java.version"), property("java.vendor"))); return false; } DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null); JavaCompiler.CompilationTask task = compiler.getTask( null, fileManager, diagnostics, args, Collections.singleton(endpoint.replaceAll("\\$", ".")), null); task.setProcessors(Collections.singleton(new WebServiceAp(options, out))); boolean result = task.call(); if (!result) { out.println(WscompileMessages.WSCOMPILE_ERROR(WscompileMessages.WSCOMPILE_COMPILATION_FAILED())); return false; } if (options.genWsdl) { DatabindingConfig config = new DatabindingConfig(); List<String> externalMetadataFileNames = options.externalMetadataFiles; boolean disableXmlSecurity = options.disableXmlSecurity; if (externalMetadataFileNames != null && externalMetadataFileNames.size() > 0) { config.setMetadataReader(new ExternalMetadataReader(getExternalFiles(externalMetadataFileNames), null, null, true, disableXmlSecurity)); } String tmpPath = options.destDir.getAbsolutePath() + File.pathSeparator + options.classpath; ClassLoader classLoader = new URLClassLoader(Options.pathToURLs(tmpPath), this.getClass().getClassLoader()); Class<?> endpointClass; try { endpointClass = classLoader.loadClass(endpoint); } catch (ClassNotFoundException e) { throw new BadCommandLineException(WscompileMessages.WSGEN_CLASS_NOT_FOUND(endpoint)); } BindingID bindingID = options.getBindingID(options.protocol); if (!options.protocolSet) { bindingID = BindingID.parse(endpointClass); } WebServiceFeatureList wsfeatures = new WebServiceFeatureList(endpointClass); // RuntimeModeler rtModeler = new RuntimeModeler(endpointClass, options.serviceName, bindingID, wsfeatures.toArray()); // rtModeler.setClassLoader(classLoader); if (options.portName != null) config.getMappingInfo().setPortName(options.portName);//rtModeler.setPortName(options.portName); // AbstractSEIModelImpl rtModel = rtModeler.buildRuntimeModel(); DatabindingFactory fac = DatabindingFactory.newInstance(); config.setEndpointClass(endpointClass); config.getMappingInfo().setServiceName(options.serviceName); config.setFeatures(wsfeatures.toArray()); config.setClassLoader(classLoader); config.getMappingInfo().setBindingID(bindingID); com.sun.xml.internal.ws.db.DatabindingImpl rt = (com.sun.xml.internal.ws.db.DatabindingImpl) fac.createRuntime(config); final File[] wsdlFileName = new File[1]; // used to capture the generated WSDL file. final Map<String, File> schemaFiles = new HashMap<>(); WSDLGenInfo wsdlGenInfo = new WSDLGenInfo(); wsdlGenInfo.setSecureXmlProcessingDisabled(disableXmlSecurity); wsdlGenInfo.setWsdlResolver( new WSDLResolver() { private File toFile(String suggestedFilename) { return new File(options.nonclassDestDir, suggestedFilename); } private Result toResult(File file) { Result result; try { result = new StreamResult(new FileOutputStream(file)); result.setSystemId(file.getPath().replace('\\', '/')); } catch (FileNotFoundException e) { errReceiver.error(e); return null; } return result; } @Override public Result getWSDL(String suggestedFilename) { File f = toFile(suggestedFilename); wsdlFileName[0] = f; return toResult(f); } public Result getSchemaOutput(String namespace, String suggestedFilename) { if (namespace == null) return null; File f = toFile(suggestedFilename); schemaFiles.put(namespace, f); return toResult(f); } @Override public Result getAbstractWSDL(Holder<String> filename) { return toResult(toFile(filename.value)); } @Override public Result getSchemaOutput(String namespace, Holder<String> filename) { return getSchemaOutput(namespace, filename.value); } // TODO pass correct impl's class name }); wsdlGenInfo.setContainer(container); wsdlGenInfo.setExtensions(ServiceFinder.find(WSDLGeneratorExtension.class).toArray()); wsdlGenInfo.setInlineSchemas(options.inlineSchemas); rt.generateWSDL(wsdlGenInfo); if (options.wsgenReport != null) generateWsgenReport(endpointClass, (AbstractSEIModelImpl) rt.getModel(), wsdlFileName[0], schemaFiles); } return true; } private String property(String key) { try { String property = System.getProperty(key); return property != null ? property : "UNKNOWN"; } catch (SecurityException ignored) { return "UNKNOWN"; } } private List<File> getExternalFiles(List<String> exts) { List<File> files = new ArrayList<>(); for (String ext : exts) { // first try absolute path ... File file = new File(ext); if (!file.exists()) { // then relative path ... file = new File(options.sourceDir.getAbsolutePath() + File.separator + ext); } files.add(file); } return files; }
Generates a small XML file that captures the key activity of wsgen, so that test harness can pick up artifacts.
/** * Generates a small XML file that captures the key activity of wsgen, * so that test harness can pick up artifacts. */
private void generateWsgenReport(Class<?> endpointClass, AbstractSEIModelImpl rtModel, File wsdlFile, Map<String, File> schemaFiles) { try { ReportOutput.Report report = TXW.create(ReportOutput.Report.class, new StreamSerializer(new BufferedOutputStream(new FileOutputStream(options.wsgenReport)))); report.wsdl(wsdlFile.getAbsolutePath()); ReportOutput.writeQName(rtModel.getServiceQName(), report.service()); ReportOutput.writeQName(rtModel.getPortName(), report.port()); ReportOutput.writeQName(rtModel.getPortTypeName(), report.portType()); report.implClass(endpointClass.getName()); for (Map.Entry<String, File> e : schemaFiles.entrySet()) { ReportOutput.Schema s = report.schema(); s.ns(e.getKey()); s.location(e.getValue().getAbsolutePath()); } report.commit(); } catch (IOException e) { // this is code for the test, so we can be lousy in the error handling throw new Error(e); } } private float getVersion(String s) { return Float.parseFloat(s); }
"Namespace" for code needed to generate the report file.
/** * "Namespace" for code needed to generate the report file. */
static class ReportOutput { @XmlElement("report") interface Report extends TypedXmlWriter { @XmlElement void wsdl(String file); // location of WSDL @XmlElement QualifiedName portType(); @XmlElement QualifiedName service(); @XmlElement QualifiedName port();
Name of the class that has WebService.
/** * Name of the class that has {@link javax.jws.WebService}. */
@XmlElement void implClass(String name); @XmlElement Schema schema(); } interface QualifiedName extends TypedXmlWriter { @XmlAttribute void uri(String ns); @XmlAttribute void localName(String localName); } interface Schema extends TypedXmlWriter { @XmlAttribute void ns(String ns); @XmlAttribute void location(String filePath); } private static void writeQName(QName n, QualifiedName w) { w.uri(n.getNamespaceURI()); w.localName(n.getLocalPart()); } } protected void usage(Options options) { // Just don't see any point in passing WsgenOptions // BadCommandLineException also shouldn't have options if (options == null) options = this.options; if (options instanceof WsgenOptions) { System.out.println(WscompileMessages.WSGEN_HELP("WSGEN", ((WsgenOptions)options).protocols, ((WsgenOptions)options).nonstdProtocols.keySet())); System.out.println(WscompileMessages.WSGEN_USAGE_EXTENSIONS()); System.out.println(WscompileMessages.WSGEN_USAGE_EXAMPLES()); } } class Listener extends WsimportListener { ConsoleErrorReporter cer = new ConsoleErrorReporter(out == null ? new PrintStream(new NullStream()) : out); @Override public void generatedFile(String fileName) { message(fileName); } @Override public void message(String msg) { out.println(msg); } @Override public void error(SAXParseException exception) { cer.error(exception); } @Override public void fatalError(SAXParseException exception) { cer.fatalError(exception); } @Override public void warning(SAXParseException exception) { cer.warning(exception); } @Override public void info(SAXParseException exception) { cer.info(exception); } } }