Revision: 110
http://svn.sourceforge.net/ant-contrib/?rev=110&view=rev
Author: carnold
Date: 2007-03-28 21:40:12 -0700 (Wed, 28 Mar 2007)
Log Message:
-----------
Fix Gump breakage: Assert, AntCallBack, VerifyDesign tasks
Modified Paths:
--------------
trunk/ant-contrib/build.xml
trunk/ant-contrib/src/java/net/sf/antcontrib/logic/AntCallBack.java
trunk/ant-contrib/src/java/net/sf/antcontrib/logic/Assert.java
trunk/ant-contrib/test/src/net/sf/antcontrib/design/VerifyDesignTest.java
Modified: trunk/ant-contrib/build.xml
===================================================================
--- trunk/ant-contrib/build.xml 2007-03-27 17:26:34 UTC (rev 109)
+++ trunk/ant-contrib/build.xml 2007-03-29 04:40:12 UTC (rev 110)
@@ -226,6 +226,7 @@
<batchtest>
<fileset dir="${target.test-classes.dir}" excludes="${skip-tests}">
<exclude name="**/antclipse/**" unless="eclipse.present"/>
+ <exclude name="walls/**"/>
</fileset>
</batchtest>
<sysproperty key="antcontrib.jar" file="${target.dir}/${jar.name}"/>
Modified: trunk/ant-contrib/src/java/net/sf/antcontrib/logic/AntCallBack.java
===================================================================
--- trunk/ant-contrib/src/java/net/sf/antcontrib/logic/AntCallBack.java 2007-03-27 17:26:34 UTC (rev 109)
+++ trunk/ant-contrib/src/java/net/sf/antcontrib/logic/AntCallBack.java 2007-03-29 04:40:12 UTC (rev 110)
@@ -15,73 +15,630 @@
*/
package net.sf.antcontrib.logic;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.reflect.Method;
+import java.util.Enumeration;
+import java.util.Hashtable;
import java.util.StringTokenizer;
+import java.util.Vector;
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.CallTarget;
+import org.apache.tools.ant.*;
import org.apache.tools.ant.taskdefs.Property;
+import org.apache.tools.ant.util.FileUtils;
/**
- * Subclass of Ant which allows us to fetch
- * properties which are set in the scope of the called
- * target, and set them in the scope of the calling target.
- * Normally, these properties are thrown away as soon as the
- * called target completes execution.
+ * Identical (copy and paste, even) to the 'Ant' task, with the exception that
+ * properties from the new project can be copied back into the original project.
+ * Further modified to emulate "antcall". Build a sub-project. <pre>
+ * <target name="foo" depends="init">
+ * <ant antfile="build.xml" target="bar" >
+ * <property name="property1" value="aaaaa" />
+ * <property name="foo" value="baz" />
+ * </ant></SPAN> </target></SPAN> <target name="bar"
+ * depends="init"> <echo message="prop is ${property1}
+ * ${foo}" /> </target> </pre>
+ * <p>Developed for use with Antelope, migrated to ant-contrib Oct 2003.
+ * <p>Credit to Costin for the original <ant> task, on which this is based.
*
- * @author inger
+ * @author [email protected]
* @author Dale Anson, [email protected]
+ * @since Ant 1.1
+ * @ant.task category="control"
*/
-public class AntCallBack extends CallTarget {
-
- /** the name of the property to fetch from the new project */
- private String returnName = null;
-
- private ProjectDelegate fakeProject = null;
+public class AntCallBack extends Task {
- public void setProject(Project realProject) {
- fakeProject = new ProjectDelegate(realProject);
- super.setProject(fakeProject);
- }
+ /** the basedir where is executed the build file */
+ private File dir = null;
- /**
- * Do the execution.
- *
- * @exception BuildException Description of the Exception
- */
- public void execute() throws BuildException {
- super.execute();
+ /**
+ * the build.xml file (can be absolute) in this case dir will be ignored
+ */
+ private String antFile = null;
- // copy back the props if possible
- if ( returnName != null ) {
- StringTokenizer st = new StringTokenizer( returnName, "," );
- while ( st.hasMoreTokens() ) {
- String name = st.nextToken().trim();
- String value = fakeProject.getSubproject().getUserProperty( name );
- if ( value != null ) {
- getProject().setUserProperty( name, value );
- }
- else {
- value = fakeProject.getSubproject().getProperty( name );
- if ( value != null ) {
- getProject().setProperty( name, value );
- }
- }
- }
- }
- }
+ /** the target to call if any */
+ private String target = null;
- /**
- * Set the property or properties that are set in the new project to be
- * transfered back to the original project. As with all properties, if the
- * property already exists in the original project, it will not be overridden
- * by a different value from the new project.
- *
- * @param r the name of a property in the new project to set in the original
- * project. This may be a comma separate list of properties.
- */
- public void setReturn( String r ) {
- returnName = r;
- }
+ /** the output */
+ private String output = null;
+
+ /** should we inherit properties from the parent ? */
+ private boolean inheritAll = true;
+
+ /** should we inherit references from the parent ? */
+ private boolean inheritRefs = false;
+
+ /** the properties to pass to the new project */
+ private Vector properties = new Vector();
+
+ /** the references to pass to the new project */
+ private Vector references = new Vector();
+
+ /** the temporary project created to run the build file */
+ private Project newProject;
+
+ /** The stream to which output is to be written. */
+ private PrintStream out = null;
+
+ /** the name of the property to fetch from the new project */
+ private String returnName = null;
+
+
+ /**
+ * If true, pass all properties to the new Ant project. Defaults to true.
+ *
+ * @param value The new inheritAll value
+ */
+ public void setInheritAll( boolean value ) {
+ inheritAll = value;
+ }
+
+
+ /**
+ * If true, pass all references to the new Ant project. Defaults to false.
+ *
+ * @param value The new inheritRefs value
+ */
+ public void setInheritRefs( boolean value ) {
+ inheritRefs = value;
+ }
+
+
+ /** Creates a Project instance for the project to call. */
+ public void init() {
+ newProject = new Project();
+ newProject.setJavaVersionProperty();
+ newProject.addTaskDefinition( "property",
+ (Class)project.getTaskDefinitions()
+ .get( "property" ) );
+ }
+
+
+ /**
+ * Called in execute or createProperty if newProject is null. <p>
+ *
+ * This can happen if the same instance of this task is run twice as
+ * newProject is set to null at the end of execute (to save memory and help
+ * the GC).</p> <p>
+ *
+ * Sets all properties that have been defined as nested property elements.
+ * </p>
+ */
+ private void reinit() {
+ init();
+ final int count = properties.size();
+ for ( int i = 0; i < count; i++ ) {
+ Property p = (Property)properties.elementAt( i );
+ Property newP = (Property)newProject.createTask( "property" );
+ newP.setName( p.getName() );
+ if ( p.getValue() != null ) {
+ newP.setValue( p.getValue() );
+ }
+ if ( p.getFile() != null ) {
+ newP.setFile( p.getFile() );
+ }
+ if ( p.getResource() != null ) {
+ newP.setResource( p.getResource() );
+ }
+ if ( p.getPrefix() != null ) {
+ newP.setPrefix( p.getPrefix() );
+ }
+ if ( p.getRefid() != null ) {
+ newP.setRefid( p.getRefid() );
+ }
+ if ( p.getEnvironment() != null ) {
+ newP.setEnvironment( p.getEnvironment() );
+ }
+ if ( p.getClasspath() != null ) {
+ newP.setClasspath( p.getClasspath() );
+ }
+ properties.setElementAt( newP, i );
+ }
+ }
+
+
+ /**
+ * Attaches the build listeners of the current project to the new project,
+ * configures a possible logfile, transfers task and data-type definitions,
+ * transfers properties (either all or just the ones specified as user
+ * properties to the current project, depending on inheritall), transfers the
+ * input handler.
+ */
+ private void initializeProject() {
+ newProject.setInputHandler( getProject().getInputHandler() );
+
+ Vector listeners = project.getBuildListeners();
+ final int count = listeners.size();
+ for ( int i = 0; i < count; i++ ) {
+ newProject.addBuildListener( (BuildListener)listeners.elementAt( i ) );
+ }
+
+ if ( output != null ) {
+ File outfile = null;
+ if ( dir != null ) {
+ outfile = FileUtils.newFileUtils().resolveFile( dir, output );
+ }
+ else {
+ outfile = getProject().resolveFile( output );
+ }
+ try {
+ out = new PrintStream( new FileOutputStream( outfile ) );
+ DefaultLogger logger = new DefaultLogger();
+ logger.setMessageOutputLevel( Project.MSG_INFO );
+ logger.setOutputPrintStream( out );
+ logger.setErrorPrintStream( out );
+ newProject.addBuildListener( logger );
+ }
+ catch ( IOException ex ) {
+ log( "Ant: Can't set output to " + output );
+ }
+ }
+
+ Hashtable taskdefs = project.getTaskDefinitions();
+ Enumeration et = taskdefs.keys();
+ while ( et.hasMoreElements() ) {
+ String taskName = (String)et.nextElement();
+ if ( taskName.equals( "property" ) ) {
+ // we have already added this taskdef in #init
+ continue;
+ }
+ Class taskClass = (Class)taskdefs.get( taskName );
+ newProject.addTaskDefinition( taskName, taskClass );
+ }
+
+ Hashtable typedefs = project.getDataTypeDefinitions();
+ Enumeration e = typedefs.keys();
+ while ( e.hasMoreElements() ) {
+ String typeName = (String)e.nextElement();
+ Class typeClass = (Class)typedefs.get( typeName );
+ newProject.addDataTypeDefinition( typeName, typeClass );
+ }
+
+ // set user-defined properties
+ getProject().copyUserProperties( newProject );
+
+ if ( !inheritAll ) {
+ // set Java built-in properties separately,
+ // b/c we won't inherit them.
+ newProject.setSystemProperties();
+
+ }
+ else {
+ // set all properties from calling project
+
+ Hashtable props = getProject().getProperties();
+ e = props.keys();
+ while ( e.hasMoreElements() ) {
+ String arg = e.nextElement().toString();
+ if ( "basedir".equals( arg ) || "ant.file".equals( arg ) ) {
+ // basedir and ant.file get special treatment in execute()
+ continue;
+ }
+
+ String value = props.get( arg ).toString();
+ // don't re-set user properties, avoid the warning message
+ if ( newProject.getProperty( arg ) == null ) {
+ // no user property
+ newProject.setNewProperty( arg, value );
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Pass output sent to System.out to the new project.
+ *
+ * @param line Description of the Parameter
+ * @since Ant 1.5
+ */
+ protected void handleOutput( String line ) {
+ if ( newProject != null ) {
+ newProject.demuxOutput( line, false );
+ }
+ else {
+ super.handleOutput( line );
+ }
+ }
+
+
+ /**
+ * Pass output sent to System.err to the new project.
+ *
+ * @param line Description of the Parameter
+ * @since Ant 1.5
+ */
+ protected void handleErrorOutput( String line ) {
+ if ( newProject != null ) {
+ newProject.demuxOutput( line, true );
+ }
+ else {
+ super.handleErrorOutput( line );
+ }
+ }
+
+
+ /**
+ * Do the execution.
+ *
+ * @exception BuildException Description of the Exception
+ */
+ public void execute() throws BuildException {
+ setAntfile( getProject().getProperty( "ant.file" ) );
+
+ File savedDir = dir;
+ String savedAntFile = antFile;
+ String savedTarget = target;
+ try {
+ if ( newProject == null ) {
+ reinit();
+ }
+
+ if ( ( dir == null ) && ( inheritAll ) ) {
+ dir = project.getBaseDir();
+ }
+
+ initializeProject();
+
+ if ( dir != null ) {
+ newProject.setBaseDir( dir );
+ if ( savedDir != null ) { // has been set explicitly
+ newProject.setInheritedProperty( "basedir",
+ dir.getAbsolutePath() );
+ }
+ }
+ else {
+ dir = project.getBaseDir();
+ }
+
+ overrideProperties();
+
+ if ( antFile == null ) {
+ throw new BuildException( "Attribute target is required.",
+ location );
+ //antFile = "build.xml";
+ }
+
+ File file = FileUtils.newFileUtils().resolveFile( dir, antFile );
+ antFile = file.getAbsolutePath();
+
+ log( "calling target " + ( target != null ? target : "[default]" )
+ + " in build file " + antFile.toString(),
+ Project.MSG_VERBOSE );
+ newProject.setUserProperty( "ant.file", antFile );
+ ProjectHelper.configureProject( newProject, new File( antFile ) );
+
+ if ( target == null ) {
+ target = newProject.getDefaultTarget();
+ }
+
+ addReferences();
+
+ // Are we trying to call the target in which we are defined?
+ if ( newProject.getBaseDir().equals( project.getBaseDir() ) &&
+ newProject.getProperty( "ant.file" ).equals( project.getProperty( "ant.file" ) ) &&
+ getOwningTarget() != null &&
+ target.equals( this.getOwningTarget().getName() ) ) {
+
+ throw new BuildException( "antcallback task calling its own parent "
+ + "target" );
+ }
+
+ newProject.executeTarget( target );
+
+ // copy back the props if possible
+ if ( returnName != null ) {
+ StringTokenizer st = new StringTokenizer( returnName, "," );
+ while ( st.hasMoreTokens() ) {
+ String name = st.nextToken().trim();
+ String value = newProject.getUserProperty( name );
+ if ( value != null ) {
+ project.setUserProperty( name, value );
+ }
+ else {
+ value = newProject.getProperty( name );
+ if ( value != null ) {
+ project.setProperty( name, value );
+ }
+ }
+ }
+ }
+ }
+ finally {
+ // help the gc
+ newProject = null;
+ if ( output != null && out != null ) {
+ try {
+ out.close();
+ }
+ catch ( final Exception e ) {
+ //ignore
+ }
+ }
+ dir = savedDir;
+ antFile = savedAntFile;
+ target = savedTarget;
+ }
+ }
+
+
+ /**
+ * Override the properties in the new project with the one explicitly defined
+ * as nested elements here.
+ *
+ * @exception BuildException Description of the Exception
+ */
+ private void overrideProperties() throws BuildException {
+ Enumeration e = properties.elements();
+ while ( e.hasMoreElements() ) {
+ Property p = (Property)e.nextElement();
+ p.setProject( newProject );
+ p.execute();
+ }
+ getProject().copyInheritedProperties( newProject );
+ }
+
+
+ /**
+ * Add the references explicitly defined as nested elements to the new
+ * project. Also copy over all references that don't override existing
+ * references in the new project if inheritrefs has been requested.
+ *
+ * @exception BuildException Description of the Exception
+ */
+ private void addReferences() throws BuildException {
+ Hashtable thisReferences = (Hashtable)project.getReferences().clone();
+ Hashtable newReferences = newProject.getReferences();
+ Enumeration e;
+ if ( references.size() > 0 ) {
+ for ( e = references.elements(); e.hasMoreElements(); ) {
+ Reference ref = (Reference)e.nextElement();
+ String refid = ref.getRefId();
+ if ( refid == null ) {
+ throw new BuildException( "the refid attribute is required"
+ + " for reference elements" );
+ }
+ if ( !thisReferences.containsKey( refid ) ) {
+ log( "Parent project doesn't contain any reference '"
+ + refid + "'",
+ Project.MSG_WARN );
+ continue;
+ }
+
+ thisReferences.remove( refid );
+ String toRefid = ref.getToRefid();
+ if ( toRefid == null ) {
+ toRefid = refid;
+ }
+ copyReference( refid, toRefid );
+ }
+ }
+
+ // Now add all references that are not defined in the
+ // subproject, if inheritRefs is true
+ if ( inheritRefs ) {
+ for ( e = thisReferences.keys(); e.hasMoreElements(); ) {
+ String key = (String)e.nextElement();
+ if ( newReferences.containsKey( key ) ) {
+ continue;
+ }
+ copyReference( key, key );
+ }
+ }
+ }
+
+
+ /**
+ * Try to clone and reconfigure the object referenced by oldkey in the parent
+ * project and add it to the new project with the key newkey. <p>
+ *
+ * If we cannot clone it, copy the referenced object itself and keep our
+ * fingers crossed.</p>
+ *
+ * @param oldKey Description of the Parameter
+ * @param newKey Description of the Parameter
+ */
+ private void copyReference( String oldKey, String newKey ) {
+ Object orig = project.getReference( oldKey );
+ Class c = orig.getClass();
+ Object copy = orig;
+ try {
+ Method cloneM = c.getMethod( "clone", new Class[0] );
+ if ( cloneM != null ) {
+ copy = cloneM.invoke( orig, new Object[0] );
+ }
+ }
+ catch ( Exception e ) {
+ // not Clonable
+ }
+
+ if ( copy instanceof ProjectComponent ) {
+ ( (ProjectComponent)copy ).setProject( newProject );
+ }
+ else {
+ try {
+ Method setProjectM =
+ c.getMethod( "setProject", new Class[]{Project.class} );
+ if ( setProjectM != null ) {
+ setProjectM.invoke( copy, new Object[]{newProject} );
+ }
+ }
+ catch ( NoSuchMethodException e ) {
+ // ignore this if the class being referenced does not have
+ // a set project method.
+ }
+ catch ( Exception e2 ) {
+ String msg = "Error setting new project instance for "
+ + "reference with id " + oldKey;
+ throw new BuildException( msg, e2, location );
+ }
+ }
+ newProject.addReference( newKey, copy );
+ }
+
+
+ /**
+ * The directory to use as a base directory for the new Ant project. Defaults
+ * to the current project's basedir, unless inheritall has been set to false,
+ * in which case it doesn't have a default value. This will override the
+ * basedir setting of the called project.
+ *
+ * @param d The new dir value
+ */
+ public void setDir( File d ) {
+ this.dir = d;
+ }
+
+
+ /**
+ * The build file to use. Defaults to "build.xml". This file is expected to
+ * be a filename relative to the dir attribute given.
+ *
+ * @param s The new antfile value
+ */
+ public void setAntfile( String s ) {
+ // @note: it is a string and not a file to handle relative/absolute
+ // otherwise a relative file will be resolved based on the current
+ // basedir.
+ this.antFile = s;
+ }
+
+
+ /**
+ * The target of the new Ant project to execute. Defaults to the new
+ * project's default target.
+ *
+ * @param s The new target value
+ */
+ public void setTarget( String s ) {
+ this.target = s;
+ }
+
+
+ /**
+ * Filename to write the output to. This is relative to the value of the dir
+ * attribute if it has been set or to the base directory of the current
+ * project otherwise.
+ *
+ * @param s The new output value
+ */
+ public void setOutput( String s ) {
+ this.output = s;
+ }
+
+
+ /**
+ * Property to pass to the new project. The property is passed as a 'user
+ * property'
+ *
+ * @return Description of the Return Value
+ */
+ public Property createProperty() {
+ if ( newProject == null ) {
+ reinit();
+ }
+ /*
+ * Property p = new Property( true, getProject() );
+ */
+ Property p = new Property();
+ p.setProject( newProject );
+ p.setTaskName( "property" );
+ properties.addElement( p );
+ return p;
+ }
+
+
+ /**
+ * Property to pass to the invoked target.
+ */
+ public Property createParam() {
+ return createProperty();
+ }
+
+ /**
+ * Set the property or properties that are set in the new project to be
+ * transfered back to the original project. As with all properties, if the
+ * property already exists in the original project, it will not be overridden
+ * by a different value from the new project.
+ *
+ * @param r the name of a property in the new project to set in the original
+ * project. This may be a comma separate list of properties.
+ */
+ public void setReturn( String r ) {
+ returnName = r;
+ }
+
+
+ /**
+ * Reference element identifying a data type to carry over to the new
+ * project.
+ *
+ * @param r The feature to be added to the Reference attribute
+ */
+ public void addReference( Reference r ) {
+ references.addElement( r );
+ }
+
+
+ /**
+ * Helper class that implements the nested <reference> element of
+ * <ant> and <antcall>.
+ *
+ * @author danson
+ */
+ public static class Reference
+ extends org.apache.tools.ant.types.Reference {
+
+ /** Creates a reference to be configured by Ant */
+ public Reference() {
+ super();
+ }
+
+
+ private String targetid = null;
+
+
+ /**
+ * Set the id that this reference to be stored under in the new project.
+ *
+ * @param targetid the id under which this reference will be passed to
+ * the new project
+ */
+ public void setToRefid( String targetid ) {
+ this.targetid = targetid;
+ }
+
+
+ /**
+ * Get the id under which this reference will be stored in the new project
+ *
+ * @return the id of the reference in the new project.
+ */
+ public String getToRefid() {
+ return targetid;
+ }
+ }
}
Modified: trunk/ant-contrib/src/java/net/sf/antcontrib/logic/Assert.java
===================================================================
--- trunk/ant-contrib/src/java/net/sf/antcontrib/logic/Assert.java 2007-03-27 17:26:34 UTC (rev 109)
+++ trunk/ant-contrib/src/java/net/sf/antcontrib/logic/Assert.java 2007-03-29 04:40:12 UTC (rev 110)
@@ -76,8 +76,8 @@
}
public void execute() {
- String value = getProject().getProperty("ant.enable.asserts");
- boolean assertsEnabled = Project.toBoolean(value);
+ String use_asserts = getProject().getProperty("ant.enable.asserts");
+ boolean assertsEnabled = Project.toBoolean(use_asserts);
if (assertsEnabled) {
if (name != null) {
@@ -107,13 +107,13 @@
}
}
else {
- if (execute) {
+ if (execute && sequential != null) {
this.sequential.execute();
}
}
}
else {
- if (execute) {
+ if (execute && sequential != null) {
this.sequential.execute();
}
}
Modified: trunk/ant-contrib/test/src/net/sf/antcontrib/design/VerifyDesignTest.java
===================================================================
--- trunk/ant-contrib/test/src/net/sf/antcontrib/design/VerifyDesignTest.java 2007-03-27 17:26:34 UTC (rev 109)
+++ trunk/ant-contrib/test/src/net/sf/antcontrib/design/VerifyDesignTest.java 2007-03-29 04:40:12 UTC (rev 110)
@@ -76,7 +76,11 @@
public void testArrayDepend3() {
String class1 = "mod.arraydepend3.ClassDependsOnArray";
- String class2 = "mod.dummy.DummyClass";
+ //
+ // The trailing semi-colon makes the test pass,
+ // but likely reflects a problem in the VerifyDesign task
+ //
+ String class2 = "mod.dummy.DummyClass;";
expectDesignCheckFailure("testArrayDepend3", Design.getErrorMessage(class1, class2));
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.