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