Package org.apache.ws.resource.tool

Source Code of org.apache.ws.resource.tool.Wsdl2Java

/*=============================================================================*
*  Copyright 2004 The Apache Software Foundation
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*=============================================================================*/
package org.apache.ws.resource.tool;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.ws.resource.ResourceDefinition;
import org.apache.ws.resource.i18n.Keys;
import org.apache.ws.resource.i18n.MessagesImpl;
import org.apache.ws.resource.impl.ResourceDefinitionImpl;
import org.apache.ws.resource.tool.velocity.ImplementsListBuilder;
import org.apache.ws.resource.tool.velocity.ServiceProperties;
import org.apache.ws.util.XmlBeanNameUtils;
import org.apache.ws.util.OperationInfo;
import org.apache.ws.util.i18n.Messages;
import org.apache.ws.util.velocity.CommonsLogLogSystem;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.impl.common.XmlErrorPrinter;
import org.apache.xmlbeans.impl.common.NameUtil;
import org.apache.xmlbeans.impl.tool.SchemaCompiler;


import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.wsdl.Fault;
import javax.wsdl.Message;
import javax.wsdl.Part;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.xml.namespace.QName;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.FilenameFilter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;

/**
* Generates Java Web service types and skeletons from a WSRF WSDL.
*
* @author Ian Springer (ian DOT springer AT hp DOT com)
*/
public class Wsdl2Java
{
    private static final Messages MSG = MessagesImpl.getInstance();

    /**
     * DOCUMENT_ME
     */
    protected static final Options CMD_LINE_OPTIONS = new Options();

    static
    {
        initCmdLineOptions();
    }

    private File[] m_wsdlFiles;
    private Wsdl2JavaOptions m_options;
    private Map m_portTypeInfoMap = new HashMap();
    private WSDLReader m_wsdlReader;
    private File m_outputDir;
    private File[] m_classpath;
    private File m_xmlbeansDir;
    protected String WEBAPP_NAME = "wsrf";

    /**
     * Creates a new {@link Wsdl2Java} object.
     *
     * @param wsdlFiles DOCUMENT_ME
     * @param outputDir DOCUMENT_ME
     * @param classpathFiles
     * @param options   DOCUMENT_ME
     */
    public Wsdl2Java( File[] wsdlFiles,
                      File outputDir,
                      File[] classpathFiles,
                      Wsdl2JavaOptions options ) throws Exception
    {
        m_wsdlFiles = wsdlFiles;
        if ( m_wsdlFiles.length == 0 )
        {
            System.out.println( MSG.getMessage( Keys.WARN_EMPTY_WSDLS ) );
        }
        for (int i = 0; i < wsdlFiles.length; i++)
        {
            File wsdlFile = wsdlFiles[i];
            if(!wsdlFile.getName().endsWith(".wsdl"))
            {
                System.out.println(MSG.getMessage( Keys.ERROR_ONLY_WSDLS , wsdlFile.getName()));
                System.exit(0);
            }
        }
        m_outputDir = outputDir;
        m_xmlbeansDir = new File( m_outputDir, ".xmlbeans" );
        m_classpath = classpathFiles;
        validateClasspath();
        m_options = ( options != null ) ? options : new Wsdl2JavaOptions();
        m_wsdlReader = WSDLFactory.newInstance().newWSDLReader();
        initVelocity();
        initPortTypeInfoMap();
    }

    private void validateClasspath()
            throws MalformedURLException
    {
        URLClassLoader cpClassLoader = new URLClassLoader( toURLs( m_classpath ), null );
        try
        {
            cpClassLoader.loadClass( XmlObject.class.getName() );
        }
        catch ( ClassNotFoundException cnfe )
        {
            throw new IllegalStateException( "Specified classpath must contain the XMLBeans runtime jar (e.g. xbean-v1HEAD-SNAPSHOT-20041129.jar)" );
        }
        try
        {
            cpClassLoader.loadClass( org.oasisOpen.docs.wsrf.x2004.x06.wsrfWSResourceProperties12Draft01.GetResourcePropertyDocument.class.getName() );
        }
        catch ( ClassNotFoundException cnfe )
        {
            throw new IllegalStateException( "Specified classpath must contain the WSRF generated XMLBeans jar (e.g. wsrf-xbeans-SNAPSHOT.jar)" );
        }
    }

