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

Print this page


   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  */
  25 
  26 package com.sun.tools.internal.ws.wscompile;
  27 

  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;
  50 
  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;
  75 
  76 /**
  77  * @author Vivek Pandey
  78  */
  79 
  80 /*
  81  * All annotation types are supported.
  82  */
  83 public class WsgenTool {
  84     private final PrintStream out;
  85     private final WsgenOptions options = new WsgenOptions();
  86 
  87 
  88     public WsgenTool(OutputStream out, Container container) {
  89         this.out = (out instanceof PrintStream)?(PrintStream)out:new PrintStream(out);
  90         this.container = container;
  91     }
  92 
  93 
  94     public WsgenTool(OutputStream out) {
  95         this(out, null);
  96     }
  97 
  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     }
 136 
 137     private final Container container;
 138 
 139     private int round = 0;
 140 
 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     }
 152 
 153 






 154     public boolean buildModel(String endpoint, Listener listener) throws BadCommandLineException {
 155         final ErrorReceiverFilter errReceiver = new ErrorReceiverFilter(listener);
 156 
 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         }
 180 
 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();
 193 
 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             }
 209 
 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();
 220 
 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);
 228 
 229             final File[] wsdlFileName = new File[1]; // used to capture the generated WSDL file.
 230             final Map<String,File> schemaFiles = new HashMap<String,File>();
 231 
 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                         }
 249 

 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                     });
 270 
 271             wsdlGenInfo.setContainer(container);
 272             wsdlGenInfo.setExtensions(ServiceFinder.find(WSDLGeneratorExtension.class).toArray());
 273             wsdlGenInfo.setInlineSchemas(options.inlineSchemas);
 274             rt.generateWSDL(wsdlGenInfo);
 275 
 276 
 277             if(options.wsgenReport!=null)
 278                 generateWsgenReport(endpointClass,(AbstractSEIModelImpl)rt.getModel(),wsdlFileName[0],schemaFiles);
 279         }
 280         return true;
 281     }
 282 














 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))));
 291 
 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());
 296 
 297             report.implClass(endpointClass.getName());
 298 
 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             }
 304 
 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     }
 311 
 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();
 326 
 327             /**
 328              * Name of the class that has {@link javax.jws.WebService}.
 329              */
 330             @XmlElement
 331             void implClass(String name);
 332 
 333             @XmlElement
 334             Schema schema();
 335         }
 336 
 337         interface QualifiedName extends TypedXmlWriter {
 338             @XmlAttribute
 339             void uri(String ns);

 340             @XmlAttribute
 341             void localName(String localName);
 342         }
 343 
 344         interface Schema extends TypedXmlWriter {
 345             @XmlAttribute
 346             void ns(String ns);

 347             @XmlAttribute
 348             void location(String filePath);
 349         }
 350 
 351         private static void writeQName( QName n, QualifiedName w ) {
 352             w.uri(n.getNamespaceURI());
 353             w.localName(n.getLocalPart());
 354         }
 355     }
 356 
 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     }
 365 
 366     class Listener extends WsimportListener {
 367         ConsoleErrorReporter cer = new ConsoleErrorReporter(out == null ? new PrintStream(new NullStream()) : out);
 368 
 369         @Override
 370         public void generatedFile(String fileName) {
 371             message(fileName);
 372         }
 373 
 374         @Override
 375         public void message(String msg) {
 376             out.println(msg);
 377         }
 378 
 379         @Override
 380         public void error(SAXParseException exception) {
 381             cer.error(exception);
 382         }
 383 
   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  */
  25 
  26 package com.sun.tools.internal.ws.wscompile;
  27 
  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;
  51 
  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;
  77 
  78 /**
  79  * @author Vivek Pandey
  80  */
  81 
  82 /*
  83  * All annotation types are supported.
  84  */
  85 public class WsgenTool {
  86     private final PrintStream out;
  87     private final WsgenOptions options = new WsgenOptions();
  88 
  89 
  90     public WsgenTool(OutputStream out, Container container) {
  91         this.out = (out instanceof PrintStream) ? (PrintStream) out : new PrintStream(out);
  92         this.container = container;
  93     }
  94 
  95 
  96     public WsgenTool(OutputStream out) {
  97         this(out, null);
  98     }
  99 
 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     }
 138 
 139     private final Container container;
 140 


 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     }
 152 
 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);
 162 
 163         boolean bootCP = useBootClasspath(EndpointReference.class) || useBootClasspath(XmlSeeAlso.class);
 164         Collection<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 
 187         JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();//        compiler = JavacTool.create();
 188         DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
 189         StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
 190         JavaCompiler.CompilationTask task = compiler.getTask(
 191                 null,
 192                 fileManager,
 193                 diagnostics,
 194                 args,
 195                 Collections.singleton(endpoint.replaceAll("\\$", ".")),
 196                 null);
 197         task.setProcessors(Collections.singleton(new WebServiceAp(options, out)));
 198         boolean result = task.call();
 199 
 200         if (!result) {
 201             out.println(WscompileMessages.WSCOMPILE_ERROR(WscompileMessages.WSCOMPILE_COMPILATION_FAILED()));
 202             return false;
 203         }
 204         if (options.genWsdl) {
 205             DatabindingConfig config = new DatabindingConfig();
 206 
 207             List<String> externalMetadataFileNames = options.externalMetadataFiles;
 208             boolean disableSecureXmlProcessing = options.disableSecureXmlProcessing;
 209             if (externalMetadataFileNames != null && externalMetadataFileNames.size() > 0) {
 210                 config.setMetadataReader(new ExternalMetadataReader(getExternalFiles(externalMetadataFileNames), null, null, true, disableSecureXmlProcessing));
 211             }
 212 
 213             String tmpPath = options.destDir.getAbsolutePath() + File.pathSeparator + options.classpath;
 214             ClassLoader classLoader = new URLClassLoader(Options.pathToURLs(tmpPath),
 215                     this.getClass().getClassLoader());
 216             Class<?> endpointClass;
 217             try {
 218                 endpointClass = classLoader.loadClass(endpoint);
 219             } catch (ClassNotFoundException e) {
 220                 throw new BadCommandLineException(WscompileMessages.WSGEN_CLASS_NOT_FOUND(endpoint));
 221             }
 222 
 223             BindingID bindingID = options.getBindingID(options.protocol);
 224             if (!options.protocolSet) {
 225                 bindingID = BindingID.parse(endpointClass);
 226             }
 227             WebServiceFeatureList wsfeatures = new WebServiceFeatureList(endpointClass);
 228 //            RuntimeModeler rtModeler = new RuntimeModeler(endpointClass, options.serviceName, bindingID, wsfeatures.toArray());
 229 //            rtModeler.setClassLoader(classLoader);
 230             if (options.portName != null)
 231                 config.getMappingInfo().setPortName(options.portName);//rtModeler.setPortName(options.portName);
 232 //            AbstractSEIModelImpl rtModel = rtModeler.buildRuntimeModel();
 233 
 234             DatabindingFactory fac = DatabindingFactory.newInstance();
 235             config.setEndpointClass(endpointClass);
 236             config.getMappingInfo().setServiceName(options.serviceName);
 237             config.setFeatures(wsfeatures.toArray());
 238             config.setClassLoader(classLoader);
 239             config.getMappingInfo().setBindingID(bindingID);
 240             com.sun.xml.internal.ws.db.DatabindingImpl rt = (com.sun.xml.internal.ws.db.DatabindingImpl) fac.createRuntime(config);
 241 
 242             final File[] wsdlFileName = new File[1]; // used to capture the generated WSDL file.
 243             final Map<String, File> schemaFiles = new HashMap<String, File>();
 244 
 245             WSDLGenInfo wsdlGenInfo = new WSDLGenInfo();
 246             wsdlGenInfo.setSecureXmlProcessingDisabled(disableSecureXmlProcessing);
 247 
 248             wsdlGenInfo.setWsdlResolver(
 249                     new WSDLResolver() {
 250                         private File toFile(String suggestedFilename) {
 251                             return new File(options.nonclassDestDir, suggestedFilename);
 252                         }
 253 
 254                         private Result toResult(File file) {
 255                             Result result;
 256                             try {
 257                                 result = new StreamResult(new FileOutputStream(file));
 258                                 result.setSystemId(file.getPath().replace('\\', '/'));
 259                             } catch (FileNotFoundException e) {
 260                                 errReceiver.error(e);
 261                                 return null;
 262                             }
 263                             return result;
 264                         }
 265 
 266                         @Override
 267                         public Result getWSDL(String suggestedFilename) {
 268                             File f = toFile(suggestedFilename);
 269                             wsdlFileName[0] = f;
 270                             return toResult(f);
 271                         }
 272 
 273                         public Result getSchemaOutput(String namespace, String suggestedFilename) {
 274                             if (namespace == null)
 275                                 return null;
 276                             File f = toFile(suggestedFilename);
 277                             schemaFiles.put(namespace, f);
 278                             return toResult(f);
 279                         }
 280 
 281                         @Override
 282                         public Result getAbstractWSDL(Holder<String> filename) {
 283                             return toResult(toFile(filename.value));
 284                         }
 285 
 286                         @Override
 287                         public Result getSchemaOutput(String namespace, Holder<String> filename) {
 288                             return getSchemaOutput(namespace, filename.value);
 289                         }
 290                         // TODO pass correct impl's class name
 291                     });
 292 
 293             wsdlGenInfo.setContainer(container);
 294             wsdlGenInfo.setExtensions(ServiceFinder.find(WSDLGeneratorExtension.class).toArray());
 295             wsdlGenInfo.setInlineSchemas(options.inlineSchemas);
 296             rt.generateWSDL(wsdlGenInfo);
 297 
 298 
 299             if (options.wsgenReport != null)
 300                 generateWsgenReport(endpointClass, (AbstractSEIModelImpl) rt.getModel(), wsdlFileName[0], schemaFiles);
 301         }
 302         return true;
 303     }
 304 
 305     private List<File> getExternalFiles(List<String> exts) {
 306         List<File> files = new ArrayList<File>();
 307         for (String ext : exts) {
 308             // first try absolute path ...
 309             File file = new File(ext);
 310             if (!file.exists()) {
 311                 // then relative path ...
 312                 file = new File(options.sourceDir.getAbsolutePath() + File.separator + ext);
 313             }
 314             files.add(file);
 315         }
 316         return files;
 317     }
 318 
 319     /**
 320      * Generates a small XML file that captures the key activity of wsgen,
 321      * so that test harness can pick up artifacts.
 322      */
 323     private void generateWsgenReport(Class<?> endpointClass, AbstractSEIModelImpl rtModel, File wsdlFile, Map<String, File> schemaFiles) {
 324         try {
 325             ReportOutput.Report report = TXW.create(ReportOutput.Report.class,
 326                     new StreamSerializer(new BufferedOutputStream(new FileOutputStream(options.wsgenReport))));
 327 
 328             report.wsdl(wsdlFile.getAbsolutePath());
 329             ReportOutput.writeQName(rtModel.getServiceQName(), report.service());
 330             ReportOutput.writeQName(rtModel.getPortName(), report.port());
 331             ReportOutput.writeQName(rtModel.getPortTypeName(), report.portType());
 332 
 333             report.implClass(endpointClass.getName());
 334 
 335             for (Map.Entry<String, File> e : schemaFiles.entrySet()) {
 336                 ReportOutput.Schema s = report.schema();
 337                 s.ns(e.getKey());
 338                 s.location(e.getValue().getAbsolutePath());
 339             }
 340 
 341             report.commit();
 342         } catch (IOException e) {
 343             // this is code for the test, so we can be lousy in the error handling
 344             throw new Error(e);
 345         }
 346     }
 347 
 348     /**
 349      * "Namespace" for code needed to generate the report file.
 350      */
 351     static class ReportOutput {
 352         @XmlElement("report")
 353         interface Report extends TypedXmlWriter {
 354             @XmlElement
 355             void wsdl(String file); // location of WSDL
 356 
 357             @XmlElement
 358             QualifiedName portType();
 359 
 360             @XmlElement
 361             QualifiedName service();
 362 
 363             @XmlElement
 364             QualifiedName port();
 365 
 366             /**
 367              * Name of the class that has {@link javax.jws.WebService}.
 368              */
 369             @XmlElement
 370             void implClass(String name);
 371 
 372             @XmlElement
 373             Schema schema();
 374         }
 375 
 376         interface QualifiedName extends TypedXmlWriter {
 377             @XmlAttribute
 378             void uri(String ns);
 379 
 380             @XmlAttribute
 381             void localName(String localName);
 382         }
 383 
 384         interface Schema extends TypedXmlWriter {
 385             @XmlAttribute
 386             void ns(String ns);
 387 
 388             @XmlAttribute
 389             void location(String filePath);
 390         }
 391 
 392         private static void writeQName(QName n, QualifiedName w) {
 393             w.uri(n.getNamespaceURI());
 394             w.localName(n.getLocalPart());
 395         }
 396     }
 397 
 398     protected void usage(Options options) {
 399         // Just don't see any point in passing WsgenOptions
 400         // BadCommandLineException also shouldn't have options
 401         if (options == null)
 402             options = this.options;
 403         if (options instanceof WsgenOptions) {
 404             System.out.println(WscompileMessages.WSGEN_HELP("WSGEN",
 405                     ((WsgenOptions)options).protocols,
 406                     ((WsgenOptions)options).nonstdProtocols.keySet()));
 407             System.out.println(WscompileMessages.WSGEN_USAGE_EXAMPLES());
 408         }
 409     }
 410 
 411     class Listener extends WsimportListener {
 412         ConsoleErrorReporter cer = new ConsoleErrorReporter(out == null ? new PrintStream(new NullStream()) : out);
 413 
 414         @Override
 415         public void generatedFile(String fileName) {
 416             message(fileName);
 417         }
 418 
 419         @Override
 420         public void message(String msg) {
 421             out.println(msg);
 422         }
 423 
 424         @Override
 425         public void error(SAXParseException exception) {
 426             cer.error(exception);
 427         }
 428