git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271481 13f79535-47bb-0310-9956-ffa450edef68master
@@ -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> | |||
* | |||
* <ejbjar srcdir="${build.classes}" basejarname="vsmp" descriptordir="${rsc.dir}/hrmanager"> | |||
* <borland destdir="tstlib"> | |||
* <classpath refid="classpath" /> | |||
* </borland> | |||
* <include name="**\ejb-jar.xml"/> | |||
* <support dir="${build.classes}"> | |||
* <include name="demo\smp\*.class"/> | |||
* <include name="demo\helper\*.class"/> | |||
* </support> | |||
* </ejbjar> | |||
*</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 ); | |||
} | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} | |||
} |
@@ -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" ); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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 <ejb-name> | |||
* 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 <ejb-name> 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(); | |||
} | |||
} | |||
} | |||
} |
@@ -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 ); | |||
} |
@@ -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() | |||
} | |||
@@ -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" ); | |||
} | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} | |||
} |
@@ -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> | |||
* | |||
* <ejbjar srcdir="${build.classes}" basejarname="vsmp" descriptordir="${rsc.dir}/hrmanager"> | |||
* <borland destdir="tstlib"> | |||
* <classpath refid="classpath" /> | |||
* </borland> | |||
* <include name="**\ejb-jar.xml"/> | |||
* <support dir="${build.classes}"> | |||
* <include name="demo\smp\*.class"/> | |||
* <include name="demo\helper\*.class"/> | |||
* </support> | |||
* </ejbjar> | |||
*</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 ); | |||
} | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} | |||
} |
@@ -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" ); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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 <ejb-name> | |||
* 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 <ejb-name> 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(); | |||
} | |||
} | |||
} | |||
} |
@@ -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 ); | |||
} |
@@ -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() | |||
} | |||
@@ -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" ); | |||
} | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} | |||
} |
@@ -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 ); | |||
} | |||
} | |||
} |