    private URL[] toURLs( File[] files ) throws MalformedURLException
    {
        URL[] urls = new URL[files.length];
        for ( int i = 0; i < files.length; i++ )
        {
            urls[i] = files[i].toURL();
        }
        return urls;
    }

    /**
     * DOCUMENT_ME
     *
     * @return DOCUMENT_ME
     */
    public Wsdl2JavaOptions getOptions()
    {
        return m_options;
    }

    /**
     * DOCUMENT_ME
     *
     * @return DOCUMENT_ME
     */
    public File getOutputDir()
    {
        return m_outputDir;
    }

    /**
     * DOCUMENT_ME
     *
     * @return DOCUMENT_ME
     */
    public File[] getWsdlFiles()
    {
        return m_wsdlFiles;
    }

    /**
     * DOCUMENT_ME
     *
     * @throws Exception DOCUMENT_ME
     */
    public void generate()
            throws Exception
    {
        for ( int i = 0; i < m_wsdlFiles.length; i++ )
        {
            processWsdlFile( m_wsdlFiles[i] );
        }
    }

    private void processWsdlFile( File wsdlFile )
            throws Exception
    {
        System.out.println( "Processing WSDL file \"" + wsdlFile + "\"..." );
        Definition def = m_wsdlReader.readWSDL( wsdlFile.getPath() );
        generateXmlBeans( wsdlFile );
        Iterator serviceIter = def.getServices().values().iterator();
        while ( serviceIter.hasNext() )
        {
            Service service = (Service) serviceIter.next();
            Iterator iterator = service.getPorts().values().iterator();
            while (iterator.hasNext())
            {
                Port port = (Port) iterator.next();
                ResourceDefinition resourceDef = new ResourceDefinitionImpl( def, port, wsdlFile.toURL());
                File serviceDir = new File( m_outputDir, resourceDef.getName() );
                System.out.println( "Processing WSRF WSDL port \"" + resourceDef.getName() + "\"..." );
                processTemplates( resourceDef, wsdlFile, serviceDir );
                copyWsdlFile( wsdlFile, serviceDir );
            }
        }

    }

    /**
     * DOCUMENT_ME
     *
     * @param args DOCUMENT_ME
     *
     * @throws ParseException DOCUMENT_ME
     */
    public static void main( String[] args )
            throws ParseException
    {
        CommandLine cmdLine = new PosixParser().parse( CMD_LINE_OPTIONS, args, true );
        checkForRequiredOption( cmdLine, Opts.OUTPUT_DIR );
        checkForRequiredOption( cmdLine, Opts.CLASSPATH );
        File outputDir = new File( cmdLine.getOptionValue( Opts.OUTPUT_DIR ) );
        File[] classpathFiles = toFileArray( cmdLine.getOptionValue( Opts.CLASSPATH ) );

        Wsdl2JavaOptions options = new Wsdl2Java.Wsdl2JavaOptions();

        if ( cmdLine.hasOption( Opts.VERBOSE ) )
        {
            options.setVerbose( Boolean.valueOf( cmdLine.getOptionValue( Opts.VERBOSE ) ).booleanValue() );
        }

        File[] wsdlFiles = new File[cmdLine.getArgs().length];
        for ( int i = 0; i < cmdLine.getArgs().length; i++ )
        {
            wsdlFiles[i] = new File( cmdLine.getArgs()[i] );
        }

        try
        {
            System.out.println( MSG.getMessage( Keys.WSDL4J_PASSED_ARGUMENTS,
                    Integer.toString( wsdlFiles.length ),
                    outputDir ) );
            new Wsdl2Java( wsdlFiles, outputDir, classpathFiles, options ).generate();
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            System.exit( 1 );
        }
    }

    /**
     * DOCUMENT_ME
     *
     * @param ptName DOCUMENT_ME
     *
     * @return DOCUMENT_ME
     */
    protected PortType2JavaInfo getPortType2JavaInfo( QName ptName )
    {
        return (PortType2JavaInfo) m_portTypeInfoMap.get( ptName );
    }

    /**
     * DOCUMENT_ME
     *
     * @param ptInfo DOCUMENT_ME
     */
    protected void addPortType2JavaInfo( PortType2JavaInfo ptInfo )
    {
        m_portTypeInfoMap.put( ptInfo.getName(), ptInfo );
    }

