Package org.apache.ws.resource.tool

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

/*=============================================================================*
*  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.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.handler.ResourceHandler;
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.metadataexchange.v2004_09.porttype.MetadataExchangePortType;
import org.apache.ws.resource.tool.velocity.ImplementsListBuilder;
import org.apache.ws.resource.tool.velocity.ServiceProperties;
import org.apache.ws.util.OperationInfo;
import org.apache.ws.util.WsrfWsdlUtils;
import org.apache.ws.util.XmlBeanNameUtils;
import org.apache.ws.util.i18n.Messages;
import org.apache.ws.util.jsr109.DummyEndpoint;
import org.apache.ws.util.jsr109.DummyEndpointImpl;
import org.apache.ws.util.velocity.CommonsLogLogSystem;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.impl.common.NameUtil;
import org.apache.xmlbeans.impl.common.XmlErrorPrinter;
import org.apache.xmlbeans.impl.tool.SchemaCompiler;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Message;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.Service;
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.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
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;

/**
* Generates Java Web service types and skeletons from a WSRF WSDL. The types are
* generated as XMLBeans.
*
* @author Ian Springer
*/
public class Wsdl2Java
{
   private static final Messages MSG = MessagesImpl.getInstance(  );

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

   static
   {
      initCmdLineOptions(  );
   }

   private static final String   WEBAPP_NAME                    = "wsrf";

   /** DOCUMENT_ME */
   protected static final String VELOCITY_CONTEXT_KEY_GENERATED = "generated";
   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;

