ohair@286: /* ohair@286: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. ohair@286: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ohair@286: * ohair@286: * This code is free software; you can redistribute it and/or modify it ohair@286: * under the terms of the GNU General Public License version 2 only, as ohair@286: * published by the Free Software Foundation. Oracle designates this ohair@286: * particular file as subject to the "Classpath" exception as provided ohair@286: * by Oracle in the LICENSE file that accompanied this code. ohair@286: * ohair@286: * This code is distributed in the hope that it will be useful, but WITHOUT ohair@286: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ohair@286: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ohair@286: * version 2 for more details (a copy is included in the LICENSE file that ohair@286: * accompanied this code). ohair@286: * ohair@286: * You should have received a copy of the GNU General Public License version ohair@286: * 2 along with this work; if not, write to the Free Software Foundation, ohair@286: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ohair@286: * ohair@286: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@286: * or visit www.oracle.com if you need additional information or have any ohair@286: * questions. ohair@286: */ ohair@286: ohair@286: package com.sun.tools.internal.ws.wscompile; ohair@286: ohair@286: import com.sun.codemodel.internal.CodeWriter; ohair@286: import com.sun.codemodel.internal.writer.ProgressCodeWriter; ohair@286: import com.sun.tools.internal.ws.ToolVersion; ohair@286: import com.sun.tools.internal.ws.api.TJavaGeneratorExtension; ohair@286: import com.sun.tools.internal.ws.processor.generator.CustomExceptionGenerator; ohair@286: import com.sun.tools.internal.ws.processor.generator.GeneratorBase; ohair@286: import com.sun.tools.internal.ws.processor.generator.SeiGenerator; ohair@286: import com.sun.tools.internal.ws.processor.generator.ServiceGenerator; ohair@286: import com.sun.tools.internal.ws.processor.generator.JwsImplGenerator; ohair@286: import com.sun.tools.internal.ws.processor.model.Model; ohair@286: import com.sun.tools.internal.ws.processor.modeler.wsdl.ConsoleErrorReporter; ohair@286: import com.sun.tools.internal.ws.processor.modeler.wsdl.WSDLModeler; ohair@286: import com.sun.tools.internal.ws.processor.util.DirectoryUtil; ohair@286: import com.sun.tools.internal.ws.resources.WscompileMessages; ohair@286: import com.sun.tools.internal.ws.resources.WsdlMessages; ohair@286: import com.sun.tools.internal.ws.util.WSDLFetcher; ohair@286: import com.sun.tools.internal.ws.wsdl.parser.MetadataFinder; ohair@286: import com.sun.tools.internal.ws.wsdl.parser.WSDLInternalizationLogic; ohair@286: import com.sun.tools.internal.xjc.util.NullStream; ohair@286: import com.sun.xml.internal.ws.api.server.Container; ohair@286: import com.sun.xml.internal.ws.util.ServiceFinder; ohair@286: import com.sun.istack.internal.tools.ParallelWorldClassLoader; ohair@286: import org.xml.sax.EntityResolver; ohair@286: import org.xml.sax.SAXParseException; ohair@286: ohair@286: import javax.xml.bind.JAXBPermission; ohair@286: import javax.xml.stream.*; ohair@286: import javax.xml.ws.EndpointContext; ohair@286: import java.io.*; ohair@286: import java.util.*; ohair@286: import java.net.Authenticator; ohair@286: import java.util.jar.JarEntry; ohair@286: import java.util.jar.JarOutputStream; ohair@286: import org.xml.sax.SAXException; ohair@286: ohair@286: /** ohair@286: * @author Vivek Pandey ohair@286: */ ohair@286: public class WsimportTool { ohair@286: private static final String WSIMPORT = "wsimport"; ohair@286: private final PrintStream out; ohair@286: private final Container container; ohair@286: ohair@286: /** ohair@286: * Wsimport specific options ohair@286: */ ohair@286: protected WsimportOptions options = new WsimportOptions(); ohair@286: ohair@286: public WsimportTool(OutputStream out) { ohair@286: this(out, null); ohair@286: } ohair@286: ohair@286: public WsimportTool(OutputStream logStream, Container container) { ohair@286: this.out = (logStream instanceof PrintStream)?(PrintStream)logStream:new PrintStream(logStream); ohair@286: this.container = container; ohair@286: } ohair@286: ohair@286: protected class Listener extends WsimportListener { ohair@286: ConsoleErrorReporter cer = new ConsoleErrorReporter(out == null ? new PrintStream(new NullStream()) : out); ohair@286: ohair@286: @Override ohair@286: public void generatedFile(String fileName) { ohair@286: message(fileName); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void message(String msg) { ohair@286: out.println(msg); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void error(SAXParseException exception) { ohair@286: cer.error(exception); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void fatalError(SAXParseException exception) { ohair@286: cer.fatalError(exception); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void warning(SAXParseException exception) { ohair@286: cer.warning(exception); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void debug(SAXParseException exception) { ohair@286: cer.debug(exception); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void info(SAXParseException exception) { ohair@286: cer.info(exception); ohair@286: } ohair@286: ohair@286: public void enableDebugging(){ ohair@286: cer.enableDebugging(); ohair@286: } ohair@286: } ohair@286: ohair@286: protected class Receiver extends ErrorReceiverFilter { ohair@286: ohair@286: private Listener listener; ohair@286: ohair@286: public Receiver(Listener listener) { ohair@286: super(listener); ohair@286: this.listener = listener; ohair@286: } ohair@286: ohair@286: public void info(SAXParseException exception) { ohair@286: if (options.verbose) ohair@286: super.info(exception); ohair@286: } ohair@286: ohair@286: public void warning(SAXParseException exception) { ohair@286: if (!options.quiet) ohair@286: super.warning(exception); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void pollAbort() throws AbortException { ohair@286: if (listener.isCanceled()) ohair@286: throw new AbortException(); ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void debug(SAXParseException exception){ ohair@286: if(options.debugMode){ ohair@286: listener.debug(exception); ohair@286: } ohair@286: } ohair@286: } ohair@286: ohair@286: public boolean run(String[] args) { ohair@286: Listener listener = new Listener(); ohair@286: Receiver receiver = new Receiver(listener); ohair@286: return run(args, listener, receiver); ohair@286: } ohair@286: ohair@286: protected boolean run(String[] args, Listener listener, ohair@286: Receiver receiver) { ohair@286: for (String arg : args) { ohair@286: if (arg.equals("-version")) { ohair@286: listener.message( ohair@286: WscompileMessages.WSIMPORT_VERSION(ToolVersion.VERSION.MAJOR_VERSION)); ohair@286: return true; ohair@286: } ohair@286: if (arg.equals("-fullversion")) { ohair@286: listener.message( ohair@286: WscompileMessages.WSIMPORT_FULLVERSION(ToolVersion.VERSION.toString())); ohair@286: return true; ohair@286: } ohair@286: } ohair@286: ohair@286: Authenticator orig = null; ohair@286: try { ohair@286: parseArguments(args, listener, receiver); ohair@286: ohair@286: try { ohair@286: orig = DefaultAuthenticator.getCurrentAuthenticator(); ohair@286: ohair@286: Model wsdlModel = buildWsdlModel(listener, receiver); ohair@286: if (wsdlModel == null) ohair@286: return false; ohair@286: ohair@286: if (!generateCode(listener, receiver, wsdlModel, true)) ohair@286: return false; ohair@286: ohair@286: /* Not so fast! ohair@286: } catch(AbortException e){ ohair@286: //error might have been reported ohair@286: * ohair@286: */ ohair@286: }catch (IOException e) { ohair@286: receiver.error(e); ohair@286: return false; ohair@286: }catch (XMLStreamException e) { ohair@286: receiver.error(e); ohair@286: return false; ohair@286: } ohair@286: if (!options.nocompile){ ohair@286: if(!compileGeneratedClasses(receiver, listener)){ ohair@286: listener.message(WscompileMessages.WSCOMPILE_COMPILATION_FAILED()); ohair@286: return false; ohair@286: } ohair@286: } ohair@286: try { ohair@286: if (options.clientjar != null) { ohair@286: //add all the generated class files to the list of generated files ohair@286: addClassesToGeneratedFiles(); ohair@286: jarArtifacts(listener); ohair@286: ohair@286: } ohair@286: } catch (IOException e) { ohair@286: receiver.error(e); ohair@286: return false; ohair@286: } ohair@286: ohair@286: } catch (Options.WeAreDone done) { ohair@286: usage(done.getOptions()); ohair@286: } catch (BadCommandLineException e) { ohair@286: if (e.getMessage() != null) { ohair@286: System.out.println(e.getMessage()); ohair@286: System.out.println(); ohair@286: } ohair@286: usage(e.getOptions()); ohair@286: return false; ohair@286: } finally{ ohair@286: deleteGeneratedFiles(); ohair@286: if (!options.disableAuthenticator) { ohair@286: Authenticator.setDefault(orig); ohair@286: } ohair@286: } ohair@286: if(receiver.hadError()) { ohair@286: return false; ohair@286: } ohair@286: return true; ohair@286: } ohair@286: ohair@286: private void deleteGeneratedFiles() { ohair@286: Set trackedRootPackages = new HashSet(); ohair@286: ohair@286: if (options.clientjar != null) { ohair@286: //remove all non-java artifacts as they will packaged in jar. ohair@286: Iterable generatedFiles = options.getGeneratedFiles(); ohair@286: synchronized (generatedFiles) { ohair@286: for (File file : generatedFiles) { ohair@286: if (!file.getName().endsWith(".java")) { ohair@286: file.delete(); ohair@286: trackedRootPackages.add(file.getParentFile()); ohair@286: ohair@286: } ohair@286: ohair@286: } ohair@286: } ohair@286: //remove empty package dirs ohair@286: for(File pkg:trackedRootPackages) { ohair@286: ohair@286: while(pkg.list() != null && pkg.list().length ==0 && !pkg.equals(options.destDir)) { ohair@286: File parentPkg = pkg.getParentFile(); ohair@286: pkg.delete(); ohair@286: pkg = parentPkg; ohair@286: } ohair@286: } ohair@286: } ohair@286: if(!options.keep) { ohair@286: options.removeGeneratedFiles(); ohair@286: } ohair@286: ohair@286: } ohair@286: ohair@286: private void addClassesToGeneratedFiles() throws IOException { ohair@286: Iterable generatedFiles = options.getGeneratedFiles(); ohair@286: final List trackedClassFiles = new ArrayList(); ohair@286: for(File f: generatedFiles) { ohair@286: if(f.getName().endsWith(".java")) { ohair@286: String relativeDir = DirectoryUtil.getRelativePathfromCommonBase(f.getParentFile(),options.sourceDir); ohair@286: final String className = f.getName().substring(0,f.getName().indexOf(".java")); ohair@286: File classDir = new File(options.destDir,relativeDir); ohair@286: if(classDir.exists()) { ohair@286: classDir.listFiles(new FilenameFilter() { ohair@286: ohair@286: public boolean accept(File dir, String name) { ohair@286: if(name.equals(className+".class") || (name.startsWith(className+"$") && name.endsWith(".class"))) { ohair@286: trackedClassFiles.add(new File(dir,name)); ohair@286: return true; ohair@286: } ohair@286: return false; ohair@286: } ohair@286: }); ohair@286: } ohair@286: } ohair@286: } ohair@286: for(File f: trackedClassFiles) { ohair@286: options.addGeneratedFile(f); ohair@286: } ohair@286: } ohair@286: ohair@286: private void jarArtifacts(WsimportListener listener) throws IOException { ohair@286: File zipFile = new File(options.clientjar); ohair@286: if(!zipFile.isAbsolute()) { ohair@286: zipFile = new File(options.destDir, options.clientjar); ohair@286: } ohair@286: ohair@286: if (zipFile.exists()) { ohair@286: //TODO ohair@286: } ohair@286: FileOutputStream fos = null; ohair@286: if( !options.quiet ) ohair@286: listener.message(WscompileMessages.WSIMPORT_ARCHIVING_ARTIFACTS(zipFile)); ohair@286: ohair@286: ohair@286: fos = new FileOutputStream(zipFile); ohair@286: JarOutputStream jos = new JarOutputStream(fos); ohair@286: ohair@286: String base = options.destDir.getCanonicalPath(); ohair@286: for(File f: options.getGeneratedFiles()) { ohair@286: //exclude packaging the java files in the jar ohair@286: if(f.getName().endsWith(".java")) { ohair@286: continue; ohair@286: } ohair@286: if(options.verbose) { ohair@286: listener.message(WscompileMessages.WSIMPORT_ARCHIVE_ARTIFACT(f, options.clientjar)); ohair@286: } ohair@286: String entry = f.getCanonicalPath().substring(base.length()+1); ohair@286: BufferedInputStream bis = new BufferedInputStream( ohair@286: new FileInputStream(f)); ohair@286: JarEntry jarEntry = new JarEntry(entry); ohair@286: jos.putNextEntry(jarEntry); ohair@286: int bytesRead; ohair@286: byte[] buffer = new byte[1024]; ohair@286: while ((bytesRead = bis.read(buffer)) != -1) { ohair@286: jos.write(buffer, 0, bytesRead); ohair@286: } ohair@286: bis.close(); ohair@286: ohair@286: } ohair@286: ohair@286: jos.close(); ohair@286: ohair@286: } ohair@286: ohair@286: protected void parseArguments(String[] args, Listener listener, ohair@286: Receiver receiver) throws BadCommandLineException { ohair@286: options.parseArguments(args); ohair@286: options.validate(); ohair@286: if (options.debugMode) ohair@286: listener.enableDebugging(); ohair@286: options.parseBindings(receiver); ohair@286: } ohair@286: ohair@286: protected Model buildWsdlModel(Listener listener, ohair@286: Receiver receiver) throws BadCommandLineException, XMLStreamException, IOException { ohair@286: if( !options.quiet ) ohair@286: listener.message(WscompileMessages.WSIMPORT_PARSING_WSDL()); ohair@286: ohair@286: //set auth info ohair@286: //if(options.authFile != null) ohair@286: if (!options.disableAuthenticator) { ohair@286: Authenticator.setDefault(new DefaultAuthenticator(receiver, options.authFile)); ohair@286: } ohair@286: ohair@286: MetadataFinder forest = new MetadataFinder(new WSDLInternalizationLogic(), options, receiver); ohair@286: forest.parseWSDL(); ohair@286: if (forest.isMexMetadata) ohair@286: receiver.reset(); ohair@286: ohair@286: WSDLModeler wsdlModeler = new WSDLModeler(options, receiver,forest); ohair@286: Model wsdlModel = wsdlModeler.buildModel(); ohair@286: if (wsdlModel == null) { ohair@286: listener.message(WsdlMessages.PARSING_PARSE_FAILED()); ohair@286: } ohair@286: ohair@286: if(options.clientjar != null) { ohair@286: if( !options.quiet ) ohair@286: listener.message(WscompileMessages.WSIMPORT_FETCHING_METADATA()); ohair@286: options.wsdlLocation = new WSDLFetcher(options,listener).fetchWsdls(forest); ohair@286: } ohair@286: ohair@286: return wsdlModel; ohair@286: } ohair@286: ohair@286: protected boolean generateCode(Listener listener, Receiver receiver, ohair@286: Model wsdlModel, boolean generateService) ohair@286: throws IOException { ohair@286: //generated code ohair@286: if( !options.quiet ) ohair@286: listener.message(WscompileMessages.WSIMPORT_GENERATING_CODE()); ohair@286: ohair@286: TJavaGeneratorExtension[] genExtn = ServiceFinder.find(TJavaGeneratorExtension.class).toArray(); ohair@286: CustomExceptionGenerator.generate(wsdlModel, options, receiver); ohair@286: SeiGenerator.generate(wsdlModel, options, receiver, genExtn); ohair@286: if(receiver.hadError()){ ohair@286: throw new AbortException(); ohair@286: } ohair@286: if (generateService) ohair@286: { ohair@286: ServiceGenerator.generate(wsdlModel, options, receiver); ohair@286: } ohair@286: for (GeneratorBase g : ServiceFinder.find(GeneratorBase.class)) { ohair@286: g.init(wsdlModel, options, receiver); ohair@286: g.doGeneration(); ohair@286: } ohair@286: ohair@286: List implFiles = null; ohair@286: if (options.isGenerateJWS) { ohair@286: implFiles = JwsImplGenerator.generate(wsdlModel, options, receiver); ohair@286: } ohair@286: ohair@286: for (Plugin plugin: options.activePlugins) { ohair@286: try { ohair@286: plugin.run(wsdlModel, options, receiver); ohair@286: } catch (SAXException sex) { ohair@286: // fatal error. error should have been reported ohair@286: return false; ohair@286: } ohair@286: } ohair@286: ohair@286: CodeWriter cw; ohair@286: if (options.filer != null) { ohair@286: cw = new FilerCodeWriter(options.sourceDir, options); ohair@286: } else { ohair@286: cw = new WSCodeWriter(options.sourceDir, options); ohair@286: } ohair@286: ohair@286: if (options.verbose) ohair@286: cw = new ProgressCodeWriter(cw, out); ohair@286: options.getCodeModel().build(cw); ohair@286: ohair@286: if (options.isGenerateJWS) { ohair@286: //move Impl files to implDestDir ohair@286: return JwsImplGenerator.moveToImplDestDir(implFiles, options, receiver); ohair@286: } ohair@286: ohair@286: return true; ohair@286: } ohair@286: ohair@286: public void setEntityResolver(EntityResolver resolver){ ohair@286: this.options.entityResolver = resolver; ohair@286: } ohair@286: ohair@286: /* ohair@286: * To take care of JDK6-JDK6u3, where 2.1 API classes are not there ohair@286: */ ohair@286: private static boolean useBootClasspath(Class clazz) { ohair@286: try { ohair@286: ParallelWorldClassLoader.toJarUrl(clazz.getResource('/'+clazz.getName().replace('.','/')+".class")); ohair@286: return true; ohair@286: } catch(Exception e) { ohair@286: return false; ohair@286: } ohair@286: } ohair@286: ohair@286: protected boolean compileGeneratedClasses(ErrorReceiver receiver, WsimportListener listener){ ohair@286: List sourceFiles = new ArrayList(); ohair@286: ohair@286: for (File f : options.getGeneratedFiles()) { ohair@286: if (f.exists() && f.getName().endsWith(".java")) { ohair@286: sourceFiles.add(f.getAbsolutePath()); ohair@286: } ohair@286: } ohair@286: ohair@286: if (sourceFiles.size() > 0) { ohair@286: String classDir = options.destDir.getAbsolutePath(); ohair@286: String classpathString = createClasspathString(); ohair@286: boolean bootCP = useBootClasspath(EndpointContext.class) || useBootClasspath(JAXBPermission.class); ohair@286: String[] args = new String[4 + (bootCP ? 1 : 0) + (options.debug ? 1 : 0) ohair@286: + (options.encoding != null ? 2 : 0) + sourceFiles.size()]; ohair@286: args[0] = "-d"; ohair@286: args[1] = classDir; ohair@286: args[2] = "-classpath"; ohair@286: args[3] = classpathString; ohair@286: int baseIndex = 4; ohair@286: //javac is not working in osgi as the url starts with a bundle ohair@286: if (bootCP) { ohair@286: args[baseIndex++] = "-Xbootclasspath/p:"+JavaCompilerHelper.getJarFile(EndpointContext.class)+File.pathSeparator+JavaCompilerHelper.getJarFile(JAXBPermission.class); ohair@286: } ohair@286: ohair@286: if (options.debug) { ohair@286: args[baseIndex++] = "-g"; ohair@286: } ohair@286: ohair@286: if (options.encoding != null) { ohair@286: args[baseIndex++] = "-encoding"; ohair@286: args[baseIndex++] = options.encoding; ohair@286: } ohair@286: ohair@286: for (int i = 0; i < sourceFiles.size(); ++i) { ohair@286: args[baseIndex + i] = sourceFiles.get(i); ohair@286: } ohair@286: ohair@286: listener.message(WscompileMessages.WSIMPORT_COMPILING_CODE()); ohair@286: if(options.verbose){ ohair@286: StringBuffer argstr = new StringBuffer(); ohair@286: for(String arg:args){ ohair@286: argstr.append(arg).append(" "); ohair@286: } ohair@286: listener.message("javac "+ argstr.toString()); ohair@286: } ohair@286: ohair@286: return JavaCompilerHelper.compile(args, out, receiver); ohair@286: } ohair@286: //there are no files to compile, so return true? ohair@286: return true; ohair@286: } ohair@286: ohair@286: private String createClasspathString() { ohair@286: StringBuilder classpathStr = new StringBuilder(System.getProperty("java.class.path")); ohair@286: for(String s: options.cmdlineJars) { ohair@286: classpathStr.append(File.pathSeparator); ohair@286: classpathStr.append(new File(s).toString()); ohair@286: } ohair@286: return classpathStr.toString(); ohair@286: } ohair@286: ohair@286: protected void usage(Options options) { ohair@286: System.out.println(WscompileMessages.WSIMPORT_HELP(WSIMPORT)); ohair@286: System.out.println(WscompileMessages.WSIMPORT_USAGE_EXTENSIONS()); ohair@286: System.out.println(WscompileMessages.WSIMPORT_USAGE_EXAMPLES()); ohair@286: } ohair@286: }