    private static void checkForRequiredOption( CommandLine cmdLine,
                                                String opt )
    {
        if ( !cmdLine.hasOption( opt ) )
        {
            System.err.println( MSG.getMessage( Keys.OPT_REQUIRED, opt ) );
            System.exit( 1 );
        }
    }

    private static void initCmdLineOptions()
    {
        CMD_LINE_OPTIONS.addOption( Opts.OUTPUT_DIR,
                LongOpts.OUTPUT_DIR,
                true,
                MSG.getMessage( Keys.OPT_OUTPUT_DIR_FOR_GEN_SRC ) );
        CMD_LINE_OPTIONS.addOption( Opts.CLASSPATH,
                LongOpts.CLASSPATH,
                true,
                MSG.getMessage( Keys.OPT_CLASSPATH_SENT_TO_XMLBEANS ) );
        CMD_LINE_OPTIONS.addOption( Opts.VERBOSE,
                LongOpts.VERBOSE,
                false,
                MSG.getMessage( Keys.OPT_ENABLE_VERBOSE ) );
    }

    private String getJarFileName( File wsdlFile )
    {
        String wsdlFileName = wsdlFile.getName();
        String baseName = wsdlFileName.substring( 0, wsdlFileName.lastIndexOf( "." ) );
        return baseName + "-xbeans.jar";
    }

    private File getPackageDir( String targetNamespace, File serviceDir )
    {
        String javaPackageName = GenerationUtils.getJavaPackageName( targetNamespace );
        File javaDir = new File( serviceDir, "src/java" );
        return new File( javaDir,
                javaPackageName.replace( '.', '/' ) );
    }

    private File getTempDir()
    {
        String userTempDir = System.getProperty( "java.io.tmpdir" );
        File userDir = new File( userTempDir );
        userDir.mkdirs();
        File tempClassesDir = new File( userDir, "tmp" + new Date().getTime() );
        tempClassesDir.mkdir();
        return tempClassesDir;
    }