   /**
    * 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(  );
   }

   /**
    * 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] );
      }
   }

   /**
    * 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 targetNamespace DOCUMENT_ME
    * @param serviceDir DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   protected File getPackageDir( String targetNamespace,
                                 File   serviceDir )
   {
      String javaPackageName = GenerationUtils.getJavaPackageName( targetNamespace );
      File   javaDir = new File( serviceDir, "src/java" );
      return new File( javaDir,
                       javaPackageName.replace( '.', '/' ) );
   }

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

   /**
    * DOCUMENT_ME
    *
    * @param resourceDef DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   protected String getValidJavaName( ResourceDefinition resourceDef )
   {
      String qualifiedClassName =
         NameUtil.getClassNameFromQName( new QName( resourceDef.getDefinition(  ).getTargetNamespace(  ),
                                                    resourceDef.getName(  ) ) );
      return qualifiedClassName.substring( qualifiedClassName.lastIndexOf( "." ) + 1 );
   }

   /**
    * DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   protected String getWebbappName(  )
   {
      return WEBAPP_NAME;
   }

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

   /**
    * Builds the {@link ServiceProperties} object which is a javabean used for storing values
    * which are passed to the VelocityContext for code generation.
    *
    * @param resourceDef The definition we are working on.
    * @param wsdlFile The {@link File} representation of the wsdl file.
    * @param serviceDir The {@link File} representation of the directory we are writing the service to.
    * @return The ServiceProperties object.
    */
   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 javaServiceName = getValidJavaName( resourceDef );
      props.setServiceName( javaServiceName );
      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 );
         props.setCustomPropertyNames( resourceDef.getCustomPropertyNames(  ) );
      }

      if ( resourceDef.implementsResourceCapability( MetadataExchangePortType.NAME ) )
      {
         props.setHasMetadata( true );
      }

      // define the names of the resource props that we initialize for the user...
      if ( hasScheduledResourceTerminationPortType( resourceDef ) )
      {
         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
                                + "!\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 WSRF-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 );

      props.setWsdlServiceName( resourceDef.getWsdlServiceName(  ) );

      props.setServiceMethodMap( resourceDef.getAllOperations(  ) );
      return props;
   }

   /**
    *
    * @param context
    * @param templateLocation
    * @param outputFile
    * @throws Exception
    */
   protected 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.
          */
         outputFile.getParentFile().mkdirs();
         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(  );
      }
   }

   /**
    *
    * @param resourceDef
    * @param wsdlFile
    * @param serviceDir
    * @throws Exception
    */
   protected void processTemplates( ResourceDefinition resourceDef,
                                    File               wsdlFile,
                                    File               serviceDir )
   throws Exception
   {
      String capitalizedServiceName = getValidJavaName( resourceDef );
      try
      {
         VelocityContext   context = new VelocityContext(  );
         ServiceProperties props = buildServiceProperties( resourceDef, wsdlFile, serviceDir );
         context.put( VELOCITY_CONTEXT_KEY_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, "Abstract" + capitalizedServiceName + "Home.java" );
         processTemplate( context, "templates/AbstractHome.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.wsdd.vm", outputFile );

         outputFile = new File( packageDir, capitalizedServiceName + "_wsrf-config.xml" );
         processTemplate( context, "templates/wsrf-config.xml.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 );
         }

         /*
            //jsr109 artifacts
            outputFile = new File( packageDir, "web.xml" );
            processTemplate( context, "templates/jsr109/web.vm", outputFile );
            outputFile = new File( packageDir, "webservices.xml" );
            processTemplate( context, "templates/jsr109/webservices.vm", outputFile );
            outputFile = new File( packageDir, capitalizedServiceName + "_jaxrpc-mapping.xml" );
            processTemplate( context, "templates/jsr109/jaxrpc-mapping.vm", outputFile );
          */
      }
      catch ( Exception e )
      {
         e.printStackTrace(  );
      }
   }

   /**
    * Provides a hook for adding to the Velocity Context.
    *
    * @param context
    * @return VelocityContext
    */
   protected VelocityContext updateVelocityContext( VelocityContext    context,
                                                    ResourceDefinition resourceDef )
   {
      //dummy endpoint vars for jsr109...
      context.put( "jsr109EndpointClassName",
                   DummyEndpointImpl.class.getName(  ) );
      context.put( "jsr109EndpointInterfaceName",
                   DummyEndpoint.class.getName(  ) );
      context.put( "jsr109EndpointDummyJavaOperation",
                   DummyEndpoint.class.getMethods(  )[0].getName(  ) );

      //handler var for jsr109
      context.put( "resourceHandlerClassName",
                   ResourceHandler.class.getName(  ) );
      return context;
   }

   /**
    * DOCUMENT_ME
    *
    * @param classpath DOCUMENT_ME
    *
    * @return DOCUMENT_ME
    */
   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 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 ) );
   }

   /**
    * 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 ) );
   }

   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 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 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(  ) );
   }

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

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

      return constName;
   }

   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;
   }

   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 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 faultClassName = NameUtil.getClassNameFromQName( faultName );
            faultClassName = faultClassName.substring( faultClassName.lastIndexOf( "." ) + 1 );
            QName  newFaultName = new QName( faultName.getNamespaceURI(  ),
                                             faultClassName );
            String exceptionFaultName = faultClassName + "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( newFaultName, 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 );
               }
            }
         }
      }
   }

   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 );
      }
   }

   private boolean hasScheduledResourceTerminationPortType( ResourceDefinition resourceDef )
   {
      return resourceDef.implementsResourceCapability( org.apache.ws.resource.lifetime.v2004_06.porttype.ScheduledResourceTerminationPortType.NAME )
             || resourceDef.implementsResourceCapability( org.apache.ws.resource.lifetime.v2004_11.porttype.ScheduledResourceTerminationPortType.NAME );
   }

   private void initPortTypeInfoMap(  )
   {
      // WSRF 2004/06
      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(  ) );

      // WSRF 2004/11
      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(  ) );

      // WSMEX 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 processWsdlFile( File wsdlFile )
   throws Exception
   {
      System.out.println( "Processing WSDL file \"" + wsdlFile + "\"..." );
      Definition def = m_wsdlReader.readWSDL( wsdlFile.getPath(  ) );
      if ( WsrfWsdlUtils.getSchemaElements( def ).length != 0 )
      {
         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,
                                           service.getQName(  ), 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 );
         }
      }
   }

   /**
    * 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.
    * <p/>
    * 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 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;
   }

   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)" );
      }
   }

   /**
    * 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;
      }
   }
}
TOP

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

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.
mailto:coftware@gmail.com">coftware#gmail.com.