Browse Source

Zap these for now and deal with em later

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271481 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 23 years ago
parent
commit
df05a786a5
40 changed files with 0 additions and 17358 deletions
  1. +0
    -524
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java
  2. +0
    -252
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandGenerateClient.java
  3. +0
    -133
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DDCreator.java
  4. +0
    -159
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DDCreatorHelper.java
  5. +0
    -420
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java
  6. +0
    -49
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java
  7. +0
    -567
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java
  8. +0
    -192
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/Ejbc.java
  9. +0
    -286
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbcHelper.java
  10. +0
    -958
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java
  11. +0
    -407
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetDeploymentTool.java
  12. +0
    -1688
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbc.java
  13. +0
    -339
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbcTask.java
  14. +0
    -36
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/InnerClassFilenameFilter.java
  15. +0
    -70
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JbossDeploymentTool.java
  16. +0
    -430
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WLRun.java
  17. +0
    -173
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WLStop.java
  18. +0
    -856
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java
  19. +0
    -105
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicTOPLinkDeploymentTool.java
  20. +0
    -1035
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java
  21. +0
    -524
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java
  22. +0
    -252
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/BorlandGenerateClient.java
  23. +0
    -133
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/DDCreator.java
  24. +0
    -159
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/DDCreatorHelper.java
  25. +0
    -420
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java
  26. +0
    -49
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java
  27. +0
    -567
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java
  28. +0
    -192
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/Ejbc.java
  29. +0
    -286
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/EjbcHelper.java
  30. +0
    -958
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java
  31. +0
    -407
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetDeploymentTool.java
  32. +0
    -1688
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbc.java
  33. +0
    -339
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbcTask.java
  34. +0
    -36
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/InnerClassFilenameFilter.java
  35. +0
    -70
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/JbossDeploymentTool.java
  36. +0
    -430
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/WLRun.java
  37. +0
    -173
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/WLStop.java
  38. +0
    -856
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java
  39. +0
    -105
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicTOPLinkDeploymentTool.java
  40. +0
    -1035
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java

+ 0
- 524
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java View File

@@ -1,524 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import org.apache.aut.nativelib.ExecManager;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.myrmidon.framework.Execute;
import org.apache.tools.ant.taskdefs.exec.ExecuteStreamHandler;
import org.apache.tools.ant.types.Argument;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.util.FileUtils;

/**
* BorlandDeploymentTool is dedicated to the Borland Application Server 4.5 and
* 4.5.1 This task generates and compiles the stubs and skeletons for all ejb
* described into the Deployement Descriptor, builds the jar file including the
* support files and verify whether the produced jar is valid or not. The
* supported options are:
* <ul>
* <li> debug (boolean) : turn on the debug mode for generation of stubs and
* skeletons (default:false)</li>
* <li> verify (boolean) : turn on the verification at the end of the jar
* production (default:true) </li>
* <li> verifyargs (String) : add optional argument to verify command (see vbj
* com.inprise.ejb.util.Verify)</li>
* <li> basdtd (String) : location of the BAS DTD </li>
* <li> generateclient (boolean) : turn on the client jar file generation
* </li>
* </ul>
* <PRE>
*
* &lt;ejbjar srcdir=&quot;${build.classes}&quot; basejarname=&quot;vsmp&quot; descriptordir=&quot;${rsc.dir}/hrmanager&quot;&gt;
* &lt;borland destdir=&quot;tstlib&quot;&gt;
* &lt;classpath refid=&quot;classpath&quot; /&gt;
* &lt;/borland&gt;
* &lt;include name=&quot;**\ejb-jar.xml&quot;/&gt;
* &lt;support dir=&quot;${build.classes}&quot;&gt;
* &lt;include name=&quot;demo\smp\*.class&quot;/&gt;
* &lt;include name=&quot;demo\helper\*.class&quot;/&gt;
* &lt;/support&gt;
* &lt;/ejbjar&gt;
*</PRE>
*
* @author <a href="mailto:benoit.moussaud@criltelecom.com">Benoit Moussaud</a>
*/
public class BorlandDeploymentTool
extends GenericDeploymentTool
implements ExecuteStreamHandler
{
public final static String PUBLICID_BORLAND_EJB
= "-//Inprise Corporation//DTD Enterprise JavaBeans 1.1//EN";

protected final static String DEFAULT_BAS45_EJB11_DTD_LOCATION
= "/com/inprise/j2ee/xml/dtds/ejb-jar.dtd";

protected final static String DEFAULT_BAS_DTD_LOCATION
= "/com/inprise/j2ee/xml/dtds/ejb-inprise.dtd";

protected final static String BAS_DD = "ejb-inprise.xml";

/**
* Java2iiop executable *
*/
protected final static String JAVA2IIOP = "java2iiop";

/**
* Verify class
*/
protected final static String VERIFY = "com.inprise.ejb.util.Verify";

/**
* Instance variable that stores the suffix for the borland jarfile.
*/
private String jarSuffix = "-ejb.jar";

/**
* Instance variable that determines whether the debug mode is on
*/
private boolean java2iiopdebug = false;

/**
* Instance variable that determines whetger the client jar file is
* generated
*/
private boolean generateclient = false;
/**
* Instance variable that determines whether it is necessary to verify the
* produced jar
*/
private boolean verify = true;
private String verifyArgs = "";

private Hashtable _genfiles = new Hashtable();

/**
* Instance variable that stores the location of the borland DTD file.
*/
private String borlandDTD;

/**
* Setter used to store the location of the borland DTD. This can be a file
* on the system or a resource on the classpath.
*
* @param inString the string to use as the DTD location.
*/
public void setBASdtd( String inString )
{
this.borlandDTD = inString;
}

/**
* set the debug mode for java2iiop (default false)
*
* @param debug The new Debug value
*/
public void setDebug( boolean debug )
{
this.java2iiopdebug = debug;
}

/**
* setter used to store whether the task will include the generate client
* task. (see : BorlandGenerateClient task)
*
* @param b The new Generateclient value
*/
public void setGenerateclient( boolean b )
{
this.generateclient = b;
}

/**
* @param is The new ProcessErrorStream value
* @exception IOException Description of Exception
*/
public void setProcessErrorStream( InputStream is )
throws IOException
{
BufferedReader reader = new BufferedReader( new InputStreamReader( is ) );
String s = reader.readLine();
if( s != null )
{
getLogger().debug( "[java2iiop] " + s );
}// end of if ()
}

public void setProcessInputStream( OutputStream param1 )
throws IOException
{
}

/**
* @param is
* @exception IOException Description of Exception
*/
public void setProcessOutputStream( InputStream is )
throws IOException
{
try
{
BufferedReader reader = new BufferedReader( new InputStreamReader( is ) );
String javafile;
while( ( javafile = reader.readLine() ) != null )
{
getLogger().debug( "buffer:" + javafile );
if( javafile.endsWith( ".java" ) )
{
String classfile = toClassFile( javafile );
String key = classfile.substring( getConfig().srcDir.getAbsolutePath().length() + 1 );
getLogger().debug( " generated : " + classfile );
getLogger().debug( " key : " + key );
_genfiles.put( key, new File( classfile ) );
}// end of if ()
}// end of while ()
reader.close();
}
catch( Exception e )
{
String msg = "Exception while parsing java2iiop output. Details: " + e.toString();
throw new TaskException( msg, e );
}
}

/**
* Setter used to store the suffix for the generated borland jar file.
*
* @param inString the string to use as the suffix.
*/
public void setSuffix( String inString )
{
this.jarSuffix = inString;
}

/**
* set the verify mode for the produced jar (default true)
*
* @param verify The new Verify value
*/
public void setVerify( boolean verify )
{
this.verify = verify;
}

/**
* sets some additional args to send to verify command
*
* @param args addtions command line parameters
*/
public void setVerifyArgs( String args )
{
this.verifyArgs = args;
}

// implementation of org.apache.tools.ant.taskdefs.ExecuteStreamHandler interface

public void start()
throws IOException
{
}

public void stop()
{
}

protected DescriptorHandler getBorlandDescriptorHandler( final File srcDir )
{
DescriptorHandler handler =
new DescriptorHandler( getTask(), srcDir )
{
protected void processElement()
{
if( currentElement.equals( "type-storage" ) )
{
// Get the filename of vendor specific descriptor
String fileNameWithMETA = currentText;
//trim the META_INF\ off of the file name
String fileName = fileNameWithMETA.substring( META_DIR.length(),
fileNameWithMETA.length() );
File descriptorFile = new File( srcDir, fileName );

ejbFiles.put( fileNameWithMETA, descriptorFile );
}
}
};
handler.registerDTD( PUBLICID_BORLAND_EJB,
borlandDTD == null ? DEFAULT_BAS_DTD_LOCATION : borlandDTD );

for( Iterator i = getConfig().dtdLocations.iterator(); i.hasNext(); )
{
EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation)i.next();
handler.registerDTD( dtdLocation.getPublicId(), dtdLocation.getLocation() );
}
return handler;
}

/**
* Add any vendor specific files which should be included in the EJB Jar.
*
* @param ejbFiles The feature to be added to the VendorFiles attribute
* @param ddPrefix The feature to be added to the VendorFiles attribute
*/
protected void addVendorFiles( Hashtable ejbFiles, String ddPrefix )
{
final File borlandDD = new File( getConfig().descriptorDir, ddPrefix + BAS_DD );
if( borlandDD.exists() )
{
final String message = "Borland specific file found " + borlandDD;
getLogger().debug( message );
ejbFiles.put( META_DIR + BAS_DD, borlandDD );
}
else
{
final String message = "Unable to locate borland deployment descriptor. " +
"It was expected to be in " + borlandDD.getPath();
getLogger().warn( message );
return;
}
}

/**
* Method used to encapsulate the writing of the JAR file. Iterates over the
* filenames/java.io.Files in the Hashtable stored on the instance variable
* ejbFiles.
*
* @param baseName Description of Parameter
* @param jarFile Description of Parameter
* @param files Description of Parameter
* @param publicId Description of Parameter
* @exception TaskException Description of Exception
*/
protected void writeJar( String baseName, File jarFile, Hashtable files, String publicId )
throws TaskException
{
//build the home classes list.
ArrayList homes = new ArrayList();
Iterator it = files.keySet().iterator();
while( it.hasNext() )
{
String clazz = (String)it.next();
if( clazz.endsWith( "Home.class" ) )
{
//remove .class extension
String home = toClass( clazz );
homes.add( home );
getLogger().debug( " Home " + home );
}// end of if ()
}// end of while ()

buildBorlandStubs( homes.iterator(), files );

//add the gen files to the collection
files.putAll( _genfiles );

super.writeJar( baseName, jarFile, files, publicId );

if( verify )
{
verifyBorlandJar( jarFile );
}// end of if ()

if( generateclient )
{
generateClient( jarFile );
}// end of if ()
}

/**
* Get the vendor specific name of the Jar that will be output. The
* modification date of this jar will be checked against the dependent bean
* classes.
*
* @param baseName Description of Parameter
* @return The VendorOutputJarFile value
*/
File getVendorOutputJarFile( String baseName )
{
return new File( getDestDir(), baseName + jarSuffix );
}

/**
* Generate stubs & sketelton for each home found into the DD Add all the
* generate class file into the ejb files
*
* @param ithomes : iterator on home class
* @param files : file list , updated by the adding generated files
*/
private void buildBorlandStubs( Iterator ithomes, Hashtable files )
{
final ExecManager execManager = (ExecManager)getService( ExecManager.class );
final Execute exe = new Execute( execManager );
exe.setWorkingDirectory( getTask().getBaseDirectory() );

final Commandline cmd = buildCommandline( ithomes );
exe.setCommandline( cmd );

getLogger().debug( "Calling java2iiop" );
getLogger().debug( cmd.toString() );

try
{
final int result = exe.execute();
if( result != 0 )
{
String msg = "Failed executing java2iiop (ret code is " + result + ")";
throw new TaskException( msg );
}
}
catch( java.io.IOException e )
{
getLogger().error( "java2iiop exception :" + e.getMessage() );
throw new TaskException( "Error", e );
}
}

private Commandline buildCommandline( final Iterator ithomes )
{
final Commandline cmd = new Commandline();
cmd.setExecutable( JAVA2IIOP );
//debug ?
if( java2iiopdebug )
{
cmd.addArgument( "-VBJdebug" );
}// end of if ()
//set the classpath
cmd.addArgument( "-VBJclasspath" );
cmd.addArguments( FileUtils.translateCommandline( getCombinedClasspath() ) );
//list file
cmd.addArgument( "-list_files" );
//no TIE classes
cmd.addArgument( "-no_tie" );
//root dir
cmd.addArgument( "-root_dir" );
cmd.addArgument( getConfig().srcDir.getAbsolutePath() );
//compiling order
cmd.addArgument( "-compile" );
//add the home class
while( ithomes.hasNext() )
{
cmd.addArgument( ithomes.next().toString() );
}
return cmd;
}

/**
* Generate the client jar corresponding to the jar file passed as paremeter
* the method uses the BorlandGenerateClient task.
*
* @param sourceJar java.io.File representing the produced jar file
*/
private void generateClient( File sourceJar )
{
//UGLY HACK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//getTask().getProject().addTaskDefinition( "internal_bas_generateclient",
//org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient.class );

org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient gentask = null;
getLogger().info( "generate client for " + sourceJar );
try
{
String args = verifyArgs;
args += " " + sourceJar.getPath();

gentask = (BorlandGenerateClient)getTask().getProject().createTask( "internal_bas_generateclient" );
gentask.setEjbjar( sourceJar );
gentask.setDebug( java2iiopdebug );
Path classpath = getCombinedClasspath();
if( classpath != null )
{
gentask.setClasspath( classpath );
}
gentask.execute();
}
catch( Exception e )
{
//TO DO : delete the file if it is not a valid file.
String msg = "Exception while calling " + VERIFY + " Details: " + e.toString();
throw new TaskException( msg, e );
}
}

/**
* convert a class file name : A/B/C/toto.class into a class name:
* A.B.C.toto
*
* @param filename Description of Parameter
* @return Description of the Returned Value
*/
private String toClass( String filename )
{
//remove the .class
String classname = filename.substring( 0, filename.lastIndexOf( ".class" ) );
classname = classname.replace( '\\', '.' );
return classname;
}

/**
* convert a file name : A/B/C/toto.java into a class name: A/B/C/toto.class
*
* @param filename Description of Parameter
* @return Description of the Returned Value
*/
private String toClassFile( String filename )
{
//remove the .class
String classfile = filename.substring( 0, filename.lastIndexOf( ".java" ) );
classfile = classfile + ".class";
return classfile;
}

/**
* Verify the produced jar file by invoking the Borland verify tool
*
* @param sourceJar java.io.File representing the produced jar file
*/
private void verifyBorlandJar( File sourceJar )
throws TaskException
{
org.apache.tools.ant.taskdefs.Java javaTask = null;
getLogger().info( "verify " + sourceJar );
try
{

String args = verifyArgs;
args += " " + sourceJar.getPath();

javaTask = (Java)getTask().getProject().createTask( "java" );
javaTask.setClassname( VERIFY );
Argument arguments = javaTask.createArg();
arguments.setLine( args );
Path classpath = getCombinedClasspath();
if( classpath != null )
{
javaTask.setClasspath( classpath );
javaTask.setFork( true );
}

getLogger().debug( "Calling " + VERIFY + " for " + sourceJar.toString() );
javaTask.execute();
}
catch( Exception e )
{
//TO DO : delete the file if it is not a valid file.
String msg = "Exception while calling " + VERIFY + " Details: " + e.toString();
throw new TaskException( msg, e );
}
}

}

+ 0
- 252
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandGenerateClient.java View File

@@ -1,252 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import org.apache.aut.nativelib.ExecManager;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.Task;
import org.apache.myrmidon.framework.Execute;
import org.apache.tools.ant.types.Argument;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Path;