    protected ServiceProperties buildServiceProperties( ResourceDefinition resourceDef,
                                                      File wsdlFile,
                                                      File serviceDir )
    {
        ServiceProperties props = new ServiceProperties(resourceDef);       
        String targetNamespace = resourceDef.getDefinition().getTargetNamespace();
        props.setPackageName( GenerationUtils.getJavaPackageName( targetNamespace ) );
        String serviceName = resourceDef.getName();
        String capitalizedServiceName = StringUtils.capitalize( serviceName );
        props.setServiceName( capitalizedServiceName );
        props.setSrcDir( new File( serviceDir, "src/java" ).getAbsolutePath() );
        props.setJarDir( new File(m_xmlbeansDir,"lib").getAbsolutePath() );
        props.setJarFileName( getJarFileName( wsdlFile ) );
        props.setClassesDir( new File( serviceDir, "classes" ).getAbsolutePath() );
        props.setEndpointURL( resourceDef.getEndpointURL() );
        props.setEndpointServiceName( serviceName );
        props.setServiceImplements( ImplementsListBuilder.getServiceImplementsList( resourceDef, m_portTypeInfoMap ) );
        props.setNamespace( targetNamespace );
        props.setPrefix( GenerationUtils.getPrefix( targetNamespace ) );
        props.setCustomMappings( GenerationUtils.getOperationInfoMap( resourceDef ) );
        props.setHasProperties( resourceDef.hasProperties() );
        props.setWebappName(getWebbappName());

        if (resourceDef.hasProperties())
        {
            QName[] propertyNames = resourceDef.getPropertyNames();
            Map propMap = new HashMap();
            for ( int i = 0; i < propertyNames.length; i++ )
            {
                QName propertyName = propertyNames[i];
                String propName = getJavaConstantName( propertyName, propMap );
                propMap.put( propName, propertyName );
            }
            props.setPropertyMap( propMap );
        }

        // define the names of the resource props that we initialize for the user...
        props.addImplementedProperty(org.apache.ws.resource.lifetime.v2004_06.porttype.ScheduledResourceTerminationPortType.PROP_QNAME_TERMINATION_TIME);
        props.addImplementedProperty(org.apache.ws.resource.lifetime.v2004_06.porttype.ScheduledResourceTerminationPortType.PROP_QNAME_CURRENT_TIME);
        props.addImplementedProperty(org.apache.ws.resource.lifetime.v2004_11.porttype.ScheduledResourceTerminationPortType.PROP_QNAME_TERMINATION_TIME);
        props.addImplementedProperty(org.apache.ws.resource.lifetime.v2004_11.porttype.ScheduledResourceTerminationPortType.PROP_QNAME_CURRENT_TIME);

        props.setResourceImplements( ImplementsListBuilder.getResourceImplementsList( resourceDef, m_portTypeInfoMap ) );
        QName propertiesDocumentName = resourceDef.getPropertiesDocumentName();
        if( propertiesDocumentName != null)
        {
        props.setPropertyDocumentName(
                XmlBeanNameUtils.getDocumentElementXmlBeanClassName(
                  propertiesDocumentName       ) );
        }
        props.setWsdlName( wsdlFile.getName() );
        props.setResourcekey( new QName( targetNamespace, "ResourceIdentifier" ) );
        Iterator ptNameIter = resourceDef.getImplementedResourceCapabilities().keySet().iterator();
        while ( ptNameIter.hasNext() )
        {
            QName ptName = (QName) ptNameIter.next();
            PortType2JavaInfo ptInfo = (PortType2JavaInfo) m_portTypeInfoMap.get( ptName );
            if ( ptInfo != null )
            {
                if ( ptInfo.getResourceTemplateFileName() != null )
                {
                    props.addResourceIncludeFile( ptInfo.getResourceTemplateFileName() );
                }
                if ( ptInfo.getResourceInitMethodIncludeLocation() != null )
                {
                    props.addResourceInitIncludeLocation( ptInfo.getResourceInitMethodIncludeLocation() );
                }
                if ( ptInfo.getAbstractResourceInitMethodIncludeLocation() != null )
                {
                    props.addAbstractResourceInitIncludeLocation( ptInfo.getAbstractResourceInitMethodIncludeLocation() );
                }
                if ( ptInfo.getServiceTemplateFileName() != null )
                {
                    props.addServiceIncludeFile( ptInfo.getServiceTemplateFileName() );
                }
            }
            else
            {
                System.err.println("\n\nUnable to find a port type info for the implemented capability: " + ptName.toString() + "!!!!!!\n\n");
            }
        }

        if(isDraft01Specific(resourceDef))
        {
            props.setNamespaceVersionHolder(org.apache.ws.resource.properties.v2004_06.impl.NamespaceVersionHolderImpl.class);
        }
        else if(isDraft05Specific(resourceDef))
        {
            props.setNamespaceVersionHolder(org.apache.ws.resource.properties.v2004_11.impl.NamespaceVersionHolderImpl.class);
        }

        /*
         * These props are for JIRA APOLLO-4 and could be added to context obj
         * The question is whether the service name here should be the real wsdl
         * service name or the service name as we use it...
         */
        String portName = resourceDef.getPort().getName();
        props.setPortName(portName);
        QName portTypeQName = resourceDef.getPortType().getQName();
        props.setPortTypeQName(portTypeQName);
        QName serviceQname = new QName(targetNamespace,serviceName);
        props.setServiceQName(serviceQname);
        return props;
    }

    private String getJavaConstantName( QName propertyName, Map propMap )
    {
        String constName = propertyName.getLocalPart().toUpperCase();
        for ( int count = 2; propMap.containsKey( constName ); count++ )
        {
            constName += count;
        }
        return constName;
    }

    protected String getWebbappName()
    {
        return WEBAPP_NAME;
    }

    private boolean isDraft05Specific(ResourceDefinition resourceDef)
    {
        return resourceDef.implementsResourceCapability(org.apache.ws.resource.properties.v2004_11.porttype.GetMultipleResourcePropertiesPortType.NAME)
        || resourceDef.implementsResourceCapability(org.apache.ws.resource.properties.v2004_11.porttype.GetResourcePropertyDocumentPortType.NAME)
        || resourceDef.implementsResourceCapability(org.apache.ws.resource.properties.v2004_11.porttype.DeleteResourcePropertiesPortType.NAME)
        || resourceDef.implementsResourceCapability(org.apache.ws.resource.properties.v2004_11.porttype.GetResourcePropertyPortType.NAME)
        || resourceDef.implementsResourceCapability(org.apache.ws.resource.properties.v2004_11.porttype.InsertResourcePropertiesPortType.NAME)
        || resourceDef.implementsResourceCapability(org.apache.ws.resource.properties.v2004_11.porttype.QueryResourcePropertiesPortType.NAME)
        || resourceDef.implementsResourceCapability(org.apache.ws.resource.properties.v2004_11.porttype.SetResourcePropertiesPortType.NAME)
        || resourceDef.implementsResourceCapability(org.apache.ws.resource.properties.v2004_11.porttype.UpdateResourcePropertiesPortType.NAME);
    }

