com.sun.tools.ws.wscompile.WsgenTool Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of webservices-osgi Show documentation
Show all versions of webservices-osgi Show documentation
Metro Web Services Runtime OSGi Bundle
The newest version!
/*
* Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package com.sun.tools.ws.wscompile;
import com.oracle.webservices.api.databinding.WSDLResolver;
import com.sun.tools.ws.ToolVersion;
import com.sun.tools.ws.processor.modeler.annotation.WebServiceAp;
import com.sun.tools.ws.processor.modeler.wsdl.ConsoleErrorReporter;
import com.sun.tools.ws.resources.WscompileMessages;
import com.sun.tools.xjc.util.NullStream;
import com.sun.xml.txw2.TXW;
import com.sun.xml.txw2.TypedXmlWriter;
import com.sun.xml.txw2.annotation.XmlAttribute;
import com.sun.xml.txw2.annotation.XmlElement;
import com.sun.xml.txw2.output.StreamSerializer;
import com.sun.xml.ws.api.BindingID;
import com.sun.xml.ws.api.databinding.DatabindingConfig;
import com.sun.xml.ws.api.databinding.DatabindingFactory;
import com.sun.xml.ws.api.databinding.WSDLGenInfo;
import com.sun.xml.ws.api.server.Container;
import com.sun.xml.ws.api.wsdl.writer.WSDLGeneratorExtension;
import com.sun.xml.ws.binding.WebServiceFeatureList;
import com.sun.xml.ws.model.ExternalMetadataReader;
import com.sun.xml.ws.model.AbstractSEIModelImpl;
import com.sun.xml.ws.util.ServiceFinder;
import org.xml.sax.SAXParseException;
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 jakarta.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.Locale;
import java.util.Map;
import java.util.ServiceLoader;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import org.xml.sax.ext.Locator2Impl;
/**
* @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;
/**
*
*/
public boolean buildModel(String endpoint, WsimportListener listener) throws BadCommandLineException {
final ErrorReceiverFilter errReceiver = new ErrorReceiverFilter(listener);
if (!options.nosource) {
List 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);
}
if (options.javacOptions != null) {
args.addAll(options.getJavacOptions(args, listener));
}
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;
}
DiagnosticListener diagnostics = diagnostic -> {
boolean fromFile = diagnostic.getSource() != null;
StringBuilder message = new StringBuilder();
if (fromFile) {
message.append(diagnostic.getSource().getName());
}
message.append(diagnostic.getMessage(Locale.getDefault()));
if (fromFile) {
message.append("");
}
switch (diagnostic.getKind()) {
case ERROR:
Locator2Impl l = new Locator2Impl();
if (fromFile) {
l.setSystemId(diagnostic.getSource().getName());
} else {
l.setSystemId(null);
}
l.setLineNumber((int) diagnostic.getLineNumber());
l.setColumnNumber((int) diagnostic.getColumnNumber());
SAXParseException ex = new SAXParseException(message.toString(), l);
listener.error(ex);
break;
case MANDATORY_WARNING:
case WARNING:
listener.message(message.toString());
break;
default:
if (options.verbose) {
listener.message(message.toString());
}
}
};
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 externalMetadataFileNames = options.externalMetadataFiles;
boolean disableXmlSecurity = options.disableXmlSecurity;
if (externalMetadataFileNames != null && !externalMetadataFileNames.isEmpty()) {
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.ws.db.DatabindingImpl rt = (com.sun.xml.ws.db.DatabindingImpl) fac.createRuntime(config);
final File[] wsdlFileName = new File[1]; // used to capture the generated WSDL file.
final Map 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 filename) {
return toResult(toFile(filename.value));
}
@Override
public Result getSchemaOutput(String namespace, Holder filename) {
return getSchemaOutput(namespace, filename.value);
}
// TODO pass correct impl's class name
});
wsdlGenInfo.setContainer(container);
wsdlGenInfo.setExtensions(ServiceFinder.find(WSDLGeneratorExtension.class, ServiceLoader.load(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 getExternalFiles(List exts) {
List 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.
*/
private void generateWsgenReport(Class> endpointClass, AbstractSEIModelImpl rtModel, File wsdlFile, Map 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 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);
}
}
/**
* "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 {@link jakarta.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);
}
}
}