Emitter.java |
/* * The Apache Software License, Version 1.1 * * * Copyright (c) 2001-2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Axis" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.jboss.axis.wsdl.toJava; import org.jboss.axis.encoding.DefaultSOAPEncodingTypeMappingImpl; import org.jboss.axis.encoding.DefaultTypeMappingImpl; import org.jboss.axis.encoding.TypeMapping; import org.jboss.axis.enums.Scope; import org.jboss.axis.i18n.Messages; import org.jboss.axis.utils.ClassUtils; import org.jboss.axis.utils.JavaUtils; import org.jboss.axis.wsdl.gen.GeneratorFactory; import org.jboss.axis.wsdl.gen.Parser; import org.jboss.axis.wsdl.symbolTable.BaseTypeMapping; import org.jboss.axis.wsdl.symbolTable.SymTabEntry; import org.jboss.axis.wsdl.symbolTable.SymbolTable; import org.w3c.dom.Document; import org.xml.sax.SAXException; import javax.wsdl.WSDLException; import javax.xml.namespace.QName; import javax.xml.parsers.ParserConfigurationException; import java.io.FileInputStream; import java.io.IOException; import java.lang.reflect.Constructor; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.Vector; /** * This class produces java files for stubs, skeletons, and types from a * WSDL document. * * @author Russell Butek (butek@us.ibm.com) * @author Tom Jordahl (tjordahl@macromedia.com) * @author Rich Scheuerle (scheu@us.ibm.com) * @author Steve Graham (sggraham@us.ibm.com) */ public class Emitter extends Parser { public static final String DEFAULT_NSTOPKG_FILE = "NStoPkg.properties"; protected HashMap namespaceMap = new HashMap(); protected String typeMappingVersion = "1.1"; protected BaseTypeMapping baseTypeMapping = null; protected Namespaces namespaces = null; protected String NStoPkgFilename = null; private boolean bEmitServer = false; private boolean bDeploySkeleton = false; private boolean bEmitTestCase = false; private boolean bGenerateAll = false; private boolean bHelperGeneration = false; private String packageName = null; private Scope scope = null; private GeneratedFileInfo fileInfo = new GeneratedFileInfo(); private HashMap delayedNamespacesMap = new HashMap(); private String outputDir = null; /** * Default constructor. */ public Emitter() { setFactory(new JavaGeneratorFactory(this)); } // ctor /////////////////////////////////////////////////// // // Command line switches // /** * Turn on/off server skeleton creation * * @param value */ public void setServerSide(boolean value) { this.bEmitServer = value; } // setServerSide /** * Indicate if we should be emitting server side code and deploy/undeploy */ public boolean isServerSide() { return bEmitServer; } // isServerSide /** * Turn on/off server skeleton deploy * * @param value */ public void setSkeletonWanted(boolean value) { bDeploySkeleton = value; } // setSkeletonWanted /** * Indicate if we should be deploying skeleton or implementation */ public boolean isSkeletonWanted() { return bDeploySkeleton; } // isSkeletonWanted /** * Turn on/off Helper class generation * * @param value */ public void setHelperWanted(boolean value) { bHelperGeneration = value; } // setHelperWanted /** * Indicate if we should be generating Helper classes */ public boolean isHelperWanted() { return bHelperGeneration; } // isHelperWanted /** * Turn on/off test case creation * * @param value */ public void setTestCaseWanted(boolean value) { this.bEmitTestCase = value; } // setTestCaseWanted public boolean isTestCaseWanted() { return bEmitTestCase; } // isTestCaseWanted /** * By default, code is generated only for referenced elements. * Call bGenerateAll(true) and WSDL2Java will generate code for all * elements in the scope regardless of whether they are * referenced. Scope means: by default, all WSDL files; if * generateImports(false), then only the immediate WSDL file. */ public void setAllWanted(boolean all) { bGenerateAll = all; } // setAllWanted public boolean isAllWanted() { return bGenerateAll; } // isAllWanted public Namespaces getNamespaces() { return namespaces; } // getNamespaces /** * Set the output directory to use in emitted source files */ public void setOutputDir(String outputDir) { this.outputDir = outputDir; } /** * Get the output directory to use for emitted source files */ public String getOutputDir() { return outputDir; } /** * Get global package name to use instead of mapping namespaces */ public String getPackageName() { return packageName; } /** * Set a global package name to use instead of mapping namespaces */ public void setPackageName(String packageName) { this.packageName = packageName; } /** * Set the scope for the deploy.xml file. * * @param scope One of 'null', * Scope.APPLICATION, Scope.REQUEST, Scope.SESSION. * Anything else is equivalent to 'null' null and no explicit * scope tag will appear in deploy.xml. */ public void setScope(Scope scope) { this.scope = scope; } // setScope /** * Get the scope for the deploy.xml file. */ public Scope getScope() { return scope; } // getScope /** * Set the NStoPkg mappings filename. */ public void setNStoPkg(String NStoPkgFilename) { if (NStoPkgFilename != null) { this.NStoPkgFilename = NStoPkgFilename; } } // setNStoPkg /** * Set a map of namespace -> Java package names */ public void setNamespaceMap(HashMap map) { delayedNamespacesMap = map; } /** * Get the map of namespace -> Java package names */ public HashMap getNamespaceMap() { return delayedNamespacesMap; } /** * Sets the <code>WriterFactory Class</code> to use * * @param factory the name of the factory <code>Class</code> */ public void setFactory(String factory) { try { Class clazz = ClassUtils.forName(factory); GeneratorFactory genFac = null; try { Constructor ctor = clazz.getConstructor(new Class[]{getClass()}); genFac = (GeneratorFactory) ctor.newInstance(new Object[]{this}); } catch (NoSuchMethodException ex) { genFac = (GeneratorFactory)clazz.newInstance(); } setFactory(genFac); } catch (Exception ex) { ex.printStackTrace(); } } // setFactory // // Command line switches // /////////////////////////////////////////////////// /** * Returns an object which contains of information on all generated files * including the class name, filename and a type string. * * @return An org.jboss.axis.wsdl.toJava.GeneratedFileInfo object * @see org.jboss.axis.wsdl.toJava.GeneratedFileInfo */ public GeneratedFileInfo getGeneratedFileInfo() { return fileInfo; } /** * This method returns a list of all generated class names. */ public List getGeneratedClassNames() { return fileInfo.getClassNames(); } /** * This method returns a list of all generated file names. */ public List getGeneratedFileNames() { return fileInfo.getFileNames(); } /** * Get the Package name for the specified namespace */ public String getPackage(String namespace) { return namespaces.getCreate(namespace); } /** * Get the Package name for the specified QName */ public String getPackage(QName qName) { return getPackage(qName.getNamespaceURI()); } /** * Convert the specified QName into a full Java Name. */ public String getJavaName(QName qName) { // If this is one of our special 'collection' qnames. // get the element type and append [] if (qName.getLocalPart().indexOf("[") > 0) { String localPart = qName.getLocalPart().substring(0, qName.getLocalPart().indexOf("[")); QName eQName = new QName(qName.getNamespaceURI(), localPart); return getJavaName(eQName) + "[]"; } // Handle the special "java" namespace for types if (qName.getNamespaceURI().equalsIgnoreCase("java")) { return qName.getLocalPart(); } // The QName may represent a base java name, so check this first String fullJavaName = getFactory().getBaseTypeMapping().getBaseName(qName); if (fullJavaName != null) return fullJavaName; // Use the namespace uri to get the appropriate package String pkg = getPackage(qName.getNamespaceURI()); if (pkg != null) { fullJavaName = pkg + "." + Utils.xmlNameToJavaClass(qName.getLocalPart()); } else { fullJavaName = Utils.xmlNameToJavaClass(qName.getLocalPart()); } return fullJavaName; } // getJavaName /** * Emit appropriate Java files for a WSDL at a given URL. * <p/> * This method will time out after the number of milliseconds specified * by our timeoutms member. */ public void run(String wsdlURL) throws Exception { setup(); super.run(wsdlURL); } // run /** * Call this method if your WSDL document has already been * parsed as an XML DOM document. * * @param context context This is directory context for the Document. * If the Document were from file "/x/y/z.wsdl" then the context * could be "/x/y" (even "/x/y/z.wsdl" would work). * If context is null, then the context becomes the current directory. * @param doc doc This is the XML Document containing the WSDL. */ public void run(String context, Document doc) throws IOException, SAXException, WSDLException, ParserConfigurationException { setup(); super.run(context, doc); } // run private void setup() throws IOException { if (baseTypeMapping == null) { setTypeMappingVersion(typeMappingVersion); } getFactory().setBaseTypeMapping(baseTypeMapping); namespaces = new Namespaces(outputDir); if (packageName != null) { namespaces.setDefaultPackage(packageName); } else { // First, read the namespace mapping file - configurable, by default // NStoPkg.properties - if it exists, and load the namespaceMap HashMap // with its data. getNStoPkgFromPropsFile(namespaces); if (delayedNamespacesMap != null) { namespaces.putAll(delayedNamespacesMap); } } } // setup protected void sanityCheck(SymbolTable symbolTable) { Iterator it = symbolTable.getHashMap().values().iterator(); while (it.hasNext()) { Vector v = (Vector)it.next(); for (int i = 0; i < v.size(); ++i) { SymTabEntry entry = (SymTabEntry)v.elementAt(i); String namespace = entry.getQName().getNamespaceURI(); String packageName = org.jboss.axis.wsdl.toJava.Utils.makePackageName(namespace); String localName = entry.getQName().getLocalPart(); if (localName.equals(packageName) && packageName.equals(namespaces.getCreate(namespace))) { packageName += "_pkg"; namespaces.put(namespace, packageName); } } } } /** * Tries to load the namespace-to-package mapping file. * <ol> * <li>if a file name is explicitly set using <code>setNStoPkg()</code>, tries * to load the mapping from this file. If this fails, the built-in default * mapping is used. * <p/> * <li>if no file name is set, tries to load the file <code>DEFAULT_NSTOPKG_FILE</code> * as a java resource. If this fails, the built-in dfault mapping is used. * </ol> * * @param namespaces a hashmap which is filled with the namespace-to-package mapping * in this method * @see #setNStoPkg(String) * @see #DEFAULT_NSTOPKG_FILE * @see org.jboss.axis.utils.ClassUtils#getResourceAsStream(java.lang.Class,String) */ private void getNStoPkgFromPropsFile(HashMap namespaces) throws IOException { Properties mappings = new Properties(); if (NStoPkgFilename != null) { try { mappings.load(new FileInputStream(NStoPkgFilename)); if (verbose) { System.out.println(Messages.getMessage("nsToPkgFileLoaded00", NStoPkgFilename)); } } catch (Throwable t) { // loading the custom mapping file failed. We do not try // to load the mapping from a default mapping file. throw new IOException(Messages.getMessage("nsToPkgFileNotFound00", NStoPkgFilename)); } } else { try { mappings.load(new FileInputStream(DEFAULT_NSTOPKG_FILE)); if (verbose) { System.out.println(Messages.getMessage("nsToPkgFileLoaded00", DEFAULT_NSTOPKG_FILE)); } } catch (Throwable t) { try { mappings.load(ClassUtils.getResourceAsStream(Emitter.class, DEFAULT_NSTOPKG_FILE)); if (verbose) { System.out.println(Messages.getMessage("nsToPkgDefaultFileLoaded00", DEFAULT_NSTOPKG_FILE)); } } catch (Throwable t1) { // loading the default mapping file failed. // The built-in default mapping is used // No message is given, since this is generally what happens } } } Enumeration keys = mappings.propertyNames(); while (keys.hasMoreElements()) { String key = (String)keys.nextElement(); namespaces.put(key, mappings.getProperty(key)); } } // getNStoPkgFromPropsFile public void setTypeMappingVersion(String typeMappingVersion) { if (typeMappingVersion.equals("1.1")) { baseTypeMapping = new BaseTypeMapping() { final TypeMapping defaultTM = DefaultTypeMappingImpl.getSingleton(); public String getBaseName(QName qNameIn) { javax.xml.namespace.QName qName = new javax.xml.namespace.QName(qNameIn.getNamespaceURI(), qNameIn.getLocalPart()); Class cls = defaultTM.getClassForQName(qName); if (cls == null) return null; else return JavaUtils.getTextClassName(cls.getName()); } }; } else { baseTypeMapping = new BaseTypeMapping() { final TypeMapping defaultTM = DefaultSOAPEncodingTypeMappingImpl.create(); public String getBaseName(QName qNameIn) { javax.xml.namespace.QName qName = new javax.xml.namespace.QName(qNameIn.getNamespaceURI(), qNameIn.getLocalPart()); Class cls = defaultTM.getClassForQName(qName); if (cls == null) return null; else return JavaUtils.getTextClassName(cls.getName()); } }; } } // The remainder are deprecated methods. /** * Get the GeneratorFactory. * * @deprecated Call getFactory instead. This doesn't return * a WriterFactory, it returns a GeneratorFactory. */ public GeneratorFactory getWriterFactory() { return getFactory(); } // getWriterFactory /** * Call this method if you have a uri for the WSDL document * * @param uri wsdlURI the location of the WSDL file. * @deprecated Call run(uri) instead. */ public void emit(String uri) throws Exception { run(uri); } // emit /** * Call this method if your WSDL document has already been * parsed as an XML DOM document. * * @param context context This is directory context for the Document. * If the Document were from file "/x/y/z.wsdl" then the context could be "/x/y" * (even "/x/y/z.wsdl" would work). If context is null, then the context * becomes the current directory. * @param doc doc This is the XML Document containing the WSDL. * @deprecated Call run(context, doc) instead. */ public void emit(String context, Document doc) throws IOException, SAXException, WSDLException, ParserConfigurationException { run(context, doc); } // emit /** * Turn on/off server-side binding generation * * @param value * @deprecated Use setServerSide(value) */ public void generateServerSide(boolean value) { setServerSide(value); } /** * Indicate if we should be emitting server side code and deploy/undeploy * * @deprecated Use isServerSide() */ public boolean getGenerateServerSide() { return isServerSide(); } /** * Turn on/off server skeleton deploy * * @param value * @deprecated Use setSkeletonWanted(value) */ public void deploySkeleton(boolean value) { setSkeletonWanted(value); } /** * Indicate if we should be deploying skeleton or implementation * * @deprecated Use isSkeletonWanted() */ public boolean getDeploySkeleton() { return isSkeletonWanted(); } /** * Turn on/off Helper class generation * * @param value * @deprecated Use setHelperWanted(value) */ public void setHelperGeneration(boolean value) { setHelperWanted(value); } /** * Indicate if we should be generating Helper classes * * @deprecated Use isHelperWanted() */ public boolean getHelperGeneration() { return isHelperWanted(); } /** * Turn on/off generation of elements from imported files. * * @param generateImports * @deprecated Use setImports(generateImports) */ public void generateImports(boolean generateImports) { setImports(generateImports); } // generateImports /** * Turn on/off debug messages. * * @param value * @deprecated Use setDebug(value) */ public void debug(boolean value) { setDebug(value); } // debug /** * Return the status of the debug switch. * * @deprecated Use isDebug() */ public boolean getDebug() { return isDebug(); } // getDebug /** * Turn on/off verbose messages * * @param value * @deprecated Use setVerbose(value) */ public void verbose(boolean value) { setVerbose(value); } /** * Return the status of the verbose switch * * @deprecated Use isVerbose() */ public boolean getVerbose() { return isVerbose(); } /** * Turn on/off test case creation * * @param value * @deprecated Use setTestCaseWanted() */ public void generateTestCase(boolean value) { setTestCaseWanted(value); } /** * @deprecated Use setAllWanted(all) */ public void generateAll(boolean all) { setAllWanted(all); } // generateAll }
Emitter.java |