    private boolean isDraft01Specific(ResourceDefinition resourceDef)
    {
        return resourceDef.implementsResourceCapability(org.apache.ws.resource.properties.v2004_06.porttype.GetMultipleResourcePropertiesPortType.NAME)
           || resourceDef.implementsResourceCapability(org.apache.ws.resource.properties.v2004_06.porttype.GetResourcePropertyPortType.NAME)
           || resourceDef.implementsResourceCapability(org.apache.ws.resource.properties.v2004_06.porttype.QueryResourcePropertiesPortType.NAME)
           || resourceDef.implementsResourceCapability(org.apache.ws.resource.properties.v2004_06.porttype.SetResourcePropertiesPortType.NAME);
    }

    private void generateXmlBeans( File wsdlFile )
            throws Exception
    {
        System.out.println( "Generating XMLBeans for WSDL file \"" + wsdlFile + "\"..." );
        SchemaCompiler.Parameters scompParams = new SchemaCompiler.Parameters();
        scompParams.setSrcDir( new File( m_xmlbeansDir, "src" ) );
        File tempClassesDir = getTempDir();
        scompParams.setClassesDir( tempClassesDir );
        scompParams.setWsdlFiles( new File[]
        {
            wsdlFile
        } );

        String xmlbeansJarFileName = getJarFileName( wsdlFile );
        File[] classpath = removeJarFromClasspathArray(xmlbeansJarFileName, m_classpath);
        scompParams.setClasspath( classpath );
        scompParams.setDownload( true )// download remote xsd inputs/imports
        scompParams.setDebug( true );     // compile w/ debug symbols
        scompParams.setVerbose( m_options.isVerbose() );
        scompParams.setQuiet( ! m_options.isVerbose() );
        final boolean beNoisy = true;
        XmlErrorPrinter xErrorListener = new XmlErrorPrinter( beNoisy, null );
        scompParams.setErrorListener( xErrorListener );
        File jarDir = new File( m_xmlbeansDir, "lib" );
        jarDir.mkdirs();
        scompParams.setOutputJar( new File( jarDir, xmlbeansJarFileName ) );
        try
        {
            if ( !SchemaCompiler.compile( scompParams ) )
            {
                throw new Exception( xErrorListener.toString() );
            }
        }
        finally
        {
            //delete the temp directory
            FileUtils.deleteDirectory( tempClassesDir );
        }
    }

    /**
     * This method is used to remove an existing xmlbeans jar of the same name from the
     * array of files passed to scomp.  This will avoid the potential deletion of the
     * previously generated jar file and scomps lack of regenerating classes for existing jars.
     *
     * This will ensure scomp generates the jar for the given xbeans jar name.
     *
     * @param xmlbeansJarFileName
     * @param classpath
     */
    private File[] removeJarFromClasspathArray(String xmlbeansJarFileName, File[] classpath)
    {
        List fileList = new ArrayList();
        for (int i = 0; i < classpath.length; i++)
        {
            File file = classpath[i];
            if( ! xmlbeansJarFileName.equals(file.getName()))
            {
                fileList.add(file);
            }
            else
            {
                System.out.println("Found existing generated xmlbean jar in the classpath at location: " + file.toString() +
                                   " ...This will be removed from the classpath sent to Scomp in order " +
                                   "to regenerate all imports.");
            }
        }

        return (File[])fileList.toArray(new File[0]);
    }

    private void copyWsdlFile( File wsdlFile, File serviceDir )
            throws IOException
    {
        File javaDir = new File( serviceDir, "src" );
        File wsdlDir = new File( javaDir, "wsdl" );
        wsdlDir.mkdirs();
        FileUtils.copyFile( wsdlFile, new File( wsdlDir, wsdlFile.getName() ) );
    }

