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

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

mercurial