/**
* BorlandGenerateClient is dedicated to the Borland Application Server 4.5 This
* task generates the client jar using as input the ejb jar file. Two mode are
* available: java mode (default) and fork mode. With the fork mode, it is
* impossible to add classpath to the commmand line.
*
* @author <a href="mailto:benoit.moussaud@criltelecom.com">Benoit Moussaud</a>
*/
public class BorlandGenerateClient extends Task
{
final static String JAVA_MODE = "java";
final static String FORK_MODE = "fork";

/**
* debug the generateclient task
*/
boolean debug = false;

/**
* hold the ejbjar file name
*/
File ejbjarfile = null;

/**
* hold the client jar file name
*/
File clientjarfile = null;

/**
* hold the mode (java|fork)
*/
String mode = JAVA_MODE;

/**
* hold the classpath
*/
Path classpath;

public void setClasspath( Path classpath )
throws TaskException
{
if( this.classpath == null )
{
this.classpath = classpath;
}
else
{
this.classpath.append( classpath );
}
}

public void setClientjar( File clientjar )
{
clientjarfile = clientjar;
}

public void setDebug( boolean debug )
{
this.debug = debug;
}

public void setEjbjar( File ejbfile )
{
ejbjarfile = ejbfile;
}

public void setMode( String s )
{
mode = s;
}

public Path createClasspath()
throws TaskException
{
if( this.classpath == null )
{
this.classpath = new Path();
}
Path path1 = this.classpath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Do the work. The work is actually done by creating a separate JVM to run
* a java task.
*
* @exception TaskException if someting goes wrong with the build
*/
public void execute()
throws TaskException
{
if( ejbjarfile == null ||
ejbjarfile.isDirectory() )
{
throw new TaskException( "invalid ejb jar file." );
}// end of if ()

if( clientjarfile == null ||
clientjarfile.isDirectory() )
{
getLogger().debug( "invalid or missing client jar file." );
String ejbjarname = ejbjarfile.getAbsolutePath();
//clientname = ejbjarfile+client.jar
String clientname = ejbjarname.substring( 0, ejbjarname.lastIndexOf( "." ) );
clientname = clientname + "client.jar";
clientjarfile = new File( clientname );

}// end of if ()

if( mode == null )
{
getLogger().info( "mode is null default mode is java" );
setMode( JAVA_MODE );
}// end of if ()

getLogger().info( "client jar file is " + clientjarfile );

if( mode.equalsIgnoreCase( FORK_MODE ) )
{
executeFork();
}// end of if ()
else
{
executeJava();
}// end of else
}

/**
* launch the generate client using system api
*
* @exception TaskException Description of Exception
*/
protected void executeFork()
throws TaskException
{
try
{

final Commandline cmd = buildCommand();

getLogger().info( "mode : fork" );
getLogger().debug( "Calling java2iiop" );

final ExecManager execManager = (ExecManager)getService( ExecManager.class );
final Execute exe = new Execute( execManager );
exe.setWorkingDirectory( new File( "." ) );
exe.setCommandline( cmd );
exe.execute();
}
catch( Exception e )
{
// Have to catch this because of the semantics of calling main()
String msg = "Exception while calling generateclient Details: " + e.toString();
throw new TaskException( msg, e );
}

}

private Commandline buildCommand()
{
final Commandline cmd = new Commandline();
cmd.setExecutable( "iastool" );
cmd.addArgument( "generateclient" );
if( debug )
{
cmd.addArgument( "-trace" );
}

cmd.addArgument( "-short" );
cmd.addArgument( "-jarfile" );
// ejb jar file
cmd.addArgument( ejbjarfile.getAbsolutePath() );
//client jar file
cmd.addArgument( "-single" );
cmd.addArgument( "-clientjarfile" );
cmd.addArgument( clientjarfile.getAbsolutePath() );
return cmd;
}

/**
* launch the generate client using java api
*
* @exception TaskException Description of Exception
*/
protected void executeJava()
throws TaskException
{
try
{
getLogger().info( "mode : java" );

org.apache.tools.ant.taskdefs.Java execTask = null;
execTask = null;//(Java)getProject().createTask( "java" );

execTask.setDir( new File( "." ) );
execTask.setClassname( "com.inprise.server.commandline.EJBUtilities" );
//classpath
//add at the end of the classpath
//the system classpath in order to find the tools.jar file
// TODO - make sure tools.jar is in the classpath
//execTask.addClasspath( classpath.concatSystemClasspath( "last" ) );

execTask.setFork( true );
execTask.addArg( new Argument( "generateclient" ) );
if( debug )
{
execTask.addArg( new Argument( "-trace" ) );
}// end of if ()

//
execTask.addArg( new Argument( "-short" ) );
execTask.addArg( new Argument( "-jarfile" ) );
// ejb jar file
execTask.addArg( new Argument( ejbjarfile.getAbsolutePath() ) );
//client jar file
execTask.addArg( new Argument( "-single" ) );
execTask.addArg( new Argument( "-clientjarfile" ) );
execTask.addArg( new Argument( clientjarfile.getAbsolutePath() ) );

getLogger().debug( "Calling EJBUtilities" );
execTask.execute();

}
catch( final Exception e )
{
// Have to catch this because of the semantics of calling main()
final String message =
"Exception while calling generateclient Details: " + e.toString();
throw new TaskException( message, e );
}
}
}

+ 0
- 133
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DDCreator.java View File

@@ -1,133 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.Argument;
import org.apache.tools.ant.types.DirectoryScanner;
import org.apache.tools.ant.types.Path;

/**
* Build a serialised deployment descriptor given a text file description of the
* descriptor in the format supported by WebLogic. This ant task is a front end
* for the weblogic DDCreator tool.
*
* @author <a href="mailto:conor@cortexebusiness.com.au">Conor MacNeill</a> ,
* Cortex ebusiness Pty Limited
*/
public class DDCreator extends MatchingTask
{

/**
* The classpath to be used in the weblogic ejbc calls. It must contain the
* weblogic classes necessary fro DDCreator <b>and</b> the implementation
* classes of the home and remote interfaces.
*/
private String classpath;
/**
* The root directory of the tree containing the textual deployment
* desciptors. The actual deployment descriptor files are selected using
* include and exclude constructs on the EJBC task, as supported by the
* MatchingTask superclass.
*/
private File descriptorDirectory;

/**
* The directory where generated serialised deployment descriptors are
* placed.
*/
private File generatedFilesDirectory;

/**
* Set the classpath to be used for this compilation.
*
* @param s the classpath to use for the ddcreator tool.
*/
public void setClasspath( final Path p )
{
this.classpath = p.toString();
}

/**
* Set the directory from where the text descriptions of the deployment
* descriptors are to be read.
*
* @param dirName the name of the directory containing the text deployment
* descriptor files.
*/
public void setDescriptors( String dirName )
{
descriptorDirectory = new File( dirName );
}

/**
* Set the directory into which the serialised deployment descriptors are to
* be written.
*
* @param dirName the name of the directory into which the serialised
* deployment descriptors are written.
*/
public void setDest( String dirName )
{
generatedFilesDirectory = new File( dirName );
}

/**
* Do the work. The work is actually done by creating a helper task. This
* approach allows the classpath of the helper task to be set. Since the
* weblogic tools require the class files of the project's home and remote
* interfaces to be available in the classpath, this also avoids having to
* start ant with the class path of the project it is building.
*
* @exception TaskException if someting goes wrong with the build
*/
public void execute()
throws TaskException
{
if( descriptorDirectory == null ||
!descriptorDirectory.isDirectory() )
{
throw new TaskException( "descriptors directory " + descriptorDirectory.getPath() +
" is not valid" );
}
if( generatedFilesDirectory == null ||
!generatedFilesDirectory.isDirectory() )
{
throw new TaskException( "dest directory " + generatedFilesDirectory.getPath() +
" is not valid" );
}

String args = descriptorDirectory + " " + generatedFilesDirectory;

// get all the files in the descriptor directory
DirectoryScanner ds = super.getDirectoryScanner( descriptorDirectory );

String[] files = ds.getIncludedFiles();

for( int i = 0; i < files.length; ++i )
{
args += " " + files[ i ];
}

String systemClassPath = System.getProperty( "java.class.path" );
String execClassPath = systemClassPath + File.separator + classpath;
Java ddCreatorTask = (Java)getProject().createTask( "java" );
ddCreatorTask.setFork( true );
ddCreatorTask.setClassname( "org.apache.tools.ant.taskdefs.optional.ejb.DDCreatorHelper" );
Argument arguments = ddCreatorTask.createArg();
arguments.setLine( args );
ddCreatorTask.setClasspath( new Path( execClassPath ) );
if( ddCreatorTask.executeJava() != 0 )
{
throw new TaskException( "Execution of ddcreator helper failed" );
}
}
}

+ 0
- 159
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DDCreatorHelper.java View File

@@ -1,159 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import javax.ejb.deployment.DeploymentDescriptor;

/**
* A helper class which performs the actual work of the ddcreator task. This
* class is run with a classpath which includes the weblogic tools and the home
* and remote interface class files referenced in the deployment descriptors
* being built.
*
* @author <a href="mailto:conor@cortexebusiness.com.au">Conor MacNeill</a> ,
* Cortex ebusiness Pty Limited
*/
public class DDCreatorHelper
{

/**
* The descriptor text files for which a serialised descriptor is to be
* created.
*/
String[] descriptors;
/**
* The root directory of the tree containing the textual deployment
* desciptors.
*/
private File descriptorDirectory;

/**
* The directory where generated serialised desployment descriptors are
* written.
*/
private File generatedFilesDirectory;

/**
* Initialise the helper with the command arguments.
*
* @param args Description of Parameter
*/
private DDCreatorHelper( String[] args )
{
int index = 0;
descriptorDirectory = new File( args[ index++ ] );
generatedFilesDirectory = new File( args[ index++ ] );

descriptors = new String[ args.length - index ];
for( int i = 0; index < args.length; ++i )
{
descriptors[ i ] = args[ index++ ];
}
}

/**
* The main method. The main method creates an instance of the
* DDCreatorHelper, passing it the args which it then processes.
*
* @param args The command line arguments
* @exception Exception Description of Exception
*/
public static void main( String[] args )
throws Exception
{
DDCreatorHelper helper = new DDCreatorHelper( args );
helper.process();
}

/**
* Do the actual work. The work proceeds by examining each descriptor given.
* If the serialised file does not exist or is older than the text
* description, the weblogic DDCreator tool is invoked directly to build the
* serialised descriptor.
*
* @exception Exception Description of Exception
*/
private void process()
throws Exception
{
for( int i = 0; i < descriptors.length; ++i )
{
String descriptorName = descriptors[ i ];
File descriptorFile = new File( descriptorDirectory, descriptorName );

int extIndex = descriptorName.lastIndexOf( "." );
String serName = null;
if( extIndex != -1 )
{
serName = descriptorName.substring( 0, extIndex ) + ".ser";
}
else
{
serName = descriptorName + ".ser";
}
File serFile = new File( generatedFilesDirectory, serName );

// do we need to regenerate the file
if( !serFile.exists() || serFile.lastModified() < descriptorFile.lastModified()
|| regenerateSerializedFile( serFile ) )
{

String[] args = {"-noexit",
"-d", serFile.getParent(),
"-outputfile", serFile.getName(),
descriptorFile.getPath()};
try
{
weblogic.ejb.utils.DDCreator.main( args );
}
catch( Exception e )
{
// there was an exception - run with no exit to get proper error
String[] newArgs = {"-d", generatedFilesDirectory.getPath(),
"-outputfile", serFile.getName(),
descriptorFile.getPath()};
weblogic.ejb.utils.DDCreator.main( newArgs );
}
}
}
}

/**
* EJBC will fail if the serialized descriptor file does not match the bean
* classes. You can test for this by trying to load the deployment
* descriptor. If it fails, the serialized file needs to be regenerated
* because the associated class files don't match.
*
* @param serFile Description of Parameter
* @return Description of the Returned Value
*/
private boolean regenerateSerializedFile( File serFile )
{
try
{

FileInputStream fis = new FileInputStream( serFile );
ObjectInputStream ois = new ObjectInputStream( fis );
DeploymentDescriptor dd = (DeploymentDescriptor)ois.readObject();
fis.close();

// Since the descriptor read properly, everything should be o.k.
return false;
}
catch( Exception e )
{

// Weblogic will throw an error if the deployment descriptor does
// not match the class files.
return true;
}
}
}

+ 0
- 420
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java View File

@@ -1,420 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Hashtable;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.tools.ant.Task;
import org.xml.sax.AttributeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
* Inner class used by EjbJar to facilitate the parsing of deployment
* descriptors and the capture of appropriate information. Extends HandlerBase
* so it only implements the methods needed. During parsing creates a hashtable
* consisting of entries mapping the name it should be inserted into an EJB jar
* as to a File representing the file on disk. This list can then be accessed
* through the getFiles() method.
*
* @author RT
*/
public class DescriptorHandler
extends org.xml.sax.HandlerBase
implements LogEnabled
{
private final static int STATE_LOOKING_EJBJAR = 1;
private final static int STATE_IN_EJBJAR = 2;
private final static int STATE_IN_BEANS = 3;
private final static int STATE_IN_SESSION = 4;
private final static int STATE_IN_ENTITY = 5;
private final static int STATE_IN_MESSAGE = 6;

/**
* Bunch of constants used for storing entries in a hashtable, and for
* constructing the filenames of various parts of the ejb jar.
*/
private final static String EJB_REF = "ejb-ref";
private final static String HOME_INTERFACE = "home";
private final static String REMOTE_INTERFACE = "remote";
private final static String LOCAL_HOME_INTERFACE = "local-home";
private final static String LOCAL_INTERFACE = "local";
private final static String BEAN_CLASS = "ejb-class";
private final static String PK_CLASS = "prim-key-class";
private final static String EJB_NAME = "ejb-name";
private final static String EJB_JAR = "ejb-jar";
private final static String ENTERPRISE_BEANS = "enterprise-beans";
private final static String ENTITY_BEAN = "entity";
private final static String SESSION_BEAN = "session";
private final static String MESSAGE_BEAN = "message-driven";

private String publicId = null;

/**
* The state of the parsing
*/
private int parseState = STATE_LOOKING_EJBJAR;

/**
* Instance variable used to store the name of the current element being
* processed by the SAX parser. Accessed by the SAX parser call-back methods
* startElement() and endElement().
*/
protected String currentElement = null;

/**
* The text of the current element
*/
protected String currentText = null;

/**
* Instance variable that stores the names of the files as they will be put
* into the jar file, mapped to File objects Accessed by the SAX parser
* call-back method characters().
*/
protected Hashtable ejbFiles = null;

/**
* Instance variable that stores the value found in the &lt;ejb-name&gt;
* element
*/
protected String ejbName = null;

private Hashtable fileDTDs = new Hashtable();

private Hashtable resourceDTDs = new Hashtable();

private boolean inEJBRef = false;

private Hashtable urlDTDs = new Hashtable();

private Task owningTask;

/**
* The directory containing the bean classes and interfaces. This is used
* for performing dependency file lookups.
*/
private File srcDir;

private Logger m_logger;

/**
* Provide component with a logger.
*
* @param logger the logger
*/
public void enableLogging( Logger logger )
{
m_logger = logger;
}

protected final Logger getLogger()
{
return m_logger;
}

public DescriptorHandler( Task task, File srcDir )
{
this.owningTask = task;
this.srcDir = srcDir;
}

/**
* Getter method that returns the value of the &lt;ejb-name&gt; element.
*
* @return The EjbName value
*/
public String getEjbName()
{
return ejbName;
}

/**
* Getter method that returns the set of files to include in the EJB jar.
*
* @return The Files value
*/
public Hashtable getFiles()
{
return ( ejbFiles == null ) ? new Hashtable() : ejbFiles;
}

/**
* Get the publicId of the DTD
*
* @return The PublicId value
*/
public String getPublicId()
{
return publicId;
}

/**
* SAX parser call-back method invoked whenever characters are located
* within an element. currentAttribute (modified by startElement and
* endElement) tells us whether we are in an interesting element (one of the
* up to four classes of an EJB). If so then converts the classname from the
* format org.apache.tools.ant.Parser to the convention for storing such a
* class, org/apache/tools/ant/Parser.class. This is then resolved into a
* file object under the srcdir which is stored in a Hashtable.
*
* @param ch A character array containing all the characters in the element,
* and maybe others that should be ignored.
* @param start An integer marking the position in the char array to start
* reading from.
* @param length An integer representing an offset into the char array where
* the current data terminates.
* @exception SAXException Description of Exception
*/
public void characters( char[] ch, int start, int length )
throws SAXException
{

currentText += new String( ch, start, length );
}

/**
* SAX parser call-back method that is invoked when an element is exited.
* Used to blank out (set to the empty string, not nullify) the name of the
* currentAttribute. A better method would be to use a stack as an instance
* variable, however since we are only interested in leaf-node data this is
* a simpler and workable solution.
*
* @param name The name of the attribute being exited. Ignored in this
* implementation.
* @exception SAXException Description of Exception
*/
public void endElement( String name )
throws SAXException
{
processElement();
currentText = "";
this.currentElement = "";
if( name.equals( EJB_REF ) )
{
inEJBRef = false;
}
else if( parseState == STATE_IN_ENTITY && name.equals( ENTITY_BEAN ) )
{
parseState = STATE_IN_BEANS;
}
else if( parseState == STATE_IN_SESSION && name.equals( SESSION_BEAN ) )
{
parseState = STATE_IN_BEANS;
}
else if( parseState == STATE_IN_MESSAGE && name.equals( MESSAGE_BEAN ) )
{
parseState = STATE_IN_BEANS;
}
else if( parseState == STATE_IN_BEANS && name.equals( ENTERPRISE_BEANS ) )
{
parseState = STATE_IN_EJBJAR;
}
else if( parseState == STATE_IN_EJBJAR && name.equals( EJB_JAR ) )
{
parseState = STATE_LOOKING_EJBJAR;
}
}

public void registerDTD( String publicId, String location )
{
if( location == null )
{
return;
}

File fileDTD = new File( location );
if( fileDTD.exists() )
{
if( publicId != null )
{
fileDTDs.put( publicId, fileDTD );
getLogger().debug( "Mapped publicId " + publicId + " to file " + fileDTD );
}
return;
}

if( getClass().getResource( location ) != null )
{
if( publicId != null )
{
resourceDTDs.put( publicId, location );
getLogger().debug( "Mapped publicId " + publicId + " to resource " + location );
}
}

try
{
if( publicId != null )
{
URL urldtd = new URL( location );
urlDTDs.put( publicId, urldtd );
}
}
catch( java.net.MalformedURLException e )
{
//ignored
}

}

public InputSource resolveEntity( String publicId, String systemId )
throws SAXException
{
this.publicId = publicId;

File dtdFile = (File)fileDTDs.get( publicId );
if( dtdFile != null )
{
try
{
getLogger().debug( "Resolved " + publicId + " to local file " + dtdFile );
return new InputSource( new FileInputStream( dtdFile ) );
}
catch( FileNotFoundException ex )
{
// ignore
}
}

String dtdResourceName = (String)resourceDTDs.get( publicId );
if( dtdResourceName != null )
{
InputStream is = this.getClass().getResourceAsStream( dtdResourceName );
if( is != null )
{
getLogger().debug( "Resolved " + publicId + " to local resource " + dtdResourceName );
return new InputSource( is );
}
}

URL dtdUrl = (URL)urlDTDs.get( publicId );
if( dtdUrl != null )
{
try
{
InputStream is = dtdUrl.openStream();
getLogger().debug( "Resolved " + publicId + " to url " + dtdUrl );
return new InputSource( is );
}
catch( IOException ioe )
{
//ignore
}
}

getLogger().info( "Could not resolve ( publicId: " + publicId + ", systemId: " + systemId + ") to a local entity" );

return null;
}

/**
* SAX parser call-back method that is used to initialize the values of some
* instance variables to ensure safe operation.
*
* @exception SAXException Description of Exception
*/
public void startDocument()
throws SAXException
{
this.ejbFiles = new Hashtable( 10, 1 );
this.currentElement = null;
inEJBRef = false;
}

/**
* SAX parser call-back method that is invoked when a new element is entered
* into. Used to store the context (attribute name) in the currentAttribute
* instance variable.
*
* @param name The name of the element being entered.
* @param attrs Attributes associated to the element.
* @exception SAXException Description of Exception
*/
public void startElement( String name, AttributeList attrs )
throws SAXException
{
this.currentElement = name;
currentText = "";
if( name.equals( EJB_REF ) )
{
inEJBRef = true;
}
else if( parseState == STATE_LOOKING_EJBJAR && name.equals( EJB_JAR ) )
{
parseState = STATE_IN_EJBJAR;
}
else if( parseState == STATE_IN_EJBJAR && name.equals( ENTERPRISE_BEANS ) )
{
parseState = STATE_IN_BEANS;
}
else if( parseState == STATE_IN_BEANS && name.equals( SESSION_BEAN ) )
{
parseState = STATE_IN_SESSION;
}
else if( parseState == STATE_IN_BEANS && name.equals( ENTITY_BEAN ) )
{
parseState = STATE_IN_ENTITY;
}
else if( parseState == STATE_IN_BEANS && name.equals( MESSAGE_BEAN ) )
{
parseState = STATE_IN_MESSAGE;
}
}

protected void processElement()
{
if( inEJBRef ||
( parseState != STATE_IN_ENTITY && parseState != STATE_IN_SESSION && parseState != STATE_IN_MESSAGE ) )
{
return;
}

if( currentElement.equals( HOME_INTERFACE ) ||
currentElement.equals( REMOTE_INTERFACE ) ||
currentElement.equals( LOCAL_INTERFACE ) ||
currentElement.equals( LOCAL_HOME_INTERFACE ) ||
currentElement.equals( BEAN_CLASS ) ||
currentElement.equals( PK_CLASS ) )
{

// Get the filename into a String object
File classFile = null;
String className = currentText.trim();

// If it's a primitive wrapper then we shouldn't try and put
// it into the jar, so ignore it.
if( !className.startsWith( "java." ) &&
!className.startsWith( "javax." ) )
{
// Translate periods into path separators, add .class to the
// name, create the File object and add it to the Hashtable.
className = className.replace( '.', File.separatorChar );
className += ".class";
classFile = new File( srcDir, className );
ejbFiles.put( className, classFile );
}
}

// Get the value of the <ejb-name> tag. Only the first occurence.
if( currentElement.equals( EJB_NAME ) )
{
if( ejbName == null )
{
ejbName = currentText.trim();
}
}
}
}

+ 0
- 49
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java View File

@@ -1,49 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import javax.xml.parsers.SAXParser;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.Task;

public interface EJBDeploymentTool
{
/**
* Process a deployment descriptor, generating the necessary vendor specific
* deployment files.
*
* @param descriptorFilename the name of the deployment descriptor
* @param saxParser a SAX parser which can be used to parse the deployment
* descriptor.
* @exception TaskException Description of Exception
*/
void processDescriptor( String descriptorFilename, SAXParser saxParser )
throws TaskException;

/**
* Called to validate that the tool parameters have been configured.
*
* @exception TaskException Description of Exception
*/
void validateConfigured()
throws TaskException;

/**
* Set the task which owns this tool
*
* @param task The new Task value
*/
void setTask( Task task );

/**
* Configure this tool for use in the ejbjar task.
*
* @param config Description of Parameter
*/
void configure( EjbJar.Config config );
}

+ 0
- 567
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java View File

@@ -1,567 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;// Standard java imports

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.DirectoryScanner;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.xml.sax.SAXException;

/**
* <p>
*
* Provides automated ejb jar file creation for ant. Extends the MatchingTask
* class provided in the default ant distribution to provide a directory
* scanning EJB jarfile generator.</p> <p>
*
* The task works by taking the deployment descriptors one at a time and parsing
* them to locate the names of the classes which should be placed in the jar.
* The classnames are translated to java.io.Files by replacing periods with
* File.separatorChar and resolving the generated filename as a relative path
* under the srcDir attribute. All necessary files are then assembled into a
* jarfile. One jarfile is constructed for each deployment descriptor found.
* </p> <p>
*
* Functionality is currently provided for standard EJB1.1 jars and Weblogic 5.1
* jars. The weblogic deployment descriptors, used in constructing the Weblogic
* jar, are located based on a simple naming convention. The name of the
* standard deployment descriptor is taken upto the first instance of a String,
* specified by the attribute baseNameTerminator, and then the regular Weblogic
* descriptor name is appended. For example if baseNameTerminator is set to '-',
* its default value, and a standard descriptor is called Foo-ejb-jar.xml then
* the files Foo-weblogic-ejb-jar.xml and Foo-weblogic-cmp-rdbms-jar.xml will be
* looked for, and if found, included in the jarfile.</p> <p>
*
* Attributes and setter methods are provided to support optional generation of
* Weblogic5.1 jars, optional deletion of generic jar files, setting alternate
* values for baseNameTerminator, and setting the strings to append to the names
* of the generated jarfiles.</p>
*
* @author <a href="mailto:tfennell@sapient.com">Tim Fennell</a>
*/
public class EjbJar extends MatchingTask
{

private Config config = new Config();

/**
* Instance variable that stores the suffix for the generated jarfile.
*/
private String genericJarSuffix = "-generic.jar";

/**
* The list of deployment tools we are going to run.
*/
private ArrayList deploymentTools = new ArrayList();

/**
* Stores a handle to the directory to put the Jar files in. This is only
* used by the generic deployment descriptor tool which is created if no
* other deployment descriptor tools are provided. Normally each deployment
* tool will specify the desitination dir itself.
*/
private File destDir;

/**
* Set the base name of the EJB jar that is to be created if it is not to be
* determined from the name of the deployment descriptor files.
*
* @param inValue the basename that will be used when writing the jar file
* containing the EJB
*/
public void setBasejarname( String inValue )
{
config.baseJarName = inValue;
if( config.namingScheme == null )
{
config.namingScheme = new NamingScheme();
config.namingScheme.setValue( NamingScheme.BASEJARNAME );
}
else if( !config.namingScheme.getValue().equals( NamingScheme.BASEJARNAME ) )
{
throw new TaskException( "The basejarname attribute is not compatible with the " +
config.namingScheme.getValue() + " naming scheme" );
}
}

/**
* Set the baseNameTerminator. The basename terminator is the string which
* terminates the bean name. The convention used by this task is that bean
* descriptors are named as the BeanName with some suffix. The
* baseNameTerminator string separates the bean name and the suffix and is
* used to determine the bean name.
*
* @param inValue a string which marks the end of the basename.
*/
public void setBasenameterminator( String inValue )
{
config.baseNameTerminator = inValue;
}

/**
* Set the classpath to use when resolving classes for inclusion in the jar.
*
* @param classpath the classpath to use.
*/
public void setClasspath( Path classpath )
{
config.classpath = classpath;
}

/**
* Set the descriptor directory. The descriptor directory contains the EJB
* deployment descriptors. These are XML files that declare the properties
* of a bean in a particular deployment scenario. Such properties include,
* for example, the transactional nature of the bean and the security access
* control to the bean's methods.
*
* @param inDir the directory containing the deployment descriptors.
*/
public void setDescriptordir( File inDir )
{
config.descriptorDir = inDir;
}

/**
* Set the destination directory. The EJB jar files will be written into
* this directory. The jar files that exist in this directory are also used
* when determining if the contents of the jar file have changed. Note that
* this parameter is only used if no deployment tools are specified.
* Typically each deployment tool will specify its own destination
* directory.
*
* @param inDir The new Destdir value
*/
public void setDestdir( File inDir )
{
this.destDir = inDir;
}

/**
* Set the flat dest dir flag. This flag controls whether the destination
* jars are written out in the destination directory with the same
* hierarchal structure from which the deployment descriptors have been
* read. If this is set to true the generated EJB jars are written into the
* root of the destination directory, otherwise they are written out in the
* same relative position as the deployment descriptors in the descriptor
* directory.
*
* @param inValue the new value of the flatdestdir flag.
*/
public void setFlatdestdir( boolean inValue )
{
config.flatDestDir = inValue;
}

/**
* Set the suffix for the generated jar file. When generic jars are
* generated, they have a suffix which is appended to the the bean name to
* create the name of the jar file. Note that this suffix includes the
* extension fo te jar file and should therefore end with an appropriate
* extension such as .jar or .ear
*
* @param inString the string to use as the suffix.
*/
public void setGenericjarsuffix( String inString )
{
this.genericJarSuffix = inString;
}

/**
* Set the Manifest file to use when jarring. As of EJB 1.1, manifest files
* are no longer used to configure the EJB. However, they still have a vital
* importance if the EJB is intended to be packaged in an EAR file. By
* adding "Class-Path" settings to a Manifest file, the EJB can look for
* classes inside the EAR file itself, allowing for easier deployment. This
* is outlined in the J2EE specification, and all J2EE components are meant
* to support it.
*
* @param manifest The new Manifest value
*/
public void setManifest( File manifest )
{
config.manifest = manifest;
}

/**
* Set the naming scheme used to determine the name of the generated jars
* from the deployment descriptor
*
* @param namingScheme The new Naming value
*/
public void setNaming( NamingScheme namingScheme )
{
config.namingScheme = namingScheme;
if( !config.namingScheme.getValue().equals( NamingScheme.BASEJARNAME ) &&
config.baseJarName != null )
{
throw new TaskException( "The basejarname attribute is not compatible with the " +
config.namingScheme.getValue() + " naming scheme" );
}
}

/**
* Set the srcdir attribute. The source directory is the directory that
* contains the classes that will be added to the EJB jar. Typically this
* will include the home and remote interfaces and the bean class.
*
* @param inDir the source directory.
*/
public void setSrcdir( File inDir )
{
config.srcDir = inDir;
}

/**
* Create a Borland nested element used to configure a deployment tool for
* Borland server.
*
* @return the deployment tool instance to be configured.
*/
public BorlandDeploymentTool createBorland()
{
getLogger().debug( "Borland deployment tools" );

BorlandDeploymentTool tool = new BorlandDeploymentTool();
tool.setTask( this );
deploymentTools.add( tool );
return tool;
}

/**
* creates a nested classpath element. This classpath is used to locate the
* super classes and interfaces of the classes that will make up the EJB
* jar.
*
* @return the path to be configured.
*/
public Path createClasspath()
{
if( config.classpath == null )
{
config.classpath = new Path();
}
Path path1 = config.classpath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Create a DTD location record. This stores the location of a DTD. The DTD
* is identified by its public Id. The location may either be a file
* location or a resource location.
*
* @return Description of the Returned Value
*/
public DTDLocation createDTD()
{
DTDLocation dtdLocation = new DTDLocation();
config.dtdLocations.add( dtdLocation );

return dtdLocation;
}

/**
* Create a nested element used to configure a deployment tool for iPlanet
* Application Server.
*
* @return the deployment tool instance to be configured.
*/
public IPlanetDeploymentTool createIplanet()
{
getLogger().debug( "iPlanet Application Server deployment tools" );

IPlanetDeploymentTool tool = new IPlanetDeploymentTool();
tool.setTask( this );
deploymentTools.add( tool );
return tool;
}

/**
* Create a jboss nested element used to configure a deployment tool for
* Jboss server.
*
* @return the deployment tool instance to be configured.
*/
public JbossDeploymentTool createJboss()
{
JbossDeploymentTool tool = new JbossDeploymentTool();
tool.setTask( this );
deploymentTools.add( tool );
return tool;
}

/**
* Create a file set for support elements
*
* @return a fileset which can be populated with support files.
*/
public FileSet createSupport()
{
FileSet supportFileSet = new FileSet();
config.supportFileSets.add( supportFileSet );
return supportFileSet;
}

/**
* Create a weblogic nested element used to configure a deployment tool for
* Weblogic server.
*
* @return the deployment tool instance to be configured.
*/
public WeblogicDeploymentTool createWeblogic()
{
WeblogicDeploymentTool tool = new WeblogicDeploymentTool();
tool.setTask( this );
deploymentTools.add( tool );
return tool;
}

/**
* Create a nested element for weblogic when using the Toplink Object-
* Relational mapping.
*
* @return the deployment tool instance to be configured.
*/
public WeblogicTOPLinkDeploymentTool createWeblogictoplink()
{
WeblogicTOPLinkDeploymentTool tool = new WeblogicTOPLinkDeploymentTool();
tool.setTask( this );
deploymentTools.add( tool );
return tool;
}

/**
* Create a websphere nested element used to configure a deployment tool for
* Websphere 4.0 server.
*
* @return the deployment tool instance to be configured.
*/
public WebsphereDeploymentTool createWebsphere()
{
WebsphereDeploymentTool tool = new WebsphereDeploymentTool();
tool.setTask( this );
deploymentTools.add( tool );
return tool;
}

/**
* Invoked by Ant after the task is prepared, when it is ready to execute
* this task. This will configure all of the nested deployment tools to
* allow them to process the jar. If no deployment tools have been
* configured a generic tool is created to handle the jar. A parser is
* configured and then each descriptor found is passed to all the deployment
* tool elements for processing.
*
* @exception TaskException thrown whenever a problem is encountered that
* cannot be recovered from, to signal to ant that a major problem
* occurred within this task.
*/
public void execute()
throws TaskException
{
validateConfig();

if( deploymentTools.size() == 0 )
{
GenericDeploymentTool genericTool = new GenericDeploymentTool();
genericTool.setTask( this );
genericTool.setDestdir( destDir );
genericTool.setGenericJarSuffix( genericJarSuffix );
deploymentTools.add( genericTool );
}

for( Iterator i = deploymentTools.iterator(); i.hasNext(); )
{
EJBDeploymentTool tool = (EJBDeploymentTool)i.next();
tool.configure( config );
tool.validateConfigured();
}

try
{
// Create the parser using whatever parser the system dictates
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setValidating( true );
SAXParser saxParser = saxParserFactory.newSAXParser();

DirectoryScanner ds = getDirectoryScanner( config.descriptorDir );
ds.scan();
String[] files = ds.getIncludedFiles();

getLogger().debug( files.length + " deployment descriptors located." );

// Loop through the files. Each file represents one deployment
// descriptor, and hence one bean in our model.
for( int index = 0; index < files.length; ++index )
{
// process the deployment descriptor in each tool
for( Iterator i = deploymentTools.iterator(); i.hasNext(); )
{
EJBDeploymentTool tool = (EJBDeploymentTool)i.next();
tool.processDescriptor( files[ index ], saxParser );
}
}
}
catch( SAXException se )
{
String msg = "SAXException while creating parser."
+ " Details: "
+ se.getMessage();
throw new TaskException( msg, se );
}
catch( ParserConfigurationException pce )
{
String msg = "ParserConfigurationException while creating parser. "
+ "Details: " + pce.getMessage();
throw new TaskException( msg, pce );
}
}

private void validateConfig()
{
if( config.srcDir == null )
{
throw new TaskException( "The srcDir attribute must be specified" );
}

if( config.descriptorDir == null )
{
config.descriptorDir = config.srcDir;
}

if( config.namingScheme == null )
{
config.namingScheme = new NamingScheme();
config.namingScheme.setValue( NamingScheme.DESCRIPTOR );
}
else if( config.namingScheme.getValue().equals( NamingScheme.BASEJARNAME ) &&
config.baseJarName == null )
{
throw new TaskException( "The basejarname attribute must be specified " +
"with the basejarname naming scheme" );
}
}

public static class DTDLocation
{
private String publicId = null;
private String location = null;

public void setLocation( String location )
{
this.location = location;
}

public void setPublicId( String publicId )
{
this.publicId = publicId;
}

public String getLocation()
{
return location;
}

public String getPublicId()
{
return publicId;
}
}

public static class NamingScheme extends EnumeratedAttribute
{
public final static String EJB_NAME = "ejb-name";
public final static String DIRECTORY = "directory";
public final static String DESCRIPTOR = "descriptor";
public final static String BASEJARNAME = "basejarname";

public String[] getValues()
{
return new String[]{EJB_NAME, DIRECTORY, DESCRIPTOR, BASEJARNAME};
}
}

/**
* A class which contains the configuration state of the ejbjar task. This
* state is passed to the deployment tools for configuration
*
* @author RT
*/
static class Config
{

/**
* Instance variable that marks the end of the 'basename'
*/
public String baseNameTerminator = "-";

/**
* Instance variable that determines whether to use a package structure
* of a flat directory as the destination for the jar files.
*/
public boolean flatDestDir = false;

/**
* A Fileset of support classes
*/
public List supportFileSets = new ArrayList();

/**
* The list of configured DTD locations
*/
public ArrayList dtdLocations = new ArrayList();

/**
* Stores a handle to the destination EJB Jar file
*/
public String baseJarName;

/**
* The classpath to use when loading classes
*/
public Path classpath;

/**
* Stores a handle to the directory under which to search for deployment
* descriptors
*/
public File descriptorDir;

/**
* The Manifest file
*/
public File manifest;

/**
* The naming scheme used to determine the generated jar name from the
* descriptor information
*/
public NamingScheme namingScheme;
/**
* Stores a handle to the directory under which to search for class
* files
*/
public File srcDir;
}// end of execute()
}





+ 0
- 192
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/Ejbc.java View File

@@ -1,192 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.Argument;
import org.apache.tools.ant.types.DirectoryScanner;
import org.apache.tools.ant.types.Path;

/**
* Build EJB support classes using Weblogic's ejbc tool from a directory
* containing a set of deployment descriptors.
*
* @author <a href="mailto:conor@cortexebusiness.com.au">Conor MacNeill</a> ,
* Cortex ebusiness Pty Limited
*/
public class Ejbc extends MatchingTask
{

public boolean keepgenerated;

/**
* The classpath to be used in the weblogic ejbc calls. It must contain the
* weblogic classes <b>and</b> the implementation classes of the home and
* remote interfaces.
*/
private String classpath;
/**
* The root directory of the tree containing the serialised deployment
* desciptors. The actual deployment descriptor files are selected using
* include and exclude constructs on the ejbc task provided by the
* MatchingTask superclass.
*/
private File descriptorDirectory;

/**
* The directory where generated files are placed.
*/
private File generatedFilesDirectory;

/**
* The name of the manifest file generated for the EJB jar.
*/
private File generatedManifestFile;

/**
* The source directory for the home and remote interfaces. This is used to
* determine if the generated deployment classes are out of date.
*/
private File sourceDirectory;

/**
* Set the classpath to be used for this compilation.
*
* @param s The new Classpath value
*/
public void setClasspath( final Path s )
{
this.classpath = s.toString();
}

/**
* Set the directory from where the serialised deployment descriptors are to
* be read.
*
* @param dirName the name of the directory containing the serialised
* deployment descriptors.
*/
public void setDescriptors( String dirName )
{
descriptorDirectory = new File( dirName );
}

/**
* Set the directory into which the support classes, RMI stubs, etc are to
* be written
*
* @param dirName the name of the directory into which code is generated
*/
public void setDest( final File dirName )
{
generatedFilesDirectory = dirName;
}

public void setKeepgenerated( String newKeepgenerated )
{
keepgenerated = Boolean.valueOf( newKeepgenerated.trim() ).booleanValue();

}

/**
* Set the generated manifest file. For each EJB that is processed an entry
* is created in this file. This can then be used to create a jar file for
* dploying the beans.
*
* @param manifestFilename The new Manifest value
*/
public void setManifest( String manifestFilename )
{
generatedManifestFile = new File( manifestFilename );
}

/**
* Set the directory containing the source code for the home interface,
* remote interface and public key class definitions.
*
* @param dirName the directory containg the source tree for the EJB's
* interface classes.
*/
public void setSrc( String dirName )
{
sourceDirectory = new File( dirName );
}

public boolean getKeepgenerated()
{
return keepgenerated;
}

/**
* Do the work. The work is actually done by creating a separate JVM to run
* a helper task. This approach allows the classpath of the helper task to
* be set. Since the weblogic tools require the class files of the project's
* home and remote interfaces to be available in the classpath, this also
* avoids having to start ant with the class path of the project it is
* building.
*
* @exception TaskException if someting goes wrong with the build
*/
public void execute()
throws TaskException
{
if( descriptorDirectory == null ||
!descriptorDirectory.isDirectory() )
{
throw new TaskException( "descriptors directory " + descriptorDirectory.getPath() +
" is not valid" );
}
if( generatedFilesDirectory == null ||
!generatedFilesDirectory.isDirectory() )
{
throw new TaskException( "dest directory " + generatedFilesDirectory.getPath() +
" is not valid" );
}

if( sourceDirectory == null ||
!sourceDirectory.isDirectory() )
{
throw new TaskException( "src directory " + sourceDirectory.getPath() +
" is not valid" );
}

String systemClassPath = System.getProperty( "java.class.path" );
String execClassPath =
systemClassPath + File.separator + classpath + File.separator + generatedFilesDirectory;
// get all the files in the descriptor directory
DirectoryScanner ds = super.getDirectoryScanner( descriptorDirectory );

String[] files = ds.getIncludedFiles();

Java helperTask = (Java)getProject().createTask( "java" );
helperTask.setFork( true );
helperTask.setClassname( "org.apache.tools.ant.taskdefs.optional.ejb.EjbcHelper" );
String args = "";
args += " " + descriptorDirectory;
args += " " + generatedFilesDirectory;
args += " " + sourceDirectory;
args += " " + generatedManifestFile;
args += " " + keepgenerated;

for( int i = 0; i < files.length; ++i )
{
args += " " + files[ i ];
}

Argument arguments = helperTask.createArg();
arguments.setLine( args );
helperTask.setClasspath( new Path( execClassPath ) );
if( helperTask.executeJava() != 0 )
{
throw new TaskException( "Execution of ejbc helper failed" );
}
}
}

+ 0
- 286
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbcHelper.java View File

@@ -1,286 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import javax.ejb.deployment.DeploymentDescriptor;
import javax.ejb.deployment.EntityDescriptor;

/**
* A helper class which performs the actual work of the ejbc task. This class is
* run with a classpath which includes the weblogic tools and the home and
* remote interface class files referenced in the deployment descriptors being
* processed.
*
* @author <a href="mailto:conor@cortexebusiness.com.au">Conor MacNeill</a> ,
* Cortex ebusiness Pty Limited
*/
public class EjbcHelper
{

/**
* The names of the serialised deployment descriptors
*/
String[] descriptors;

/**
* The classpath to be used in the weblogic ejbc calls. It must contain the
* weblogic classes <b>and</b> the implementation classes of the home and
* remote interfaces.
*/
private String classpath;
/**
* The root directory of the tree containing the serialised deployment
* desciptors.
*/
private File descriptorDirectory;

/**
* The directory where generated files are placed.
*/
private File generatedFilesDirectory;

private boolean keepGenerated;

/**
* The name of the manifest file generated for the EJB jar.
*/
private File manifestFile;

/**
* The source directory for the home and remote interfaces. This is used to
* determine if the generated deployment classes are out of date.
*/
private File sourceDirectory;

/**
* Initialise the EjbcHelper by reading the command arguments.
*
* @param args Description of Parameter
*/
private EjbcHelper( String[] args )
{
int index = 0;
descriptorDirectory = new File( args[ index++ ] );
generatedFilesDirectory = new File( args[ index++ ] );
sourceDirectory = new File( args[ index++ ] );
manifestFile = new File( args[ index++ ] );
keepGenerated = Boolean.valueOf( args[ index++ ] ).booleanValue();

descriptors = new String[ args.length - index ];
for( int i = 0; index < args.length; ++i )
{
descriptors[ i ] = args[ index++ ];
}
}

/**
* Command line interface for the ejbc helper task.
*
* @param args The command line arguments
* @exception Exception Description of Exception
*/
public static void main( String[] args )
throws Exception
{
EjbcHelper helper = new EjbcHelper( args );
helper.process();
}

private String[] getCommandLine( boolean debug, File descriptorFile )
{
ArrayList v = new ArrayList();
if( !debug )
{
v.add( "-noexit" );
}
if( keepGenerated )
{
v.add( "-keepgenerated" );
}
v.add( "-d" );
v.add( generatedFilesDirectory.getPath() );
v.add( descriptorFile.getPath() );

String[] args = new String[ v.size() ];
v.copyInto( args );
return args;
}

/**
* Determine if the weblogic EJB support classes need to be regenerated for
* a given deployment descriptor. This process attempts to determine if the
* support classes need to be rebuilt. It does this by examining only some
* of the support classes which are typically generated. If the ejbc task is
* interrupted generating the support classes for a bean, all of the support
* classes should be removed to force regeneration of the support classes.
*
* @param descriptorFile the serialised deployment descriptor
* @return true if the support classes need to be regenerated.
* @throws IOException if the descriptor file cannot be closed.
*/
private boolean isRegenRequired( File descriptorFile )
throws IOException
{
// read in the descriptor. Under weblogic, the descriptor is a weblogic
// specific subclass which has references to the implementation classes.
// These classes must, therefore, be in the classpath when the deployment
// descriptor is loaded from the .ser file
FileInputStream fis = null;
try
{
fis = new FileInputStream( descriptorFile );
ObjectInputStream ois = new ObjectInputStream( fis );
DeploymentDescriptor dd = (DeploymentDescriptor)ois.readObject();
fis.close();

String homeInterfacePath = dd.getHomeInterfaceClassName().replace( '.', '/' ) + ".java";
String remoteInterfacePath = dd.getRemoteInterfaceClassName().replace( '.', '/' ) + ".java";
String primaryKeyClassPath = null;
if( dd instanceof EntityDescriptor )
{
primaryKeyClassPath = ( (EntityDescriptor)dd ).getPrimaryKeyClassName().replace( '.', '/' ) + ".java";
;
}

File homeInterfaceSource = new File( sourceDirectory, homeInterfacePath );
File remoteInterfaceSource = new File( sourceDirectory, remoteInterfacePath );
File primaryKeyClassSource = null;
if( primaryKeyClassPath != null )
{
primaryKeyClassSource = new File( sourceDirectory, remoteInterfacePath );
}

// are any of the above out of date.
// we find the implementation classes and see if they are older than any
// of the above or the .ser file itself.
String beanClassBase = dd.getEnterpriseBeanClassName().replace( '.', '/' );
File ejbImplentationClass
= new File( generatedFilesDirectory, beanClassBase + "EOImpl.class" );
File homeImplementationClass
= new File( generatedFilesDirectory, beanClassBase + "HomeImpl.class" );
File beanStubClass
= new File( generatedFilesDirectory, beanClassBase + "EOImpl_WLStub.class" );

// if the implementation classes don;t exist regenerate
if( !ejbImplentationClass.exists() || !homeImplementationClass.exists() ||
!beanStubClass.exists() )
{
return true;
}

// Is the ser file or any of the source files newer then the class files.
// firstly find the oldest of the two class files.
long classModificationTime = ejbImplentationClass.lastModified();
if( homeImplementationClass.lastModified() < classModificationTime )
{
classModificationTime = homeImplementationClass.lastModified();
}
if( beanStubClass.lastModified() < classModificationTime )
{
classModificationTime = beanStubClass.lastModified();
}

if( descriptorFile.lastModified() > classModificationTime ||
homeInterfaceSource.lastModified() > classModificationTime ||
remoteInterfaceSource.lastModified() > classModificationTime )
{
return true;
}

if( primaryKeyClassSource != null &&
primaryKeyClassSource.lastModified() > classModificationTime )
{
return true;
}
}
catch( Throwable descriptorLoadException )
{
System.out.println( "Exception occurred reading " + descriptorFile.getName() + " - continuing" );
// any problems - just regenerate
return true;
}
finally
{
if( fis != null )
{
fis.close();
}
}

return false;
}

/**
* Process the descriptors in turn generating support classes for each and a
* manifest file for all of the beans.
*
* @exception Exception Description of Exception
*/
private void process()
throws Exception
{
String manifest = "Manifest-Version: 1.0\n\n";
for( int i = 0; i < descriptors.length; ++i )
{
String descriptorName = descriptors[ i ];
File descriptorFile = new File( descriptorDirectory, descriptorName );

if( isRegenRequired( descriptorFile ) )
{
System.out.println( "Running ejbc for " + descriptorFile.getName() );
regenerateSupportClasses( descriptorFile );
}
else
{
System.out.println( descriptorFile.getName() + " is up to date" );
}
manifest += "Name: " + descriptorName.replace( '\\', '/' ) + "\nEnterprise-Bean: True\n\n";
}

FileWriter fw = new FileWriter( manifestFile );
PrintWriter pw = new PrintWriter( fw );
pw.print( manifest );
fw.flush();
fw.close();
}

/**
* Perform the weblogic.ejbc call to regenerate the support classes. Note
* that this method relies on an undocumented -noexit option to the ejbc
* tool to stop the ejbc tool exiting the VM altogether.
*
* @param descriptorFile Description of Parameter
* @exception Exception Description of Exception
*/
private void regenerateSupportClasses( File descriptorFile )
throws Exception
{
// create a Java task to do the rebuild


String[] args = getCommandLine( false, descriptorFile );

try
{
weblogic.ejbc.main( args );
}
catch( Exception e )
{
// run with no exit for better reporting
String[] newArgs = getCommandLine( true, descriptorFile );
weblogic.ejbc.main( newArgs );
}
}
}

+ 0
- 958
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java View File

@@ -1,958 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import javax.xml.parsers.SAXParser;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.DirectoryScanner;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.PathUtil;
import org.apache.tools.ant.types.ScannerUtil;
import org.apache.tools.ant.util.depend.Dependencies;
import org.apache.tools.ant.util.depend.Filter;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
* A deployment tool which creates generic EJB jars. Generic jars contains only
* those classes and META-INF entries specified in the EJB 1.1 standard This
* class is also used as a framework for the creation of vendor specific
* deployment tools. A number of template methods are provided through which the
* vendor specific tool can hook into the EJB creation process.
*
* @author RT
*/
public class GenericDeploymentTool
extends AbstractLogEnabled
implements EJBDeploymentTool
{
/**
* Private constants that are used when constructing the standard jarfile
*/
protected final static String META_DIR = "META-INF/";
protected final static String EJB_DD = "ejb-jar.xml";

/**
* Instance variable that stores the suffix for the generated jarfile.
*/
private String genericJarSuffix = "-generic.jar";

/**
* The classloader generated from the given classpath to load the super
* classes and super interfaces.
*/
private ClassLoader classpathLoader = null;

/**
* List of files have been loaded into the EJB jar
*/
private List addedfiles;

/**
* The classpath to use with this deployment tool. This is appended to any
* paths from the ejbjar task itself.
*/
private Path classpath;

/**
* The configuration from the containing task. This config combined with the
* settings of the individual attributes here constitues the complete config
* for this deployment tool.
*/
private EjbJar.Config config;

/**
* Stores a handle to the directory to put the Jar files in
*/
private File destDir;

/**
* Handler used to parse the EJB XML descriptor
*/
private DescriptorHandler handler;

/**
* The task to which this tool belongs. This is used to access services
* provided by the ant core, such as logging.
*/
private Task task;

/**
* Set the classpath to be used for this compilation.
*
* @param classpath The new Classpath value
*/
public void setClasspath( Path classpath )
{
this.classpath = classpath;
}

/**
* Setter used to store the value of destination directory prior to
* execute() being called.
*
* @param inDir the destination directory.
*/
public void setDestdir( File inDir )
{
this.destDir = inDir;
}

/**
* Setter used to store the suffix for the generated jar file.
*
* @param inString the string to use as the suffix.
*/
public void setGenericJarSuffix( String inString )
{
this.genericJarSuffix = inString;
}

/**
* Set the task which owns this tool
*
* @param task The new Task value
*/
public void setTask( Task task )
{
this.task = task;
}

/**
* Get the prefix for vendor deployment descriptors. This will contain the
* path and the start of the descriptor name, depending on the naming scheme
*
* @param baseName Description of Parameter
* @param descriptorFileName Description of Parameter
* @return The VendorDDPrefix value
*/
public String getVendorDDPrefix( String baseName, String descriptorFileName )
{
String ddPrefix = null;

if( config.namingScheme.getValue().equals( EjbJar.NamingScheme.DESCRIPTOR ) )
{
ddPrefix = baseName + config.baseNameTerminator;
}
else if( config.namingScheme.getValue().equals( EjbJar.NamingScheme.BASEJARNAME ) ||
config.namingScheme.getValue().equals( EjbJar.NamingScheme.EJB_NAME ) ||
config.namingScheme.getValue().equals( EjbJar.NamingScheme.DIRECTORY ) )
{
String canonicalDescriptor = descriptorFileName.replace( '\\', '/' );
int index = canonicalDescriptor.lastIndexOf( '/' );
if( index == -1 )
{
ddPrefix = "";
}
else
{
ddPrefix = descriptorFileName.substring( 0, index + 1 );
}
}
return ddPrefix;
}

/**
* Configure this tool for use in the ejbjar task.
*
* @param config Description of Parameter
*/
public void configure( EjbJar.Config config )
{
this.config = config;

classpathLoader = null;
}

/**
* Add the classpath for the user classes
*
* @return Description of the Returned Value
*/
public Path createClasspath()
{
if( classpath == null )
{
classpath = new Path();
}
Path path1 = classpath;
final Path path = new Path();
path1.addPath( path );
return path;
}

public void processDescriptor( String descriptorFileName, SAXParser saxParser )
{

checkConfiguration( descriptorFileName, saxParser );

try
{
handler = getDescriptorHandler( config.srcDir );

// Retrive the files to be added to JAR from EJB descriptor
Hashtable ejbFiles = parseEjbFiles( descriptorFileName, saxParser );

// Add any support classes specified in the build file
addSupportClasses( ejbFiles );

// Determine the JAR filename (without filename extension)
String baseName = getJarBaseName( descriptorFileName );

String ddPrefix = getVendorDDPrefix( baseName, descriptorFileName );

// First the regular deployment descriptor
ejbFiles.put( META_DIR + EJB_DD,
new File( config.descriptorDir, descriptorFileName ) );

// now the vendor specific files, if any
addVendorFiles( ejbFiles, ddPrefix );

// add any dependent files
checkAndAddDependants( ejbFiles );

// Lastly create File object for the Jar files. If we are using
// a flat destination dir, then we need to redefine baseName!
if( config.flatDestDir && baseName.length() != 0 )
{
int startName = baseName.lastIndexOf( File.separator );
if( startName == -1 )
{
startName = 0;
}

int endName = baseName.length();
baseName = baseName.substring( startName, endName );
}

File jarFile = getVendorOutputJarFile( baseName );

// Check to see if we need a build and start doing the work!
if( needToRebuild( ejbFiles, jarFile ) )
{
// Log that we are going to build...
final String message =
"building " + jarFile.getName() + " with " + String.valueOf( ejbFiles.size() ) + " files";
getLogger().info( message );

// Use helper method to write the jarfile
String publicId = getPublicId();
writeJar( baseName, jarFile, ejbFiles, publicId );

}
else
{
// Log that the file is up to date...
getLogger().debug( jarFile.toString() + " is up to date." );
}

}
catch( SAXException se )
{
String msg = "SAXException while parsing '"
+ descriptorFileName.toString()
+ "'. This probably indicates badly-formed XML."
+ " Details: "
+ se.getMessage();
throw new TaskException( msg, se );
}
catch( IOException ioe )
{
String msg = "IOException while parsing'"
+ descriptorFileName.toString()
+ "'. This probably indicates that the descriptor"
+ " doesn't exist. Details: "
+ ioe.getMessage();
throw new TaskException( msg, ioe );
}
}

/**
* Called to validate that the tool parameters have been configured.
*
* @throws TaskException If the Deployment Tool's configuration isn't valid
*/
public void validateConfigured()
throws TaskException
{
if( ( destDir == null ) || ( !destDir.isDirectory() ) )
{
String msg = "A valid destination directory must be specified "
+ "using the \"destdir\" attribute.";
throw new TaskException( msg );
}
}

/**
* Returns a Classloader object which parses the passed in generic EjbJar
* classpath. The loader is used to dynamically load classes from
* javax.ejb.* and the classes being added to the jar.
*
* @return The ClassLoaderForBuild value
*/
protected ClassLoader getClassLoaderForBuild()
throws TaskException
{
if( classpathLoader != null )
{
return classpathLoader;
}

Path combinedClasspath = getCombinedClasspath();

// only generate a new ClassLoader if we have a classpath
if( combinedClasspath == null )
{
classpathLoader = getClass().getClassLoader();
}
else
{
final URL[] urls = PathUtil.toURLs( combinedClasspath );
classpathLoader = new URLClassLoader( urls );
}

return classpathLoader;
}

/**
* Get the classpath by combining the one from the surrounding task, if any
* and the one from this tool.
*
* @return The CombinedClasspath value
*/
protected Path getCombinedClasspath()
{
Path combinedPath = classpath;
if( config.classpath != null )
{
if( combinedPath == null )
{
combinedPath = config.classpath;
}
else
{
combinedPath.append( config.classpath );
}
}

return combinedPath;
}

/**
* Get the basename terminator.
*
* @return The Config value
*/
protected EjbJar.Config getConfig()
{
return config;
}

protected DescriptorHandler getDescriptorHandler( File srcDir )
{
DescriptorHandler handler = new DescriptorHandler( getTask(), srcDir );

registerKnownDTDs( handler );

// register any DTDs supplied by the user
for( Iterator i = getConfig().dtdLocations.iterator(); i.hasNext(); )
{
EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation)i.next();
handler.registerDTD( dtdLocation.getPublicId(), dtdLocation.getLocation() );
}
return handler;
}

/**
* Get the desitination directory.
*
* @return The DestDir value
*/
protected File getDestDir()
{
return destDir;
}

/**
* Using the EJB descriptor file name passed from the <code>ejbjar</code>
* task, this method returns the "basename" which will be used to name the
* completed JAR file.
*
* @param descriptorFileName String representing the file name of an EJB
* descriptor to be processed
* @return The "basename" which will be used to name the completed JAR file
*/
protected String getJarBaseName( String descriptorFileName )
{

String baseName = "";

// Work out what the base name is
if( config.namingScheme.getValue().equals( EjbJar.NamingScheme.BASEJARNAME ) )
{
String canonicalDescriptor = descriptorFileName.replace( '\\', '/' );
int index = canonicalDescriptor.lastIndexOf( '/' );
if( index != -1 )
{
baseName = descriptorFileName.substring( 0, index + 1 );
}
baseName += config.baseJarName;
}
else if( config.namingScheme.getValue().equals( EjbJar.NamingScheme.DESCRIPTOR ) )
{
int lastSeparatorIndex = descriptorFileName.lastIndexOf( File.separator );
int endBaseName = -1;
if( lastSeparatorIndex != -1 )
{
endBaseName = descriptorFileName.indexOf( config.baseNameTerminator,
lastSeparatorIndex );
}
else
{
endBaseName = descriptorFileName.indexOf( config.baseNameTerminator );
}

if( endBaseName != -1 )
{
baseName = descriptorFileName.substring( 0, endBaseName );
}
baseName = descriptorFileName.substring( 0, endBaseName );
}
else if( config.namingScheme.getValue().equals( EjbJar.NamingScheme.DIRECTORY ) )
{
int lastSeparatorIndex = descriptorFileName.lastIndexOf( File.separator );
String dirName = descriptorFileName.substring( 0, lastSeparatorIndex );
int dirSeparatorIndex = dirName.lastIndexOf( File.separator );
if( dirSeparatorIndex != -1 )
{
dirName = dirName.substring( dirSeparatorIndex + 1 );
}

baseName = dirName;
}
else if( config.namingScheme.getValue().equals( EjbJar.NamingScheme.EJB_NAME ) )
{
baseName = handler.getEjbName();
}
return baseName;
}

/**
* Returns the Public ID of the DTD specified in the EJB descriptor. Not
* every vendor-specific <code>DeploymentTool</code> will need to reference
* this value or may want to determine this value in a vendor-specific way.
*
* @return Public ID of the DTD specified in the EJB descriptor.
*/
protected String getPublicId()
{
return handler.getPublicId();
}

/**
* Get the task for this tool.
*
* @return The Task value
*/
protected Task getTask()
{
return task;
}

/**
* Utility method that encapsulates the logic of adding a file entry to a
* .jar file. Used by execute() to add entries to the jar file as it is
* constructed.
*
* @param jStream A JarOutputStream into which to write the jar entry.
* @param inputFile A File from which to read the contents the file being
* added.
* @param logicalFilename A String representing the name, including all
* relevant path information, that should be stored for the entry being
* added.
* @exception TaskException Description of Exception
*/
protected void addFileToJar( JarOutputStream jStream,
File inputFile,
String logicalFilename )
throws TaskException
{
FileInputStream iStream = null;
try
{
if( !addedfiles.contains( logicalFilename ) )
{
iStream = new FileInputStream( inputFile );
// Create the zip entry and add it to the jar file
ZipEntry zipEntry = new ZipEntry( logicalFilename.replace( '\\', '/' ) );
jStream.putNextEntry( zipEntry );

// Create the file input stream, and buffer everything over
// to the jar output stream
byte[] byteBuffer = new byte[ 2 * 1024 ];
int count = 0;
do
{
jStream.write( byteBuffer, 0, count );
count = iStream.read( byteBuffer, 0, byteBuffer.length );
} while( count != -1 );

//add it to list of files in jar
addedfiles.add( logicalFilename );
}
}
catch( IOException ioe )
{
final String message = "WARNING: IOException while adding entry " +
logicalFilename + " to jarfile from " + inputFile.getPath() + " " +
ioe.getClass().getName() + "-" + ioe.getMessage();
getLogger().warn( message );
}
finally
{
// Close up the file input stream for the class file
if( iStream != null )
{
try
{
iStream.close();
}
catch( IOException closeException )
{
}
}
}
}

/**
* Adds any classes the user specifies using <i>support</i> nested elements
* to the <code>ejbFiles</code> Hashtable.
*
* @param ejbFiles Hashtable of EJB classes (and other) files that will be
* added to the completed JAR file
*/
protected void addSupportClasses( Hashtable ejbFiles )
{
// add in support classes if any
Project project = task.getProject();
for( Iterator i = config.supportFileSets.iterator(); i.hasNext(); )
{
FileSet supportFileSet = (FileSet)i.next();
File supportBaseDir = supportFileSet.getDir();
DirectoryScanner supportScanner = ScannerUtil.getDirectoryScanner( supportFileSet );
supportScanner.scan();
String[] supportFiles = supportScanner.getIncludedFiles();
for( int j = 0; j < supportFiles.length; ++j )
{
ejbFiles.put( supportFiles[ j ], new File( supportBaseDir, supportFiles[ j ] ) );
}
}
}

/**
* Add any vendor specific files which should be included in the EJB Jar.
*
* @param ejbFiles The feature to be added to the VendorFiles attribute
* @param ddPrefix The feature to be added to the VendorFiles attribute
*/
protected void addVendorFiles( Hashtable ejbFiles, String ddPrefix )
{
// nothing to add for generic tool.
}// end of writeJar

/**
* Add all available classes, that depend on Remote, Home, Bean, PK
*
* @param checkEntries files, that are extracted from the deployment
* descriptor
* @exception TaskException Description of Exception
*/
protected void checkAndAddDependants( Hashtable checkEntries )
throws TaskException
{
Dependencies visitor = new Dependencies();
Set set = new TreeSet();
Set newSet = new HashSet();
final String base = config.srcDir.getAbsolutePath() + File.separator;

Iterator i = checkEntries.keySet().iterator();
while( i.hasNext() )
{
String entryName = (String)i.next();
if( entryName.endsWith( ".class" ) )
{
newSet.add( entryName.substring( 0, entryName.length() - ".class".length() ).replace( File.separatorChar, '/' ) );
}
}
set.addAll( newSet );

do
{
i = newSet.iterator();
while( i.hasNext() )
{
String fileName = base + ( (String)i.next() ).replace( '/', File.separatorChar ) + ".class";

try
{
JavaClass javaClass = new ClassParser( fileName ).parse();
javaClass.accept( visitor );
}
catch( IOException e )
{
getLogger().info( "exception: " + e.getMessage() );
}
}
newSet.clear();
newSet.addAll( visitor.getDependencies() );
visitor.clearDependencies();

Dependencies.applyFilter( newSet,
new Filter()
{
public boolean accept( Object object )
{
String fileName = base + ( (String)object ).replace( '/', File.separatorChar ) + ".class";
return new File( fileName ).exists();
}
} );
newSet.removeAll( set );
set.addAll( newSet );
} while( newSet.size() > 0 );

i = set.iterator();
while( i.hasNext() )
{
String next = ( (String)i.next() ).replace( '/', File.separatorChar );
checkEntries.put( next + ".class", new File( base + next + ".class" ) );
getLogger().debug( "dependent class: " + next + ".class" + " - " + base + next + ".class" );
}
}

/**
* This method is called as the first step in the processDescriptor method
* to allow vendor-specific subclasses to validate the task configuration
* prior to processing the descriptor. If the configuration is invalid, a
* TaskException should be thrown.
*
* @param descriptorFileName String representing the file name of an EJB
* descriptor to be processed
* @param saxParser SAXParser which may be used to parse the XML descriptor
* @exception TaskException Description of Exception
* @thows TaskException Thrown if the configuration is invalid
*/
protected void checkConfiguration( String descriptorFileName,
SAXParser saxParser )
throws TaskException
{

/*
* For the GenericDeploymentTool, do nothing. Vendor specific
* subclasses should throw a TaskException if the configuration is
* invalid for their server.
*/
}

/**
* This method checks the timestamp on each file listed in the <code>
* ejbFiles</code> and compares them to the timestamp on the <code>jarFile
* </code>. If the <code>jarFile</code>'s timestamp is more recent than each
* EJB file, <code>true</code> is returned. Otherwise, <code>false
* </code> is returned. TODO: find a way to check the manifest-file, that is
* found by naming convention
*
* @param ejbFiles Hashtable of EJB classes (and other) files that will be
* added to the completed JAR file
* @param jarFile JAR file which will contain all of the EJB classes (and
* other) files
* @return boolean indicating whether or not the <code>jarFile</code> is up
* to date
*/
protected boolean needToRebuild( Hashtable ejbFiles, File jarFile )
{
if( jarFile.exists() )
{
long lastBuild = jarFile.lastModified();

if( config.manifest != null && config.manifest.exists() &&
config.manifest.lastModified() > lastBuild )
{
getLogger().debug( "Build needed because manifest " + config.manifest + " is out of date" );
return true;
}

Iterator fileIter = ejbFiles.values().iterator();

// Loop through the files seeing if any has been touched
// more recently than the destination jar.
while( fileIter.hasNext() )
{
File currentFile = (File)fileIter.next();
if( lastBuild < currentFile.lastModified() )
{
getLogger().debug( "Build needed because " + currentFile.getPath() + " is out of date" );
return true;
}
}
return false;
}

return true;
}

/**
* This method returns a list of EJB files found when the specified EJB
* descriptor is parsed and processed.
*
* @param descriptorFileName String representing the file name of an EJB
* descriptor to be processed
* @param saxParser SAXParser which may be used to parse the XML descriptor
* @return Hashtable of EJB class (and other) files to be added to the
* completed JAR file
* @throws SAXException Any SAX exception, possibly wrapping another
* exception
* @throws IOException An IOException from the parser, possibly from a the
* byte stream or character stream
*/
protected Hashtable parseEjbFiles( String descriptorFileName, SAXParser saxParser )
throws IOException, SAXException
{
FileInputStream descriptorStream = null;
Hashtable ejbFiles = null;

try
{

/*
* Parse the ejb deployment descriptor. While it may not
* look like much, we use a SAXParser and an inner class to
* get hold of all the classfile names for the descriptor.
*/
descriptorStream = new FileInputStream( new File( config.descriptorDir, descriptorFileName ) );
saxParser.parse( new InputSource( descriptorStream ), handler );

ejbFiles = handler.getFiles();

}
finally
{
if( descriptorStream != null )
{
try
{
descriptorStream.close();
}
catch( IOException closeException )
{
}
}
}

return ejbFiles;
}

/**
* Register the locations of all known DTDs. vendor-specific subclasses
* should override this method to define the vendor-specific locations of
* the EJB DTDs
*
* @param handler Description of Parameter
*/
protected void registerKnownDTDs( DescriptorHandler handler )
{
// none to register for generic
}

/**
* Returns true, if the meta-inf dir is being explicitly set, false
* otherwise.
*
* @return Description of the Returned Value
*/
protected boolean usingBaseJarName()
{
return config.baseJarName != null;
}

/**
* Method used to encapsulate the writing of the JAR file. Iterates over the
* filenames/java.io.Files in the Hashtable stored on the instance variable
* ejbFiles.
*
* @param baseName Description of Parameter
* @param jarfile Description of Parameter
* @param files Description of Parameter
* @param publicId Description of Parameter
* @exception TaskException Description of Exception
*/
protected void writeJar( String baseName, File jarfile, Hashtable files,
String publicId )
throws TaskException
{

JarOutputStream jarStream = null;
try
{
// clean the addedfiles ArrayList
addedfiles = new ArrayList();

/*
* If the jarfile already exists then whack it and recreate it.
* Should probably think of a more elegant way to handle this
* so that in case of errors we don't leave people worse off
* than when we started =)
*/
if( jarfile.exists() )
{
jarfile.delete();
}
jarfile.getParentFile().mkdirs();
jarfile.createNewFile();

InputStream in = null;
Manifest manifest = null;
try
{
File manifestFile = new File( getConfig().descriptorDir, baseName + "-manifest.mf" );
if( manifestFile.exists() )
{
in = new FileInputStream( manifestFile );
}
else if( config.manifest != null )
{
in = new FileInputStream( config.manifest );
if( in == null )
{
throw new TaskException( "Could not find manifest file: " + config.manifest );
}
}
else
{
String defaultManifest = "/org/apache/tools/ant/defaultManifest.mf";
in = this.getClass().getResourceAsStream( defaultManifest );
if( in == null )
{
throw new TaskException( "Could not find default manifest: " + defaultManifest );
}
}

manifest = new Manifest( in );
}
catch( IOException e )
{
throw new TaskException( "Unable to read manifest", e );
}
finally
{
if( in != null )
{
in.close();
}
}

// Create the streams necessary to write the jarfile

jarStream = new JarOutputStream( new FileOutputStream( jarfile ), manifest );
jarStream.setMethod( JarOutputStream.DEFLATED );

// Loop through all the class files found and add them to the jar
for( Iterator entryIterator = files.keySet().iterator(); entryIterator.hasNext(); )
{
String entryName = (String)entryIterator.next();
File entryFile = (File)files.get( entryName );

getLogger().debug( "adding file '" + entryName + "'" );

addFileToJar( jarStream, entryFile, entryName );

// See if there are any inner classes for this class and add them in if there are
InnerClassFilenameFilter flt = new InnerClassFilenameFilter( entryFile.getName() );
File entryDir = entryFile.getParentFile();
String[] innerfiles = entryDir.list( flt );
for( int i = 0, n = innerfiles.length; i < n; i++ )
{

//get and clean up innerclass name
int entryIndex = entryName.lastIndexOf( entryFile.getName() ) - 1;
if( entryIndex < 0 )
{
entryName = innerfiles[ i ];
}
else
{
entryName = entryName.substring( 0, entryIndex ) + File.separatorChar + innerfiles[ i ];
}
// link the file
entryFile = new File( config.srcDir, entryName );

getLogger().debug( "adding innerclass file '" + entryName + "'" );

addFileToJar( jarStream, entryFile, entryName );

}
}
}
catch( IOException ioe )
{
String msg = "IOException while processing ejb-jar file '"
+ jarfile.toString()
+ "'. Details: "
+ ioe.getMessage();
throw new TaskException( msg, ioe );
}
finally
{
if( jarStream != null )
{
try
{
jarStream.close();
}
catch( IOException closeException )
{
}
}
}
}

/**
* Get the vendor specific name of the Jar that will be output. The
* modification date of this jar will be checked against the dependent bean
* classes.
*
* @param baseName Description of Parameter
* @return The VendorOutputJarFile value
*/
File getVendorOutputJarFile( String baseName )
{
return new File( destDir, baseName + genericJarSuffix );
}
}

+ 0
- 407
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetDeploymentTool.java View File

@@ -1,407 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import javax.xml.parsers.SAXParser;
import org.apache.myrmidon.api.TaskException;
import org.xml.sax.SAXException;

/**
* This class is used to generate iPlanet Application Server (iAS) 6.0 stubs and
* skeletons and build an EJB Jar file. It is designed to be used with the Ant
* <code>ejbjar</code> task. If only stubs and skeletons need to be generated
* (in other words, if no JAR file needs to be created), refer to the <code>iplanet-ejbc</code>
* task and the <code>IPlanetEjbcTask</code> class. <p>
*
* The following attributes may be specified by the user:
* <ul>
* <li> <i>destdir</i> -- The base directory into which the generated JAR
* files will be written. Each JAR file is written in directories which
* correspond to their location within the "descriptordir" namespace. This is
* a required attribute.
* <li> <i>classpath</i> -- The classpath used when generating EJB stubs and
* skeletons. This is an optional attribute (if omitted, the classpath
* specified in the "ejbjar" parent task will be used). If specified, the
* classpath elements will be prepended to the classpath specified in the
* parent "ejbjar" task. Note that nested "classpath" elements may also be
* used.
* <li> <i>keepgenerated</i> -- Indicates whether or not the Java source files
* which are generated by ejbc will be saved or automatically deleted. If
* "yes", the source files will be retained. This is an optional attribute (if
* omitted, it defaults to "no").
* <li> <i>debug</i> -- Indicates whether or not the ejbc utility should log
* additional debugging statements to the standard output. If "yes", the
* additional debugging statements will be generated (if omitted, it defaults
* to "no").
* <li> <i>iashome</i> -- May be used to specify the "home" directory for this
* iPlanet Application server installation. This is used to find the ejbc
* utility if it isn't included in the user's system path. This is an optional
* attribute (if specified, it should refer to the <code>[install-location]/iplanet/ias6/ias
* </code> directory). If omitted, the ejbc utility
* must be on the user's system path.
* <li> <i>suffix</i> -- String value appended to the JAR filename when
* creating each JAR. This attribute is not required (if omitted, it defaults
* to ".jar").
* </ul>
* <p>
*
* For each EJB descriptor found in the "ejbjar" parent task, this deployment
* tool will locate the three classes that comprise the EJB. If these class
* files cannot be located in the specified <code>srcdir</code> directory, the
* task will fail. The task will also attempt to locate the EJB stubs and
* skeletons in this directory. If found, the timestamps on the stubs and
* skeletons will be checked to ensure they are up to date. Only if these files
* cannot be found or if they are out of date will ejbc be called.
*
* @author Greg Nelson <a href="mailto:greg@netscape.com">greg@netscape.com</a>
* @see IPlanetEjbc
*/
public class IPlanetDeploymentTool extends GenericDeploymentTool
{

/*
* Regardless of the name of the iAS-specific EJB descriptor file, it will
* written in the completed JAR file as "ias-ejb-jar.xml". This is the
* naming convention implemented by iAS.
*/
private final static String IAS_DD = "ias-ejb-jar.xml";
private String jarSuffix = ".jar";
private boolean keepgenerated = false;
private boolean debug = false;

/*
* Filenames of the standard EJB descriptor (which is passed to this class
* from the parent "ejbjar" task) and the iAS-specific EJB descriptor
* (whose name is determined by this class). Both filenames are relative
* to the directory specified by the "srcdir" attribute in the ejbjar task.
*/
private String descriptorName;

/*
* The displayName variable stores the value of the "display-name" element
* from the standard EJB descriptor. As a future enhancement to this task,
* we may determine the name of the EJB JAR file using this display-name,
* but this has not be implemented yet.
*/
private String displayName;
private String iasDescriptorName;

/*
* Attributes set by the Ant build file
*/
private File iashome;

/**
* Sets whether or not debugging output will be generated when ejbc is
* executed.
*
* @param debug A boolean indicating if debugging output should be generated
*/
public void setDebug( boolean debug )
{
this.debug = debug;
}

/**
* Since iAS doesn't generate a "generic" JAR as part of its processing,
* this attribute is ignored and a warning message is displayed to the user.
*
* @param inString the string to use as the suffix. This parameter is
* ignored.
*/
public void setGenericJarSuffix( String inString )
{
final String message = "Since a generic JAR file is not created during processing, the "
+ "iPlanet Deployment Tool does not support the "
+ "\"genericjarsuffix\" attribute. It will be ignored.";
getLogger().warn( message );
}

/**
* Setter method used to store the "home" directory of the user's iAS
* installation. The directory specified should typically be <code>[install-location]/iplanet/ias6/ias</code>
* .
*
* @param iashome The home directory for the user's iAS installation.
*/
public void setIashome( File iashome )
{
this.iashome = iashome;
}

/**
* Setter method used to specify whether the Java source files generated by
* the ejbc utility should be saved or automatically deleted.
*
* @param keepgenerated boolean which, if <code>true</code>, indicates that
* Java source files generated by ejbc for the stubs and skeletons
* should be kept.
*/
public void setKeepgenerated( boolean keepgenerated )
{
this.keepgenerated = keepgenerated;
}

/**
* Setter method used to specify the filename suffix (for example, ".jar")
* for the JAR files to be created.
*
* @param jarSuffix The string to use as the JAR filename suffix.
*/
public void setSuffix( String jarSuffix )
{
this.jarSuffix = jarSuffix;
}

public void processDescriptor( String descriptorName, SAXParser saxParser )
{
this.descriptorName = descriptorName;

getLogger().debug( "iPlanet Deployment Tool processing: " + descriptorName + " (and " + getIasDescriptorName() + ")" );

super.processDescriptor( descriptorName, saxParser );
}

/**
* The iAS ejbc utility doesn't require the Public ID of the descriptor's
* DTD for it to process correctly--this method always returns <code>null
* </code>.
*
* @return <code>null</code>.
*/
protected String getPublicId()
{
return null;
}

/**
* Add the iAS-specific EJB descriptor to the list of files which will be
* written to the JAR file.
*
* @param ejbFiles Hashtable of EJB class (and other) files to be added to
* the completed JAR file.
* @param ddPrefix The feature to be added to the VendorFiles attribute
*/
protected void addVendorFiles( Hashtable ejbFiles, String ddPrefix )
{
ejbFiles.put( META_DIR + IAS_DD, new File( getConfig().descriptorDir,
getIasDescriptorName() ) );
}

/**
* Verifies that the user selections are valid.
*
* @param descriptorFileName String representing the file name of an EJB
* descriptor to be processed
* @param saxParser SAXParser which may be used to parse the XML descriptor
* @throws TaskException If the user selections are invalid.
*/
protected void checkConfiguration( String descriptorFileName,
SAXParser saxParser )
throws TaskException
{

int startOfName = descriptorFileName.lastIndexOf( File.separatorChar ) + 1;
String stdXml = descriptorFileName.substring( startOfName );
if( stdXml.equals( EJB_DD ) && ( getConfig().baseJarName == null ) )
{
String msg = "No name specified for the completed JAR file. The EJB"
+ " descriptor should be prepended with the JAR "
+ "name or it should be specified using the "
+ "attribute \"basejarname\" in the \"ejbjar\" task.";
throw new TaskException( msg );
}

File iasDescriptor = new File( getConfig().descriptorDir,
getIasDescriptorName() );
if( ( !iasDescriptor.exists() ) || ( !iasDescriptor.isFile() ) )
{
String msg = "The iAS-specific EJB descriptor ("
+ iasDescriptor + ") was not found.";
throw new TaskException( msg );
}

if( ( iashome != null ) && ( !iashome.isDirectory() ) )
{
String msg = "If \"iashome\" is specified, it must be a valid "
+ "directory (it was set to " + iashome + ").";
throw new TaskException( msg );
}
}

/**
* This method returns a list of EJB files found when the specified EJB
* descriptor is parsed and processed.
*
* @param descriptorFileName String representing the file name of an EJB
* descriptor to be processed
* @param saxParser SAXParser which may be used to parse the XML descriptor
* @return Hashtable of EJB class (and other) files to be added to the
* completed JAR file
* @throws IOException An IOException from the parser, possibly from the
* byte stream or character stream
* @throws SAXException Any SAX exception, possibly wrapping another
* exception
*/
protected Hashtable parseEjbFiles( String descriptorFileName,
SAXParser saxParser )
throws IOException, SAXException
{

Hashtable files;

/*
* Build and populate an instance of the ejbc utility
*/
IPlanetEjbc ejbc = new IPlanetEjbc(
new File( getConfig().descriptorDir,
descriptorFileName ),
new File( getConfig().descriptorDir,
getIasDescriptorName() ),
getConfig().srcDir,
getCombinedClasspath().toString(),
saxParser );
ejbc.setRetainSource( keepgenerated );
ejbc.setDebugOutput( debug );
if( iashome != null )
{
ejbc.setIasHomeDir( iashome );
}

/*
* Execute the ejbc utility -- stubs/skeletons are rebuilt, if needed
*/
try
{
ejbc.execute();
}
catch( IPlanetEjbc.EjbcException e )
{
throw new TaskException( "An error has occurred while trying to "
+ "execute the iAS ejbc utility", e );
}

displayName = ejbc.getDisplayName();
files = ejbc.getEjbFiles();

/*
* Add CMP descriptors to the list of EJB files
*/
String[] cmpDescriptors = ejbc.getCmpDescriptors();
if( cmpDescriptors.length > 0 )
{
File baseDir = getConfig().descriptorDir;

int endOfPath = descriptorFileName.lastIndexOf( File.separator );
String relativePath = descriptorFileName.substring( 0, endOfPath + 1 );

for( int i = 0; i < cmpDescriptors.length; i++ )
{
int endOfCmp = cmpDescriptors[ i ].lastIndexOf( '/' );
String cmpDescriptor = cmpDescriptors[ i ].substring( endOfCmp + 1 );

File cmpFile = new File( baseDir, relativePath + cmpDescriptor );
if( !cmpFile.exists() )
{
throw new TaskException( "The CMP descriptor file ("
+ cmpFile + ") could not be found." );
}
files.put( cmpDescriptors[ i ], cmpFile );
}
}

return files;
}

/**
* Get the name of the Jar that will be written. The modification date of
* this jar will be checked against the dependent bean classes.
*
* @param baseName String name of the EJB JAR file to be written (without a
* filename extension).
* @return File representing the JAR file which will be written.
*/
File getVendorOutputJarFile( String baseName )
{
File jarFile = new File( getDestDir(), baseName + jarSuffix );
getLogger().debug( "JAR file name: " + jarFile.toString() );
return jarFile;
}

/**
* Determines the name of the iAS-specific EJB descriptor using the
* specified standard EJB descriptor name. In general, the standard
* descriptor will be named "[basename]-ejb-jar.xml", and this method will
* return "[basename]-ias-ejb-jar.xml".
*
* @return The name of the iAS-specific EJB descriptor file.
*/
private String getIasDescriptorName()
{

/*
* Only calculate the descriptor name once
*/
if( iasDescriptorName != null )
{
return iasDescriptorName;
}

String path = "";// Directory path of the EJB descriptor
String basename;// Filename appearing before name terminator
String remainder;// Filename appearing after the name terminator

/*
* Find the end of the standard descriptor's relative path
*/
int startOfFileName = descriptorName.lastIndexOf( File.separatorChar );
if( startOfFileName != -1 )
{
path = descriptorName.substring( 0, startOfFileName + 1 );
}

/*
* Check to see if the standard name is used (there's no basename)
*/
if( descriptorName.substring( startOfFileName + 1 ).equals( EJB_DD ) )
{
basename = "";
remainder = EJB_DD;

}
else
{
int endOfBaseName = descriptorName.indexOf(
getConfig().baseNameTerminator,
startOfFileName );
/*
* Check for the odd case where the terminator and/or filename
* extension aren't found. These will ensure "ias-" appears at the
* end of the name and before the '.' (if present).
*/
if( endOfBaseName < 0 )
{
endOfBaseName = descriptorName.lastIndexOf( '.' ) - 1;
if( endOfBaseName < 0 )
{
endOfBaseName = descriptorName.length() - 1;
}
}

basename = descriptorName.substring( startOfFileName + 1,
endOfBaseName + 1 );
remainder = descriptorName.substring( endOfBaseName + 1 );
}

iasDescriptorName = path + basename + "ias-" + remainder;
return iasDescriptorName;
}
}

+ 0
- 1688
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbc.java
File diff suppressed because it is too large
View File


+ 0
- 339
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbcTask.java View File

@@ -1,339 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.xml.sax.SAXException;

/**
* Task to compile EJB stubs and skeletons for the iPlanet Application Server.
* The EJBs to be processed are specified by the EJB 1.1 standard XML
* descriptor, and additional attributes are obtained from the iPlanet
* Application Server-specific XML descriptor. Since the XML descriptors can
* include multiple EJBs, this is a convenient way of specifying many EJBs in a
* single Ant task. The following attributes are allowed:
* <ul>
* <li> <i>ejbdescriptor</i> -- Standard EJB 1.1 XML descriptor (typically
* titled "ejb-jar.xml"). This attribute is required.
* <li> <i>iasdescriptor</i> -- EJB XML descriptor for iPlanet Application
* Server (typically titled "ias-ejb-jar.xml). This attribute is required.
*
* <li> <i>dest</i> -- The is the base directory where the RMI stubs and
* skeletons are written. In addition, the class files for each bean (home
* interface, remote interface, and EJB implementation) must be found in this
* directory. This attribute is required.
* <li> <i>classpath</i> -- The classpath used when generating EJB stubs and
* skeletons. This is an optional attribute (if omitted, the classpath
* specified when Ant was started will be used). Nested "classpath" elements
* may also be used.
* <li> <i>keepgenerated</i> -- Indicates whether or not the Java source files
* which are generated by ejbc will be saved or automatically deleted. If
* "yes", the source files will be retained. This is an optional attribute (if
* omitted, it defaults to "no").
* <li> <i>debug</i> -- Indicates whether or not the ejbc utility should log
* additional debugging statements to the standard output. If "yes", the
* additional debugging statements will be generated (if omitted, it defaults
* to "no").
* <li> <i>iashome</i> -- May be used to specify the "home" directory for this
* iPlanet Application Server installation. This is used to find the ejbc
* utility if it isn't included in the user's system path. This is an optional
* attribute (if specified, it should refer to the <code>[install-location]/iplanet/ias6/ias
* </code> directory). If omitted, the ejbc utility
* must be on the user's system path.
* </ul>
* <p>
*
* For each EJB specified, this task will locate the three classes that comprise
* the EJB. If these class files cannot be located in the <code>dest</code>
* directory, the task will fail. The task will also attempt to locate the EJB
* stubs and skeletons in this directory. If found, the timestamps on the stubs
* and skeletons will be checked to ensure they are up to date. Only if these
* files cannot be found or if they are out of date will ejbc be called to
* generate new stubs and skeletons.
*
* @author Greg Nelson <a href="mailto:greg@netscape.com">greg@netscape.com</a>
* @see IPlanetEjbc
*/
public class IPlanetEjbcTask extends Task
{
private boolean keepgenerated = false;
private boolean debug = false;
private Path classpath;
private File dest;

/*
* Attributes set by the Ant build file
*/
private File ejbdescriptor;
private File iasdescriptor;
private File iashome;

/**
* Sets the classpath to be used when compiling the EJB stubs and skeletons.
*
* @param classpath The classpath to be used.
*/
public void setClasspath( Path classpath )
{
if( this.classpath == null )
{
this.classpath = classpath;
}
else
{
this.classpath.append( classpath );
}
}

/**
* Sets whether or not debugging output will be generated when ejbc is
* executed.
*
* @param debug A boolean indicating if debugging output should be generated
*/
public void setDebug( boolean debug )
{
this.debug = debug;
}

/**
* Sets the destination directory where the EJB "source" classes must exist
* and where the stubs and skeletons will be written. The destination
* directory must exist before this task is executed.
*
* @param dest The directory where the compiled classes will be written.
*/
public void setDest( File dest )
{
this.dest = dest;
}

/**
* Sets the location of the standard XML EJB descriptor. Typically, this
* file is named "ejb-jar.xml".
*
* @param ejbdescriptor The name and location of the EJB descriptor.
*/
public void setEjbdescriptor( File ejbdescriptor )
{
this.ejbdescriptor = ejbdescriptor;
}

/**
* Sets the location of the iAS-specific XML EJB descriptor. Typically, this
* file is named "ias-ejb-jar.xml".
*
* @param iasdescriptor The name and location of the iAS-specific EJB
* descriptor.
*/
public void setIasdescriptor( File iasdescriptor )
{
this.iasdescriptor = iasdescriptor;
}

/**
* Setter method used to store the "home" directory of the user's iAS
* installation. The directory specified should typically be <code>[install-location]/iplanet/ias6/ias</code>
* .
*
* @param iashome The home directory for the user's iAS installation.
*/
public void setIashome( File iashome )
{
this.iashome = iashome;
}

/**
* Sets whether or not the Java source files which are generated by the ejbc
* process should be retained or automatically deleted.
*
* @param keepgenerated A boolean indicating if the Java source files for
* the stubs and skeletons should be retained.
*/
public void setKeepgenerated( boolean keepgenerated )
{
this.keepgenerated = keepgenerated;
}

/**
* Creates a nested classpath element.
*
* @return Description of the Returned Value
*/
public Path createClasspath()
{
if( classpath == null )
{
classpath = new Path();
}
Path path1 = classpath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Does the work.
*
* @exception TaskException Description of Exception
*/
public void execute()
throws TaskException
{
checkConfiguration();

executeEjbc( getParser() );
}

/**
* Returns a SAXParser that may be used to process the XML descriptors.
*
* @return Parser which may be used to process the EJB descriptors.
* @throws TaskException If the parser cannot be created or configured.
*/
private SAXParser getParser()
throws TaskException
{

SAXParser saxParser = null;
try
{
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setValidating( true );
saxParser = saxParserFactory.newSAXParser();
}
catch( SAXException e )
{
String msg = "Unable to create a SAXParser: " + e.getMessage();
throw new TaskException( msg, e );
}
catch( ParserConfigurationException e )
{
String msg = "Unable to create a SAXParser: " + e.getMessage();
throw new TaskException( msg, e );
}

return saxParser;
}

/**
* Verifies that the user selections are valid.
*
* @throws TaskException If the user selections are invalid.
*/
private void checkConfiguration()
throws TaskException
{

if( ejbdescriptor == null )
{
String msg = "The standard EJB descriptor must be specified using "
+ "the \"ejbdescriptor\" attribute.";
throw new TaskException( msg );
}
if( ( !ejbdescriptor.exists() ) || ( !ejbdescriptor.isFile() ) )
{
String msg = "The standard EJB descriptor (" + ejbdescriptor
+ ") was not found or isn't a file.";
throw new TaskException( msg );
}

if( iasdescriptor == null )
{
String msg = "The iAS-speific XML descriptor must be specified using"
+ " the \"iasdescriptor\" attribute.";
throw new TaskException( msg );
}
if( ( !iasdescriptor.exists() ) || ( !iasdescriptor.isFile() ) )
{
String msg = "The iAS-specific XML descriptor (" + iasdescriptor
+ ") was not found or isn't a file.";
throw new TaskException( msg );
}

if( dest == null )
{
String msg = "The destination directory must be specified using "
+ "the \"dest\" attribute.";
throw new TaskException( msg );
}
if( ( !dest.exists() ) || ( !dest.isDirectory() ) )
{
String msg = "The destination directory (" + dest + ") was not "
+ "found or isn't a directory.";
throw new TaskException( msg );
}

if( ( iashome != null ) && ( !iashome.isDirectory() ) )
{
String msg = "If \"iashome\" is specified, it must be a valid "
+ "directory (it was set to " + iashome + ").";
throw new TaskException( msg );
}
}

/**
* Executes the EJBc utility using the SAXParser provided.
*
* @param saxParser SAXParser that may be used to process the EJB
* descriptors
* @throws TaskException If there is an error reading or parsing the XML
* descriptors
*/
private void executeEjbc( SAXParser saxParser )
throws TaskException
{
String classpath = null;
if( classpath != null )
{
classpath = this.classpath.toString();
}

IPlanetEjbc ejbc = new IPlanetEjbc( ejbdescriptor,
iasdescriptor,
dest,
classpath,
saxParser );
ejbc.setRetainSource( keepgenerated );
ejbc.setDebugOutput( debug );
if( iashome != null )
{
ejbc.setIasHomeDir( iashome );
}

try
{
ejbc.execute();
}
catch( IOException e )
{
String msg = "An IOException occurred while trying to read the XML "
+ "descriptor file: " + e.getMessage();
throw new TaskException( msg, e );
}
catch( SAXException e )
{
String msg = "A SAXException occurred while trying to read the XML "
+ "descriptor file: " + e.getMessage();
throw new TaskException( msg, e );
}
catch( IPlanetEjbc.EjbcException e )
{
String msg = "An exception occurred while trying to run the ejbc "
+ "utility: " + e.getMessage();
throw new TaskException( msg, e );
}
}
}

+ 0
- 36
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/InnerClassFilenameFilter.java View File

@@ -1,36 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.FilenameFilter;

public class InnerClassFilenameFilter implements FilenameFilter
{
private String baseClassName;

InnerClassFilenameFilter( String baseclass )
{
int extidx = baseclass.lastIndexOf( ".class" );
if( extidx == -1 )
{
extidx = baseclass.length() - 1;
}
baseClassName = baseclass.substring( 0, extidx );
}

public boolean accept( File Dir, String filename )
{
if( ( filename.lastIndexOf( "." ) != filename.lastIndexOf( ".class" ) )
|| ( filename.indexOf( baseClassName + "$" ) != 0 ) )
{
return false;
}
return true;
}
}

+ 0
- 70
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JbossDeploymentTool.java View File

@@ -1,70 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.util.Hashtable;

/**
* The deployment tool to add the jboss specific deployment descriptor to the
* ejb jar file. Jboss only requires one additional file jboss.xml and does not
* require any additional compilation.
*
* @author <a href="mailto:p.austin@talk21.com">Paul Austin</a>
* @version 1.0
* @see EjbJar#createJboss
*/
public class JbossDeploymentTool extends GenericDeploymentTool
{
protected final static String JBOSS_DD = "jboss.xml";
protected final static String JBOSS_CMPD = "jaws.xml";

/**
* Instance variable that stores the suffix for the jboss jarfile.
*/
private String jarSuffix = ".jar";

/**
* Add any vendor specific files which should be included in the EJB Jar.
*
* @param ejbFiles The feature to be added to the VendorFiles attribute
* @param ddPrefix The feature to be added to the VendorFiles attribute
*/
protected void addVendorFiles( Hashtable ejbFiles, String ddPrefix )
{
File jbossDD = new File( getConfig().descriptorDir, ddPrefix + JBOSS_DD );
if( jbossDD.exists() )
{
ejbFiles.put( META_DIR + JBOSS_DD, jbossDD );
}
else
{
getLogger().warn( "Unable to locate jboss deployment descriptor. It was expected to be in " + jbossDD.getPath() );
return;
}

File jbossCMPD = new File( getConfig().descriptorDir, ddPrefix + JBOSS_CMPD );
if( jbossCMPD.exists() )
{
ejbFiles.put( META_DIR + JBOSS_CMPD, jbossCMPD );
}
}

/**
* Get the vendor specific name of the Jar that will be output. The
* modification date of this jar will be checked against the dependent bean
* classes.
*
* @param baseName Description of Parameter
* @return The VendorOutputJarFile value
*/
File getVendorOutputJarFile( String baseName )
{
return new File( getDestDir(), baseName + jarSuffix );
}
}

+ 0
- 430
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WLRun.java View File

@@ -1,430 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.types.Path;

/**
* Execute a Weblogic server.
*
* @author <a href="mailto:conor@cortexebusiness.com.au">Conor MacNeill</a> ,
* Cortex ebusiness Pty Limited
*/
public class WLRun extends Task
{
protected final static String DEFAULT_WL51_POLICY_FILE = "weblogic.policy";
protected final static String DEFAULT_WL60_POLICY_FILE = "lib/weblogic.policy";
protected final static String DEFAULT_PROPERTIES_FILE = "weblogic.properties";

private String weblogicMainClass = "weblogic.Server";

/**
* Addional arguments to pass to the JVM used to run weblogic
*/
private String additionalArgs = "";

/**
* The name of the weblogic server - used to select the server's directory
* in the weblogic home directory.
*/
private String weblogicSystemName = "myserver";

/**
* The file containing the weblogic properties for this server.
*/
private String weblogicPropertiesFile = null;

/**
* additional args to pass to the spawned jvm
*/
private String additionalJvmArgs = "";

/**
* The location of the BEA Home under which this server is run. WL6 only
*/
private File beaHome = null;

/**
* The management username
*/
private String managementUsername = "system";

/**
* The management password
*/
private String managementPassword = null;

/**
* The provate key password - used for SSL
*/
private String pkPassword = null;

/**
* The classpath to be used when running the Java VM. It must contain the
* weblogic classes <b>and</b> the implementation classes of the home and
* remote interfaces.
*/
private Path classpath;

/**
* The security policy to use when running the weblogic server
*/
private String securityPolicy;

/**
* The weblogic classpath to the be used when running weblogic.
*/
private Path weblogicClasspath;

/**
* The weblogic domain
*/
private String weblogicDomainName;

/**
* The weblogic system home directory
*/
private File weblogicSystemHome;

public void setArgs( String args )
{
additionalArgs = args;
}

/**
* The location of the BEA Home.
*
* @param beaHome the BEA Home directory.
*/
public void setBEAHome( File beaHome )
{
this.beaHome = beaHome;
}

/**
* Set the classpath to be used for this execution.
*
* @param classpath The new Classpath value
*/
public void setClasspath( Path classpath )
{
this.classpath = classpath;
}

/**
* Set the Domain to run in
*
* @param domain the domain
*/
public void setDomain( String domain )
{
this.weblogicDomainName = domain;
}

/**
* The location where weblogic lives.
*
* @param weblogicHome the home directory of weblogic.
*/
public void setHome( File weblogicHome )
{
weblogicSystemHome = weblogicHome;
}

/**
* Set the additional arguments to pass to the weblogic JVM
*
* @param args the arguments to be passed to the JVM
*/
public void setJvmargs( String args )
{
this.additionalJvmArgs = args;
}

/**
* Set the name of the server to run
*
* @param serverName The new Name value
*/
public void setName( String serverName )
{
this.weblogicSystemName = serverName;
}

/**
* Set the private key password so the server can decrypt the SSL private
* key file.
*
* @param pkpassword the private key password,
*/
public void setPKPassword( String pkpassword )
{
this.pkPassword = pkpassword;
}

/**
* Set the management password of the server
*
* @param password the management pasword of the server.
*/
public void setPassword( String password )
{
this.managementPassword = password;
}

/**
* Set the security policy for this invocation of weblogic.
*
* @param securityPolicy the security policy to use.
*/
public void setPolicy( String securityPolicy )
{
this.securityPolicy = securityPolicy;
}

/**
* Set the properties file to use. The location of the properties file is
* relative to the weblogi system home
*
* @param propertiesFilename the properties file name
*/
public void setProperties( String propertiesFilename )
{
this.weblogicPropertiesFile = propertiesFilename;
}

/**
* Set the management username to run the server
*
* @param username the management username of the server.
*/
public void setUsername( String username )
{
this.managementUsername = username;
}

public void setWeblogicMainClass( String c )
{
weblogicMainClass = c;
}

/**
* Set the weblogic classpath. The weblogic classpath is used by weblogic to
* support dynamic class loading.
*
* @param weblogicClasspath the weblogic classpath
*/
public void setWlclasspath( Path weblogicClasspath )
{
this.weblogicClasspath = weblogicClasspath;
}

/**
* Add the classpath for the user classes
*
* @return Description of the Returned Value
*/
public Path createClasspath()
{
if( classpath == null )
{
classpath = new Path();
}
Path path1 = classpath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Get the classpath to the weblogic classpaths
*
* @return Description of the Returned Value
*/
public Path createWLClasspath()
{
if( weblogicClasspath == null )
{
weblogicClasspath = new Path();
}
Path path1 = weblogicClasspath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Do the work. The work is actually done by creating a separate JVM to run
* a helper task. This approach allows the classpath of the helper task to
* be set. Since the weblogic tools require the class files of the project's
* home and remote interfaces to be available in the classpath, this also
* avoids having to start ant with the class path of the project it is
* building.
*
* @exception TaskException if someting goes wrong with the build
*/
public void execute()
throws TaskException
{
if( weblogicSystemHome == null )
{
throw new TaskException( "weblogic home must be set" );
}
if( !weblogicSystemHome.isDirectory() )
{
throw new TaskException( "weblogic home directory " + weblogicSystemHome.getPath() +
" is not valid" );
}

if( beaHome != null )
{
executeWLS6();
}
else
{
executeWLS();
}
}

private void executeWLS()
throws TaskException
{
File securityPolicyFile = findSecurityPolicyFile( DEFAULT_WL51_POLICY_FILE );
File propertiesFile = null;

if( weblogicPropertiesFile == null )
{
weblogicPropertiesFile = DEFAULT_PROPERTIES_FILE;
}
propertiesFile = new File( weblogicSystemHome, weblogicPropertiesFile );
if( !propertiesFile.exists() )
{
// OK, properties file may be absolute
propertiesFile = getContext().resolveFile( weblogicPropertiesFile );
if( !propertiesFile.exists() )
{
throw new TaskException( "Properties file " + weblogicPropertiesFile +
" not found in weblogic home " + weblogicSystemHome +
" or as absolute file" );
}
}

Java weblogicServer = (Java)getProject().createTask( "java" );
weblogicServer.setFork( true );
weblogicServer.setClassname( weblogicMainClass );

String jvmArgs = additionalJvmArgs;

if( weblogicClasspath != null )
{
jvmArgs += " -Dweblogic.class.path=" + weblogicClasspath;
}

jvmArgs += " -Djava.security.manager -Djava.security.policy==" + securityPolicyFile;
jvmArgs += " -Dweblogic.system.home=" + weblogicSystemHome;
jvmArgs += " -Dweblogic.system.name=" + weblogicSystemName;
jvmArgs += " -Dweblogic.system.propertiesFile=" + weblogicPropertiesFile;

weblogicServer.createJvmarg().setLine( jvmArgs );
weblogicServer.createArg().setLine( additionalArgs );

if( classpath != null )
{
weblogicServer.setClasspath( classpath );
}
if( weblogicServer.executeJava() != 0 )
{
throw new TaskException( "Execution of weblogic server failed" );
}
}

private void executeWLS6()
throws TaskException
{
File securityPolicyFile = findSecurityPolicyFile( DEFAULT_WL60_POLICY_FILE );
if( !beaHome.isDirectory() )
{
throw new TaskException( "BEA home " + beaHome.getPath() +
" is not valid" );
}

File configFile = new File( weblogicSystemHome, "config/" + weblogicDomainName + "/config.xml" );
if( !configFile.exists() )
{
throw new TaskException( "Server config file " + configFile + " not found." );
}

if( managementPassword == null )
{
throw new TaskException( "You must supply a management password to start the server" );
}

Java weblogicServer = (Java)getProject().createTask( "java" );
weblogicServer.setFork( true );
weblogicServer.setDir( weblogicSystemHome );
weblogicServer.setClassname( weblogicMainClass );

String jvmArgs = additionalJvmArgs;

jvmArgs += " -Dweblogic.Domain=" + weblogicDomainName;
jvmArgs += " -Dweblogic.Name=" + weblogicSystemName;
jvmArgs += " -Dweblogic.system.home=" + weblogicSystemHome;

jvmArgs += " -Dbea.home=" + beaHome;
jvmArgs += " -Djava.security.policy==" + securityPolicyFile;

jvmArgs += " -Dweblogic.management.username=" + managementUsername;
jvmArgs += " -Dweblogic.management.password=" + managementPassword;
if( pkPassword != null )
{
jvmArgs += " -Dweblogic.pkpassword=" + pkPassword;
}

weblogicServer.createJvmarg().setLine( jvmArgs );
weblogicServer.createArg().setLine( additionalArgs );

if( classpath != null )
{
weblogicServer.setClasspath( classpath );
}

if( weblogicServer.executeJava() != 0 )
{
throw new TaskException( "Execution of weblogic server failed" );
}
}

private File findSecurityPolicyFile( String defaultSecurityPolicy )
{
String securityPolicy = this.securityPolicy;
if( securityPolicy == null )
{
securityPolicy = defaultSecurityPolicy;
}
File securityPolicyFile = new File( weblogicSystemHome, securityPolicy );
// If an explicit securityPolicy file was specified, it maybe an
// absolute path. Use the project to resolve it.
if( this.securityPolicy != null && !securityPolicyFile.exists() )
{
final String filename = securityPolicy;
securityPolicyFile = getContext().resolveFile( filename );
}
// If we still can't find it, complain
if( !securityPolicyFile.exists() )
{
throw new TaskException( "Security policy " + securityPolicy +
" was not found." );
}
return securityPolicyFile;
}
}

+ 0
- 173
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WLStop.java View File

@@ -1,173 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.types.Path;

/**
* Shutdown a Weblogic server.
*
* @author <a href="mailto:conor@cortexebusiness.com.au">Conor MacNeill</a> ,
* Cortex ebusiness Pty Limited
*/
public class WLStop extends Task
{

/**
* The delay (in seconds) to wait before shutting down.
*/
private int delay = 0;

/**
* The location of the BEA Home under which this server is run. WL6 only
*/
private File beaHome = null;
/**
* The classpath to be used. It must contains the weblogic.Admin class.
*/
private Path classpath;

/**
* The password to use to shutdown the weblogic server.
*/
private String password;

/**
* The URL which the weblogic server is listening on.
*/
private String serverURL;

/**
* The weblogic username to use to request the shutdown.
*/
private String username;

/**
* The location of the BEA Home.
*
* @param beaHome the BEA Home directory.
*/
public void setBEAHome( File beaHome )
{
this.beaHome = beaHome;
}

/**
* Set the classpath to be used for this compilation.
*
* @param path The new Classpath value
*/
public void setClasspath( Path path )
{
this.classpath = path;
}

/**
* Set the delay (in seconds) before shutting down the server.
*
* @param s the selay.
*/
public void setDelay( String s )
{
delay = Integer.parseInt( s );
}

/**
* Set the password to use to request shutdown of the server.
*
* @param s the password.
*/
public void setPassword( String s )
{
this.password = s;
}

/**
* Set the URL to which the weblogic server is listening.
*
* @param s the url.
*/
public void setUrl( String s )
{
this.serverURL = s;
}

/**
* Set the username to use to request shutdown of the server.
*
* @param s the username.
*/
public void setUser( String s )
{
this.username = s;
}

/**
* Add the classpath for the user classes
*
* @return Description of the Returned Value
*/
public Path createClasspath()
{
if( classpath == null )
{
classpath = new Path();
}
Path path1 = classpath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Do the work. The work is actually done by creating a separate JVM to run
* the weblogic admin task This approach allows the classpath of the helper
* task to be set.
*
* @exception TaskException if someting goes wrong with the build
*/
public void execute()
throws TaskException
{
if( username == null || password == null )
{
throw new TaskException( "weblogic username and password must both be set" );
}

if( serverURL == null )
{
throw new TaskException( "The url of the weblogic server must be provided." );
}

Java weblogicAdmin = (Java)getProject().createTask( "java" );
weblogicAdmin.setFork( true );
weblogicAdmin.setClassname( "weblogic.Admin" );
String args;

if( beaHome == null )
{
args = serverURL + " SHUTDOWN " + username + " " + password + " " + delay;
}
else
{
args = " -url " + serverURL +
" -username " + username +
" -password " + password +
" SHUTDOWN " + " " + delay;
}

weblogicAdmin.setArgs( args );
weblogicAdmin.setClasspath( classpath );
weblogicAdmin.execute();
}

}

+ 0
- 856
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java View File

@@ -1,856 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.avalon.excalibur.io.FileUtil;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.PathUtil;
import org.xml.sax.InputSource;

public class WeblogicDeploymentTool extends GenericDeploymentTool
{
public final static String PUBLICID_EJB11
= "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN";
public final static String PUBLICID_EJB20
= "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN";
public final static String PUBLICID_WEBLOGIC_EJB510
= "-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN";
public final static String PUBLICID_WEBLOGIC_EJB600
= "-//BEA Systems, Inc.//DTD WebLogic 6.0.0 EJB//EN";

protected final static String DEFAULT_WL51_EJB11_DTD_LOCATION
= "/weblogic/ejb/deployment/xml/ejb-jar.dtd";
protected final static String DEFAULT_WL60_EJB11_DTD_LOCATION
= "/weblogic/ejb20/dd/xml/ejb11-jar.dtd";
protected final static String DEFAULT_WL60_EJB20_DTD_LOCATION
= "/weblogic/ejb20/dd/xml/ejb20-jar.dtd";

protected final static String DEFAULT_WL51_DTD_LOCATION
= "/weblogic/ejb/deployment/xml/weblogic-ejb-jar.dtd";
protected final static String DEFAULT_WL60_51_DTD_LOCATION
= "/weblogic/ejb20/dd/xml/weblogic510-ejb-jar.dtd";
protected final static String DEFAULT_WL60_DTD_LOCATION
= "/weblogic/ejb20/dd/xml/weblogic600-ejb-jar.dtd";

protected final static String DEFAULT_COMPILER = "default";

protected final static String WL_DD = "weblogic-ejb-jar.xml";
protected final static String WL_CMP_DD = "weblogic-cmp-rdbms-jar.xml";

protected final static String COMPILER_EJB11 = "weblogic.ejbc";
protected final static String COMPILER_EJB20 = "weblogic.ejbc20";

/**
* Instance variable that stores the suffix for the weblogic jarfile.
*/
private String jarSuffix = ".jar";

/**
* Instance variable that determines whether generic ejb jars are kept.
*/
private boolean keepgenerated = false;

/**
* Instance variable that stores the fully qualified classname of the
* weblogic EJBC compiler
*/
private String ejbcClass = null;

private String additionalArgs = "";

private boolean keepGeneric = false;

private String compiler = null;

private boolean alwaysRebuild = true;

/**
* controls whether ejbc is run on the generated jar
*/
private boolean noEJBC = false;

/**
* Indicates if the old CMP location convention is to be used.
*/
private boolean newCMP = false;

/**
* The classpath to the weblogic classes.
*/
private Path wlClasspath = null;

/**
* The weblogic.StdoutSeverityLevel to use when running the JVM that
* executes ejbc. Set to 16 to avoid the warnings about EJB Home and Remotes
* being in the classpath
*/
private Integer jvmDebugLevel = null;

/**
* Instance variable that stores the location of the ejb 1.1 DTD file.
*/
private String ejb11DTD;

/**
* Instance variable that stores the location of the weblogic DTD file.
*/
private String weblogicDTD;

/**
* sets some additional args to send to ejbc.
*
* @param args The new Args value
*/
public void setArgs( String args )
{
this.additionalArgs = args;
}

/**
* The compiler (switch <code>-compiler</code>) to use
*
* @param compiler The new Compiler value
*/
public void setCompiler( String compiler )
{
this.compiler = compiler;
}

/**
* Setter used to store the location of the Sun's Generic EJB DTD. This can
* be a file on the system or a resource on the classpath.
*
* @param inString the string to use as the DTD location.
*/
public void setEJBdtd( String inString )
{
this.ejb11DTD = inString;
}

/**
* Set the classname of the ejbc compiler
*
* @param ejbcClass The new EjbcClass value
*/
public void setEjbcClass( String ejbcClass )
{
this.ejbcClass = ejbcClass;
}

/**
* Sets the weblogic.StdoutSeverityLevel to use when running the JVM that
* executes ejbc. Set to 16 to avoid the warnings about EJB Home and Remotes
* being in the classpath
*
* @param jvmDebugLevel The new JvmDebugLevel value
*/
public void setJvmDebugLevel( Integer jvmDebugLevel )
{
this.jvmDebugLevel = jvmDebugLevel;
}

/**
* Sets whether -keepgenerated is passed to ejbc (that is, the .java source
* files are kept).
*
* @param inValue either 'true' or 'false'
*/
public void setKeepgenerated( String inValue )
{
this.keepgenerated = Boolean.valueOf( inValue ).booleanValue();
}

/**
* Setter used to store the value of keepGeneric
*
* @param inValue a string, either 'true' or 'false'.
*/
public void setKeepgeneric( boolean inValue )
{
this.keepGeneric = inValue;
}

/**
* Set the value of the newCMP scheme. The old CMP scheme locates the
* weblogic CMP descriptor based on the naming convention where the weblogic
* CMP file is expected to be named with the bean name as the prefix. Under
* this scheme the name of the CMP descriptor does not match the name
* actually used in the main weblogic EJB descriptor. Also, descriptors
* which contain multiple CMP references could not be used.
*
* @param newCMP The new NewCMP value
*/
public void setNewCMP( boolean newCMP )
{
this.newCMP = newCMP;
}

/**
* Do not EJBC the jar after it has been put together.
*
* @param noEJBC The new NoEJBC value
*/
public void setNoEJBC( boolean noEJBC )
{
this.noEJBC = noEJBC;
}

/**
* Set the value of the oldCMP scheme. This is an antonym for newCMP
*
* @param oldCMP The new OldCMP value
*/
public void setOldCMP( boolean oldCMP )
{
this.newCMP = !oldCMP;
}

/**
* Set the rebuild flag to false to only update changes in the jar rather
* than rerunning ejbc
*
* @param rebuild The new Rebuild value
*/
public void setRebuild( boolean rebuild )
{
this.alwaysRebuild = rebuild;
}

/**
* Setter used to store the suffix for the generated weblogic jar file.
*
* @param inString the string to use as the suffix.
*/
public void setSuffix( String inString )
{
this.jarSuffix = inString;
}

public void setWLClasspath( Path wlClasspath )
{
this.wlClasspath = wlClasspath;
}

/**
* Setter used to store the location of the weblogic DTD. This can be a file
* on the system or a resource on the classpath.
*
* @param inString the string to use as the DTD location.
*/
public void setWLdtd( String inString )
{
this.weblogicDTD = inString;
}

/**
* Setter used to store the location of the ejb-jar DTD. This can be a file
* on the system or a resource on the classpath.
*
* @param inString the string to use as the DTD location.
*/
public void setWeblogicdtd( String inString )
{
setEJBdtd( inString );
}

/**
* Get the ejbc compiler class
*
* @return The EjbcClass value
*/
public String getEjbcClass()
{
return ejbcClass;
}

public Integer getJvmDebugLevel()
{
return jvmDebugLevel;
}

/**
* Get the classpath to the weblogic classpaths
*
* @return Description of the Returned Value
*/
public Path createWLClasspath()
{
if( wlClasspath == null )
{
wlClasspath = new Path();
}
Path path1 = wlClasspath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Called to validate that the tool parameters have been configured.
*
* @exception TaskException Description of Exception
*/
public void validateConfigured()
throws TaskException
{
super.validateConfigured();
}

/**
* Helper method invoked by isRebuildRequired to get a ClassLoader for a Jar
* File passed to it.
*
* @param classjar java.io.File representing jar file to get classes from.
* @return The ClassLoaderFromJar value
* @exception IOException Description of Exception
*/
protected ClassLoader getClassLoaderFromJar( File classjar )
throws IOException, TaskException
{
Path lookupPath = new Path();
lookupPath.setLocation( classjar );

Path classpath = getCombinedClasspath();
if( classpath != null )
{
lookupPath.append( classpath );
}

final URL[] urls = PathUtil.toURLs( lookupPath );
return new URLClassLoader( urls );
}

protected DescriptorHandler getWeblogicDescriptorHandler( final File srcDir )
{
DescriptorHandler handler =
new DescriptorHandler( getTask(), srcDir )
{
protected void processElement()
{
if( currentElement.equals( "type-storage" ) )
{
// Get the filename of vendor specific descriptor
String fileNameWithMETA = currentText;
//trim the META_INF\ off of the file name
String fileName = fileNameWithMETA.substring( META_DIR.length(),
fileNameWithMETA.length() );
File descriptorFile = new File( srcDir, fileName );

ejbFiles.put( fileNameWithMETA, descriptorFile );
}
}
};

handler.registerDTD( PUBLICID_WEBLOGIC_EJB510, DEFAULT_WL51_DTD_LOCATION );
handler.registerDTD( PUBLICID_WEBLOGIC_EJB510, DEFAULT_WL60_51_DTD_LOCATION );
handler.registerDTD( PUBLICID_WEBLOGIC_EJB600, DEFAULT_WL60_DTD_LOCATION );
handler.registerDTD( PUBLICID_WEBLOGIC_EJB510, weblogicDTD );
handler.registerDTD( PUBLICID_WEBLOGIC_EJB600, weblogicDTD );

for( Iterator i = getConfig().dtdLocations.iterator(); i.hasNext(); )
{
EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation)i.next();
handler.registerDTD( dtdLocation.getPublicId(), dtdLocation.getLocation() );
}
return handler;
}

/**
* Helper method to check to see if a weblogic EBJ1.1 jar needs to be
* rebuilt using ejbc. Called from writeJar it sees if the "Bean" classes
* are the only thing that needs to be updated and either updates the Jar
* with the Bean classfile or returns true, saying that the whole weblogic
* jar needs to be regened with ejbc. This allows faster build times for
* working developers. <p>
*
* The way weblogic ejbc works is it creates wrappers for the publicly
* defined methods as they are exposed in the remote interface. If the
* actual bean changes without changing the the method signatures then only
* the bean classfile needs to be updated and the rest of the weblogic jar
* file can remain the same. If the Interfaces, ie. the method signatures
* change or if the xml deployment dicriptors changed, the whole jar needs
* to be rebuilt with ejbc. This is not strictly true for the xml files. If
* the JNDI name changes then the jar doesnt have to be rebuild, but if the
* resources references change then it does. At this point the weblogic jar
* gets rebuilt if the xml files change at all.
*
* @param genericJarFile java.io.File The generic jar file.
* @param weblogicJarFile java.io.File The weblogic jar file to check to see
* if it needs to be rebuilt.
* @return The RebuildRequired value
*/
protected boolean isRebuildRequired( File genericJarFile, File weblogicJarFile )
throws TaskException
{
boolean rebuild = false;

JarFile genericJar = null;
JarFile wlJar = null;
File newWLJarFile = null;
JarOutputStream newJarStream = null;

try
{
getLogger().debug( "Checking if weblogic Jar needs to be rebuilt for jar " + weblogicJarFile.getName() );
// Only go forward if the generic and the weblogic file both exist
if( genericJarFile.exists() && genericJarFile.isFile()
&& weblogicJarFile.exists() && weblogicJarFile.isFile() )
{
//open jar files
genericJar = new JarFile( genericJarFile );
wlJar = new JarFile( weblogicJarFile );

Hashtable genericEntries = new Hashtable();
Hashtable wlEntries = new Hashtable();
Hashtable replaceEntries = new Hashtable();

//get the list of generic jar entries
for( Iterator e = genericJar.entries(); e.hasNext(); )
{
JarEntry je = (JarEntry)e.next();
genericEntries.put( je.getName().replace( '\\', '/' ), je );
}
//get the list of weblogic jar entries
for( Iterator e = wlJar.entries(); e.hasNext(); )
{
JarEntry je = (JarEntry)e.next();
wlEntries.put( je.getName(), je );
}

//Cycle Through generic and make sure its in weblogic
ClassLoader genericLoader = getClassLoaderFromJar( genericJarFile );
for( Iterator e = genericEntries.keys(); e.hasNext(); )
{
String filepath = (String)e.next();
if( wlEntries.containsKey( filepath ) )
{// File name/path match

// Check files see if same
JarEntry genericEntry = (JarEntry)genericEntries.get( filepath );
JarEntry wlEntry = (JarEntry)wlEntries.get( filepath );
if( ( genericEntry.getCrc() != wlEntry.getCrc() ) || // Crc's Match
( genericEntry.getSize() != wlEntry.getSize() ) )
{// Size Match

if( genericEntry.getName().endsWith( ".class" ) )
{
//File are different see if its an object or an interface
String classname = genericEntry.getName().replace( File.separatorChar, '.' );
classname = classname.substring( 0, classname.lastIndexOf( ".class" ) );
Class genclass = genericLoader.loadClass( classname );
if( genclass.isInterface() )
{
//Interface changed rebuild jar.
getLogger().debug( "Interface " + genclass.getName() + " has changed" );
rebuild = true;
break;
}
else
{
//Object class Changed update it.
replaceEntries.put( filepath, genericEntry );
}
}
else
{
// is it the manifest. If so ignore it
if( !genericEntry.getName().equals( "META-INF/MANIFEST.MF" ) )
{
//File other then class changed rebuild
getLogger().debug( "Non class file " + genericEntry.getName() + " has changed" );
rebuild = true;
break;
}
}
}
}
else
{// a file doesnt exist rebuild

getLogger().debug( "File " + filepath + " not present in weblogic jar" );
rebuild = true;
break;
}
}

if( !rebuild )
{
getLogger().debug( "No rebuild needed - updating jar" );
newWLJarFile = new File( weblogicJarFile.getAbsolutePath() + ".temp" );
if( newWLJarFile.exists() )
{
newWLJarFile.delete();
}

newJarStream = new JarOutputStream( new FileOutputStream( newWLJarFile ) );
newJarStream.setLevel( 0 );

//Copy files from old weblogic jar
for( Iterator e = wlEntries.iterator(); e.hasNext(); )
{
byte[] buffer = new byte[ 1024 ];
int bytesRead;
InputStream is;
JarEntry je = (JarEntry)e.next();
if( je.getCompressedSize() == -1 ||
je.getCompressedSize() == je.getSize() )
{
newJarStream.setLevel( 0 );
}
else
{
newJarStream.setLevel( 9 );
}

// Update with changed Bean class
if( replaceEntries.containsKey( je.getName() ) )
{
getLogger().debug( "Updating Bean class from generic Jar " + je.getName() );
// Use the entry from the generic jar
je = (JarEntry)replaceEntries.get( je.getName() );
is = genericJar.getInputStream( je );
}
else
{//use fle from original weblogic jar

is = wlJar.getInputStream( je );
}
newJarStream.putNextEntry( new JarEntry( je.getName() ) );

while( ( bytesRead = is.read( buffer ) ) != -1 )
{
newJarStream.write( buffer, 0, bytesRead );
}
is.close();
}
}
else
{
getLogger().debug( "Weblogic Jar rebuild needed due to changed interface or XML" );
}
}
else
{
rebuild = true;
}
}
catch( ClassNotFoundException cnfe )
{
String cnfmsg = "ClassNotFoundException while processing ejb-jar file"
+ ". Details: "
+ cnfe.getMessage();
throw new TaskException( cnfmsg, cnfe );
}
catch( IOException ioe )
{
String msg = "IOException while processing ejb-jar file "
+ ". Details: "
+ ioe.getMessage();
throw new TaskException( msg, ioe );
}
finally
{
// need to close files and perhaps rename output
if( genericJar != null )
{
try
{
genericJar.close();
}
catch( IOException closeException )
{
}
}

if( wlJar != null )
{
try
{
wlJar.close();
}
catch( IOException closeException )
{
}
}

if( newJarStream != null )
{
try
{
newJarStream.close();
}
catch( IOException closeException )
{
}

weblogicJarFile.delete();
newWLJarFile.renameTo( weblogicJarFile );
if( !weblogicJarFile.exists() )
{
rebuild = true;
}
}
}

return rebuild;
}

/**
* Add any vendor specific files which should be included in the EJB Jar.
*
* @param ejbFiles The feature to be added to the VendorFiles attribute
* @param ddPrefix The feature to be added to the VendorFiles attribute
*/
protected void addVendorFiles( Hashtable ejbFiles, String ddPrefix )
{
File weblogicDD = new File( getConfig().descriptorDir, ddPrefix + WL_DD );

if( weblogicDD.exists() )
{
ejbFiles.put( META_DIR + WL_DD,
weblogicDD );
}
else
{
final String message = "Unable to locate weblogic deployment descriptor. It was expected to be in " +
weblogicDD.getPath();
getLogger().warn( message );
return;
}

if( !newCMP )
{
getLogger().debug( "The old method for locating CMP files has been DEPRECATED." );
getLogger().debug( "Please adjust your weblogic descriptor and set newCMP=\"true\" " + "to use the new CMP descriptor inclusion mechanism. " );
// The the weblogic cmp deployment descriptor
File weblogicCMPDD = new File( getConfig().descriptorDir, ddPrefix + WL_CMP_DD );

if( weblogicCMPDD.exists() )
{
ejbFiles.put( META_DIR + WL_CMP_DD,
weblogicCMPDD );
}
}
else
{
// now that we have the weblogic descriptor, we parse the file
// to find other descriptors needed to deploy the bean.
// this could be the weblogic-cmp-rdbms.xml or any other O/R
// mapping tool descriptors.
try
{
File ejbDescriptor = (File)ejbFiles.get( META_DIR + EJB_DD );
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setValidating( true );
SAXParser saxParser = saxParserFactory.newSAXParser();
DescriptorHandler handler = getWeblogicDescriptorHandler( ejbDescriptor.getParentFile() );
saxParser.parse( new InputSource
( new FileInputStream
( weblogicDD ) ),
handler );

Hashtable ht = handler.getFiles();
Iterator e = ht.keys();
while( e.hasNext() )
{
String key = (String)e.next();
ejbFiles.put( key, ht.get( key ) );
}
}
catch( Exception e )
{
String msg = "Exception while adding Vendor specific files: " + e.toString();
throw new TaskException( msg, e );
}
}
}

protected void registerKnownDTDs( DescriptorHandler handler )
{
// register all the known DTDs
handler.registerDTD( PUBLICID_EJB11, DEFAULT_WL51_EJB11_DTD_LOCATION );
handler.registerDTD( PUBLICID_EJB11, DEFAULT_WL60_EJB11_DTD_LOCATION );
handler.registerDTD( PUBLICID_EJB11, ejb11DTD );
handler.registerDTD( PUBLICID_EJB20, DEFAULT_WL60_EJB20_DTD_LOCATION );
}

/**
* Method used to encapsulate the writing of the JAR file. Iterates over the
* filenames/java.io.Files in the Hashtable stored on the instance variable
* ejbFiles.
*
* @param baseName Description of Parameter
* @param jarFile Description of Parameter
* @param files Description of Parameter
* @param publicId Description of Parameter
* @exception TaskException Description of Exception
*/
protected void writeJar( String baseName, File jarFile, Hashtable files,
String publicId )
throws TaskException
{
// need to create a generic jar first.
File genericJarFile = super.getVendorOutputJarFile( baseName );
super.writeJar( baseName, genericJarFile, files, publicId );

if( alwaysRebuild || isRebuildRequired( genericJarFile, jarFile ) )
{
buildWeblogicJar( genericJarFile, jarFile, publicId );
}
if( !keepGeneric )
{
getLogger().debug( "deleting generic jar " + genericJarFile.toString() );
genericJarFile.delete();
}
}

/**
* Get the vendor specific name of the Jar that will be output. The
* modification date of this jar will be checked against the dependent bean
* classes.
*
* @param baseName Description of Parameter
* @return The VendorOutputJarFile value
*/
File getVendorOutputJarFile( String baseName )
{
return new File( getDestDir(), baseName + jarSuffix );
}

/**
* Helper method invoked by execute() for each WebLogic jar to be built.
* Encapsulates the logic of constructing a java task for calling
* weblogic.ejbc and executing it.
*
* @param sourceJar java.io.File representing the source (EJB1.1) jarfile.
* @param destJar java.io.File representing the destination, WebLogic
* jarfile.
*/
private void buildWeblogicJar( File sourceJar, File destJar, String publicId )
throws TaskException
{
org.apache.tools.ant.taskdefs.Java javaTask = null;

if( noEJBC )
{
try
{
FileUtil.copyFile( sourceJar, destJar );
if( !keepgenerated )
{
sourceJar.delete();
}
return;
}
catch( IOException e )
{
throw new TaskException( "Unable to write EJB jar", e );
}
}

String ejbcClassName = ejbcClass;

try
{
javaTask = (Java)getTask().getProject().createTask( "java" );

if( getJvmDebugLevel() != null )
{
javaTask.createJvmarg().setLine( " -Dweblogic.StdoutSeverityLevel=" + jvmDebugLevel );
}

if( ejbcClassName == null )
{
// try to determine it from publicId
if( PUBLICID_EJB11.equals( publicId ) )
{
ejbcClassName = COMPILER_EJB11;
}
else if( PUBLICID_EJB20.equals( publicId ) )
{
ejbcClassName = COMPILER_EJB20;
}
else
{
getLogger().warn( "Unrecognized publicId " + publicId + " - using EJB 1.1 compiler" );
ejbcClassName = COMPILER_EJB11;
}
}

javaTask.setClassname( ejbcClassName );
javaTask.createArg().setLine( additionalArgs );
if( keepgenerated )
{
javaTask.createArg().setValue( "-keepgenerated" );
}
if( compiler == null )
{
// try to use the compiler specified by build.compiler. Right now we are just going
// to allow Jikes
String buildCompiler = getTask().getContext().getProperty( "build.compiler" ).toString();
if( buildCompiler != null && buildCompiler.equals( "jikes" ) )
{
javaTask.createArg().setValue( "-compiler" );
javaTask.createArg().setValue( "jikes" );
}
}
else
{
if( !compiler.equals( DEFAULT_COMPILER ) )
{
javaTask.createArg().setValue( "-compiler" );
javaTask.createArg().setLine( compiler );
}
}
javaTask.createArg().setValue( sourceJar.getPath() );
javaTask.createArg().setValue( destJar.getPath() );

Path classpath = wlClasspath;
if( classpath == null )
{
classpath = getCombinedClasspath();
}

javaTask.setFork( true );
if( classpath != null )
{
javaTask.setClasspath( classpath );
}

getLogger().debug( "Calling " + ejbcClassName + " for " + sourceJar.toString() );

if( javaTask.executeJava() != 0 )
{
throw new TaskException( "Ejbc reported an error" );
}
}
catch( Exception e )
{
// Have to catch this because of the semantics of calling main()
String msg = "Exception while calling " + ejbcClassName + ". Details: " + e.toString();
throw new TaskException( msg, e );
}
}
}

+ 0
- 105
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicTOPLinkDeploymentTool.java View File

@@ -1,105 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.util.Hashtable;
import org.apache.myrmidon.api.TaskException;

public class WeblogicTOPLinkDeploymentTool extends WeblogicDeploymentTool
{

private final static String TL_DTD_LOC = "http://www.objectpeople.com/tlwl/dtd/toplink-cmp_2_5_1.dtd";
private String toplinkDTD;

private String toplinkDescriptor;

/**
* Setter used to store the name of the toplink descriptor.
*
* @param inString the string to use as the descriptor name.
*/
public void setToplinkdescriptor( String inString )
{
this.toplinkDescriptor = inString;
}

/**
* Setter used to store the location of the toplink DTD file. This is
* expected to be an URL (file or otherwise). If running this on NT using a
* file URL, the safest thing would be to not use a drive spec in the URL
* and make sure the file resides on the drive that ANT is running from.
* This will keep the setting in the build XML platform independent.
*
* @param inString the string to use as the DTD location.
*/
public void setToplinkdtd( String inString )
{
this.toplinkDTD = inString;
}

/**
* Called to validate that the tool parameters have been configured.
*
* @exception TaskException Description of Exception
*/
public void validateConfigured()
throws TaskException
{
super.validateConfigured();
if( toplinkDescriptor == null )
{
throw new TaskException( "The toplinkdescriptor attribute must be specified" );
}
}

protected DescriptorHandler getDescriptorHandler( File srcDir )
{
DescriptorHandler handler = super.getDescriptorHandler( srcDir );
if( toplinkDTD != null )
{
handler.registerDTD( "-//The Object People, Inc.//DTD TOPLink for WebLogic CMP 2.5.1//EN",
toplinkDTD );
}
else
{
handler.registerDTD( "-//The Object People, Inc.//DTD TOPLink for WebLogic CMP 2.5.1//EN",
TL_DTD_LOC );
}
return handler;
}

/**
* Add any vendor specific files which should be included in the EJB Jar.
*
* @param ejbFiles The feature to be added to the VendorFiles attribute
* @param ddPrefix The feature to be added to the VendorFiles attribute
*/
protected void addVendorFiles( Hashtable ejbFiles, String ddPrefix )
{
super.addVendorFiles( ejbFiles, ddPrefix );
// Then the toplink deployment descriptor

// Setup a naming standard here?.


File toplinkDD = new File( getConfig().descriptorDir, ddPrefix + toplinkDescriptor );

if( toplinkDD.exists() )
{
ejbFiles.put( META_DIR + toplinkDescriptor,
toplinkDD );
}
else
{
final String message = "Unable to locate toplink deployment descriptor. It was expected to be in " +
toplinkDD.getPath();
getLogger().warn( message );
}
}
}

+ 0
- 1035
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java
File diff suppressed because it is too large
View File


+ 0
- 524
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java View File

@@ -1,524 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import org.apache.aut.nativelib.ExecManager;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.myrmidon.framework.Execute;
import org.apache.tools.ant.taskdefs.exec.ExecuteStreamHandler;
import org.apache.tools.ant.types.Argument;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.util.FileUtils;

/**
* BorlandDeploymentTool is dedicated to the Borland Application Server 4.5 and
* 4.5.1 This task generates and compiles the stubs and skeletons for all ejb
* described into the Deployement Descriptor, builds the jar file including the
* support files and verify whether the produced jar is valid or not. The
* supported options are:
* <ul>
* <li> debug (boolean) : turn on the debug mode for generation of stubs and
* skeletons (default:false)</li>
* <li> verify (boolean) : turn on the verification at the end of the jar
* production (default:true) </li>
* <li> verifyargs (String) : add optional argument to verify command (see vbj
* com.inprise.ejb.util.Verify)</li>
* <li> basdtd (String) : location of the BAS DTD </li>
* <li> generateclient (boolean) : turn on the client jar file generation
* </li>
* </ul>
* <PRE>
*
* &lt;ejbjar srcdir=&quot;${build.classes}&quot; basejarname=&quot;vsmp&quot; descriptordir=&quot;${rsc.dir}/hrmanager&quot;&gt;
* &lt;borland destdir=&quot;tstlib&quot;&gt;
* &lt;classpath refid=&quot;classpath&quot; /&gt;
* &lt;/borland&gt;
* &lt;include name=&quot;**\ejb-jar.xml&quot;/&gt;
* &lt;support dir=&quot;${build.classes}&quot;&gt;
* &lt;include name=&quot;demo\smp\*.class&quot;/&gt;
* &lt;include name=&quot;demo\helper\*.class&quot;/&gt;
* &lt;/support&gt;
* &lt;/ejbjar&gt;
*</PRE>
*
* @author <a href="mailto:benoit.moussaud@criltelecom.com">Benoit Moussaud</a>
*/
public class BorlandDeploymentTool
extends GenericDeploymentTool
implements ExecuteStreamHandler
{
public final static String PUBLICID_BORLAND_EJB
= "-//Inprise Corporation//DTD Enterprise JavaBeans 1.1//EN";

protected final static String DEFAULT_BAS45_EJB11_DTD_LOCATION
= "/com/inprise/j2ee/xml/dtds/ejb-jar.dtd";

protected final static String DEFAULT_BAS_DTD_LOCATION
= "/com/inprise/j2ee/xml/dtds/ejb-inprise.dtd";

protected final static String BAS_DD = "ejb-inprise.xml";

/**
* Java2iiop executable *
*/
protected final static String JAVA2IIOP = "java2iiop";

/**
* Verify class
*/
protected final static String VERIFY = "com.inprise.ejb.util.Verify";

/**
* Instance variable that stores the suffix for the borland jarfile.
*/
private String jarSuffix = "-ejb.jar";

/**
* Instance variable that determines whether the debug mode is on
*/
private boolean java2iiopdebug = false;

/**
* Instance variable that determines whetger the client jar file is
* generated
*/
private boolean generateclient = false;
/**
* Instance variable that determines whether it is necessary to verify the
* produced jar
*/
private boolean verify = true;
private String verifyArgs = "";

private Hashtable _genfiles = new Hashtable();

/**
* Instance variable that stores the location of the borland DTD file.
*/
private String borlandDTD;

/**
* Setter used to store the location of the borland DTD. This can be a file
* on the system or a resource on the classpath.
*
* @param inString the string to use as the DTD location.
*/
public void setBASdtd( String inString )
{
this.borlandDTD = inString;
}

/**
* set the debug mode for java2iiop (default false)
*
* @param debug The new Debug value
*/
public void setDebug( boolean debug )
{
this.java2iiopdebug = debug;
}

/**
* setter used to store whether the task will include the generate client
* task. (see : BorlandGenerateClient task)
*
* @param b The new Generateclient value
*/
public void setGenerateclient( boolean b )
{
this.generateclient = b;
}

/**
* @param is The new ProcessErrorStream value
* @exception IOException Description of Exception
*/
public void setProcessErrorStream( InputStream is )
throws IOException
{
BufferedReader reader = new BufferedReader( new InputStreamReader( is ) );
String s = reader.readLine();
if( s != null )
{
getLogger().debug( "[java2iiop] " + s );
}// end of if ()
}

public void setProcessInputStream( OutputStream param1 )
throws IOException
{
}

/**
* @param is
* @exception IOException Description of Exception
*/
public void setProcessOutputStream( InputStream is )
throws IOException
{
try
{
BufferedReader reader = new BufferedReader( new InputStreamReader( is ) );
String javafile;
while( ( javafile = reader.readLine() ) != null )
{
getLogger().debug( "buffer:" + javafile );
if( javafile.endsWith( ".java" ) )
{
String classfile = toClassFile( javafile );
String key = classfile.substring( getConfig().srcDir.getAbsolutePath().length() + 1 );
getLogger().debug( " generated : " + classfile );
getLogger().debug( " key : " + key );
_genfiles.put( key, new File( classfile ) );
}// end of if ()
}// end of while ()
reader.close();
}
catch( Exception e )
{
String msg = "Exception while parsing java2iiop output. Details: " + e.toString();
throw new TaskException( msg, e );
}
}

/**
* Setter used to store the suffix for the generated borland jar file.
*
* @param inString the string to use as the suffix.
*/
public void setSuffix( String inString )
{
this.jarSuffix = inString;
}

/**
* set the verify mode for the produced jar (default true)
*
* @param verify The new Verify value
*/
public void setVerify( boolean verify )
{
this.verify = verify;
}

/**
* sets some additional args to send to verify command
*
* @param args addtions command line parameters
*/
public void setVerifyArgs( String args )
{
this.verifyArgs = args;
}

// implementation of org.apache.tools.ant.taskdefs.ExecuteStreamHandler interface

public void start()
throws IOException
{
}

public void stop()
{
}

protected DescriptorHandler getBorlandDescriptorHandler( final File srcDir )
{
DescriptorHandler handler =
new DescriptorHandler( getTask(), srcDir )
{
protected void processElement()
{
if( currentElement.equals( "type-storage" ) )
{
// Get the filename of vendor specific descriptor
String fileNameWithMETA = currentText;
//trim the META_INF\ off of the file name
String fileName = fileNameWithMETA.substring( META_DIR.length(),
fileNameWithMETA.length() );
File descriptorFile = new File( srcDir, fileName );

ejbFiles.put( fileNameWithMETA, descriptorFile );
}
}
};
handler.registerDTD( PUBLICID_BORLAND_EJB,
borlandDTD == null ? DEFAULT_BAS_DTD_LOCATION : borlandDTD );

for( Iterator i = getConfig().dtdLocations.iterator(); i.hasNext(); )
{
EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation)i.next();
handler.registerDTD( dtdLocation.getPublicId(), dtdLocation.getLocation() );
}
return handler;
}

/**
* Add any vendor specific files which should be included in the EJB Jar.
*
* @param ejbFiles The feature to be added to the VendorFiles attribute
* @param ddPrefix The feature to be added to the VendorFiles attribute
*/
protected void addVendorFiles( Hashtable ejbFiles, String ddPrefix )
{
final File borlandDD = new File( getConfig().descriptorDir, ddPrefix + BAS_DD );
if( borlandDD.exists() )
{
final String message = "Borland specific file found " + borlandDD;
getLogger().debug( message );
ejbFiles.put( META_DIR + BAS_DD, borlandDD );
}
else
{
final String message = "Unable to locate borland deployment descriptor. " +
"It was expected to be in " + borlandDD.getPath();
getLogger().warn( message );
return;
}
}

/**
* Method used to encapsulate the writing of the JAR file. Iterates over the
* filenames/java.io.Files in the Hashtable stored on the instance variable
* ejbFiles.
*
* @param baseName Description of Parameter
* @param jarFile Description of Parameter
* @param files Description of Parameter
* @param publicId Description of Parameter
* @exception TaskException Description of Exception
*/
protected void writeJar( String baseName, File jarFile, Hashtable files, String publicId )
throws TaskException
{
//build the home classes list.
ArrayList homes = new ArrayList();
Iterator it = files.keySet().iterator();
while( it.hasNext() )
{
String clazz = (String)it.next();
if( clazz.endsWith( "Home.class" ) )
{
//remove .class extension
String home = toClass( clazz );
homes.add( home );
getLogger().debug( " Home " + home );
}// end of if ()
}// end of while ()

buildBorlandStubs( homes.iterator(), files );

//add the gen files to the collection
files.putAll( _genfiles );

super.writeJar( baseName, jarFile, files, publicId );

if( verify )
{
verifyBorlandJar( jarFile );
}// end of if ()

if( generateclient )
{
generateClient( jarFile );
}// end of if ()
}

/**
* Get the vendor specific name of the Jar that will be output. The
* modification date of this jar will be checked against the dependent bean
* classes.
*
* @param baseName Description of Parameter
* @return The VendorOutputJarFile value
*/
File getVendorOutputJarFile( String baseName )
{
return new File( getDestDir(), baseName + jarSuffix );
}

/**
* Generate stubs & sketelton for each home found into the DD Add all the
* generate class file into the ejb files
*
* @param ithomes : iterator on home class
* @param files : file list , updated by the adding generated files
*/
private void buildBorlandStubs( Iterator ithomes, Hashtable files )
{
final ExecManager execManager = (ExecManager)getService( ExecManager.class );
final Execute exe = new Execute( execManager );
exe.setWorkingDirectory( getTask().getBaseDirectory() );

final Commandline cmd = buildCommandline( ithomes );
exe.setCommandline( cmd );

getLogger().debug( "Calling java2iiop" );
getLogger().debug( cmd.toString() );

try
{
final int result = exe.execute();
if( result != 0 )
{
String msg = "Failed executing java2iiop (ret code is " + result + ")";
throw new TaskException( msg );
}
}
catch( java.io.IOException e )
{
getLogger().error( "java2iiop exception :" + e.getMessage() );
throw new TaskException( "Error", e );
}
}

private Commandline buildCommandline( final Iterator ithomes )
{
final Commandline cmd = new Commandline();
cmd.setExecutable( JAVA2IIOP );
//debug ?
if( java2iiopdebug )
{
cmd.addArgument( "-VBJdebug" );
}// end of if ()
//set the classpath
cmd.addArgument( "-VBJclasspath" );
cmd.addArguments( FileUtils.translateCommandline( getCombinedClasspath() ) );
//list file
cmd.addArgument( "-list_files" );
//no TIE classes
cmd.addArgument( "-no_tie" );
//root dir
cmd.addArgument( "-root_dir" );
cmd.addArgument( getConfig().srcDir.getAbsolutePath() );
//compiling order
cmd.addArgument( "-compile" );
//add the home class
while( ithomes.hasNext() )
{
cmd.addArgument( ithomes.next().toString() );
}
return cmd;
}

/**
* Generate the client jar corresponding to the jar file passed as paremeter
* the method uses the BorlandGenerateClient task.
*
* @param sourceJar java.io.File representing the produced jar file
*/
private void generateClient( File sourceJar )
{
//UGLY HACK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//getTask().getProject().addTaskDefinition( "internal_bas_generateclient",
//org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient.class );

org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient gentask = null;
getLogger().info( "generate client for " + sourceJar );
try
{
String args = verifyArgs;
args += " " + sourceJar.getPath();

gentask = (BorlandGenerateClient)getTask().getProject().createTask( "internal_bas_generateclient" );
gentask.setEjbjar( sourceJar );
gentask.setDebug( java2iiopdebug );
Path classpath = getCombinedClasspath();
if( classpath != null )
{
gentask.setClasspath( classpath );
}
gentask.execute();
}
catch( Exception e )
{
//TO DO : delete the file if it is not a valid file.
String msg = "Exception while calling " + VERIFY + " Details: " + e.toString();
throw new TaskException( msg, e );
}
}

/**
* convert a class file name : A/B/C/toto.class into a class name:
* A.B.C.toto
*
* @param filename Description of Parameter
* @return Description of the Returned Value
*/
private String toClass( String filename )
{
//remove the .class
String classname = filename.substring( 0, filename.lastIndexOf( ".class" ) );
classname = classname.replace( '\\', '.' );
return classname;
}

/**
* convert a file name : A/B/C/toto.java into a class name: A/B/C/toto.class
*
* @param filename Description of Parameter
* @return Description of the Returned Value
*/
private String toClassFile( String filename )
{
//remove the .class
String classfile = filename.substring( 0, filename.lastIndexOf( ".java" ) );
classfile = classfile + ".class";
return classfile;
}

/**
* Verify the produced jar file by invoking the Borland verify tool
*
* @param sourceJar java.io.File representing the produced jar file
*/
private void verifyBorlandJar( File sourceJar )
throws TaskException
{
org.apache.tools.ant.taskdefs.Java javaTask = null;
getLogger().info( "verify " + sourceJar );
try
{

String args = verifyArgs;
args += " " + sourceJar.getPath();

javaTask = (Java)getTask().getProject().createTask( "java" );
javaTask.setClassname( VERIFY );
Argument arguments = javaTask.createArg();
arguments.setLine( args );
Path classpath = getCombinedClasspath();
if( classpath != null )
{
javaTask.setClasspath( classpath );
javaTask.setFork( true );
}

getLogger().debug( "Calling " + VERIFY + " for " + sourceJar.toString() );
javaTask.execute();
}
catch( Exception e )
{
//TO DO : delete the file if it is not a valid file.
String msg = "Exception while calling " + VERIFY + " Details: " + e.toString();
throw new TaskException( msg, e );
}
}

}

+ 0
- 252
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/BorlandGenerateClient.java View File

@@ -1,252 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import org.apache.aut.nativelib.ExecManager;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.Task;
import org.apache.myrmidon.framework.Execute;
import org.apache.tools.ant.types.Argument;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Path;

/**
* BorlandGenerateClient is dedicated to the Borland Application Server 4.5 This
* task generates the client jar using as input the ejb jar file. Two mode are
* available: java mode (default) and fork mode. With the fork mode, it is
* impossible to add classpath to the commmand line.
*
* @author <a href="mailto:benoit.moussaud@criltelecom.com">Benoit Moussaud</a>
*/
public class BorlandGenerateClient extends Task
{
final static String JAVA_MODE = "java";
final static String FORK_MODE = "fork";

/**
* debug the generateclient task
*/
boolean debug = false;

/**
* hold the ejbjar file name
*/
File ejbjarfile = null;

/**
* hold the client jar file name
*/
File clientjarfile = null;

/**
* hold the mode (java|fork)
*/
String mode = JAVA_MODE;

/**
* hold the classpath
*/
Path classpath;

public void setClasspath( Path classpath )
throws TaskException
{
if( this.classpath == null )
{
this.classpath = classpath;
}
else
{
this.classpath.append( classpath );
}
}

public void setClientjar( File clientjar )
{
clientjarfile = clientjar;
}

public void setDebug( boolean debug )
{
this.debug = debug;
}

public void setEjbjar( File ejbfile )
{
ejbjarfile = ejbfile;
}

public void setMode( String s )
{
mode = s;
}

public Path createClasspath()
throws TaskException
{
if( this.classpath == null )
{
this.classpath = new Path();
}
Path path1 = this.classpath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Do the work. The work is actually done by creating a separate JVM to run
* a java task.
*
* @exception TaskException if someting goes wrong with the build
*/
public void execute()
throws TaskException
{
if( ejbjarfile == null ||
ejbjarfile.isDirectory() )
{
throw new TaskException( "invalid ejb jar file." );
}// end of if ()

if( clientjarfile == null ||
clientjarfile.isDirectory() )
{
getLogger().debug( "invalid or missing client jar file." );
String ejbjarname = ejbjarfile.getAbsolutePath();
//clientname = ejbjarfile+client.jar
String clientname = ejbjarname.substring( 0, ejbjarname.lastIndexOf( "." ) );
clientname = clientname + "client.jar";
clientjarfile = new File( clientname );

}// end of if ()

if( mode == null )
{
getLogger().info( "mode is null default mode is java" );
setMode( JAVA_MODE );
}// end of if ()

getLogger().info( "client jar file is " + clientjarfile );

if( mode.equalsIgnoreCase( FORK_MODE ) )
{
executeFork();
}// end of if ()
else
{
executeJava();
}// end of else
}

/**
* launch the generate client using system api
*
* @exception TaskException Description of Exception
*/
protected void executeFork()
throws TaskException
{
try
{

final Commandline cmd = buildCommand();

getLogger().info( "mode : fork" );
getLogger().debug( "Calling java2iiop" );

final ExecManager execManager = (ExecManager)getService( ExecManager.class );
final Execute exe = new Execute( execManager );
exe.setWorkingDirectory( new File( "." ) );
exe.setCommandline( cmd );
exe.execute();
}
catch( Exception e )
{
// Have to catch this because of the semantics of calling main()
String msg = "Exception while calling generateclient Details: " + e.toString();
throw new TaskException( msg, e );
}

}

private Commandline buildCommand()
{
final Commandline cmd = new Commandline();
cmd.setExecutable( "iastool" );
cmd.addArgument( "generateclient" );
if( debug )
{
cmd.addArgument( "-trace" );
}

cmd.addArgument( "-short" );
cmd.addArgument( "-jarfile" );
// ejb jar file
cmd.addArgument( ejbjarfile.getAbsolutePath() );
//client jar file
cmd.addArgument( "-single" );
cmd.addArgument( "-clientjarfile" );
cmd.addArgument( clientjarfile.getAbsolutePath() );
return cmd;
}

/**
* launch the generate client using java api
*
* @exception TaskException Description of Exception
*/
protected void executeJava()
throws TaskException
{
try
{
getLogger().info( "mode : java" );

org.apache.tools.ant.taskdefs.Java execTask = null;
execTask = null;//(Java)getProject().createTask( "java" );

execTask.setDir( new File( "." ) );
execTask.setClassname( "com.inprise.server.commandline.EJBUtilities" );
//classpath
//add at the end of the classpath
//the system classpath in order to find the tools.jar file
// TODO - make sure tools.jar is in the classpath
//execTask.addClasspath( classpath.concatSystemClasspath( "last" ) );

execTask.setFork( true );
execTask.addArg( new Argument( "generateclient" ) );
if( debug )
{
execTask.addArg( new Argument( "-trace" ) );
}// end of if ()

//
execTask.addArg( new Argument( "-short" ) );
execTask.addArg( new Argument( "-jarfile" ) );
// ejb jar file
execTask.addArg( new Argument( ejbjarfile.getAbsolutePath() ) );
//client jar file
execTask.addArg( new Argument( "-single" ) );
execTask.addArg( new Argument( "-clientjarfile" ) );
execTask.addArg( new Argument( clientjarfile.getAbsolutePath() ) );

getLogger().debug( "Calling EJBUtilities" );
execTask.execute();

}
catch( final Exception e )
{
// Have to catch this because of the semantics of calling main()
final String message =
"Exception while calling generateclient Details: " + e.toString();
throw new TaskException( message, e );
}
}
}

+ 0
- 133
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/DDCreator.java View File

@@ -1,133 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.Argument;
import org.apache.tools.ant.types.DirectoryScanner;
import org.apache.tools.ant.types.Path;

/**
* Build a serialised deployment descriptor given a text file description of the
* descriptor in the format supported by WebLogic. This ant task is a front end
* for the weblogic DDCreator tool.
*
* @author <a href="mailto:conor@cortexebusiness.com.au">Conor MacNeill</a> ,
* Cortex ebusiness Pty Limited
*/
public class DDCreator extends MatchingTask
{

/**
* The classpath to be used in the weblogic ejbc calls. It must contain the
* weblogic classes necessary fro DDCreator <b>and</b> the implementation
* classes of the home and remote interfaces.
*/
private String classpath;
/**
* The root directory of the tree containing the textual deployment
* desciptors. The actual deployment descriptor files are selected using
* include and exclude constructs on the EJBC task, as supported by the
* MatchingTask superclass.
*/
private File descriptorDirectory;

/**
* The directory where generated serialised deployment descriptors are
* placed.
*/
private File generatedFilesDirectory;

/**
* Set the classpath to be used for this compilation.
*
* @param s the classpath to use for the ddcreator tool.
*/
public void setClasspath( final Path p )
{
this.classpath = p.toString();
}

/**
* Set the directory from where the text descriptions of the deployment
* descriptors are to be read.
*
* @param dirName the name of the directory containing the text deployment
* descriptor files.
*/
public void setDescriptors( String dirName )
{
descriptorDirectory = new File( dirName );
}

/**
* Set the directory into which the serialised deployment descriptors are to
* be written.
*
* @param dirName the name of the directory into which the serialised
* deployment descriptors are written.
*/
public void setDest( String dirName )
{
generatedFilesDirectory = new File( dirName );
}

/**
* Do the work. The work is actually done by creating a helper task. This
* approach allows the classpath of the helper task to be set. Since the
* weblogic tools require the class files of the project's home and remote
* interfaces to be available in the classpath, this also avoids having to
* start ant with the class path of the project it is building.
*
* @exception TaskException if someting goes wrong with the build
*/
public void execute()
throws TaskException
{
if( descriptorDirectory == null ||
!descriptorDirectory.isDirectory() )
{
throw new TaskException( "descriptors directory " + descriptorDirectory.getPath() +
" is not valid" );
}
if( generatedFilesDirectory == null ||
!generatedFilesDirectory.isDirectory() )
{
throw new TaskException( "dest directory " + generatedFilesDirectory.getPath() +
" is not valid" );
}

String args = descriptorDirectory + " " + generatedFilesDirectory;

// get all the files in the descriptor directory
DirectoryScanner ds = super.getDirectoryScanner( descriptorDirectory );

String[] files = ds.getIncludedFiles();

for( int i = 0; i < files.length; ++i )
{
args += " " + files[ i ];
}

String systemClassPath = System.getProperty( "java.class.path" );
String execClassPath = systemClassPath + File.separator + classpath;
Java ddCreatorTask = (Java)getProject().createTask( "java" );
ddCreatorTask.setFork( true );
ddCreatorTask.setClassname( "org.apache.tools.ant.taskdefs.optional.ejb.DDCreatorHelper" );
Argument arguments = ddCreatorTask.createArg();
arguments.setLine( args );
ddCreatorTask.setClasspath( new Path( execClassPath ) );
if( ddCreatorTask.executeJava() != 0 )
{
throw new TaskException( "Execution of ddcreator helper failed" );
}
}
}

+ 0
- 159
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/DDCreatorHelper.java View File

@@ -1,159 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import javax.ejb.deployment.DeploymentDescriptor;

/**
* A helper class which performs the actual work of the ddcreator task. This
* class is run with a classpath which includes the weblogic tools and the home
* and remote interface class files referenced in the deployment descriptors
* being built.
*
* @author <a href="mailto:conor@cortexebusiness.com.au">Conor MacNeill</a> ,
* Cortex ebusiness Pty Limited
*/
public class DDCreatorHelper
{

/**
* The descriptor text files for which a serialised descriptor is to be
* created.
*/
String[] descriptors;
/**
* The root directory of the tree containing the textual deployment
* desciptors.
*/
private File descriptorDirectory;

/**
* The directory where generated serialised desployment descriptors are
* written.
*/
private File generatedFilesDirectory;

/**
* Initialise the helper with the command arguments.
*
* @param args Description of Parameter
*/
private DDCreatorHelper( String[] args )
{
int index = 0;
descriptorDirectory = new File( args[ index++ ] );
generatedFilesDirectory = new File( args[ index++ ] );

descriptors = new String[ args.length - index ];
for( int i = 0; index < args.length; ++i )
{
descriptors[ i ] = args[ index++ ];
}
}

/**
* The main method. The main method creates an instance of the
* DDCreatorHelper, passing it the args which it then processes.
*
* @param args The command line arguments
* @exception Exception Description of Exception
*/
public static void main( String[] args )
throws Exception
{
DDCreatorHelper helper = new DDCreatorHelper( args );
helper.process();
}

/**
* Do the actual work. The work proceeds by examining each descriptor given.
* If the serialised file does not exist or is older than the text
* description, the weblogic DDCreator tool is invoked directly to build the
* serialised descriptor.
*
* @exception Exception Description of Exception
*/
private void process()
throws Exception
{
for( int i = 0; i < descriptors.length; ++i )
{
String descriptorName = descriptors[ i ];
File descriptorFile = new File( descriptorDirectory, descriptorName );

int extIndex = descriptorName.lastIndexOf( "." );
String serName = null;
if( extIndex != -1 )
{
serName = descriptorName.substring( 0, extIndex ) + ".ser";
}
else
{
serName = descriptorName + ".ser";
}
File serFile = new File( generatedFilesDirectory, serName );

// do we need to regenerate the file
if( !serFile.exists() || serFile.lastModified() < descriptorFile.lastModified()
|| regenerateSerializedFile( serFile ) )
{

String[] args = {"-noexit",
"-d", serFile.getParent(),
"-outputfile", serFile.getName(),
descriptorFile.getPath()};
try
{
weblogic.ejb.utils.DDCreator.main( args );
}
catch( Exception e )
{
// there was an exception - run with no exit to get proper error
String[] newArgs = {"-d", generatedFilesDirectory.getPath(),
"-outputfile", serFile.getName(),
descriptorFile.getPath()};
weblogic.ejb.utils.DDCreator.main( newArgs );
}
}
}
}

/**
* EJBC will fail if the serialized descriptor file does not match the bean
* classes. You can test for this by trying to load the deployment
* descriptor. If it fails, the serialized file needs to be regenerated
* because the associated class files don't match.
*
* @param serFile Description of Parameter
* @return Description of the Returned Value
*/
private boolean regenerateSerializedFile( File serFile )
{
try
{

FileInputStream fis = new FileInputStream( serFile );
ObjectInputStream ois = new ObjectInputStream( fis );
DeploymentDescriptor dd = (DeploymentDescriptor)ois.readObject();
fis.close();

// Since the descriptor read properly, everything should be o.k.
return false;
}
catch( Exception e )
{

// Weblogic will throw an error if the deployment descriptor does
// not match the class files.
return true;
}
}
}

+ 0
- 420
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java View File

@@ -1,420 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Hashtable;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.tools.ant.Task;
import org.xml.sax.AttributeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
* Inner class used by EjbJar to facilitate the parsing of deployment
* descriptors and the capture of appropriate information. Extends HandlerBase
* so it only implements the methods needed. During parsing creates a hashtable
* consisting of entries mapping the name it should be inserted into an EJB jar
* as to a File representing the file on disk. This list can then be accessed
* through the getFiles() method.
*
* @author RT
*/
public class DescriptorHandler
extends org.xml.sax.HandlerBase
implements LogEnabled
{
private final static int STATE_LOOKING_EJBJAR = 1;
private final static int STATE_IN_EJBJAR = 2;
private final static int STATE_IN_BEANS = 3;
private final static int STATE_IN_SESSION = 4;
private final static int STATE_IN_ENTITY = 5;
private final static int STATE_IN_MESSAGE = 6;

/**
* Bunch of constants used for storing entries in a hashtable, and for
* constructing the filenames of various parts of the ejb jar.
*/
private final static String EJB_REF = "ejb-ref";
private final static String HOME_INTERFACE = "home";
private final static String REMOTE_INTERFACE = "remote";
private final static String LOCAL_HOME_INTERFACE = "local-home";
private final static String LOCAL_INTERFACE = "local";
private final static String BEAN_CLASS = "ejb-class";
private final static String PK_CLASS = "prim-key-class";
private final static String EJB_NAME = "ejb-name";
private final static String EJB_JAR = "ejb-jar";
private final static String ENTERPRISE_BEANS = "enterprise-beans";
private final static String ENTITY_BEAN = "entity";
private final static String SESSION_BEAN = "session";
private final static String MESSAGE_BEAN = "message-driven";

private String publicId = null;

/**
* The state of the parsing
*/
private int parseState = STATE_LOOKING_EJBJAR;

/**
* Instance variable used to store the name of the current element being
* processed by the SAX parser. Accessed by the SAX parser call-back methods
* startElement() and endElement().
*/
protected String currentElement = null;

/**
* The text of the current element
*/
protected String currentText = null;

/**
* Instance variable that stores the names of the files as they will be put
* into the jar file, mapped to File objects Accessed by the SAX parser
* call-back method characters().
*/
protected Hashtable ejbFiles = null;

/**
* Instance variable that stores the value found in the &lt;ejb-name&gt;
* element
*/
protected String ejbName = null;

private Hashtable fileDTDs = new Hashtable();

private Hashtable resourceDTDs = new Hashtable();

private boolean inEJBRef = false;

private Hashtable urlDTDs = new Hashtable();

private Task owningTask;

/**
* The directory containing the bean classes and interfaces. This is used
* for performing dependency file lookups.
*/
private File srcDir;

private Logger m_logger;

/**
* Provide component with a logger.
*
* @param logger the logger
*/
public void enableLogging( Logger logger )
{
m_logger = logger;
}

protected final Logger getLogger()
{
return m_logger;
}

public DescriptorHandler( Task task, File srcDir )
{
this.owningTask = task;
this.srcDir = srcDir;
}

/**
* Getter method that returns the value of the &lt;ejb-name&gt; element.
*
* @return The EjbName value
*/
public String getEjbName()
{
return ejbName;
}

/**
* Getter method that returns the set of files to include in the EJB jar.
*
* @return The Files value
*/
public Hashtable getFiles()
{
return ( ejbFiles == null ) ? new Hashtable() : ejbFiles;
}

/**
* Get the publicId of the DTD
*
* @return The PublicId value
*/
public String getPublicId()
{
return publicId;
}

/**
* SAX parser call-back method invoked whenever characters are located
* within an element. currentAttribute (modified by startElement and
* endElement) tells us whether we are in an interesting element (one of the
* up to four classes of an EJB). If so then converts the classname from the
* format org.apache.tools.ant.Parser to the convention for storing such a
* class, org/apache/tools/ant/Parser.class. This is then resolved into a
* file object under the srcdir which is stored in a Hashtable.
*
* @param ch A character array containing all the characters in the element,
* and maybe others that should be ignored.
* @param start An integer marking the position in the char array to start
* reading from.
* @param length An integer representing an offset into the char array where
* the current data terminates.
* @exception SAXException Description of Exception
*/
public void characters( char[] ch, int start, int length )
throws SAXException
{

currentText += new String( ch, start, length );
}

/**
* SAX parser call-back method that is invoked when an element is exited.
* Used to blank out (set to the empty string, not nullify) the name of the
* currentAttribute. A better method would be to use a stack as an instance
* variable, however since we are only interested in leaf-node data this is
* a simpler and workable solution.
*
* @param name The name of the attribute being exited. Ignored in this
* implementation.
* @exception SAXException Description of Exception
*/
public void endElement( String name )
throws SAXException
{
processElement();
currentText = "";
this.currentElement = "";
if( name.equals( EJB_REF ) )
{
inEJBRef = false;
}
else if( parseState == STATE_IN_ENTITY && name.equals( ENTITY_BEAN ) )
{
parseState = STATE_IN_BEANS;
}
else if( parseState == STATE_IN_SESSION && name.equals( SESSION_BEAN ) )
{
parseState = STATE_IN_BEANS;
}
else if( parseState == STATE_IN_MESSAGE && name.equals( MESSAGE_BEAN ) )
{
parseState = STATE_IN_BEANS;
}
else if( parseState == STATE_IN_BEANS && name.equals( ENTERPRISE_BEANS ) )
{
parseState = STATE_IN_EJBJAR;
}
else if( parseState == STATE_IN_EJBJAR && name.equals( EJB_JAR ) )
{
parseState = STATE_LOOKING_EJBJAR;
}
}

public void registerDTD( String publicId, String location )
{
if( location == null )
{
return;
}

File fileDTD = new File( location );
if( fileDTD.exists() )
{
if( publicId != null )
{
fileDTDs.put( publicId, fileDTD );
getLogger().debug( "Mapped publicId " + publicId + " to file " + fileDTD );
}
return;
}

if( getClass().getResource( location ) != null )
{
if( publicId != null )
{
resourceDTDs.put( publicId, location );
getLogger().debug( "Mapped publicId " + publicId + " to resource " + location );
}
}

try
{
if( publicId != null )
{
URL urldtd = new URL( location );
urlDTDs.put( publicId, urldtd );
}
}
catch( java.net.MalformedURLException e )
{
//ignored
}

}

public InputSource resolveEntity( String publicId, String systemId )
throws SAXException
{
this.publicId = publicId;

File dtdFile = (File)fileDTDs.get( publicId );
if( dtdFile != null )
{
try
{
getLogger().debug( "Resolved " + publicId + " to local file " + dtdFile );
return new InputSource( new FileInputStream( dtdFile ) );
}
catch( FileNotFoundException ex )
{
// ignore
}
}

String dtdResourceName = (String)resourceDTDs.get( publicId );
if( dtdResourceName != null )
{
InputStream is = this.getClass().getResourceAsStream( dtdResourceName );
if( is != null )
{
getLogger().debug( "Resolved " + publicId + " to local resource " + dtdResourceName );
return new InputSource( is );
}
}

URL dtdUrl = (URL)urlDTDs.get( publicId );
if( dtdUrl != null )
{
try
{
InputStream is = dtdUrl.openStream();
getLogger().debug( "Resolved " + publicId + " to url " + dtdUrl );
return new InputSource( is );
}
catch( IOException ioe )
{
//ignore
}
}

getLogger().info( "Could not resolve ( publicId: " + publicId + ", systemId: " + systemId + ") to a local entity" );

return null;
}

/**
* SAX parser call-back method that is used to initialize the values of some
* instance variables to ensure safe operation.
*
* @exception SAXException Description of Exception
*/
public void startDocument()
throws SAXException
{
this.ejbFiles = new Hashtable( 10, 1 );
this.currentElement = null;
inEJBRef = false;
}

/**
* SAX parser call-back method that is invoked when a new element is entered
* into. Used to store the context (attribute name) in the currentAttribute
* instance variable.
*
* @param name The name of the element being entered.
* @param attrs Attributes associated to the element.
* @exception SAXException Description of Exception
*/
public void startElement( String name, AttributeList attrs )
throws SAXException
{
this.currentElement = name;
currentText = "";
if( name.equals( EJB_REF ) )
{
inEJBRef = true;
}
else if( parseState == STATE_LOOKING_EJBJAR && name.equals( EJB_JAR ) )
{
parseState = STATE_IN_EJBJAR;
}
else if( parseState == STATE_IN_EJBJAR && name.equals( ENTERPRISE_BEANS ) )
{
parseState = STATE_IN_BEANS;
}
else if( parseState == STATE_IN_BEANS && name.equals( SESSION_BEAN ) )
{
parseState = STATE_IN_SESSION;
}
else if( parseState == STATE_IN_BEANS && name.equals( ENTITY_BEAN ) )
{
parseState = STATE_IN_ENTITY;
}
else if( parseState == STATE_IN_BEANS && name.equals( MESSAGE_BEAN ) )
{
parseState = STATE_IN_MESSAGE;
}
}

protected void processElement()
{
if( inEJBRef ||
( parseState != STATE_IN_ENTITY && parseState != STATE_IN_SESSION && parseState != STATE_IN_MESSAGE ) )
{
return;
}

if( currentElement.equals( HOME_INTERFACE ) ||
currentElement.equals( REMOTE_INTERFACE ) ||
currentElement.equals( LOCAL_INTERFACE ) ||
currentElement.equals( LOCAL_HOME_INTERFACE ) ||
currentElement.equals( BEAN_CLASS ) ||
currentElement.equals( PK_CLASS ) )
{

// Get the filename into a String object
File classFile = null;
String className = currentText.trim();

// If it's a primitive wrapper then we shouldn't try and put
// it into the jar, so ignore it.
if( !className.startsWith( "java." ) &&
!className.startsWith( "javax." ) )
{
// Translate periods into path separators, add .class to the
// name, create the File object and add it to the Hashtable.
className = className.replace( '.', File.separatorChar );
className += ".class";
classFile = new File( srcDir, className );
ejbFiles.put( className, classFile );
}
}

// Get the value of the <ejb-name> tag. Only the first occurence.
if( currentElement.equals( EJB_NAME ) )
{
if( ejbName == null )
{
ejbName = currentText.trim();
}
}
}
}

+ 0
- 49
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java View File

@@ -1,49 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import javax.xml.parsers.SAXParser;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.Task;

public interface EJBDeploymentTool
{
/**
* Process a deployment descriptor, generating the necessary vendor specific
* deployment files.
*
* @param descriptorFilename the name of the deployment descriptor
* @param saxParser a SAX parser which can be used to parse the deployment
* descriptor.
* @exception TaskException Description of Exception
*/
void processDescriptor( String descriptorFilename, SAXParser saxParser )
throws TaskException;

/**
* Called to validate that the tool parameters have been configured.
*
* @exception TaskException Description of Exception
*/
void validateConfigured()
throws TaskException;

/**
* Set the task which owns this tool
*
* @param task The new Task value
*/
void setTask( Task task );

/**
* Configure this tool for use in the ejbjar task.
*
* @param config Description of Parameter
*/
void configure( EjbJar.Config config );
}

+ 0
- 567
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java View File

@@ -1,567 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;// Standard java imports

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.DirectoryScanner;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.xml.sax.SAXException;

/**
* <p>
*
* Provides automated ejb jar file creation for ant. Extends the MatchingTask
* class provided in the default ant distribution to provide a directory
* scanning EJB jarfile generator.</p> <p>
*
* The task works by taking the deployment descriptors one at a time and parsing
* them to locate the names of the classes which should be placed in the jar.
* The classnames are translated to java.io.Files by replacing periods with
* File.separatorChar and resolving the generated filename as a relative path
* under the srcDir attribute. All necessary files are then assembled into a
* jarfile. One jarfile is constructed for each deployment descriptor found.
* </p> <p>
*
* Functionality is currently provided for standard EJB1.1 jars and Weblogic 5.1
* jars. The weblogic deployment descriptors, used in constructing the Weblogic
* jar, are located based on a simple naming convention. The name of the
* standard deployment descriptor is taken upto the first instance of a String,
* specified by the attribute baseNameTerminator, and then the regular Weblogic
* descriptor name is appended. For example if baseNameTerminator is set to '-',
* its default value, and a standard descriptor is called Foo-ejb-jar.xml then
* the files Foo-weblogic-ejb-jar.xml and Foo-weblogic-cmp-rdbms-jar.xml will be
* looked for, and if found, included in the jarfile.</p> <p>
*
* Attributes and setter methods are provided to support optional generation of
* Weblogic5.1 jars, optional deletion of generic jar files, setting alternate
* values for baseNameTerminator, and setting the strings to append to the names
* of the generated jarfiles.</p>
*
* @author <a href="mailto:tfennell@sapient.com">Tim Fennell</a>
*/
public class EjbJar extends MatchingTask
{

private Config config = new Config();

/**
* Instance variable that stores the suffix for the generated jarfile.
*/
private String genericJarSuffix = "-generic.jar";

/**
* The list of deployment tools we are going to run.
*/
private ArrayList deploymentTools = new ArrayList();

/**
* Stores a handle to the directory to put the Jar files in. This is only
* used by the generic deployment descriptor tool which is created if no
* other deployment descriptor tools are provided. Normally each deployment
* tool will specify the desitination dir itself.
*/
private File destDir;

/**
* Set the base name of the EJB jar that is to be created if it is not to be
* determined from the name of the deployment descriptor files.
*
* @param inValue the basename that will be used when writing the jar file
* containing the EJB
*/
public void setBasejarname( String inValue )
{
config.baseJarName = inValue;
if( config.namingScheme == null )
{
config.namingScheme = new NamingScheme();
config.namingScheme.setValue( NamingScheme.BASEJARNAME );
}
else if( !config.namingScheme.getValue().equals( NamingScheme.BASEJARNAME ) )
{
throw new TaskException( "The basejarname attribute is not compatible with the " +
config.namingScheme.getValue() + " naming scheme" );
}
}

/**
* Set the baseNameTerminator. The basename terminator is the string which
* terminates the bean name. The convention used by this task is that bean
* descriptors are named as the BeanName with some suffix. The
* baseNameTerminator string separates the bean name and the suffix and is
* used to determine the bean name.
*
* @param inValue a string which marks the end of the basename.
*/
public void setBasenameterminator( String inValue )
{
config.baseNameTerminator = inValue;
}

/**
* Set the classpath to use when resolving classes for inclusion in the jar.
*
* @param classpath the classpath to use.
*/
public void setClasspath( Path classpath )
{
config.classpath = classpath;
}

/**
* Set the descriptor directory. The descriptor directory contains the EJB
* deployment descriptors. These are XML files that declare the properties
* of a bean in a particular deployment scenario. Such properties include,
* for example, the transactional nature of the bean and the security access
* control to the bean's methods.
*
* @param inDir the directory containing the deployment descriptors.
*/
public void setDescriptordir( File inDir )
{
config.descriptorDir = inDir;
}

/**
* Set the destination directory. The EJB jar files will be written into
* this directory. The jar files that exist in this directory are also used
* when determining if the contents of the jar file have changed. Note that
* this parameter is only used if no deployment tools are specified.
* Typically each deployment tool will specify its own destination
* directory.
*
* @param inDir The new Destdir value
*/
public void setDestdir( File inDir )
{
this.destDir = inDir;
}

/**
* Set the flat dest dir flag. This flag controls whether the destination
* jars are written out in the destination directory with the same
* hierarchal structure from which the deployment descriptors have been
* read. If this is set to true the generated EJB jars are written into the
* root of the destination directory, otherwise they are written out in the
* same relative position as the deployment descriptors in the descriptor
* directory.
*
* @param inValue the new value of the flatdestdir flag.
*/
public void setFlatdestdir( boolean inValue )
{
config.flatDestDir = inValue;
}

/**
* Set the suffix for the generated jar file. When generic jars are
* generated, they have a suffix which is appended to the the bean name to
* create the name of the jar file. Note that this suffix includes the
* extension fo te jar file and should therefore end with an appropriate
* extension such as .jar or .ear
*
* @param inString the string to use as the suffix.
*/
public void setGenericjarsuffix( String inString )
{
this.genericJarSuffix = inString;
}

/**
* Set the Manifest file to use when jarring. As of EJB 1.1, manifest files
* are no longer used to configure the EJB. However, they still have a vital
* importance if the EJB is intended to be packaged in an EAR file. By
* adding "Class-Path" settings to a Manifest file, the EJB can look for
* classes inside the EAR file itself, allowing for easier deployment. This
* is outlined in the J2EE specification, and all J2EE components are meant
* to support it.
*
* @param manifest The new Manifest value
*/
public void setManifest( File manifest )
{
config.manifest = manifest;
}

/**
* Set the naming scheme used to determine the name of the generated jars
* from the deployment descriptor
*
* @param namingScheme The new Naming value
*/
public void setNaming( NamingScheme namingScheme )
{
config.namingScheme = namingScheme;
if( !config.namingScheme.getValue().equals( NamingScheme.BASEJARNAME ) &&
config.baseJarName != null )
{
throw new TaskException( "The basejarname attribute is not compatible with the " +
config.namingScheme.getValue() + " naming scheme" );
}
}

/**
* Set the srcdir attribute. The source directory is the directory that
* contains the classes that will be added to the EJB jar. Typically this
* will include the home and remote interfaces and the bean class.
*
* @param inDir the source directory.
*/
public void setSrcdir( File inDir )
{
config.srcDir = inDir;
}

/**
* Create a Borland nested element used to configure a deployment tool for
* Borland server.
*
* @return the deployment tool instance to be configured.
*/
public BorlandDeploymentTool createBorland()
{
getLogger().debug( "Borland deployment tools" );

BorlandDeploymentTool tool = new BorlandDeploymentTool();
tool.setTask( this );
deploymentTools.add( tool );
return tool;
}

/**
* creates a nested classpath element. This classpath is used to locate the
* super classes and interfaces of the classes that will make up the EJB
* jar.
*
* @return the path to be configured.
*/
public Path createClasspath()
{
if( config.classpath == null )
{
config.classpath = new Path();
}
Path path1 = config.classpath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Create a DTD location record. This stores the location of a DTD. The DTD
* is identified by its public Id. The location may either be a file
* location or a resource location.
*
* @return Description of the Returned Value
*/
public DTDLocation createDTD()
{
DTDLocation dtdLocation = new DTDLocation();
config.dtdLocations.add( dtdLocation );

return dtdLocation;
}

/**
* Create a nested element used to configure a deployment tool for iPlanet
* Application Server.
*
* @return the deployment tool instance to be configured.
*/
public IPlanetDeploymentTool createIplanet()
{
getLogger().debug( "iPlanet Application Server deployment tools" );

IPlanetDeploymentTool tool = new IPlanetDeploymentTool();
tool.setTask( this );
deploymentTools.add( tool );
return tool;
}

/**
* Create a jboss nested element used to configure a deployment tool for
* Jboss server.
*
* @return the deployment tool instance to be configured.
*/
public JbossDeploymentTool createJboss()
{
JbossDeploymentTool tool = new JbossDeploymentTool();
tool.setTask( this );
deploymentTools.add( tool );
return tool;
}

/**
* Create a file set for support elements
*
* @return a fileset which can be populated with support files.
*/
public FileSet createSupport()
{
FileSet supportFileSet = new FileSet();
config.supportFileSets.add( supportFileSet );
return supportFileSet;
}

/**
* Create a weblogic nested element used to configure a deployment tool for
* Weblogic server.
*
* @return the deployment tool instance to be configured.
*/
public WeblogicDeploymentTool createWeblogic()
{
WeblogicDeploymentTool tool = new WeblogicDeploymentTool();
tool.setTask( this );
deploymentTools.add( tool );
return tool;
}

/**
* Create a nested element for weblogic when using the Toplink Object-
* Relational mapping.
*
* @return the deployment tool instance to be configured.
*/
public WeblogicTOPLinkDeploymentTool createWeblogictoplink()
{
WeblogicTOPLinkDeploymentTool tool = new WeblogicTOPLinkDeploymentTool();
tool.setTask( this );
deploymentTools.add( tool );
return tool;
}

/**
* Create a websphere nested element used to configure a deployment tool for
* Websphere 4.0 server.
*
* @return the deployment tool instance to be configured.
*/
public WebsphereDeploymentTool createWebsphere()
{
WebsphereDeploymentTool tool = new WebsphereDeploymentTool();
tool.setTask( this );
deploymentTools.add( tool );
return tool;
}

/**
* Invoked by Ant after the task is prepared, when it is ready to execute
* this task. This will configure all of the nested deployment tools to
* allow them to process the jar. If no deployment tools have been
* configured a generic tool is created to handle the jar. A parser is
* configured and then each descriptor found is passed to all the deployment
* tool elements for processing.
*
* @exception TaskException thrown whenever a problem is encountered that
* cannot be recovered from, to signal to ant that a major problem
* occurred within this task.
*/
public void execute()
throws TaskException
{
validateConfig();

if( deploymentTools.size() == 0 )
{
GenericDeploymentTool genericTool = new GenericDeploymentTool();
genericTool.setTask( this );
genericTool.setDestdir( destDir );
genericTool.setGenericJarSuffix( genericJarSuffix );
deploymentTools.add( genericTool );
}

for( Iterator i = deploymentTools.iterator(); i.hasNext(); )
{
EJBDeploymentTool tool = (EJBDeploymentTool)i.next();
tool.configure( config );
tool.validateConfigured();
}

try
{
// Create the parser using whatever parser the system dictates
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setValidating( true );
SAXParser saxParser = saxParserFactory.newSAXParser();

DirectoryScanner ds = getDirectoryScanner( config.descriptorDir );
ds.scan();
String[] files = ds.getIncludedFiles();

getLogger().debug( files.length + " deployment descriptors located." );

// Loop through the files. Each file represents one deployment
// descriptor, and hence one bean in our model.
for( int index = 0; index < files.length; ++index )
{
// process the deployment descriptor in each tool
for( Iterator i = deploymentTools.iterator(); i.hasNext(); )
{
EJBDeploymentTool tool = (EJBDeploymentTool)i.next();
tool.processDescriptor( files[ index ], saxParser );
}
}
}
catch( SAXException se )
{
String msg = "SAXException while creating parser."
+ " Details: "
+ se.getMessage();
throw new TaskException( msg, se );
}
catch( ParserConfigurationException pce )
{
String msg = "ParserConfigurationException while creating parser. "
+ "Details: " + pce.getMessage();
throw new TaskException( msg, pce );
}
}

private void validateConfig()
{
if( config.srcDir == null )
{
throw new TaskException( "The srcDir attribute must be specified" );
}

if( config.descriptorDir == null )
{
config.descriptorDir = config.srcDir;
}

if( config.namingScheme == null )
{
config.namingScheme = new NamingScheme();
config.namingScheme.setValue( NamingScheme.DESCRIPTOR );
}
else if( config.namingScheme.getValue().equals( NamingScheme.BASEJARNAME ) &&
config.baseJarName == null )
{
throw new TaskException( "The basejarname attribute must be specified " +
"with the basejarname naming scheme" );
}
}

public static class DTDLocation
{
private String publicId = null;
private String location = null;

public void setLocation( String location )
{
this.location = location;
}

public void setPublicId( String publicId )
{
this.publicId = publicId;
}

public String getLocation()
{
return location;
}

public String getPublicId()
{
return publicId;
}
}

public static class NamingScheme extends EnumeratedAttribute
{
public final static String EJB_NAME = "ejb-name";
public final static String DIRECTORY = "directory";
public final static String DESCRIPTOR = "descriptor";
public final static String BASEJARNAME = "basejarname";

public String[] getValues()
{
return new String[]{EJB_NAME, DIRECTORY, DESCRIPTOR, BASEJARNAME};
}
}

/**
* A class which contains the configuration state of the ejbjar task. This
* state is passed to the deployment tools for configuration
*
* @author RT
*/
static class Config
{

/**
* Instance variable that marks the end of the 'basename'
*/
public String baseNameTerminator = "-";

/**
* Instance variable that determines whether to use a package structure
* of a flat directory as the destination for the jar files.
*/
public boolean flatDestDir = false;

/**
* A Fileset of support classes
*/
public List supportFileSets = new ArrayList();

/**
* The list of configured DTD locations
*/
public ArrayList dtdLocations = new ArrayList();

/**
* Stores a handle to the destination EJB Jar file
*/
public String baseJarName;

/**
* The classpath to use when loading classes
*/
public Path classpath;

/**
* Stores a handle to the directory under which to search for deployment
* descriptors
*/
public File descriptorDir;

/**
* The Manifest file
*/
public File manifest;

/**
* The naming scheme used to determine the generated jar name from the
* descriptor information
*/
public NamingScheme namingScheme;
/**
* Stores a handle to the directory under which to search for class
* files
*/
public File srcDir;
}// end of execute()
}





+ 0
- 192
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/Ejbc.java View File

@@ -1,192 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.Argument;
import org.apache.tools.ant.types.DirectoryScanner;
import org.apache.tools.ant.types.Path;

/**
* Build EJB support classes using Weblogic's ejbc tool from a directory
* containing a set of deployment descriptors.
*
* @author <a href="mailto:conor@cortexebusiness.com.au">Conor MacNeill</a> ,
* Cortex ebusiness Pty Limited
*/
public class Ejbc extends MatchingTask
{

public boolean keepgenerated;

/**
* The classpath to be used in the weblogic ejbc calls. It must contain the
* weblogic classes <b>and</b> the implementation classes of the home and
* remote interfaces.
*/
private String classpath;
/**
* The root directory of the tree containing the serialised deployment
* desciptors. The actual deployment descriptor files are selected using
* include and exclude constructs on the ejbc task provided by the
* MatchingTask superclass.
*/
private File descriptorDirectory;

/**
* The directory where generated files are placed.
*/
private File generatedFilesDirectory;

/**
* The name of the manifest file generated for the EJB jar.
*/
private File generatedManifestFile;

/**
* The source directory for the home and remote interfaces. This is used to
* determine if the generated deployment classes are out of date.
*/
private File sourceDirectory;

/**
* Set the classpath to be used for this compilation.
*
* @param s The new Classpath value
*/
public void setClasspath( final Path s )
{
this.classpath = s.toString();
}

/**
* Set the directory from where the serialised deployment descriptors are to
* be read.
*
* @param dirName the name of the directory containing the serialised
* deployment descriptors.
*/
public void setDescriptors( String dirName )
{
descriptorDirectory = new File( dirName );
}

/**
* Set the directory into which the support classes, RMI stubs, etc are to
* be written
*
* @param dirName the name of the directory into which code is generated
*/
public void setDest( final File dirName )
{
generatedFilesDirectory = dirName;
}

public void setKeepgenerated( String newKeepgenerated )
{
keepgenerated = Boolean.valueOf( newKeepgenerated.trim() ).booleanValue();

}

/**
* Set the generated manifest file. For each EJB that is processed an entry
* is created in this file. This can then be used to create a jar file for
* dploying the beans.
*
* @param manifestFilename The new Manifest value
*/
public void setManifest( String manifestFilename )
{
generatedManifestFile = new File( manifestFilename );
}

/**
* Set the directory containing the source code for the home interface,
* remote interface and public key class definitions.
*
* @param dirName the directory containg the source tree for the EJB's
* interface classes.
*/
public void setSrc( String dirName )
{
sourceDirectory = new File( dirName );
}

public boolean getKeepgenerated()
{
return keepgenerated;
}

/**
* Do the work. The work is actually done by creating a separate JVM to run
* a helper task. This approach allows the classpath of the helper task to
* be set. Since the weblogic tools require the class files of the project's
* home and remote interfaces to be available in the classpath, this also
* avoids having to start ant with the class path of the project it is
* building.
*
* @exception TaskException if someting goes wrong with the build
*/
public void execute()
throws TaskException
{
if( descriptorDirectory == null ||
!descriptorDirectory.isDirectory() )
{
throw new TaskException( "descriptors directory " + descriptorDirectory.getPath() +
" is not valid" );
}
if( generatedFilesDirectory == null ||
!generatedFilesDirectory.isDirectory() )
{
throw new TaskException( "dest directory " + generatedFilesDirectory.getPath() +
" is not valid" );
}

if( sourceDirectory == null ||
!sourceDirectory.isDirectory() )
{
throw new TaskException( "src directory " + sourceDirectory.getPath() +
" is not valid" );
}

String systemClassPath = System.getProperty( "java.class.path" );
String execClassPath =
systemClassPath + File.separator + classpath + File.separator + generatedFilesDirectory;
// get all the files in the descriptor directory
DirectoryScanner ds = super.getDirectoryScanner( descriptorDirectory );

String[] files = ds.getIncludedFiles();

Java helperTask = (Java)getProject().createTask( "java" );
helperTask.setFork( true );
helperTask.setClassname( "org.apache.tools.ant.taskdefs.optional.ejb.EjbcHelper" );
String args = "";
args += " " + descriptorDirectory;
args += " " + generatedFilesDirectory;
args += " " + sourceDirectory;
args += " " + generatedManifestFile;
args += " " + keepgenerated;

for( int i = 0; i < files.length; ++i )
{
args += " " + files[ i ];
}

Argument arguments = helperTask.createArg();
arguments.setLine( args );
helperTask.setClasspath( new Path( execClassPath ) );
if( helperTask.executeJava() != 0 )
{
throw new TaskException( "Execution of ejbc helper failed" );
}
}
}

+ 0
- 286
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/EjbcHelper.java View File

@@ -1,286 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import javax.ejb.deployment.DeploymentDescriptor;
import javax.ejb.deployment.EntityDescriptor;

/**
* A helper class which performs the actual work of the ejbc task. This class is
* run with a classpath which includes the weblogic tools and the home and
* remote interface class files referenced in the deployment descriptors being
* processed.
*
* @author <a href="mailto:conor@cortexebusiness.com.au">Conor MacNeill</a> ,
* Cortex ebusiness Pty Limited
*/
public class EjbcHelper
{

/**
* The names of the serialised deployment descriptors
*/
String[] descriptors;

/**
* The classpath to be used in the weblogic ejbc calls. It must contain the
* weblogic classes <b>and</b> the implementation classes of the home and
* remote interfaces.
*/
private String classpath;
/**
* The root directory of the tree containing the serialised deployment
* desciptors.
*/
private File descriptorDirectory;

/**
* The directory where generated files are placed.
*/
private File generatedFilesDirectory;

private boolean keepGenerated;

/**
* The name of the manifest file generated for the EJB jar.
*/
private File manifestFile;

/**
* The source directory for the home and remote interfaces. This is used to
* determine if the generated deployment classes are out of date.
*/
private File sourceDirectory;

/**
* Initialise the EjbcHelper by reading the command arguments.
*
* @param args Description of Parameter
*/
private EjbcHelper( String[] args )
{
int index = 0;
descriptorDirectory = new File( args[ index++ ] );
generatedFilesDirectory = new File( args[ index++ ] );
sourceDirectory = new File( args[ index++ ] );
manifestFile = new File( args[ index++ ] );
keepGenerated = Boolean.valueOf( args[ index++ ] ).booleanValue();

descriptors = new String[ args.length - index ];
for( int i = 0; index < args.length; ++i )
{
descriptors[ i ] = args[ index++ ];
}
}

/**
* Command line interface for the ejbc helper task.
*
* @param args The command line arguments
* @exception Exception Description of Exception
*/
public static void main( String[] args )
throws Exception
{
EjbcHelper helper = new EjbcHelper( args );
helper.process();
}

private String[] getCommandLine( boolean debug, File descriptorFile )
{
ArrayList v = new ArrayList();
if( !debug )
{
v.add( "-noexit" );
}
if( keepGenerated )
{
v.add( "-keepgenerated" );
}
v.add( "-d" );
v.add( generatedFilesDirectory.getPath() );
v.add( descriptorFile.getPath() );

String[] args = new String[ v.size() ];
v.copyInto( args );
return args;
}

/**
* Determine if the weblogic EJB support classes need to be regenerated for
* a given deployment descriptor. This process attempts to determine if the
* support classes need to be rebuilt. It does this by examining only some
* of the support classes which are typically generated. If the ejbc task is
* interrupted generating the support classes for a bean, all of the support
* classes should be removed to force regeneration of the support classes.
*
* @param descriptorFile the serialised deployment descriptor
* @return true if the support classes need to be regenerated.
* @throws IOException if the descriptor file cannot be closed.
*/
private boolean isRegenRequired( File descriptorFile )
throws IOException
{
// read in the descriptor. Under weblogic, the descriptor is a weblogic
// specific subclass which has references to the implementation classes.
// These classes must, therefore, be in the classpath when the deployment
// descriptor is loaded from the .ser file
FileInputStream fis = null;
try
{
fis = new FileInputStream( descriptorFile );
ObjectInputStream ois = new ObjectInputStream( fis );
DeploymentDescriptor dd = (DeploymentDescriptor)ois.readObject();
fis.close();

String homeInterfacePath = dd.getHomeInterfaceClassName().replace( '.', '/' ) + ".java";
String remoteInterfacePath = dd.getRemoteInterfaceClassName().replace( '.', '/' ) + ".java";
String primaryKeyClassPath = null;
if( dd instanceof EntityDescriptor )
{
primaryKeyClassPath = ( (EntityDescriptor)dd ).getPrimaryKeyClassName().replace( '.', '/' ) + ".java";
;
}

File homeInterfaceSource = new File( sourceDirectory, homeInterfacePath );
File remoteInterfaceSource = new File( sourceDirectory, remoteInterfacePath );
File primaryKeyClassSource = null;
if( primaryKeyClassPath != null )
{
primaryKeyClassSource = new File( sourceDirectory, remoteInterfacePath );
}

// are any of the above out of date.
// we find the implementation classes and see if they are older than any
// of the above or the .ser file itself.
String beanClassBase = dd.getEnterpriseBeanClassName().replace( '.', '/' );
File ejbImplentationClass
= new File( generatedFilesDirectory, beanClassBase + "EOImpl.class" );
File homeImplementationClass
= new File( generatedFilesDirectory, beanClassBase + "HomeImpl.class" );
File beanStubClass
= new File( generatedFilesDirectory, beanClassBase + "EOImpl_WLStub.class" );

// if the implementation classes don;t exist regenerate
if( !ejbImplentationClass.exists() || !homeImplementationClass.exists() ||
!beanStubClass.exists() )
{
return true;
}

// Is the ser file or any of the source files newer then the class files.
// firstly find the oldest of the two class files.
long classModificationTime = ejbImplentationClass.lastModified();
if( homeImplementationClass.lastModified() < classModificationTime )
{
classModificationTime = homeImplementationClass.lastModified();
}
if( beanStubClass.lastModified() < classModificationTime )
{
classModificationTime = beanStubClass.lastModified();
}

if( descriptorFile.lastModified() > classModificationTime ||
homeInterfaceSource.lastModified() > classModificationTime ||
remoteInterfaceSource.lastModified() > classModificationTime )
{
return true;
}

if( primaryKeyClassSource != null &&
primaryKeyClassSource.lastModified() > classModificationTime )
{
return true;
}
}
catch( Throwable descriptorLoadException )
{
System.out.println( "Exception occurred reading " + descriptorFile.getName() + " - continuing" );
// any problems - just regenerate
return true;
}
finally
{
if( fis != null )
{
fis.close();
}
}

return false;
}

/**
* Process the descriptors in turn generating support classes for each and a
* manifest file for all of the beans.
*
* @exception Exception Description of Exception
*/
private void process()
throws Exception
{
String manifest = "Manifest-Version: 1.0\n\n";
for( int i = 0; i < descriptors.length; ++i )
{
String descriptorName = descriptors[ i ];
File descriptorFile = new File( descriptorDirectory, descriptorName );

if( isRegenRequired( descriptorFile ) )
{
System.out.println( "Running ejbc for " + descriptorFile.getName() );
regenerateSupportClasses( descriptorFile );
}
else
{
System.out.println( descriptorFile.getName() + " is up to date" );
}
manifest += "Name: " + descriptorName.replace( '\\', '/' ) + "\nEnterprise-Bean: True\n\n";
}

FileWriter fw = new FileWriter( manifestFile );
PrintWriter pw = new PrintWriter( fw );
pw.print( manifest );
fw.flush();
fw.close();
}

/**
* Perform the weblogic.ejbc call to regenerate the support classes. Note
* that this method relies on an undocumented -noexit option to the ejbc
* tool to stop the ejbc tool exiting the VM altogether.
*
* @param descriptorFile Description of Parameter
* @exception Exception Description of Exception
*/
private void regenerateSupportClasses( File descriptorFile )
throws Exception
{
// create a Java task to do the rebuild


String[] args = getCommandLine( false, descriptorFile );

try
{
weblogic.ejbc.main( args );
}
catch( Exception e )
{
// run with no exit for better reporting
String[] newArgs = getCommandLine( true, descriptorFile );
weblogic.ejbc.main( newArgs );
}
}
}

+ 0
- 958
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java View File

@@ -1,958 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import javax.xml.parsers.SAXParser;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.DirectoryScanner;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.PathUtil;
import org.apache.tools.ant.types.ScannerUtil;
import org.apache.tools.ant.util.depend.Dependencies;
import org.apache.tools.ant.util.depend.Filter;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
* A deployment tool which creates generic EJB jars. Generic jars contains only
* those classes and META-INF entries specified in the EJB 1.1 standard This
* class is also used as a framework for the creation of vendor specific
* deployment tools. A number of template methods are provided through which the
* vendor specific tool can hook into the EJB creation process.
*
* @author RT
*/
public class GenericDeploymentTool
extends AbstractLogEnabled
implements EJBDeploymentTool
{
/**
* Private constants that are used when constructing the standard jarfile
*/
protected final static String META_DIR = "META-INF/";
protected final static String EJB_DD = "ejb-jar.xml";

/**
* Instance variable that stores the suffix for the generated jarfile.
*/
private String genericJarSuffix = "-generic.jar";

/**
* The classloader generated from the given classpath to load the super
* classes and super interfaces.
*/
private ClassLoader classpathLoader = null;

/**
* List of files have been loaded into the EJB jar
*/
private List addedfiles;

/**
* The classpath to use with this deployment tool. This is appended to any
* paths from the ejbjar task itself.
*/
private Path classpath;

/**
* The configuration from the containing task. This config combined with the
* settings of the individual attributes here constitues the complete config
* for this deployment tool.
*/
private EjbJar.Config config;

/**
* Stores a handle to the directory to put the Jar files in
*/
private File destDir;

/**
* Handler used to parse the EJB XML descriptor
*/
private DescriptorHandler handler;

/**
* The task to which this tool belongs. This is used to access services
* provided by the ant core, such as logging.
*/
private Task task;

/**
* Set the classpath to be used for this compilation.
*
* @param classpath The new Classpath value
*/
public void setClasspath( Path classpath )
{
this.classpath = classpath;
}

/**
* Setter used to store the value of destination directory prior to
* execute() being called.
*
* @param inDir the destination directory.
*/
public void setDestdir( File inDir )
{
this.destDir = inDir;
}

/**
* Setter used to store the suffix for the generated jar file.
*
* @param inString the string to use as the suffix.
*/
public void setGenericJarSuffix( String inString )
{
this.genericJarSuffix = inString;
}

/**
* Set the task which owns this tool
*
* @param task The new Task value
*/
public void setTask( Task task )
{
this.task = task;
}

/**
* Get the prefix for vendor deployment descriptors. This will contain the
* path and the start of the descriptor name, depending on the naming scheme
*
* @param baseName Description of Parameter
* @param descriptorFileName Description of Parameter
* @return The VendorDDPrefix value
*/
public String getVendorDDPrefix( String baseName, String descriptorFileName )
{
String ddPrefix = null;

if( config.namingScheme.getValue().equals( EjbJar.NamingScheme.DESCRIPTOR ) )
{
ddPrefix = baseName + config.baseNameTerminator;
}
else if( config.namingScheme.getValue().equals( EjbJar.NamingScheme.BASEJARNAME ) ||
config.namingScheme.getValue().equals( EjbJar.NamingScheme.EJB_NAME ) ||
config.namingScheme.getValue().equals( EjbJar.NamingScheme.DIRECTORY ) )
{
String canonicalDescriptor = descriptorFileName.replace( '\\', '/' );
int index = canonicalDescriptor.lastIndexOf( '/' );
if( index == -1 )
{
ddPrefix = "";
}
else
{
ddPrefix = descriptorFileName.substring( 0, index + 1 );
}
}
return ddPrefix;
}

/**
* Configure this tool for use in the ejbjar task.
*
* @param config Description of Parameter
*/
public void configure( EjbJar.Config config )
{
this.config = config;

classpathLoader = null;
}

/**
* Add the classpath for the user classes
*
* @return Description of the Returned Value
*/
public Path createClasspath()
{
if( classpath == null )
{
classpath = new Path();
}
Path path1 = classpath;
final Path path = new Path();
path1.addPath( path );
return path;
}

public void processDescriptor( String descriptorFileName, SAXParser saxParser )
{

checkConfiguration( descriptorFileName, saxParser );

try
{
handler = getDescriptorHandler( config.srcDir );

// Retrive the files to be added to JAR from EJB descriptor
Hashtable ejbFiles = parseEjbFiles( descriptorFileName, saxParser );

// Add any support classes specified in the build file
addSupportClasses( ejbFiles );

// Determine the JAR filename (without filename extension)
String baseName = getJarBaseName( descriptorFileName );

String ddPrefix = getVendorDDPrefix( baseName, descriptorFileName );

// First the regular deployment descriptor
ejbFiles.put( META_DIR + EJB_DD,
new File( config.descriptorDir, descriptorFileName ) );

// now the vendor specific files, if any
addVendorFiles( ejbFiles, ddPrefix );

// add any dependent files
checkAndAddDependants( ejbFiles );

// Lastly create File object for the Jar files. If we are using
// a flat destination dir, then we need to redefine baseName!
if( config.flatDestDir && baseName.length() != 0 )
{
int startName = baseName.lastIndexOf( File.separator );
if( startName == -1 )
{
startName = 0;
}

int endName = baseName.length();
baseName = baseName.substring( startName, endName );
}

File jarFile = getVendorOutputJarFile( baseName );

// Check to see if we need a build and start doing the work!
if( needToRebuild( ejbFiles, jarFile ) )
{
// Log that we are going to build...
final String message =
"building " + jarFile.getName() + " with " + String.valueOf( ejbFiles.size() ) + " files";
getLogger().info( message );

// Use helper method to write the jarfile
String publicId = getPublicId();
writeJar( baseName, jarFile, ejbFiles, publicId );

}
else
{
// Log that the file is up to date...
getLogger().debug( jarFile.toString() + " is up to date." );
}

}
catch( SAXException se )
{
String msg = "SAXException while parsing '"
+ descriptorFileName.toString()
+ "'. This probably indicates badly-formed XML."
+ " Details: "
+ se.getMessage();
throw new TaskException( msg, se );
}
catch( IOException ioe )
{
String msg = "IOException while parsing'"
+ descriptorFileName.toString()
+ "'. This probably indicates that the descriptor"
+ " doesn't exist. Details: "
+ ioe.getMessage();
throw new TaskException( msg, ioe );
}
}

/**
* Called to validate that the tool parameters have been configured.
*
* @throws TaskException If the Deployment Tool's configuration isn't valid
*/
public void validateConfigured()
throws TaskException
{
if( ( destDir == null ) || ( !destDir.isDirectory() ) )
{
String msg = "A valid destination directory must be specified "
+ "using the \"destdir\" attribute.";
throw new TaskException( msg );
}
}

/**
* Returns a Classloader object which parses the passed in generic EjbJar
* classpath. The loader is used to dynamically load classes from
* javax.ejb.* and the classes being added to the jar.
*
* @return The ClassLoaderForBuild value
*/
protected ClassLoader getClassLoaderForBuild()
throws TaskException
{
if( classpathLoader != null )
{
return classpathLoader;
}

Path combinedClasspath = getCombinedClasspath();

// only generate a new ClassLoader if we have a classpath
if( combinedClasspath == null )
{
classpathLoader = getClass().getClassLoader();
}
else
{
final URL[] urls = PathUtil.toURLs( combinedClasspath );
classpathLoader = new URLClassLoader( urls );
}

return classpathLoader;
}

/**
* Get the classpath by combining the one from the surrounding task, if any
* and the one from this tool.
*
* @return The CombinedClasspath value
*/
protected Path getCombinedClasspath()
{
Path combinedPath = classpath;
if( config.classpath != null )
{
if( combinedPath == null )
{
combinedPath = config.classpath;
}
else
{
combinedPath.append( config.classpath );
}
}

return combinedPath;
}

/**
* Get the basename terminator.
*
* @return The Config value
*/
protected EjbJar.Config getConfig()
{
return config;
}

protected DescriptorHandler getDescriptorHandler( File srcDir )
{
DescriptorHandler handler = new DescriptorHandler( getTask(), srcDir );

registerKnownDTDs( handler );

// register any DTDs supplied by the user
for( Iterator i = getConfig().dtdLocations.iterator(); i.hasNext(); )
{
EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation)i.next();
handler.registerDTD( dtdLocation.getPublicId(), dtdLocation.getLocation() );
}
return handler;
}

/**
* Get the desitination directory.
*
* @return The DestDir value
*/
protected File getDestDir()
{
return destDir;
}

/**
* Using the EJB descriptor file name passed from the <code>ejbjar</code>
* task, this method returns the "basename" which will be used to name the
* completed JAR file.
*
* @param descriptorFileName String representing the file name of an EJB
* descriptor to be processed
* @return The "basename" which will be used to name the completed JAR file
*/
protected String getJarBaseName( String descriptorFileName )
{

String baseName = "";

// Work out what the base name is
if( config.namingScheme.getValue().equals( EjbJar.NamingScheme.BASEJARNAME ) )
{
String canonicalDescriptor = descriptorFileName.replace( '\\', '/' );
int index = canonicalDescriptor.lastIndexOf( '/' );
if( index != -1 )
{
baseName = descriptorFileName.substring( 0, index + 1 );
}
baseName += config.baseJarName;
}
else if( config.namingScheme.getValue().equals( EjbJar.NamingScheme.DESCRIPTOR ) )
{
int lastSeparatorIndex = descriptorFileName.lastIndexOf( File.separator );
int endBaseName = -1;
if( lastSeparatorIndex != -1 )
{
endBaseName = descriptorFileName.indexOf( config.baseNameTerminator,
lastSeparatorIndex );
}
else
{
endBaseName = descriptorFileName.indexOf( config.baseNameTerminator );
}

if( endBaseName != -1 )
{
baseName = descriptorFileName.substring( 0, endBaseName );
}
baseName = descriptorFileName.substring( 0, endBaseName );
}
else if( config.namingScheme.getValue().equals( EjbJar.NamingScheme.DIRECTORY ) )
{
int lastSeparatorIndex = descriptorFileName.lastIndexOf( File.separator );
String dirName = descriptorFileName.substring( 0, lastSeparatorIndex );
int dirSeparatorIndex = dirName.lastIndexOf( File.separator );
if( dirSeparatorIndex != -1 )
{
dirName = dirName.substring( dirSeparatorIndex + 1 );
}

baseName = dirName;
}
else if( config.namingScheme.getValue().equals( EjbJar.NamingScheme.EJB_NAME ) )
{
baseName = handler.getEjbName();
}
return baseName;
}

/**
* Returns the Public ID of the DTD specified in the EJB descriptor. Not
* every vendor-specific <code>DeploymentTool</code> will need to reference
* this value or may want to determine this value in a vendor-specific way.
*
* @return Public ID of the DTD specified in the EJB descriptor.
*/
protected String getPublicId()
{
return handler.getPublicId();
}

/**
* Get the task for this tool.
*
* @return The Task value
*/
protected Task getTask()
{
return task;
}

/**
* Utility method that encapsulates the logic of adding a file entry to a
* .jar file. Used by execute() to add entries to the jar file as it is
* constructed.
*
* @param jStream A JarOutputStream into which to write the jar entry.
* @param inputFile A File from which to read the contents the file being
* added.
* @param logicalFilename A String representing the name, including all
* relevant path information, that should be stored for the entry being
* added.
* @exception TaskException Description of Exception
*/
protected void addFileToJar( JarOutputStream jStream,
File inputFile,
String logicalFilename )
throws TaskException
{
FileInputStream iStream = null;
try
{
if( !addedfiles.contains( logicalFilename ) )
{
iStream = new FileInputStream( inputFile );
// Create the zip entry and add it to the jar file
ZipEntry zipEntry = new ZipEntry( logicalFilename.replace( '\\', '/' ) );
jStream.putNextEntry( zipEntry );

// Create the file input stream, and buffer everything over
// to the jar output stream
byte[] byteBuffer = new byte[ 2 * 1024 ];
int count = 0;
do
{
jStream.write( byteBuffer, 0, count );
count = iStream.read( byteBuffer, 0, byteBuffer.length );
} while( count != -1 );

//add it to list of files in jar
addedfiles.add( logicalFilename );
}
}
catch( IOException ioe )
{
final String message = "WARNING: IOException while adding entry " +
logicalFilename + " to jarfile from " + inputFile.getPath() + " " +
ioe.getClass().getName() + "-" + ioe.getMessage();
getLogger().warn( message );
}
finally
{
// Close up the file input stream for the class file
if( iStream != null )
{
try
{
iStream.close();
}
catch( IOException closeException )
{
}
}
}
}

/**
* Adds any classes the user specifies using <i>support</i> nested elements
* to the <code>ejbFiles</code> Hashtable.
*
* @param ejbFiles Hashtable of EJB classes (and other) files that will be
* added to the completed JAR file
*/
protected void addSupportClasses( Hashtable ejbFiles )
{
// add in support classes if any
Project project = task.getProject();
for( Iterator i = config.supportFileSets.iterator(); i.hasNext(); )
{
FileSet supportFileSet = (FileSet)i.next();
File supportBaseDir = supportFileSet.getDir();
DirectoryScanner supportScanner = ScannerUtil.getDirectoryScanner( supportFileSet );
supportScanner.scan();
String[] supportFiles = supportScanner.getIncludedFiles();
for( int j = 0; j < supportFiles.length; ++j )
{
ejbFiles.put( supportFiles[ j ], new File( supportBaseDir, supportFiles[ j ] ) );
}
}
}

/**
* Add any vendor specific files which should be included in the EJB Jar.
*
* @param ejbFiles The feature to be added to the VendorFiles attribute
* @param ddPrefix The feature to be added to the VendorFiles attribute
*/
protected void addVendorFiles( Hashtable ejbFiles, String ddPrefix )
{
// nothing to add for generic tool.
}// end of writeJar

/**
* Add all available classes, that depend on Remote, Home, Bean, PK
*
* @param checkEntries files, that are extracted from the deployment
* descriptor
* @exception TaskException Description of Exception
*/
protected void checkAndAddDependants( Hashtable checkEntries )
throws TaskException
{
Dependencies visitor = new Dependencies();
Set set = new TreeSet();
Set newSet = new HashSet();
final String base = config.srcDir.getAbsolutePath() + File.separator;

Iterator i = checkEntries.keySet().iterator();
while( i.hasNext() )
{
String entryName = (String)i.next();
if( entryName.endsWith( ".class" ) )
{
newSet.add( entryName.substring( 0, entryName.length() - ".class".length() ).replace( File.separatorChar, '/' ) );
}
}
set.addAll( newSet );

do
{
i = newSet.iterator();
while( i.hasNext() )
{
String fileName = base + ( (String)i.next() ).replace( '/', File.separatorChar ) + ".class";

try
{
JavaClass javaClass = new ClassParser( fileName ).parse();
javaClass.accept( visitor );
}
catch( IOException e )
{
getLogger().info( "exception: " + e.getMessage() );
}
}
newSet.clear();
newSet.addAll( visitor.getDependencies() );
visitor.clearDependencies();

Dependencies.applyFilter( newSet,
new Filter()
{
public boolean accept( Object object )
{
String fileName = base + ( (String)object ).replace( '/', File.separatorChar ) + ".class";
return new File( fileName ).exists();
}
} );
newSet.removeAll( set );
set.addAll( newSet );
} while( newSet.size() > 0 );

i = set.iterator();
while( i.hasNext() )
{
String next = ( (String)i.next() ).replace( '/', File.separatorChar );
checkEntries.put( next + ".class", new File( base + next + ".class" ) );
getLogger().debug( "dependent class: " + next + ".class" + " - " + base + next + ".class" );
}
}

/**
* This method is called as the first step in the processDescriptor method
* to allow vendor-specific subclasses to validate the task configuration
* prior to processing the descriptor. If the configuration is invalid, a
* TaskException should be thrown.
*
* @param descriptorFileName String representing the file name of an EJB
* descriptor to be processed
* @param saxParser SAXParser which may be used to parse the XML descriptor
* @exception TaskException Description of Exception
* @thows TaskException Thrown if the configuration is invalid
*/
protected void checkConfiguration( String descriptorFileName,
SAXParser saxParser )
throws TaskException
{

/*
* For the GenericDeploymentTool, do nothing. Vendor specific
* subclasses should throw a TaskException if the configuration is
* invalid for their server.
*/
}

/**
* This method checks the timestamp on each file listed in the <code>
* ejbFiles</code> and compares them to the timestamp on the <code>jarFile
* </code>. If the <code>jarFile</code>'s timestamp is more recent than each
* EJB file, <code>true</code> is returned. Otherwise, <code>false
* </code> is returned. TODO: find a way to check the manifest-file, that is
* found by naming convention
*
* @param ejbFiles Hashtable of EJB classes (and other) files that will be
* added to the completed JAR file
* @param jarFile JAR file which will contain all of the EJB classes (and
* other) files
* @return boolean indicating whether or not the <code>jarFile</code> is up
* to date
*/
protected boolean needToRebuild( Hashtable ejbFiles, File jarFile )
{
if( jarFile.exists() )
{
long lastBuild = jarFile.lastModified();

if( config.manifest != null && config.manifest.exists() &&
config.manifest.lastModified() > lastBuild )
{
getLogger().debug( "Build needed because manifest " + config.manifest + " is out of date" );
return true;
}

Iterator fileIter = ejbFiles.values().iterator();

// Loop through the files seeing if any has been touched
// more recently than the destination jar.
while( fileIter.hasNext() )
{
File currentFile = (File)fileIter.next();
if( lastBuild < currentFile.lastModified() )
{
getLogger().debug( "Build needed because " + currentFile.getPath() + " is out of date" );
return true;
}
}
return false;
}

return true;
}

/**
* This method returns a list of EJB files found when the specified EJB
* descriptor is parsed and processed.
*
* @param descriptorFileName String representing the file name of an EJB
* descriptor to be processed
* @param saxParser SAXParser which may be used to parse the XML descriptor
* @return Hashtable of EJB class (and other) files to be added to the
* completed JAR file
* @throws SAXException Any SAX exception, possibly wrapping another
* exception
* @throws IOException An IOException from the parser, possibly from a the
* byte stream or character stream
*/
protected Hashtable parseEjbFiles( String descriptorFileName, SAXParser saxParser )
throws IOException, SAXException
{
FileInputStream descriptorStream = null;
Hashtable ejbFiles = null;

try
{

/*
* Parse the ejb deployment descriptor. While it may not
* look like much, we use a SAXParser and an inner class to
* get hold of all the classfile names for the descriptor.
*/
descriptorStream = new FileInputStream( new File( config.descriptorDir, descriptorFileName ) );
saxParser.parse( new InputSource( descriptorStream ), handler );

ejbFiles = handler.getFiles();

}
finally
{
if( descriptorStream != null )
{
try
{
descriptorStream.close();
}
catch( IOException closeException )
{
}
}
}

return ejbFiles;
}

/**
* Register the locations of all known DTDs. vendor-specific subclasses
* should override this method to define the vendor-specific locations of
* the EJB DTDs
*
* @param handler Description of Parameter
*/
protected void registerKnownDTDs( DescriptorHandler handler )
{
// none to register for generic
}

/**
* Returns true, if the meta-inf dir is being explicitly set, false
* otherwise.
*
* @return Description of the Returned Value
*/
protected boolean usingBaseJarName()
{
return config.baseJarName != null;
}

/**
* Method used to encapsulate the writing of the JAR file. Iterates over the
* filenames/java.io.Files in the Hashtable stored on the instance variable
* ejbFiles.
*
* @param baseName Description of Parameter
* @param jarfile Description of Parameter
* @param files Description of Parameter
* @param publicId Description of Parameter
* @exception TaskException Description of Exception
*/
protected void writeJar( String baseName, File jarfile, Hashtable files,
String publicId )
throws TaskException
{

JarOutputStream jarStream = null;
try
{
// clean the addedfiles ArrayList
addedfiles = new ArrayList();

/*
* If the jarfile already exists then whack it and recreate it.
* Should probably think of a more elegant way to handle this
* so that in case of errors we don't leave people worse off
* than when we started =)
*/
if( jarfile.exists() )
{
jarfile.delete();
}
jarfile.getParentFile().mkdirs();
jarfile.createNewFile();

InputStream in = null;
Manifest manifest = null;
try
{
File manifestFile = new File( getConfig().descriptorDir, baseName + "-manifest.mf" );
if( manifestFile.exists() )
{
in = new FileInputStream( manifestFile );
}
else if( config.manifest != null )
{
in = new FileInputStream( config.manifest );
if( in == null )
{
throw new TaskException( "Could not find manifest file: " + config.manifest );
}
}
else
{
String defaultManifest = "/org/apache/tools/ant/defaultManifest.mf";
in = this.getClass().getResourceAsStream( defaultManifest );
if( in == null )
{
throw new TaskException( "Could not find default manifest: " + defaultManifest );
}
}

manifest = new Manifest( in );
}
catch( IOException e )
{
throw new TaskException( "Unable to read manifest", e );
}
finally
{
if( in != null )
{
in.close();
}
}

// Create the streams necessary to write the jarfile

jarStream = new JarOutputStream( new FileOutputStream( jarfile ), manifest );
jarStream.setMethod( JarOutputStream.DEFLATED );

// Loop through all the class files found and add them to the jar
for( Iterator entryIterator = files.keySet().iterator(); entryIterator.hasNext(); )
{
String entryName = (String)entryIterator.next();
File entryFile = (File)files.get( entryName );

getLogger().debug( "adding file '" + entryName + "'" );

addFileToJar( jarStream, entryFile, entryName );

// See if there are any inner classes for this class and add them in if there are
InnerClassFilenameFilter flt = new InnerClassFilenameFilter( entryFile.getName() );
File entryDir = entryFile.getParentFile();
String[] innerfiles = entryDir.list( flt );
for( int i = 0, n = innerfiles.length; i < n; i++ )
{

//get and clean up innerclass name
int entryIndex = entryName.lastIndexOf( entryFile.getName() ) - 1;
if( entryIndex < 0 )
{
entryName = innerfiles[ i ];
}
else
{
entryName = entryName.substring( 0, entryIndex ) + File.separatorChar + innerfiles[ i ];
}
// link the file
entryFile = new File( config.srcDir, entryName );

getLogger().debug( "adding innerclass file '" + entryName + "'" );

addFileToJar( jarStream, entryFile, entryName );

}
}
}
catch( IOException ioe )
{
String msg = "IOException while processing ejb-jar file '"
+ jarfile.toString()
+ "'. Details: "
+ ioe.getMessage();
throw new TaskException( msg, ioe );
}
finally
{
if( jarStream != null )
{
try
{
jarStream.close();
}
catch( IOException closeException )
{
}
}
}
}

/**
* Get the vendor specific name of the Jar that will be output. The
* modification date of this jar will be checked against the dependent bean
* classes.
*
* @param baseName Description of Parameter
* @return The VendorOutputJarFile value
*/
File getVendorOutputJarFile( String baseName )
{
return new File( destDir, baseName + genericJarSuffix );
}
}

+ 0
- 407
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetDeploymentTool.java View File

@@ -1,407 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import javax.xml.parsers.SAXParser;
import org.apache.myrmidon.api.TaskException;
import org.xml.sax.SAXException;

/**
* This class is used to generate iPlanet Application Server (iAS) 6.0 stubs and
* skeletons and build an EJB Jar file. It is designed to be used with the Ant
* <code>ejbjar</code> task. If only stubs and skeletons need to be generated
* (in other words, if no JAR file needs to be created), refer to the <code>iplanet-ejbc</code>
* task and the <code>IPlanetEjbcTask</code> class. <p>
*
* The following attributes may be specified by the user:
* <ul>
* <li> <i>destdir</i> -- The base directory into which the generated JAR
* files will be written. Each JAR file is written in directories which
* correspond to their location within the "descriptordir" namespace. This is
* a required attribute.
* <li> <i>classpath</i> -- The classpath used when generating EJB stubs and
* skeletons. This is an optional attribute (if omitted, the classpath
* specified in the "ejbjar" parent task will be used). If specified, the
* classpath elements will be prepended to the classpath specified in the
* parent "ejbjar" task. Note that nested "classpath" elements may also be
* used.
* <li> <i>keepgenerated</i> -- Indicates whether or not the Java source files
* which are generated by ejbc will be saved or automatically deleted. If
* "yes", the source files will be retained. This is an optional attribute (if
* omitted, it defaults to "no").
* <li> <i>debug</i> -- Indicates whether or not the ejbc utility should log
* additional debugging statements to the standard output. If "yes", the
* additional debugging statements will be generated (if omitted, it defaults
* to "no").
* <li> <i>iashome</i> -- May be used to specify the "home" directory for this
* iPlanet Application server installation. This is used to find the ejbc
* utility if it isn't included in the user's system path. This is an optional
* attribute (if specified, it should refer to the <code>[install-location]/iplanet/ias6/ias
* </code> directory). If omitted, the ejbc utility
* must be on the user's system path.
* <li> <i>suffix</i> -- String value appended to the JAR filename when
* creating each JAR. This attribute is not required (if omitted, it defaults
* to ".jar").
* </ul>
* <p>
*
* For each EJB descriptor found in the "ejbjar" parent task, this deployment
* tool will locate the three classes that comprise the EJB. If these class
* files cannot be located in the specified <code>srcdir</code> directory, the
* task will fail. The task will also attempt to locate the EJB stubs and
* skeletons in this directory. If found, the timestamps on the stubs and
* skeletons will be checked to ensure they are up to date. Only if these files
* cannot be found or if they are out of date will ejbc be called.
*
* @author Greg Nelson <a href="mailto:greg@netscape.com">greg@netscape.com</a>
* @see IPlanetEjbc
*/
public class IPlanetDeploymentTool extends GenericDeploymentTool
{

/*
* Regardless of the name of the iAS-specific EJB descriptor file, it will
* written in the completed JAR file as "ias-ejb-jar.xml". This is the
* naming convention implemented by iAS.
*/
private final static String IAS_DD = "ias-ejb-jar.xml";
private String jarSuffix = ".jar";
private boolean keepgenerated = false;
private boolean debug = false;

/*
* Filenames of the standard EJB descriptor (which is passed to this class
* from the parent "ejbjar" task) and the iAS-specific EJB descriptor
* (whose name is determined by this class). Both filenames are relative
* to the directory specified by the "srcdir" attribute in the ejbjar task.
*/
private String descriptorName;

/*
* The displayName variable stores the value of the "display-name" element
* from the standard EJB descriptor. As a future enhancement to this task,
* we may determine the name of the EJB JAR file using this display-name,
* but this has not be implemented yet.
*/
private String displayName;
private String iasDescriptorName;

/*
* Attributes set by the Ant build file
*/
private File iashome;

/**
* Sets whether or not debugging output will be generated when ejbc is
* executed.
*
* @param debug A boolean indicating if debugging output should be generated
*/
public void setDebug( boolean debug )
{
this.debug = debug;
}

/**
* Since iAS doesn't generate a "generic" JAR as part of its processing,
* this attribute is ignored and a warning message is displayed to the user.
*
* @param inString the string to use as the suffix. This parameter is
* ignored.
*/
public void setGenericJarSuffix( String inString )
{
final String message = "Since a generic JAR file is not created during processing, the "
+ "iPlanet Deployment Tool does not support the "
+ "\"genericjarsuffix\" attribute. It will be ignored.";
getLogger().warn( message );
}

/**
* Setter method used to store the "home" directory of the user's iAS
* installation. The directory specified should typically be <code>[install-location]/iplanet/ias6/ias</code>
* .
*
* @param iashome The home directory for the user's iAS installation.
*/
public void setIashome( File iashome )
{
this.iashome = iashome;
}

/**
* Setter method used to specify whether the Java source files generated by
* the ejbc utility should be saved or automatically deleted.
*
* @param keepgenerated boolean which, if <code>true</code>, indicates that
* Java source files generated by ejbc for the stubs and skeletons
* should be kept.
*/
public void setKeepgenerated( boolean keepgenerated )
{
this.keepgenerated = keepgenerated;
}

/**
* Setter method used to specify the filename suffix (for example, ".jar")
* for the JAR files to be created.
*
* @param jarSuffix The string to use as the JAR filename suffix.
*/
public void setSuffix( String jarSuffix )
{
this.jarSuffix = jarSuffix;
}

public void processDescriptor( String descriptorName, SAXParser saxParser )
{
this.descriptorName = descriptorName;

getLogger().debug( "iPlanet Deployment Tool processing: " + descriptorName + " (and " + getIasDescriptorName() + ")" );

super.processDescriptor( descriptorName, saxParser );
}

/**
* The iAS ejbc utility doesn't require the Public ID of the descriptor's
* DTD for it to process correctly--this method always returns <code>null
* </code>.
*
* @return <code>null</code>.
*/
protected String getPublicId()
{
return null;
}

/**
* Add the iAS-specific EJB descriptor to the list of files which will be
* written to the JAR file.
*
* @param ejbFiles Hashtable of EJB class (and other) files to be added to
* the completed JAR file.
* @param ddPrefix The feature to be added to the VendorFiles attribute
*/
protected void addVendorFiles( Hashtable ejbFiles, String ddPrefix )
{
ejbFiles.put( META_DIR + IAS_DD, new File( getConfig().descriptorDir,
getIasDescriptorName() ) );
}

/**
* Verifies that the user selections are valid.
*
* @param descriptorFileName String representing the file name of an EJB
* descriptor to be processed
* @param saxParser SAXParser which may be used to parse the XML descriptor
* @throws TaskException If the user selections are invalid.
*/
protected void checkConfiguration( String descriptorFileName,
SAXParser saxParser )
throws TaskException
{

int startOfName = descriptorFileName.lastIndexOf( File.separatorChar ) + 1;
String stdXml = descriptorFileName.substring( startOfName );
if( stdXml.equals( EJB_DD ) && ( getConfig().baseJarName == null ) )
{
String msg = "No name specified for the completed JAR file. The EJB"
+ " descriptor should be prepended with the JAR "
+ "name or it should be specified using the "
+ "attribute \"basejarname\" in the \"ejbjar\" task.";
throw new TaskException( msg );
}

File iasDescriptor = new File( getConfig().descriptorDir,
getIasDescriptorName() );
if( ( !iasDescriptor.exists() ) || ( !iasDescriptor.isFile() ) )
{
String msg = "The iAS-specific EJB descriptor ("
+ iasDescriptor + ") was not found.";
throw new TaskException( msg );
}

if( ( iashome != null ) && ( !iashome.isDirectory() ) )
{
String msg = "If \"iashome\" is specified, it must be a valid "
+ "directory (it was set to " + iashome + ").";
throw new TaskException( msg );
}
}

/**
* This method returns a list of EJB files found when the specified EJB
* descriptor is parsed and processed.
*
* @param descriptorFileName String representing the file name of an EJB
* descriptor to be processed
* @param saxParser SAXParser which may be used to parse the XML descriptor
* @return Hashtable of EJB class (and other) files to be added to the
* completed JAR file
* @throws IOException An IOException from the parser, possibly from the
* byte stream or character stream
* @throws SAXException Any SAX exception, possibly wrapping another
* exception
*/
protected Hashtable parseEjbFiles( String descriptorFileName,
SAXParser saxParser )
throws IOException, SAXException
{

Hashtable files;

/*
* Build and populate an instance of the ejbc utility
*/
IPlanetEjbc ejbc = new IPlanetEjbc(
new File( getConfig().descriptorDir,
descriptorFileName ),
new File( getConfig().descriptorDir,
getIasDescriptorName() ),
getConfig().srcDir,
getCombinedClasspath().toString(),
saxParser );
ejbc.setRetainSource( keepgenerated );
ejbc.setDebugOutput( debug );
if( iashome != null )
{
ejbc.setIasHomeDir( iashome );
}

/*
* Execute the ejbc utility -- stubs/skeletons are rebuilt, if needed
*/
try
{
ejbc.execute();
}
catch( IPlanetEjbc.EjbcException e )
{
throw new TaskException( "An error has occurred while trying to "
+ "execute the iAS ejbc utility", e );
}

displayName = ejbc.getDisplayName();
files = ejbc.getEjbFiles();

/*
* Add CMP descriptors to the list of EJB files
*/
String[] cmpDescriptors = ejbc.getCmpDescriptors();
if( cmpDescriptors.length > 0 )
{
File baseDir = getConfig().descriptorDir;

int endOfPath = descriptorFileName.lastIndexOf( File.separator );
String relativePath = descriptorFileName.substring( 0, endOfPath + 1 );

for( int i = 0; i < cmpDescriptors.length; i++ )
{
int endOfCmp = cmpDescriptors[ i ].lastIndexOf( '/' );
String cmpDescriptor = cmpDescriptors[ i ].substring( endOfCmp + 1 );

File cmpFile = new File( baseDir, relativePath + cmpDescriptor );
if( !cmpFile.exists() )
{
throw new TaskException( "The CMP descriptor file ("
+ cmpFile + ") could not be found." );
}
files.put( cmpDescriptors[ i ], cmpFile );
}
}

return files;
}

/**
* Get the name of the Jar that will be written. The modification date of
* this jar will be checked against the dependent bean classes.
*
* @param baseName String name of the EJB JAR file to be written (without a
* filename extension).
* @return File representing the JAR file which will be written.
*/
File getVendorOutputJarFile( String baseName )
{
File jarFile = new File( getDestDir(), baseName + jarSuffix );
getLogger().debug( "JAR file name: " + jarFile.toString() );
return jarFile;
}

/**
* Determines the name of the iAS-specific EJB descriptor using the
* specified standard EJB descriptor name. In general, the standard
* descriptor will be named "[basename]-ejb-jar.xml", and this method will
* return "[basename]-ias-ejb-jar.xml".
*
* @return The name of the iAS-specific EJB descriptor file.
*/
private String getIasDescriptorName()
{

/*
* Only calculate the descriptor name once
*/
if( iasDescriptorName != null )
{
return iasDescriptorName;
}

String path = "";// Directory path of the EJB descriptor
String basename;// Filename appearing before name terminator
String remainder;// Filename appearing after the name terminator

/*
* Find the end of the standard descriptor's relative path
*/
int startOfFileName = descriptorName.lastIndexOf( File.separatorChar );
if( startOfFileName != -1 )
{
path = descriptorName.substring( 0, startOfFileName + 1 );
}

/*
* Check to see if the standard name is used (there's no basename)
*/
if( descriptorName.substring( startOfFileName + 1 ).equals( EJB_DD ) )
{
basename = "";
remainder = EJB_DD;

}
else
{
int endOfBaseName = descriptorName.indexOf(
getConfig().baseNameTerminator,
startOfFileName );
/*
* Check for the odd case where the terminator and/or filename
* extension aren't found. These will ensure "ias-" appears at the
* end of the name and before the '.' (if present).
*/
if( endOfBaseName < 0 )
{
endOfBaseName = descriptorName.lastIndexOf( '.' ) - 1;
if( endOfBaseName < 0 )
{
endOfBaseName = descriptorName.length() - 1;
}
}

basename = descriptorName.substring( startOfFileName + 1,
endOfBaseName + 1 );
remainder = descriptorName.substring( endOfBaseName + 1 );
}

iasDescriptorName = path + basename + "ias-" + remainder;
return iasDescriptorName;
}
}

+ 0
- 1688
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbc.java
File diff suppressed because it is too large
View File


+ 0
- 339
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbcTask.java View File

@@ -1,339 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.xml.sax.SAXException;

/**
* Task to compile EJB stubs and skeletons for the iPlanet Application Server.
* The EJBs to be processed are specified by the EJB 1.1 standard XML
* descriptor, and additional attributes are obtained from the iPlanet
* Application Server-specific XML descriptor. Since the XML descriptors can
* include multiple EJBs, this is a convenient way of specifying many EJBs in a
* single Ant task. The following attributes are allowed:
* <ul>
* <li> <i>ejbdescriptor</i> -- Standard EJB 1.1 XML descriptor (typically
* titled "ejb-jar.xml"). This attribute is required.
* <li> <i>iasdescriptor</i> -- EJB XML descriptor for iPlanet Application
* Server (typically titled "ias-ejb-jar.xml). This attribute is required.
*
* <li> <i>dest</i> -- The is the base directory where the RMI stubs and
* skeletons are written. In addition, the class files for each bean (home
* interface, remote interface, and EJB implementation) must be found in this
* directory. This attribute is required.
* <li> <i>classpath</i> -- The classpath used when generating EJB stubs and
* skeletons. This is an optional attribute (if omitted, the classpath
* specified when Ant was started will be used). Nested "classpath" elements
* may also be used.
* <li> <i>keepgenerated</i> -- Indicates whether or not the Java source files
* which are generated by ejbc will be saved or automatically deleted. If
* "yes", the source files will be retained. This is an optional attribute (if
* omitted, it defaults to "no").
* <li> <i>debug</i> -- Indicates whether or not the ejbc utility should log
* additional debugging statements to the standard output. If "yes", the
* additional debugging statements will be generated (if omitted, it defaults
* to "no").
* <li> <i>iashome</i> -- May be used to specify the "home" directory for this
* iPlanet Application Server installation. This is used to find the ejbc
* utility if it isn't included in the user's system path. This is an optional
* attribute (if specified, it should refer to the <code>[install-location]/iplanet/ias6/ias
* </code> directory). If omitted, the ejbc utility
* must be on the user's system path.
* </ul>
* <p>
*
* For each EJB specified, this task will locate the three classes that comprise
* the EJB. If these class files cannot be located in the <code>dest</code>
* directory, the task will fail. The task will also attempt to locate the EJB
* stubs and skeletons in this directory. If found, the timestamps on the stubs
* and skeletons will be checked to ensure they are up to date. Only if these
* files cannot be found or if they are out of date will ejbc be called to
* generate new stubs and skeletons.
*
* @author Greg Nelson <a href="mailto:greg@netscape.com">greg@netscape.com</a>
* @see IPlanetEjbc
*/
public class IPlanetEjbcTask extends Task
{
private boolean keepgenerated = false;
private boolean debug = false;
private Path classpath;
private File dest;

/*
* Attributes set by the Ant build file
*/
private File ejbdescriptor;
private File iasdescriptor;
private File iashome;

/**
* Sets the classpath to be used when compiling the EJB stubs and skeletons.
*
* @param classpath The classpath to be used.
*/
public void setClasspath( Path classpath )
{
if( this.classpath == null )
{
this.classpath = classpath;
}
else
{
this.classpath.append( classpath );
}
}

/**
* Sets whether or not debugging output will be generated when ejbc is
* executed.
*
* @param debug A boolean indicating if debugging output should be generated
*/
public void setDebug( boolean debug )
{
this.debug = debug;
}

/**
* Sets the destination directory where the EJB "source" classes must exist
* and where the stubs and skeletons will be written. The destination
* directory must exist before this task is executed.
*
* @param dest The directory where the compiled classes will be written.
*/
public void setDest( File dest )
{
this.dest = dest;
}

/**
* Sets the location of the standard XML EJB descriptor. Typically, this
* file is named "ejb-jar.xml".
*
* @param ejbdescriptor The name and location of the EJB descriptor.
*/
public void setEjbdescriptor( File ejbdescriptor )
{
this.ejbdescriptor = ejbdescriptor;
}

/**
* Sets the location of the iAS-specific XML EJB descriptor. Typically, this
* file is named "ias-ejb-jar.xml".
*
* @param iasdescriptor The name and location of the iAS-specific EJB
* descriptor.
*/
public void setIasdescriptor( File iasdescriptor )
{
this.iasdescriptor = iasdescriptor;
}

/**
* Setter method used to store the "home" directory of the user's iAS
* installation. The directory specified should typically be <code>[install-location]/iplanet/ias6/ias</code>
* .
*
* @param iashome The home directory for the user's iAS installation.
*/
public void setIashome( File iashome )
{
this.iashome = iashome;
}

/**
* Sets whether or not the Java source files which are generated by the ejbc
* process should be retained or automatically deleted.
*
* @param keepgenerated A boolean indicating if the Java source files for
* the stubs and skeletons should be retained.
*/
public void setKeepgenerated( boolean keepgenerated )
{
this.keepgenerated = keepgenerated;
}

/**
* Creates a nested classpath element.
*
* @return Description of the Returned Value
*/
public Path createClasspath()
{
if( classpath == null )
{
classpath = new Path();
}
Path path1 = classpath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Does the work.
*
* @exception TaskException Description of Exception
*/
public void execute()
throws TaskException
{
checkConfiguration();

executeEjbc( getParser() );
}

/**
* Returns a SAXParser that may be used to process the XML descriptors.
*
* @return Parser which may be used to process the EJB descriptors.
* @throws TaskException If the parser cannot be created or configured.
*/
private SAXParser getParser()
throws TaskException
{

SAXParser saxParser = null;
try
{
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setValidating( true );
saxParser = saxParserFactory.newSAXParser();
}
catch( SAXException e )
{
String msg = "Unable to create a SAXParser: " + e.getMessage();
throw new TaskException( msg, e );
}
catch( ParserConfigurationException e )
{
String msg = "Unable to create a SAXParser: " + e.getMessage();
throw new TaskException( msg, e );
}

return saxParser;
}

/**
* Verifies that the user selections are valid.
*
* @throws TaskException If the user selections are invalid.
*/
private void checkConfiguration()
throws TaskException
{

if( ejbdescriptor == null )
{
String msg = "The standard EJB descriptor must be specified using "
+ "the \"ejbdescriptor\" attribute.";
throw new TaskException( msg );
}
if( ( !ejbdescriptor.exists() ) || ( !ejbdescriptor.isFile() ) )
{
String msg = "The standard EJB descriptor (" + ejbdescriptor
+ ") was not found or isn't a file.";
throw new TaskException( msg );
}

if( iasdescriptor == null )
{
String msg = "The iAS-speific XML descriptor must be specified using"
+ " the \"iasdescriptor\" attribute.";
throw new TaskException( msg );
}
if( ( !iasdescriptor.exists() ) || ( !iasdescriptor.isFile() ) )
{
String msg = "The iAS-specific XML descriptor (" + iasdescriptor
+ ") was not found or isn't a file.";
throw new TaskException( msg );
}

if( dest == null )
{
String msg = "The destination directory must be specified using "
+ "the \"dest\" attribute.";
throw new TaskException( msg );
}
if( ( !dest.exists() ) || ( !dest.isDirectory() ) )
{
String msg = "The destination directory (" + dest + ") was not "
+ "found or isn't a directory.";
throw new TaskException( msg );
}

if( ( iashome != null ) && ( !iashome.isDirectory() ) )
{
String msg = "If \"iashome\" is specified, it must be a valid "
+ "directory (it was set to " + iashome + ").";
throw new TaskException( msg );
}
}

/**
* Executes the EJBc utility using the SAXParser provided.
*
* @param saxParser SAXParser that may be used to process the EJB
* descriptors
* @throws TaskException If there is an error reading or parsing the XML
* descriptors
*/
private void executeEjbc( SAXParser saxParser )
throws TaskException
{
String classpath = null;
if( classpath != null )
{
classpath = this.classpath.toString();
}

IPlanetEjbc ejbc = new IPlanetEjbc( ejbdescriptor,
iasdescriptor,
dest,
classpath,
saxParser );
ejbc.setRetainSource( keepgenerated );
ejbc.setDebugOutput( debug );
if( iashome != null )
{
ejbc.setIasHomeDir( iashome );
}

try
{
ejbc.execute();
}
catch( IOException e )
{
String msg = "An IOException occurred while trying to read the XML "
+ "descriptor file: " + e.getMessage();
throw new TaskException( msg, e );
}
catch( SAXException e )
{
String msg = "A SAXException occurred while trying to read the XML "
+ "descriptor file: " + e.getMessage();
throw new TaskException( msg, e );
}
catch( IPlanetEjbc.EjbcException e )
{
String msg = "An exception occurred while trying to run the ejbc "
+ "utility: " + e.getMessage();
throw new TaskException( msg, e );
}
}
}

+ 0
- 36
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/InnerClassFilenameFilter.java View File

@@ -1,36 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.FilenameFilter;

public class InnerClassFilenameFilter implements FilenameFilter
{
private String baseClassName;

InnerClassFilenameFilter( String baseclass )
{
int extidx = baseclass.lastIndexOf( ".class" );
if( extidx == -1 )
{
extidx = baseclass.length() - 1;
}
baseClassName = baseclass.substring( 0, extidx );
}

public boolean accept( File Dir, String filename )
{
if( ( filename.lastIndexOf( "." ) != filename.lastIndexOf( ".class" ) )
|| ( filename.indexOf( baseClassName + "$" ) != 0 ) )
{
return false;
}
return true;
}
}

+ 0
- 70
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/JbossDeploymentTool.java View File

@@ -1,70 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.util.Hashtable;

/**
* The deployment tool to add the jboss specific deployment descriptor to the
* ejb jar file. Jboss only requires one additional file jboss.xml and does not
* require any additional compilation.
*
* @author <a href="mailto:p.austin@talk21.com">Paul Austin</a>
* @version 1.0
* @see EjbJar#createJboss
*/
public class JbossDeploymentTool extends GenericDeploymentTool
{
protected final static String JBOSS_DD = "jboss.xml";
protected final static String JBOSS_CMPD = "jaws.xml";

/**
* Instance variable that stores the suffix for the jboss jarfile.
*/
private String jarSuffix = ".jar";

/**
* Add any vendor specific files which should be included in the EJB Jar.
*
* @param ejbFiles The feature to be added to the VendorFiles attribute
* @param ddPrefix The feature to be added to the VendorFiles attribute
*/
protected void addVendorFiles( Hashtable ejbFiles, String ddPrefix )
{
File jbossDD = new File( getConfig().descriptorDir, ddPrefix + JBOSS_DD );
if( jbossDD.exists() )
{
ejbFiles.put( META_DIR + JBOSS_DD, jbossDD );
}
else
{
getLogger().warn( "Unable to locate jboss deployment descriptor. It was expected to be in " + jbossDD.getPath() );
return;
}

File jbossCMPD = new File( getConfig().descriptorDir, ddPrefix + JBOSS_CMPD );
if( jbossCMPD.exists() )
{
ejbFiles.put( META_DIR + JBOSS_CMPD, jbossCMPD );
}
}

/**
* Get the vendor specific name of the Jar that will be output. The
* modification date of this jar will be checked against the dependent bean
* classes.
*
* @param baseName Description of Parameter
* @return The VendorOutputJarFile value
*/
File getVendorOutputJarFile( String baseName )
{
return new File( getDestDir(), baseName + jarSuffix );
}
}

+ 0
- 430
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/WLRun.java View File

@@ -1,430 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.types.Path;

/**
* Execute a Weblogic server.
*
* @author <a href="mailto:conor@cortexebusiness.com.au">Conor MacNeill</a> ,
* Cortex ebusiness Pty Limited
*/
public class WLRun extends Task
{
protected final static String DEFAULT_WL51_POLICY_FILE = "weblogic.policy";
protected final static String DEFAULT_WL60_POLICY_FILE = "lib/weblogic.policy";
protected final static String DEFAULT_PROPERTIES_FILE = "weblogic.properties";

private String weblogicMainClass = "weblogic.Server";

/**
* Addional arguments to pass to the JVM used to run weblogic
*/
private String additionalArgs = "";

/**
* The name of the weblogic server - used to select the server's directory
* in the weblogic home directory.
*/
private String weblogicSystemName = "myserver";

/**
* The file containing the weblogic properties for this server.
*/
private String weblogicPropertiesFile = null;

/**
* additional args to pass to the spawned jvm
*/
private String additionalJvmArgs = "";

/**
* The location of the BEA Home under which this server is run. WL6 only
*/
private File beaHome = null;

/**
* The management username
*/
private String managementUsername = "system";

/**
* The management password
*/
private String managementPassword = null;

/**
* The provate key password - used for SSL
*/
private String pkPassword = null;

/**
* The classpath to be used when running the Java VM. It must contain the
* weblogic classes <b>and</b> the implementation classes of the home and
* remote interfaces.
*/
private Path classpath;

/**
* The security policy to use when running the weblogic server
*/
private String securityPolicy;

/**
* The weblogic classpath to the be used when running weblogic.
*/
private Path weblogicClasspath;

/**
* The weblogic domain
*/
private String weblogicDomainName;

/**
* The weblogic system home directory
*/
private File weblogicSystemHome;

public void setArgs( String args )
{
additionalArgs = args;
}

/**
* The location of the BEA Home.
*
* @param beaHome the BEA Home directory.
*/
public void setBEAHome( File beaHome )
{
this.beaHome = beaHome;
}

/**
* Set the classpath to be used for this execution.
*
* @param classpath The new Classpath value
*/
public void setClasspath( Path classpath )
{
this.classpath = classpath;
}

/**
* Set the Domain to run in
*
* @param domain the domain
*/
public void setDomain( String domain )
{
this.weblogicDomainName = domain;
}

/**
* The location where weblogic lives.
*
* @param weblogicHome the home directory of weblogic.
*/
public void setHome( File weblogicHome )
{
weblogicSystemHome = weblogicHome;
}

/**
* Set the additional arguments to pass to the weblogic JVM
*
* @param args the arguments to be passed to the JVM
*/
public void setJvmargs( String args )
{
this.additionalJvmArgs = args;
}

/**
* Set the name of the server to run
*
* @param serverName The new Name value
*/
public void setName( String serverName )
{
this.weblogicSystemName = serverName;
}

/**
* Set the private key password so the server can decrypt the SSL private
* key file.
*
* @param pkpassword the private key password,
*/
public void setPKPassword( String pkpassword )
{
this.pkPassword = pkpassword;
}

/**
* Set the management password of the server
*
* @param password the management pasword of the server.
*/
public void setPassword( String password )
{
this.managementPassword = password;
}

/**
* Set the security policy for this invocation of weblogic.
*
* @param securityPolicy the security policy to use.
*/
public void setPolicy( String securityPolicy )
{
this.securityPolicy = securityPolicy;
}

/**
* Set the properties file to use. The location of the properties file is
* relative to the weblogi system home
*
* @param propertiesFilename the properties file name
*/
public void setProperties( String propertiesFilename )
{
this.weblogicPropertiesFile = propertiesFilename;
}

/**
* Set the management username to run the server
*
* @param username the management username of the server.
*/
public void setUsername( String username )
{
this.managementUsername = username;
}

public void setWeblogicMainClass( String c )
{
weblogicMainClass = c;
}

/**
* Set the weblogic classpath. The weblogic classpath is used by weblogic to
* support dynamic class loading.
*
* @param weblogicClasspath the weblogic classpath
*/
public void setWlclasspath( Path weblogicClasspath )
{
this.weblogicClasspath = weblogicClasspath;
}

/**
* Add the classpath for the user classes
*
* @return Description of the Returned Value
*/
public Path createClasspath()
{
if( classpath == null )
{
classpath = new Path();
}
Path path1 = classpath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Get the classpath to the weblogic classpaths
*
* @return Description of the Returned Value
*/
public Path createWLClasspath()
{
if( weblogicClasspath == null )
{
weblogicClasspath = new Path();
}
Path path1 = weblogicClasspath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Do the work. The work is actually done by creating a separate JVM to run
* a helper task. This approach allows the classpath of the helper task to
* be set. Since the weblogic tools require the class files of the project's
* home and remote interfaces to be available in the classpath, this also
* avoids having to start ant with the class path of the project it is
* building.
*
* @exception TaskException if someting goes wrong with the build
*/
public void execute()
throws TaskException
{
if( weblogicSystemHome == null )
{
throw new TaskException( "weblogic home must be set" );
}
if( !weblogicSystemHome.isDirectory() )
{
throw new TaskException( "weblogic home directory " + weblogicSystemHome.getPath() +
" is not valid" );
}

if( beaHome != null )
{
executeWLS6();
}
else
{
executeWLS();
}
}

private void executeWLS()
throws TaskException
{
File securityPolicyFile = findSecurityPolicyFile( DEFAULT_WL51_POLICY_FILE );
File propertiesFile = null;

if( weblogicPropertiesFile == null )
{
weblogicPropertiesFile = DEFAULT_PROPERTIES_FILE;
}
propertiesFile = new File( weblogicSystemHome, weblogicPropertiesFile );
if( !propertiesFile.exists() )
{
// OK, properties file may be absolute
propertiesFile = getContext().resolveFile( weblogicPropertiesFile );
if( !propertiesFile.exists() )
{
throw new TaskException( "Properties file " + weblogicPropertiesFile +
" not found in weblogic home " + weblogicSystemHome +
" or as absolute file" );
}
}

Java weblogicServer = (Java)getProject().createTask( "java" );
weblogicServer.setFork( true );
weblogicServer.setClassname( weblogicMainClass );

String jvmArgs = additionalJvmArgs;

if( weblogicClasspath != null )
{
jvmArgs += " -Dweblogic.class.path=" + weblogicClasspath;
}

jvmArgs += " -Djava.security.manager -Djava.security.policy==" + securityPolicyFile;
jvmArgs += " -Dweblogic.system.home=" + weblogicSystemHome;
jvmArgs += " -Dweblogic.system.name=" + weblogicSystemName;
jvmArgs += " -Dweblogic.system.propertiesFile=" + weblogicPropertiesFile;

weblogicServer.createJvmarg().setLine( jvmArgs );
weblogicServer.createArg().setLine( additionalArgs );

if( classpath != null )
{
weblogicServer.setClasspath( classpath );
}
if( weblogicServer.executeJava() != 0 )
{
throw new TaskException( "Execution of weblogic server failed" );
}
}

private void executeWLS6()
throws TaskException
{
File securityPolicyFile = findSecurityPolicyFile( DEFAULT_WL60_POLICY_FILE );
if( !beaHome.isDirectory() )
{
throw new TaskException( "BEA home " + beaHome.getPath() +
" is not valid" );
}

File configFile = new File( weblogicSystemHome, "config/" + weblogicDomainName + "/config.xml" );
if( !configFile.exists() )
{
throw new TaskException( "Server config file " + configFile + " not found." );
}

if( managementPassword == null )
{
throw new TaskException( "You must supply a management password to start the server" );
}

Java weblogicServer = (Java)getProject().createTask( "java" );
weblogicServer.setFork( true );
weblogicServer.setDir( weblogicSystemHome );
weblogicServer.setClassname( weblogicMainClass );

String jvmArgs = additionalJvmArgs;

jvmArgs += " -Dweblogic.Domain=" + weblogicDomainName;
jvmArgs += " -Dweblogic.Name=" + weblogicSystemName;
jvmArgs += " -Dweblogic.system.home=" + weblogicSystemHome;

jvmArgs += " -Dbea.home=" + beaHome;
jvmArgs += " -Djava.security.policy==" + securityPolicyFile;

jvmArgs += " -Dweblogic.management.username=" + managementUsername;
jvmArgs += " -Dweblogic.management.password=" + managementPassword;
if( pkPassword != null )
{
jvmArgs += " -Dweblogic.pkpassword=" + pkPassword;
}

weblogicServer.createJvmarg().setLine( jvmArgs );
weblogicServer.createArg().setLine( additionalArgs );

if( classpath != null )
{
weblogicServer.setClasspath( classpath );
}

if( weblogicServer.executeJava() != 0 )
{
throw new TaskException( "Execution of weblogic server failed" );
}
}

private File findSecurityPolicyFile( String defaultSecurityPolicy )
{
String securityPolicy = this.securityPolicy;
if( securityPolicy == null )
{
securityPolicy = defaultSecurityPolicy;
}
File securityPolicyFile = new File( weblogicSystemHome, securityPolicy );
// If an explicit securityPolicy file was specified, it maybe an
// absolute path. Use the project to resolve it.
if( this.securityPolicy != null && !securityPolicyFile.exists() )
{
final String filename = securityPolicy;
securityPolicyFile = getContext().resolveFile( filename );
}
// If we still can't find it, complain
if( !securityPolicyFile.exists() )
{
throw new TaskException( "Security policy " + securityPolicy +
" was not found." );
}
return securityPolicyFile;
}
}

+ 0
- 173
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/WLStop.java View File

@@ -1,173 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.types.Path;

/**
* Shutdown a Weblogic server.
*
* @author <a href="mailto:conor@cortexebusiness.com.au">Conor MacNeill</a> ,
* Cortex ebusiness Pty Limited
*/
public class WLStop extends Task
{

/**
* The delay (in seconds) to wait before shutting down.
*/
private int delay = 0;

/**
* The location of the BEA Home under which this server is run. WL6 only
*/
private File beaHome = null;
/**
* The classpath to be used. It must contains the weblogic.Admin class.
*/
private Path classpath;

/**
* The password to use to shutdown the weblogic server.
*/
private String password;

/**
* The URL which the weblogic server is listening on.
*/
private String serverURL;

/**
* The weblogic username to use to request the shutdown.
*/
private String username;

/**
* The location of the BEA Home.
*
* @param beaHome the BEA Home directory.
*/
public void setBEAHome( File beaHome )
{
this.beaHome = beaHome;
}

/**
* Set the classpath to be used for this compilation.
*
* @param path The new Classpath value
*/
public void setClasspath( Path path )
{
this.classpath = path;
}

/**
* Set the delay (in seconds) before shutting down the server.
*
* @param s the selay.
*/
public void setDelay( String s )
{
delay = Integer.parseInt( s );
}

/**
* Set the password to use to request shutdown of the server.
*
* @param s the password.
*/
public void setPassword( String s )
{
this.password = s;
}

/**
* Set the URL to which the weblogic server is listening.
*
* @param s the url.
*/
public void setUrl( String s )
{
this.serverURL = s;
}

/**
* Set the username to use to request shutdown of the server.
*
* @param s the username.
*/
public void setUser( String s )
{
this.username = s;
}

/**
* Add the classpath for the user classes
*
* @return Description of the Returned Value
*/
public Path createClasspath()
{
if( classpath == null )
{
classpath = new Path();
}
Path path1 = classpath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Do the work. The work is actually done by creating a separate JVM to run
* the weblogic admin task This approach allows the classpath of the helper
* task to be set.
*
* @exception TaskException if someting goes wrong with the build
*/
public void execute()
throws TaskException
{
if( username == null || password == null )
{
throw new TaskException( "weblogic username and password must both be set" );
}

if( serverURL == null )
{
throw new TaskException( "The url of the weblogic server must be provided." );
}

Java weblogicAdmin = (Java)getProject().createTask( "java" );
weblogicAdmin.setFork( true );
weblogicAdmin.setClassname( "weblogic.Admin" );
String args;

if( beaHome == null )
{
args = serverURL + " SHUTDOWN " + username + " " + password + " " + delay;
}
else
{
args = " -url " + serverURL +
" -username " + username +
" -password " + password +
" SHUTDOWN " + " " + delay;
}

weblogicAdmin.setArgs( args );
weblogicAdmin.setClasspath( classpath );
weblogicAdmin.execute();
}

}

+ 0
- 856
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java View File

@@ -1,856 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.avalon.excalibur.io.FileUtil;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.PathUtil;
import org.xml.sax.InputSource;

public class WeblogicDeploymentTool extends GenericDeploymentTool
{
public final static String PUBLICID_EJB11
= "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN";
public final static String PUBLICID_EJB20
= "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN";
public final static String PUBLICID_WEBLOGIC_EJB510
= "-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN";
public final static String PUBLICID_WEBLOGIC_EJB600
= "-//BEA Systems, Inc.//DTD WebLogic 6.0.0 EJB//EN";

protected final static String DEFAULT_WL51_EJB11_DTD_LOCATION
= "/weblogic/ejb/deployment/xml/ejb-jar.dtd";
protected final static String DEFAULT_WL60_EJB11_DTD_LOCATION
= "/weblogic/ejb20/dd/xml/ejb11-jar.dtd";
protected final static String DEFAULT_WL60_EJB20_DTD_LOCATION
= "/weblogic/ejb20/dd/xml/ejb20-jar.dtd";

protected final static String DEFAULT_WL51_DTD_LOCATION
= "/weblogic/ejb/deployment/xml/weblogic-ejb-jar.dtd";
protected final static String DEFAULT_WL60_51_DTD_LOCATION
= "/weblogic/ejb20/dd/xml/weblogic510-ejb-jar.dtd";
protected final static String DEFAULT_WL60_DTD_LOCATION
= "/weblogic/ejb20/dd/xml/weblogic600-ejb-jar.dtd";

protected final static String DEFAULT_COMPILER = "default";

protected final static String WL_DD = "weblogic-ejb-jar.xml";
protected final static String WL_CMP_DD = "weblogic-cmp-rdbms-jar.xml";

protected final static String COMPILER_EJB11 = "weblogic.ejbc";
protected final static String COMPILER_EJB20 = "weblogic.ejbc20";

/**
* Instance variable that stores the suffix for the weblogic jarfile.
*/
private String jarSuffix = ".jar";

/**
* Instance variable that determines whether generic ejb jars are kept.
*/
private boolean keepgenerated = false;

/**
* Instance variable that stores the fully qualified classname of the
* weblogic EJBC compiler
*/
private String ejbcClass = null;

private String additionalArgs = "";

private boolean keepGeneric = false;

private String compiler = null;

private boolean alwaysRebuild = true;

/**
* controls whether ejbc is run on the generated jar
*/
private boolean noEJBC = false;

/**
* Indicates if the old CMP location convention is to be used.
*/
private boolean newCMP = false;

/**
* The classpath to the weblogic classes.
*/
private Path wlClasspath = null;

/**
* The weblogic.StdoutSeverityLevel to use when running the JVM that
* executes ejbc. Set to 16 to avoid the warnings about EJB Home and Remotes
* being in the classpath
*/
private Integer jvmDebugLevel = null;

/**
* Instance variable that stores the location of the ejb 1.1 DTD file.
*/
private String ejb11DTD;

/**
* Instance variable that stores the location of the weblogic DTD file.
*/
private String weblogicDTD;

/**
* sets some additional args to send to ejbc.
*
* @param args The new Args value
*/
public void setArgs( String args )
{
this.additionalArgs = args;
}

/**
* The compiler (switch <code>-compiler</code>) to use
*
* @param compiler The new Compiler value
*/
public void setCompiler( String compiler )
{
this.compiler = compiler;
}

/**
* Setter used to store the location of the Sun's Generic EJB DTD. This can
* be a file on the system or a resource on the classpath.
*
* @param inString the string to use as the DTD location.
*/
public void setEJBdtd( String inString )
{
this.ejb11DTD = inString;
}

/**
* Set the classname of the ejbc compiler
*
* @param ejbcClass The new EjbcClass value
*/
public void setEjbcClass( String ejbcClass )
{
this.ejbcClass = ejbcClass;
}

/**
* Sets the weblogic.StdoutSeverityLevel to use when running the JVM that
* executes ejbc. Set to 16 to avoid the warnings about EJB Home and Remotes
* being in the classpath
*
* @param jvmDebugLevel The new JvmDebugLevel value
*/
public void setJvmDebugLevel( Integer jvmDebugLevel )
{
this.jvmDebugLevel = jvmDebugLevel;
}

/**
* Sets whether -keepgenerated is passed to ejbc (that is, the .java source
* files are kept).
*
* @param inValue either 'true' or 'false'
*/
public void setKeepgenerated( String inValue )
{
this.keepgenerated = Boolean.valueOf( inValue ).booleanValue();
}

/**
* Setter used to store the value of keepGeneric
*
* @param inValue a string, either 'true' or 'false'.
*/
public void setKeepgeneric( boolean inValue )
{
this.keepGeneric = inValue;
}

/**
* Set the value of the newCMP scheme. The old CMP scheme locates the
* weblogic CMP descriptor based on the naming convention where the weblogic
* CMP file is expected to be named with the bean name as the prefix. Under
* this scheme the name of the CMP descriptor does not match the name
* actually used in the main weblogic EJB descriptor. Also, descriptors
* which contain multiple CMP references could not be used.
*
* @param newCMP The new NewCMP value
*/
public void setNewCMP( boolean newCMP )
{
this.newCMP = newCMP;
}

/**
* Do not EJBC the jar after it has been put together.
*
* @param noEJBC The new NoEJBC value
*/
public void setNoEJBC( boolean noEJBC )
{
this.noEJBC = noEJBC;
}

/**
* Set the value of the oldCMP scheme. This is an antonym for newCMP
*
* @param oldCMP The new OldCMP value
*/
public void setOldCMP( boolean oldCMP )
{
this.newCMP = !oldCMP;
}

/**
* Set the rebuild flag to false to only update changes in the jar rather
* than rerunning ejbc
*
* @param rebuild The new Rebuild value
*/
public void setRebuild( boolean rebuild )
{
this.alwaysRebuild = rebuild;
}

/**
* Setter used to store the suffix for the generated weblogic jar file.
*
* @param inString the string to use as the suffix.
*/
public void setSuffix( String inString )
{
this.jarSuffix = inString;
}

public void setWLClasspath( Path wlClasspath )
{
this.wlClasspath = wlClasspath;
}

/**
* Setter used to store the location of the weblogic DTD. This can be a file
* on the system or a resource on the classpath.
*
* @param inString the string to use as the DTD location.
*/
public void setWLdtd( String inString )
{
this.weblogicDTD = inString;
}

/**
* Setter used to store the location of the ejb-jar DTD. This can be a file
* on the system or a resource on the classpath.
*
* @param inString the string to use as the DTD location.
*/
public void setWeblogicdtd( String inString )
{
setEJBdtd( inString );
}

/**
* Get the ejbc compiler class
*
* @return The EjbcClass value
*/
public String getEjbcClass()
{
return ejbcClass;
}

public Integer getJvmDebugLevel()
{
return jvmDebugLevel;
}

/**
* Get the classpath to the weblogic classpaths
*
* @return Description of the Returned Value
*/
public Path createWLClasspath()
{
if( wlClasspath == null )
{
wlClasspath = new Path();
}
Path path1 = wlClasspath;
final Path path = new Path();
path1.addPath( path );
return path;
}

/**
* Called to validate that the tool parameters have been configured.
*
* @exception TaskException Description of Exception
*/
public void validateConfigured()
throws TaskException
{
super.validateConfigured();
}

/**
* Helper method invoked by isRebuildRequired to get a ClassLoader for a Jar
* File passed to it.
*
* @param classjar java.io.File representing jar file to get classes from.
* @return The ClassLoaderFromJar value
* @exception IOException Description of Exception
*/
protected ClassLoader getClassLoaderFromJar( File classjar )
throws IOException, TaskException
{
Path lookupPath = new Path();
lookupPath.setLocation( classjar );

Path classpath = getCombinedClasspath();
if( classpath != null )
{
lookupPath.append( classpath );
}

final URL[] urls = PathUtil.toURLs( lookupPath );
return new URLClassLoader( urls );
}

protected DescriptorHandler getWeblogicDescriptorHandler( final File srcDir )
{
DescriptorHandler handler =
new DescriptorHandler( getTask(), srcDir )
{
protected void processElement()
{
if( currentElement.equals( "type-storage" ) )
{
// Get the filename of vendor specific descriptor
String fileNameWithMETA = currentText;
//trim the META_INF\ off of the file name
String fileName = fileNameWithMETA.substring( META_DIR.length(),
fileNameWithMETA.length() );
File descriptorFile = new File( srcDir, fileName );

ejbFiles.put( fileNameWithMETA, descriptorFile );
}
}
};

handler.registerDTD( PUBLICID_WEBLOGIC_EJB510, DEFAULT_WL51_DTD_LOCATION );
handler.registerDTD( PUBLICID_WEBLOGIC_EJB510, DEFAULT_WL60_51_DTD_LOCATION );
handler.registerDTD( PUBLICID_WEBLOGIC_EJB600, DEFAULT_WL60_DTD_LOCATION );
handler.registerDTD( PUBLICID_WEBLOGIC_EJB510, weblogicDTD );
handler.registerDTD( PUBLICID_WEBLOGIC_EJB600, weblogicDTD );

for( Iterator i = getConfig().dtdLocations.iterator(); i.hasNext(); )
{
EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation)i.next();
handler.registerDTD( dtdLocation.getPublicId(), dtdLocation.getLocation() );
}
return handler;
}

/**
* Helper method to check to see if a weblogic EBJ1.1 jar needs to be
* rebuilt using ejbc. Called from writeJar it sees if the "Bean" classes
* are the only thing that needs to be updated and either updates the Jar
* with the Bean classfile or returns true, saying that the whole weblogic
* jar needs to be regened with ejbc. This allows faster build times for
* working developers. <p>
*
* The way weblogic ejbc works is it creates wrappers for the publicly
* defined methods as they are exposed in the remote interface. If the
* actual bean changes without changing the the method signatures then only
* the bean classfile needs to be updated and the rest of the weblogic jar
* file can remain the same. If the Interfaces, ie. the method signatures
* change or if the xml deployment dicriptors changed, the whole jar needs
* to be rebuilt with ejbc. This is not strictly true for the xml files. If
* the JNDI name changes then the jar doesnt have to be rebuild, but if the
* resources references change then it does. At this point the weblogic jar
* gets rebuilt if the xml files change at all.
*
* @param genericJarFile java.io.File The generic jar file.
* @param weblogicJarFile java.io.File The weblogic jar file to check to see
* if it needs to be rebuilt.
* @return The RebuildRequired value
*/
protected boolean isRebuildRequired( File genericJarFile, File weblogicJarFile )
throws TaskException
{
boolean rebuild = false;

JarFile genericJar = null;
JarFile wlJar = null;
File newWLJarFile = null;
JarOutputStream newJarStream = null;

try
{
getLogger().debug( "Checking if weblogic Jar needs to be rebuilt for jar " + weblogicJarFile.getName() );
// Only go forward if the generic and the weblogic file both exist
if( genericJarFile.exists() && genericJarFile.isFile()
&& weblogicJarFile.exists() && weblogicJarFile.isFile() )
{
//open jar files
genericJar = new JarFile( genericJarFile );
wlJar = new JarFile( weblogicJarFile );

Hashtable genericEntries = new Hashtable();
Hashtable wlEntries = new Hashtable();
Hashtable replaceEntries = new Hashtable();

//get the list of generic jar entries
for( Iterator e = genericJar.entries(); e.hasNext(); )
{
JarEntry je = (JarEntry)e.next();
genericEntries.put( je.getName().replace( '\\', '/' ), je );
}
//get the list of weblogic jar entries
for( Iterator e = wlJar.entries(); e.hasNext(); )
{
JarEntry je = (JarEntry)e.next();
wlEntries.put( je.getName(), je );
}

//Cycle Through generic and make sure its in weblogic
ClassLoader genericLoader = getClassLoaderFromJar( genericJarFile );
for( Iterator e = genericEntries.keys(); e.hasNext(); )
{
String filepath = (String)e.next();
if( wlEntries.containsKey( filepath ) )
{// File name/path match

// Check files see if same
JarEntry genericEntry = (JarEntry)genericEntries.get( filepath );
JarEntry wlEntry = (JarEntry)wlEntries.get( filepath );
if( ( genericEntry.getCrc() != wlEntry.getCrc() ) || // Crc's Match
( genericEntry.getSize() != wlEntry.getSize() ) )
{// Size Match

if( genericEntry.getName().endsWith( ".class" ) )
{
//File are different see if its an object or an interface
String classname = genericEntry.getName().replace( File.separatorChar, '.' );
classname = classname.substring( 0, classname.lastIndexOf( ".class" ) );
Class genclass = genericLoader.loadClass( classname );
if( genclass.isInterface() )
{
//Interface changed rebuild jar.
getLogger().debug( "Interface " + genclass.getName() + " has changed" );
rebuild = true;
break;
}
else
{
//Object class Changed update it.
replaceEntries.put( filepath, genericEntry );
}
}
else
{
// is it the manifest. If so ignore it
if( !genericEntry.getName().equals( "META-INF/MANIFEST.MF" ) )
{
//File other then class changed rebuild
getLogger().debug( "Non class file " + genericEntry.getName() + " has changed" );
rebuild = true;
break;
}
}
}
}
else
{// a file doesnt exist rebuild

getLogger().debug( "File " + filepath + " not present in weblogic jar" );
rebuild = true;
break;
}
}

if( !rebuild )
{
getLogger().debug( "No rebuild needed - updating jar" );
newWLJarFile = new File( weblogicJarFile.getAbsolutePath() + ".temp" );
if( newWLJarFile.exists() )
{
newWLJarFile.delete();
}

newJarStream = new JarOutputStream( new FileOutputStream( newWLJarFile ) );
newJarStream.setLevel( 0 );

//Copy files from old weblogic jar
for( Iterator e = wlEntries.iterator(); e.hasNext(); )
{
byte[] buffer = new byte[ 1024 ];
int bytesRead;
InputStream is;
JarEntry je = (JarEntry)e.next();
if( je.getCompressedSize() == -1 ||
je.getCompressedSize() == je.getSize() )
{
newJarStream.setLevel( 0 );
}
else
{
newJarStream.setLevel( 9 );
}

// Update with changed Bean class
if( replaceEntries.containsKey( je.getName() ) )
{
getLogger().debug( "Updating Bean class from generic Jar " + je.getName() );
// Use the entry from the generic jar
je = (JarEntry)replaceEntries.get( je.getName() );
is = genericJar.getInputStream( je );
}
else
{//use fle from original weblogic jar

is = wlJar.getInputStream( je );
}
newJarStream.putNextEntry( new JarEntry( je.getName() ) );

while( ( bytesRead = is.read( buffer ) ) != -1 )
{
newJarStream.write( buffer, 0, bytesRead );
}
is.close();
}
}
else
{
getLogger().debug( "Weblogic Jar rebuild needed due to changed interface or XML" );
}
}
else
{
rebuild = true;
}
}
catch( ClassNotFoundException cnfe )
{
String cnfmsg = "ClassNotFoundException while processing ejb-jar file"
+ ". Details: "
+ cnfe.getMessage();
throw new TaskException( cnfmsg, cnfe );
}
catch( IOException ioe )
{
String msg = "IOException while processing ejb-jar file "
+ ". Details: "
+ ioe.getMessage();
throw new TaskException( msg, ioe );
}
finally
{
// need to close files and perhaps rename output
if( genericJar != null )
{
try
{
genericJar.close();
}
catch( IOException closeException )
{
}
}

if( wlJar != null )
{
try
{
wlJar.close();
}
catch( IOException closeException )
{
}
}

if( newJarStream != null )
{
try
{
newJarStream.close();
}
catch( IOException closeException )
{
}

weblogicJarFile.delete();
newWLJarFile.renameTo( weblogicJarFile );
if( !weblogicJarFile.exists() )
{
rebuild = true;
}
}
}

return rebuild;
}

/**
* Add any vendor specific files which should be included in the EJB Jar.
*
* @param ejbFiles The feature to be added to the VendorFiles attribute
* @param ddPrefix The feature to be added to the VendorFiles attribute
*/
protected void addVendorFiles( Hashtable ejbFiles, String ddPrefix )
{
File weblogicDD = new File( getConfig().descriptorDir, ddPrefix + WL_DD );

if( weblogicDD.exists() )
{
ejbFiles.put( META_DIR + WL_DD,
weblogicDD );
}
else
{
final String message = "Unable to locate weblogic deployment descriptor. It was expected to be in " +
weblogicDD.getPath();
getLogger().warn( message );
return;
}

if( !newCMP )
{
getLogger().debug( "The old method for locating CMP files has been DEPRECATED." );
getLogger().debug( "Please adjust your weblogic descriptor and set newCMP=\"true\" " + "to use the new CMP descriptor inclusion mechanism. " );
// The the weblogic cmp deployment descriptor
File weblogicCMPDD = new File( getConfig().descriptorDir, ddPrefix + WL_CMP_DD );

if( weblogicCMPDD.exists() )
{
ejbFiles.put( META_DIR + WL_CMP_DD,
weblogicCMPDD );
}
}
else
{
// now that we have the weblogic descriptor, we parse the file
// to find other descriptors needed to deploy the bean.
// this could be the weblogic-cmp-rdbms.xml or any other O/R
// mapping tool descriptors.
try
{
File ejbDescriptor = (File)ejbFiles.get( META_DIR + EJB_DD );
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setValidating( true );
SAXParser saxParser = saxParserFactory.newSAXParser();
DescriptorHandler handler = getWeblogicDescriptorHandler( ejbDescriptor.getParentFile() );
saxParser.parse( new InputSource
( new FileInputStream
( weblogicDD ) ),
handler );

Hashtable ht = handler.getFiles();
Iterator e = ht.keys();
while( e.hasNext() )
{
String key = (String)e.next();
ejbFiles.put( key, ht.get( key ) );
}
}
catch( Exception e )
{
String msg = "Exception while adding Vendor specific files: " + e.toString();
throw new TaskException( msg, e );
}
}
}

protected void registerKnownDTDs( DescriptorHandler handler )
{
// register all the known DTDs
handler.registerDTD( PUBLICID_EJB11, DEFAULT_WL51_EJB11_DTD_LOCATION );
handler.registerDTD( PUBLICID_EJB11, DEFAULT_WL60_EJB11_DTD_LOCATION );
handler.registerDTD( PUBLICID_EJB11, ejb11DTD );
handler.registerDTD( PUBLICID_EJB20, DEFAULT_WL60_EJB20_DTD_LOCATION );
}

/**
* Method used to encapsulate the writing of the JAR file. Iterates over the
* filenames/java.io.Files in the Hashtable stored on the instance variable
* ejbFiles.
*
* @param baseName Description of Parameter
* @param jarFile Description of Parameter
* @param files Description of Parameter
* @param publicId Description of Parameter
* @exception TaskException Description of Exception
*/
protected void writeJar( String baseName, File jarFile, Hashtable files,
String publicId )
throws TaskException
{
// need to create a generic jar first.
File genericJarFile = super.getVendorOutputJarFile( baseName );
super.writeJar( baseName, genericJarFile, files, publicId );

if( alwaysRebuild || isRebuildRequired( genericJarFile, jarFile ) )
{
buildWeblogicJar( genericJarFile, jarFile, publicId );
}
if( !keepGeneric )
{
getLogger().debug( "deleting generic jar " + genericJarFile.toString() );
genericJarFile.delete();
}
}

/**
* Get the vendor specific name of the Jar that will be output. The
* modification date of this jar will be checked against the dependent bean
* classes.
*
* @param baseName Description of Parameter
* @return The VendorOutputJarFile value
*/
File getVendorOutputJarFile( String baseName )
{
return new File( getDestDir(), baseName + jarSuffix );
}

/**
* Helper method invoked by execute() for each WebLogic jar to be built.
* Encapsulates the logic of constructing a java task for calling
* weblogic.ejbc and executing it.
*
* @param sourceJar java.io.File representing the source (EJB1.1) jarfile.
* @param destJar java.io.File representing the destination, WebLogic
* jarfile.
*/
private void buildWeblogicJar( File sourceJar, File destJar, String publicId )
throws TaskException
{
org.apache.tools.ant.taskdefs.Java javaTask = null;

if( noEJBC )
{
try
{
FileUtil.copyFile( sourceJar, destJar );
if( !keepgenerated )
{
sourceJar.delete();
}
return;
}
catch( IOException e )
{
throw new TaskException( "Unable to write EJB jar", e );
}
}

String ejbcClassName = ejbcClass;

try
{
javaTask = (Java)getTask().getProject().createTask( "java" );

if( getJvmDebugLevel() != null )
{
javaTask.createJvmarg().setLine( " -Dweblogic.StdoutSeverityLevel=" + jvmDebugLevel );
}

if( ejbcClassName == null )
{
// try to determine it from publicId
if( PUBLICID_EJB11.equals( publicId ) )
{
ejbcClassName = COMPILER_EJB11;
}
else if( PUBLICID_EJB20.equals( publicId ) )
{
ejbcClassName = COMPILER_EJB20;
}
else
{
getLogger().warn( "Unrecognized publicId " + publicId + " - using EJB 1.1 compiler" );
ejbcClassName = COMPILER_EJB11;
}
}

javaTask.setClassname( ejbcClassName );
javaTask.createArg().setLine( additionalArgs );
if( keepgenerated )
{
javaTask.createArg().setValue( "-keepgenerated" );
}
if( compiler == null )
{
// try to use the compiler specified by build.compiler. Right now we are just going
// to allow Jikes
String buildCompiler = getTask().getContext().getProperty( "build.compiler" ).toString();
if( buildCompiler != null && buildCompiler.equals( "jikes" ) )
{
javaTask.createArg().setValue( "-compiler" );
javaTask.createArg().setValue( "jikes" );
}
}
else
{
if( !compiler.equals( DEFAULT_COMPILER ) )
{
javaTask.createArg().setValue( "-compiler" );
javaTask.createArg().setLine( compiler );
}
}
javaTask.createArg().setValue( sourceJar.getPath() );
javaTask.createArg().setValue( destJar.getPath() );

Path classpath = wlClasspath;
if( classpath == null )
{
classpath = getCombinedClasspath();
}

javaTask.setFork( true );
if( classpath != null )
{
javaTask.setClasspath( classpath );
}

getLogger().debug( "Calling " + ejbcClassName + " for " + sourceJar.toString() );

if( javaTask.executeJava() != 0 )
{
throw new TaskException( "Ejbc reported an error" );
}
}
catch( Exception e )
{
// Have to catch this because of the semantics of calling main()
String msg = "Exception while calling " + ejbcClassName + ". Details: " + e.toString();
throw new TaskException( msg, e );
}
}
}

+ 0
- 105
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicTOPLinkDeploymentTool.java View File

@@ -1,105 +0,0 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.util.Hashtable;
import org.apache.myrmidon.api.TaskException;

public class WeblogicTOPLinkDeploymentTool extends WeblogicDeploymentTool
{

private final static String TL_DTD_LOC = "http://www.objectpeople.com/tlwl/dtd/toplink-cmp_2_5_1.dtd";
private String toplinkDTD;

private String toplinkDescriptor;

/**
* Setter used to store the name of the toplink descriptor.
*
* @param inString the string to use as the descriptor name.
*/
public void setToplinkdescriptor( String inString )
{
this.toplinkDescriptor = inString;
}

/**
* Setter used to store the location of the toplink DTD file. This is
* expected to be an URL (file or otherwise). If running this on NT using a
* file URL, the safest thing would be to not use a drive spec in the URL
* and make sure the file resides on the drive that ANT is running from.
* This will keep the setting in the build XML platform independent.
*
* @param inString the string to use as the DTD location.
*/
public void setToplinkdtd( String inString )
{
this.toplinkDTD = inString;
}

/**
* Called to validate that the tool parameters have been configured.
*
* @exception TaskException Description of Exception
*/
public void validateConfigured()
throws TaskException
{
super.validateConfigured();
if( toplinkDescriptor == null )
{
throw new TaskException( "The toplinkdescriptor attribute must be specified" );
}
}

protected DescriptorHandler getDescriptorHandler( File srcDir )
{
DescriptorHandler handler = super.getDescriptorHandler( srcDir );
if( toplinkDTD != null )
{
handler.registerDTD( "-//The Object People, Inc.//DTD TOPLink for WebLogic CMP 2.5.1//EN",
toplinkDTD );
}
else
{
handler.registerDTD( "-//The Object People, Inc.//DTD TOPLink for WebLogic CMP 2.5.1//EN",
TL_DTD_LOC );
}
return handler;
}

/**
* Add any vendor specific files which should be included in the EJB Jar.
*
* @param ejbFiles The feature to be added to the VendorFiles attribute
* @param ddPrefix The feature to be added to the VendorFiles attribute
*/
protected void addVendorFiles( Hashtable ejbFiles, String ddPrefix )
{
super.addVendorFiles( ejbFiles, ddPrefix );
// Then the toplink deployment descriptor

// Setup a naming standard here?.


File toplinkDD = new File( getConfig().descriptorDir, ddPrefix + toplinkDescriptor );

if( toplinkDD.exists() )
{
ejbFiles.put( META_DIR + toplinkDescriptor,
toplinkDD );
}
else
{
final String message = "Unable to locate toplink deployment descriptor. It was expected to be in " +
toplinkDD.getPath();
getLogger().warn( message );
}
}
}

+ 0
- 1035
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java
File diff suppressed because it is too large
View File


Loading…
Cancel
Save