    private void initPortTypeInfoMap()
    {
        //draft 01
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_06.GetResourcePropertyPortType2JavaInfo() );
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_06.GetMultipleResourcePropertiesPortType2JavaInfo() );
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_06.SetResourcePropertiesPortType2JavaInfo() );
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_06.QueryResourcePropertiesPortType2JavaInfo() );
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_06.ImmediateResourceTerminationPortType2JavaInfo() );
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_06.ScheduledResourceTerminationPortType2JavaInfo() );

        //draft 05
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_11.GetResourcePropertyPortType2JavaInfo() );
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_11.GetMultipleResourcePropertiesPortType2JavaInfo() );
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_11.SetResourcePropertiesPortType2JavaInfo() );
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_11.QueryResourcePropertiesPortType2JavaInfo() );
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_11.ImmediateResourceTerminationPortType2JavaInfo() );
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_11.ScheduledResourceTerminationPortType2JavaInfo() );

        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_11.InsertResourcePropertiesPortType2JavaInfo() );
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_11.UpdateResourcePropertiesPortType2JavaInfo() );
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_11.DeleteResourcePropertiesPortType2JavaInfo() );
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_11.GetResourcePropertyDocumentPortType2JavaInfo() );

        //metadataexchange 2004/09
        addPortType2JavaInfo( new org.apache.ws.resource.tool.porttype.v2004_09.MetadataExchangePortType2JavaInfo() );       
    }

    private void initVelocity()
            throws Exception
    {
        // configure to use Commons Logging for logging
        Velocity.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, CommonsLogLogSystem.class.getName() );
        // don't log warnings for invalid variable references
        Velocity.setProperty( RuntimeConstants.RUNTIME_LOG_REFERENCE_LOG_INVALID, "false" );
        // don't load any global macro libraries (override default of "VM_global_library.vm")
        Velocity.setProperty( RuntimeConstants.VM_LIBRARY, "" );
        // configure to use classpath-based resource loader
        Velocity.addProperty( RuntimeConstants.RESOURCE_LOADER, "classpath" );
        String resourceLoaderBaseKey = "classpath." + RuntimeConstants.RESOURCE_LOADER + ".";
        Velocity.setProperty( resourceLoaderBaseKey + "class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader" );
        Velocity.setProperty( resourceLoaderBaseKey + "cache", "false" );
        Velocity.setProperty( resourceLoaderBaseKey + "modificationCheckInterval", "2" );
        Velocity.init();
    }

    private void processTemplate( VelocityContext context,
                                  String templateLocation,
                                  File outputFile )
            throws Exception
    {
        /*
         *  get the Template object.  This is the parsed version of your
         *  template input file.  Note that getTemplate() can throw
         *   ResourceNotFoundException : if it doesn't find the template
         *   ParseErrorException : if there is something wrong with the VTL
         *   Exception : if something else goes wrong (this is generally
         *        indicative of a serious problem...)
         */
        try
        {
            Template template = Velocity.getTemplate( templateLocation );
            /*
             *  Now have the template engine process your template using the
             *  data placed into the context. Think of it as a  'merge'
             *  of the template and the data to produce the output stream.
             */
            FileWriter writer = new FileWriter( outputFile );
            if ( template != null )
            {
                template.merge( context, writer );
            }
            writer.close();
        }
        catch ( Exception e )
        {
            System.err.println( "Error processing template " + templateLocation );
            e.printStackTrace();
        }
    }

    /**
     * Provides a hook for adding to the Velocity Context.
     *
     * @param context
     * @return  VelocityContext
     */
    protected VelocityContext updateVelocityContext(VelocityContext context,ResourceDefinition resourceDef)
    {
        return context;
    }

    private void processTemplates( ResourceDefinition resourceDef,
                                   File wsdlFile, File serviceDir )
            throws Exception
    {
        String capitalizedServiceName = StringUtils.capitalize( resourceDef.getName() );
        try
        {
            VelocityContext context = new VelocityContext();
            ServiceProperties props = buildServiceProperties( resourceDef, wsdlFile, serviceDir );
            context.put( "generated", props );
            updateVelocityContext(context,resourceDef);

            //generate files
            File packageDir = getPackageDir( resourceDef.getDefinition().getTargetNamespace(), serviceDir );
            packageDir.mkdirs();
            File outputFile = new File( packageDir, "Abstract" + capitalizedServiceName + "Service.java" );
            processTemplate( context, "templates/AbstractService.vm", outputFile );

            outputFile = new File( packageDir, capitalizedServiceName + "Service.java" );

            if ( !outputFile.exists() )
            {
                processTemplate( context, "templates/Service.vm", outputFile );
            }

            generateFaultClasses( context, props, packageDir );

            outputFile = new File( packageDir, "Abstract" + capitalizedServiceName + "Resource.java" );
            processTemplate( context, "templates/AbstractResource.vm", outputFile );

            outputFile = new File( packageDir, capitalizedServiceName + "Resource.java" );

            if ( !outputFile.exists() )
            {
                processTemplate( context, "templates/Resource.vm", outputFile );
            }

            outputFile = new File( packageDir, capitalizedServiceName + "Home.java" );

            if ( !outputFile.exists() )
            {
                processTemplate( context, "templates/Home.vm", outputFile );
            }

            if ( resourceDef.hasProperties() )
            {
                outputFile = new File( packageDir, capitalizedServiceName + "PropertyQNames.java" );
                processTemplate( context, "templates/PropertyQNames.vm", outputFile );
            }

            outputFile = new File( packageDir, capitalizedServiceName + "_deploy.wsdd" );
            processTemplate( context, "templates/deploy.vm", outputFile );

            outputFile = new File( packageDir, capitalizedServiceName + "_jndi-config.xml" );
            processTemplate( context, "templates/jndi.vm", outputFile );

            outputFile = new File( packageDir, capitalizedServiceName + "CustomOperationsPortType.java" );
            processTemplate( context, "templates/CustomOperationsPortType.vm", outputFile );

            outputFile = new File( serviceDir, "build.xml" );
            processTemplate( context, "templates/build.xml.vm", outputFile );

            outputFile = new File( serviceDir, "build.properties" );
            if ( !outputFile.exists() )
            {
            processTemplate( context, "templates/build.properties.vm", outputFile );
            }
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
    }

    private void generateFaultClasses( VelocityContext context, ServiceProperties props, File packageDir )
            throws Exception
    {
        File outputFile;
        Iterator customOperations = props.getCustomMappings().values().iterator();
        while (customOperations.hasNext())
        {
            OperationInfo oparationInfo = (OperationInfo) customOperations.next();
            //need to determine if fault is instanceof BaseFault
            Iterator faultIterator = oparationInfo.getFaults().values().iterator();
            while (faultIterator.hasNext())
            {
                Fault fault = (Fault) faultIterator.next();
                Message message = fault.getMessage();
                Map parts = message.getParts();
                if (parts.size() != 1)
                {
                    throw new Exception( "WSDL fault message should have exactly one part." );
                }
                Part part = (Part) parts.values().iterator().next();

                QName faultName = part.getTypeName();
                boolean isType=true;
                if (faultName == null)
                {
                    faultName = part.getElementName();
                    isType = false;
                }
                if (faultName == null)
                {
                   throw new Exception( "WSDL fault message part should have either an element or a type." );
                }

                String exceptionFaultName = StringUtils.capitalize(faultName.getLocalPart()) + "Exception";
                //ok here's the file we'll generate
                outputFile = new File(packageDir, exceptionFaultName + ".java");
                context.put("faultName", exceptionFaultName);

                if (!outputFile.exists())
                {
                    try
                    {
                        if (isBaseFaultExtension(faultName, isType))
                        {
                            processTemplate(context, "templates/BaseFaultExtension.vm", outputFile);
                        }
                        else
                        {
                            processTemplate(context, "templates/CustomFault.vm", outputFile);
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception( "Unable to generate WSDL fault. Cause: " + e, e );
                    }
                }
            }
        }
    }

    /**
     * Determines if the passed in QName is for a type which extends
     * BaseFault.
     *
     * @param faultName
     * @param type
     * @return true if the "type" extends BaseFault.
     */
    private boolean isBaseFaultExtension(QName faultName, boolean type) throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException
    {
        String xmlbeanFaultClassName = null;
        Class faultClass = null;
        URLClassLoader generatedXmlBeanClassloader = getGeneratedXmlBeanClassloader();
        if(type)
        {
            xmlbeanFaultClassName = NameUtil.getClassNameFromQName(faultName);
            //type to get an instance of the class
            faultClass = generatedXmlBeanClassloader.loadClass(xmlbeanFaultClassName);
        }
        else
        {
            //attempt to get the generated "Document" class name
            xmlbeanFaultClassName = XmlBeanNameUtils.getDocumentElementXmlBeanFactoryClassName(new QName(faultName.getNamespaceURI(), faultName.getLocalPart()));
            //try to load the document class
            Class xmlbeanGeneratedClass = generatedXmlBeanClassloader.loadClass(xmlbeanFaultClassName);
            //invoke newInstance in the Xmlbean's Factory class
            Method method = xmlbeanGeneratedClass.getMethod("newInstance", null);
            Object o = method.invoke(xmlbeanGeneratedClass,null);

            //invoke the addNew... method on the object to get its type
            xmlbeanGeneratedClass = o.getClass();
            method = xmlbeanGeneratedClass.getMethod("addNew" + faultName.getLocalPart(), null);
            //get the types's Class
            faultClass = method.invoke(o,null).getClass();
        }

        //determine if the class is assignable from any known versions of BaseType
        return (org.oasisOpen.docs.wsrf.x2004.x06.wsrfWSBaseFaults12Draft01.BaseFaultType.class.isAssignableFrom(faultClass) ||
        org.oasisOpen.docs.wsrf.x2004.x11.wsrfWSBaseFaults12Draft03.BaseFaultType.class.isAssignableFrom(faultClass));
    }

    /**
     * DOCUMENT_ME
     *
     * @author $author$
     * @version $Revision: 1.8 $
     */
    static interface LongOpts
    {
        /**
         * DOCUMENT_ME
         */
        String OUTPUT_DIR = "outputDir";

        /**
         * DOCUMENT_ME
         */
        String VERBOSE = "verbose";

        /**
         * DOCUMENT_ME
         */
        String CLASSPATH = "classpath";
    }

    /**
     * DOCUMENT_ME
     *
     * @author $author$
     * @version $Revision: 1.8 $
     */
    static interface Opts
    {
        /**
         * DOCUMENT_ME
         */
        String OUTPUT_DIR = "o";

        /**
         * DOCUMENT_ME
         */
        String VERBOSE = "v";

        /**
         * DOCUMENT_ME
         */
        String CLASSPATH = "C";
    }

    /**
     * DOCUMENT_ME
     *
     * @author $author$
     * @version $Revision: 1.8 $
     */
    public static class Wsdl2JavaOptions
    {
        private boolean m_verbose;

        /**
         * Enable/disable verbose output.
         *
         * @param verbose option indicating whether or not to enable verbose output
         */
        public void setVerbose( boolean verbose )
        {
            m_verbose = verbose;
        }

        /**
         * Returns true if verbose output is enabled, or false otherwise.
         *
         * @return true if verbose output is enabled, or false otherwise
         */
        public boolean isVerbose()
        {
            return m_verbose;
        }
    }

    static File[] toFileArray( String classpath )
    {
        List classpathItems = new ArrayList();
        for ( StringTokenizer tokenizer = new StringTokenizer( classpath, File.pathSeparator );
              tokenizer.hasMoreTokens(); )
        {
            classpathItems.add( new File( tokenizer.nextToken() ) );
        }
        return (File[]) classpathItems.toArray( new File[0] );
    }

    private URLClassLoader getGeneratedXmlBeanClassloader()
    {
        File libDir = new File(m_xmlbeansDir, "lib");
        File[] jarFiles = libDir.listFiles(new FilenameFilter(){
            public boolean accept(File dir, String name)
            {
                return name.endsWith(".jar");
            }
        });
        URL[] urls = new URL[jarFiles.length];
        for (int i = 0; i < jarFiles.length; i++)
        {
            try
            {
                urls[i] = jarFiles[i].toURL();
            }
            catch (MalformedURLException murle)
            {
                throw new RuntimeException( "Unable to load XMLBeans-generated jars and convert to URLs. Cause: " + murle, murle );
            }
        }
        return new URLClassLoader(urls, this.getClass().getClassLoader());
    }

}
TOP

Related Classes of org.apache.ws.resource.tool.Wsdl2Java

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.