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