Browse Source

Started removing methods that are no longer used.

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@270215 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 24 years ago
parent
commit
c76e3274d1
2 changed files with 4 additions and 1692 deletions
  1. +2
    -846
      proposal/myrmidon/src/main/org/apache/tools/ant/Project.java
  2. +2
    -846
      proposal/myrmidon/src/todo/org/apache/tools/ant/Project.java

+ 2
- 846
proposal/myrmidon/src/main/org/apache/tools/ant/Project.java View File

@@ -8,12 +8,9 @@
package org.apache.tools.ant; package org.apache.tools.ant;


import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Properties;
import java.util.Stack; import java.util.Stack;
import java.util.Vector; import java.util.Vector;
import org.apache.myrmidon.api.TaskException; import org.apache.myrmidon.api.TaskException;
@@ -171,78 +168,6 @@ public class Project
return path.toString(); return path.toString();
} }


private static TaskException makeCircularException( String end, Stack stk )
{
StringBuffer sb = new StringBuffer( "Circular dependency: " );
sb.append( end );
String c;
do
{
c = (String)stk.pop();
sb.append( " <- " );
sb.append( c );
} while( !c.equals( end ) );
return new TaskException( new String( sb ) );
}

/**
* set the base directory; XML attribute. checks for the directory existing
* and being a directory type
*
* @param baseDir project base directory.
* @throws TaskException if the directory was invalid
*/
public void setBaseDir( File baseDir )
throws TaskException
{
baseDir = FileUtils.newFileUtils().normalize( baseDir.getAbsolutePath() );
if( !baseDir.exists() )
throw new TaskException( "Basedir " + baseDir.getAbsolutePath() + " does not exist" );
if( !baseDir.isDirectory() )
throw new TaskException( "Basedir " + baseDir.getAbsolutePath() + " is not a directory" );
this.baseDir = baseDir;
setPropertyInternal( "basedir", this.baseDir.getPath() );
String msg = "Project base dir set to: " + this.baseDir;
log( msg, MSG_VERBOSE );
}

/**
* match basedir attribute in xml
*
* @param baseD project base directory.
* @throws TaskException if the directory was invalid
*/
public void setBasedir( String baseD )
throws TaskException
{
setBaseDir( new File( baseD ) );
}

public void setCoreLoader( ClassLoader coreLoader )
{
this.coreLoader = coreLoader;
}

/**
* set the default target of the project XML attribute name.
*
* @param defaultTarget The new Default value
*/
public void setDefault( String defaultTarget )
{
this.defaultTarget = defaultTarget;
}

/**
* set the project description
*
* @param description text
*/
public void setDescription( String description )
{
this.description = description;
}

/** /**
* set the ant.java.version property, also tests for unsupported JVM * set the ant.java.version property, also tests for unsupported JVM
* versions, prints the verbose log messages * versions, prints the verbose log messages
@@ -265,18 +190,6 @@ public class Project
log( "Detected OS: " + System.getProperty( "os.name" ), MSG_VERBOSE ); log( "Detected OS: " + System.getProperty( "os.name" ), MSG_VERBOSE );
} }


/**
* ant xml property. Set the project name as an attribute of this class, and
* of the property ant.project.name
*
* @param name The new Name value
*/
public void setName( String name )
{
setUserProperty( "ant.project.name", name );
this.name = name;
}

/** /**
* set a property. An existing property of the same name will not be * set a property. An existing property of the same name will not be
* overwritten. * overwritten.
@@ -297,65 +210,6 @@ public class Project
properties.put( name, value ); properties.put( name, value );
} }


/**
* set a property. Any existing property of the same name is overwritten,
* unless it is a user property.
*
* @param name name of property
* @param value new value of the property
*/
public void setProperty( String name, String value )
{
// command line properties take precedence
if( null != userProperties.get( name ) )
{
log( "Override ignored for user property " + name, MSG_VERBOSE );
return;
}

if( null != properties.get( name ) )
{
log( "Overriding previous definition of property " + name,
MSG_VERBOSE );
}

log( "Setting project property: " + name + " -> " +
value, MSG_DEBUG );
properties.put( name, value );
}

/**
* turn all the system properties into ant properties. user properties still
* override these values
*/
public void setSystemProperties()
{
Properties systemP = System.getProperties();
Enumeration e = systemP.keys();
while( e.hasMoreElements() )
{
Object name = e.nextElement();
String value = systemP.get( name ).toString();
this.setPropertyInternal( name.toString(), value );
}
}

/**
* set a user property, which can not be overwritten by set/unset property
* calls
*
* @param name The new UserProperty value
* @param value The new UserProperty value
* @see #setProperty(String,String)
*/
public void setUserProperty( String name, String value )
{
log( "Setting ro project property: " + name + " -> " +
value, MSG_DEBUG );
userProperties.put( name, value );
properties.put( name, value );
}

/** /**
* get the base directory of the project as a file object * get the base directory of the project as a file object
* *
@@ -364,25 +218,9 @@ public class Project
*/ */
public File getBaseDir() public File getBaseDir()
{ {
if( baseDir == null )
{
try
{
setBasedir( "." );
}
catch( TaskException ex )
{
ex.printStackTrace();
}
}
return baseDir; return baseDir;
} }


public Vector getBuildListeners()
{
return listeners;
}

public ClassLoader getCoreLoader() public ClassLoader getCoreLoader()
{ {
return coreLoader; return coreLoader;
@@ -398,41 +236,11 @@ public class Project
return dataClassDefinitions; return dataClassDefinitions;
} }


/**
* get the default target of the project
*
* @return default target or null
*/
public String getDefaultTarget()
{
return defaultTarget;
}

/**
* get the project description
*
* @return description or null if no description has been set
*/
public String getDescription()
{
return description;
}

public FilterSet getGlobalFilterSet() public FilterSet getGlobalFilterSet()
{ {
return globalFilterSet; return globalFilterSet;
} }


/**
* get the project name
*
* @return name string
*/
public String getName()
{
return name;
}

/** /**
* get a copy of the property hashtable * get a copy of the property hashtable
* *
@@ -501,314 +309,11 @@ public class Project
return taskClassDefinitions; return taskClassDefinitions;
} }


/**
* get a copy of the user property hashtable
*
* @return the hashtable user properties only
*/
public Hashtable getUserProperties()
{
Hashtable propertiesCopy = new Hashtable();

Enumeration e = userProperties.keys();
while( e.hasMoreElements() )
{
Object name = e.nextElement();
Object value = properties.get( name );
propertiesCopy.put( name, value );
}

return propertiesCopy;
}

/**
* query a user property.
*
* @param name the name of the property
* @return the property value, or null for no match
*/
public String getUserProperty( String name )
{
if( name == null )
return null;
String property = (String)userProperties.get( name );
return property;
}

/**
* Topologically sort a set of Targets.
*
* @param root is the (String) name of the root Target. The sort is created
* in such a way that the sequence of Targets uptil the root target is
* the minimum possible such sequence.
* @param targets is a Hashtable representing a "name to Target" mapping
* @return a Vector of Strings with the names of the targets in sorted
* order.
* @exception TaskException if there is a cyclic dependency among the
* Targets, or if a Target does not exist.
*/
public final Vector topoSort( String root, Hashtable targets )
throws TaskException
{
Vector ret = new Vector();
Hashtable state = new Hashtable();
Stack visiting = new Stack();

// We first run a DFS based sort using the root as the starting node.
// This creates the minimum sequence of Targets to the root node.
// We then do a sort on any remaining unVISITED targets.
// This is unnecessary for doing our build, but it catches
// circular dependencies or missing Targets on the entire
// dependency tree, not just on the Targets that depend on the
// build Target.

tsort( root, targets, state, visiting, ret );
log( "Build sequence for target `" + root + "' is " + ret, MSG_VERBOSE );
for( Enumeration en = targets.keys(); en.hasMoreElements(); )
{
String curTarget = (String)( en.nextElement() );
String st = (String)state.get( curTarget );
if( st == null )
{
tsort( curTarget, targets, state, visiting, ret );
}
else if( st == VISITING )
{
throw new RuntimeException( "Unexpected node in visiting state: " + curTarget );
}
}
log( "Complete build sequence is " + ret, MSG_VERBOSE );
return ret;
}

public void addBuildListener( BuildListener listener ) public void addBuildListener( BuildListener listener )
{ {
listeners.addElement( listener ); listeners.addElement( listener );
} }


/**
* add a new datatype
*
* @param typeName name of the datatype
* @param typeClass full datatype classname
*/
public void addDataTypeDefinition( String typeName, Class typeClass )
{
if( null != dataClassDefinitions.get( typeName ) )
{
log( "Trying to override old definition of datatype " + typeName,
MSG_WARN );
}

String msg = " +User datatype: " + typeName + " " + typeClass.getName();
log( msg, MSG_DEBUG );
dataClassDefinitions.put( typeName, typeClass );
}

/**
* @param target is the Target to be added or replaced in the current
* Project.
*/
public void addOrReplaceTarget( Target target )
{
addOrReplaceTarget( target.getName(), target );
}

/**
* @param target is the Target to be added/replaced in the current Project.
* @param targetName is the name to use for the Target
*/
public void addOrReplaceTarget( String targetName, Target target )
{
String msg = " +Target: " + targetName;
log( msg, MSG_DEBUG );
target.setProject( this );
targets.put( targetName, target );
}

public void addReference( String name, Object value )
{
if( null != references.get( name ) )
{
log( "Overriding previous definition of reference to " + name,
MSG_WARN );
}
log( "Adding reference: " + name + " -> " + value, MSG_DEBUG );
references.put( name, value );
}

/**
* This call expects to add a <em>new</em> Target.
*
* @param target is the Target to be added to the current Project.
* @see Project#addOrReplaceTarget to replace existing Targets.
*/
public void addTarget( Target target )
throws TaskException
{
String name = target.getName();
if( targets.get( name ) != null )
{
throw new TaskException( "Duplicate target: `" + name + "'" );
}
addOrReplaceTarget( name, target );
}

/**
* This call expects to add a <em>new</em> Target.
*
* @param target is the Target to be added to the current Project.
* @param targetName is the name to use for the Target
* @exception TaskException if the Target already exists in the project.
* @see Project#addOrReplaceTarget to replace existing Targets.
*/
public void addTarget( String targetName, Target target )
throws TaskException
{
if( targets.get( targetName ) != null )
{
throw new TaskException( "Duplicate target: `" + targetName + "'" );
}
addOrReplaceTarget( targetName, target );
}

/**
* add a new task definition, complain if there is an overwrite attempt
*
* @param taskName name of the task
* @param taskClass full task classname
* @throws TaskException and logs as Project.MSG_ERR for conditions, that
* will cause the task execution to fail.
*/
public void addTaskDefinition( String taskName, Class taskClass )
throws TaskException
{
Class old = (Class)taskClassDefinitions.get( taskName );
if( null != old )
{
if( old.equals( taskClass ) )
{
log( "Ignoring override for task " + taskName
+ ", it is already defined by the same class.",
MSG_VERBOSE );
return;
}
else
{
log( "Trying to override old definition of task " + taskName,
MSG_WARN );

}
}

String msg = " +User task: " + taskName + " " + taskClass.getName();
log( msg, MSG_DEBUG );
checkTaskClass( taskClass );
taskClassDefinitions.put( taskName, taskClass );
}

/**
* Checks a class, whether it is suitable for serving as ant task.
*
* @param taskClass Description of Parameter
* @throws TaskException and logs as Project.MSG_ERR for conditions, that
* will cause the task execution to fail.
*/
public void checkTaskClass( final Class taskClass )
throws TaskException
{
if( !Modifier.isPublic( taskClass.getModifiers() ) )
{
final String message = taskClass + " is not public";
log( message, Project.MSG_ERR );
throw new TaskException( message );
}
if( Modifier.isAbstract( taskClass.getModifiers() ) )
{
final String message = taskClass + " is abstract";
log( message, Project.MSG_ERR );
throw new TaskException( message );
}
try
{
taskClass.getConstructor( null );
// don't have to check for public, since
// getConstructor finds public constructors only.
}
catch( NoSuchMethodException e )
{
final String message = "No public default constructor in " + taskClass;
log( message, Project.MSG_ERR );
throw new TaskException( message );
}
if( !Task.class.isAssignableFrom( taskClass ) )
TaskAdapter.checkTaskClass( taskClass, this );
}

/**
* create a new DataType instance
*
* @param typeName name of the datatype
* @return null if the datatype name is unknown
* @throws TaskException when datatype creation goes bad
*/
public Object createDataType( String typeName )
throws TaskException
{
Class c = (Class)dataClassDefinitions.get( typeName );

if( c == null )
return null;

try
{
java.lang.reflect.Constructor ctor = null;
boolean noArg = false;
// DataType can have a "no arg" constructor or take a single
// Project argument.
try
{
ctor = c.getConstructor( new Class[ 0 ] );
noArg = true;
}
catch( NoSuchMethodException nse )
{
ctor = c.getConstructor( new Class[]{Project.class} );
noArg = false;
}

Object o = null;
if( noArg )
{
o = ctor.newInstance( new Object[ 0 ] );
}
else
{
o = ctor.newInstance( new Object[]{this} );
}
if( o instanceof ProjectComponent )
{
( (ProjectComponent)o ).setProject( this );
}
String msg = " +DataType: " + typeName;
log( msg, MSG_DEBUG );
return o;
}
catch( java.lang.reflect.InvocationTargetException ite )
{
Throwable t = ite.getTargetException();
String msg = "Could not create datatype of type: "
+ typeName + " due to " + t;
throw new TaskException( msg, t );
}
catch( Throwable t )
{
String msg = "Could not create datatype of type: "
+ typeName + " due to " + t;
throw new TaskException( msg, t );
}
}

/** /**
* create a new task instance * create a new task instance
* *
@@ -819,40 +324,7 @@ public class Project
public Task createTask( String taskType ) public Task createTask( String taskType )
throws TaskException throws TaskException
{ {
Class c = (Class)taskClassDefinitions.get( taskType );

if( c == null )
return null;
try
{
Object o = c.newInstance();
Task task = null;
if( o instanceof Task )
{
task = (Task)o;
}
else
{
// "Generic" Bean - use the setter pattern
// and an Adapter
TaskAdapter taskA = new TaskAdapter();
taskA.setProxy( o );
task = taskA;
}
task.setProject( this );
//task.setTaskType( taskType );

String msg = " +Task: " + taskType;
log( msg, MSG_DEBUG );
addCreatedTask( taskType, task );
return task;
}
catch( Throwable t )
{
String msg = "Could not create task of type: "
+ taskType + " due to " + t;
throw new TaskException( msg, t );
}
throw new TaskException( "Task needs reimplementing" );
} }


public void demuxOutput( String line, boolean isError ) public void demuxOutput( String line, boolean isError )
@@ -860,7 +332,7 @@ public class Project
Task task = (Task)threadTasks.get( Thread.currentThread() ); Task task = (Task)threadTasks.get( Thread.currentThread() );
if( task == null ) if( task == null )
{ {
fireMessageLogged( this, line, isError ? MSG_ERR : MSG_INFO );
//fireMessageLogged( this, line, isError ? MSG_ERR : MSG_INFO );
} }
else else
{ {
@@ -875,113 +347,11 @@ public class Project
} }
} }


/**
* execute the targets and any targets it depends on
*
* @param targetName the target to execute
* @throws TaskException if the build failed
*/
public void executeTarget( String targetName )
throws TaskException
{
}

/**
* Initialise the project. This involves setting the default task
* definitions and loading the system properties.
*
* @exception TaskException Description of Exception
*/
public void init()
throws TaskException
{
setJavaVersionProperty();

String defs = "/org/apache/tools/ant/taskdefs/defaults.properties";

try
{
Properties props = new Properties();
InputStream in = this.getClass().getResourceAsStream( defs );
if( in == null )
{
throw new TaskException( "Can't load default task list" );
}
props.load( in );
in.close();

Enumeration enum = props.propertyNames();
while( enum.hasMoreElements() )
{
String key = (String)enum.nextElement();
String value = props.getProperty( key );
try
{
Class taskClass = Class.forName( value );
addTaskDefinition( key, taskClass );
}
catch( NoClassDefFoundError ncdfe )
{
// ignore...
}
catch( ClassNotFoundException cnfe )
{
// ignore...
}
}
}
catch( IOException ioe )
{
throw new TaskException( "Can't load default task list" );
}

String dataDefs = "/org/apache/tools/ant/types/defaults.properties";

try
{
Properties props = new Properties();
InputStream in = this.getClass().getResourceAsStream( dataDefs );
if( in == null )
{
throw new TaskException( "Can't load default datatype list" );
}
props.load( in );
in.close();

Enumeration enum = props.propertyNames();
while( enum.hasMoreElements() )
{
String key = (String)enum.nextElement();
String value = props.getProperty( key );
try
{
Class dataClass = Class.forName( value );
addDataTypeDefinition( key, dataClass );
}
catch( NoClassDefFoundError ncdfe )
{
// ignore...
}
catch( ClassNotFoundException cnfe )
{
// ignore...
}
}
}
catch( IOException ioe )
{
throw new TaskException( "Can't load default datatype list" );
}

setSystemProperties();
}

/** /**
* Output a message to the log with the default log level of MSG_INFO * Output a message to the log with the default log level of MSG_INFO
* *
* @param msg text to log * @param msg text to log
*/ */

public void log( String msg ) public void log( String msg )
{ {
log( msg, MSG_INFO ); log( msg, MSG_INFO );
@@ -996,7 +366,6 @@ public class Project
*/ */
public void log( String msg, int msgLevel ) public void log( String msg, int msgLevel )
{ {
fireMessageLogged( this, msg, msgLevel );
} }


/** /**
@@ -1009,7 +378,6 @@ public class Project
*/ */
public void log( Task task, String msg, int msgLevel ) public void log( Task task, String msg, int msgLevel )
{ {
fireMessageLogged( task, msg, msgLevel );
} }


/** /**
@@ -1022,12 +390,6 @@ public class Project
*/ */
public void log( Target target, String msg, int msgLevel ) public void log( Target target, String msg, int msgLevel )
{ {
fireMessageLogged( target, msg, msgLevel );
}

public void removeBuildListener( BuildListener listener )
{
listeners.removeElement( listener );
} }


/** /**
@@ -1142,111 +504,6 @@ public class Project
} }
} }


/**
* send build finished event to the listeners
*
* @param exception exception which indicates failure if not null
*/
protected void fireBuildFinished( Throwable exception )
{
BuildEvent event = new BuildEvent( this );
event.setException( exception );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.buildFinished( event );
}
}

/**
* send build started event to the listeners
*/
protected void fireBuildStarted()
{
BuildEvent event = new BuildEvent( this );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.buildStarted( event );
}
}

protected void fireMessageLogged( Project project, String message, int priority )
{
BuildEvent event = new BuildEvent( project );
fireMessageLoggedEvent( event, message, priority );
}

protected void fireMessageLogged( Target target, String message, int priority )
{
BuildEvent event = new BuildEvent( target );
fireMessageLoggedEvent( event, message, priority );
}

protected void fireMessageLogged( Task task, String message, int priority )
{
BuildEvent event = new BuildEvent( task );
fireMessageLoggedEvent( event, message, priority );
}

/**
* send build finished event to the listeners
*
* @param exception exception which indicates failure if not null
* @param target Description of Parameter
*/
protected void fireTargetFinished( Target target, Throwable exception )
{
BuildEvent event = new BuildEvent( target );
event.setException( exception );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.targetFinished( event );
}
}

/**
* send target started event to the listeners
*
* @param target Description of Parameter
*/
protected void fireTargetStarted( Target target )
{
BuildEvent event = new BuildEvent( target );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.targetStarted( event );
}
}

protected void fireTaskFinished( Task task, Throwable exception )
{
threadTasks.remove( Thread.currentThread() );
System.out.flush();
System.err.flush();
BuildEvent event = new BuildEvent( task );
event.setException( exception );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.taskFinished( event );
}
}

protected void fireTaskStarted( Task task )
{
// register this as the current task on the current thread.
threadTasks.put( Thread.currentThread(), task );
BuildEvent event = new BuildEvent( task );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.taskStarted( event );
}
}

/** /**
* Allows Project and subclasses to set a property unless its already * Allows Project and subclasses to set a property unless its already
* defined as a user property. There are a few cases internally to Project * defined as a user property. There are a few cases internally to Project
@@ -1263,105 +520,4 @@ public class Project
} }
properties.put( name, value ); properties.put( name, value );
} }

// one step in a recursive DFS traversal of the Target dependency tree.
// - The Hashtable "state" contains the state (VISITED or VISITING or null)
// of all the target names.
// - The Stack "visiting" contains a stack of target names that are
// currently on the DFS stack. (NB: the target names in "visiting" are
// exactly the target names in "state" that are in the VISITING state.)
// 1. Set the current target to the VISITING state, and push it onto
// the "visiting" stack.
// 2. Throw a TaskException if any child of the current node is
// in the VISITING state (implies there is a cycle.) It uses the
// "visiting" Stack to construct the cycle.
// 3. If any children have not been VISITED, tsort() the child.
// 4. Add the current target to the Vector "ret" after the children
// have been visited. Move the current target to the VISITED state.
// "ret" now contains the sorted sequence of Targets upto the current
// Target.

private final void tsort( String root, Hashtable targets,
Hashtable state, Stack visiting,
Vector ret )
throws TaskException
{
state.put( root, VISITING );
visiting.push( root );

Target target = (Target)( targets.get( root ) );

// Make sure we exist
if( target == null )
{
StringBuffer sb = new StringBuffer( "Target `" );
sb.append( root );
sb.append( "' does not exist in this project. " );
visiting.pop();
if( !visiting.empty() )
{
String parent = (String)visiting.peek();
sb.append( "It is used from target `" );
sb.append( parent );
sb.append( "'." );
}

throw new TaskException( new String( sb ) );
}

for( Enumeration en = target.getDependencies(); en.hasMoreElements(); )
{
String cur = (String)en.nextElement();
String m = (String)state.get( cur );
if( m == null )
{
// Not been visited
tsort( cur, targets, state, visiting, ret );
}
else if( m == VISITING )
{
// Currently visiting this node, so have a cycle
throw makeCircularException( cur, visiting );
}
}

String p = (String)visiting.pop();
if( root != p )
{
throw new RuntimeException( "Unexpected internal error: expected to pop " + root + " but got " + p );
}
state.put( root, VISITED );
ret.addElement( target );
}

/**
* Keep a record of all tasks that have been created so that they can be
* invalidated if a taskdef overrides the definition.
*
* @param type The feature to be added to the CreatedTask attribute
* @param task The feature to be added to the CreatedTask attribute
*/
private void addCreatedTask( String type, Task task )
{
synchronized( createdTasks )
{
Vector v = (Vector)createdTasks.get( type );
if( v == null )
{
v = new Vector();
createdTasks.put( type, v );
}
v.addElement( task );
}
}

private void fireMessageLoggedEvent( BuildEvent event, String message, int priority )
{
event.setMessage( message, priority );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.messageLogged( event );
}
}
} }

+ 2
- 846
proposal/myrmidon/src/todo/org/apache/tools/ant/Project.java View File

@@ -8,12 +8,9 @@
package org.apache.tools.ant; package org.apache.tools.ant;


import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Properties;
import java.util.Stack; import java.util.Stack;
import java.util.Vector; import java.util.Vector;
import org.apache.myrmidon.api.TaskException; import org.apache.myrmidon.api.TaskException;
@@ -171,78 +168,6 @@ public class Project
return path.toString(); return path.toString();
} }


private static TaskException makeCircularException( String end, Stack stk )
{
StringBuffer sb = new StringBuffer( "Circular dependency: " );
sb.append( end );
String c;
do
{
c = (String)stk.pop();
sb.append( " <- " );
sb.append( c );
} while( !c.equals( end ) );
return new TaskException( new String( sb ) );
}

/**
* set the base directory; XML attribute. checks for the directory existing
* and being a directory type
*
* @param baseDir project base directory.
* @throws TaskException if the directory was invalid
*/
public void setBaseDir( File baseDir )
throws TaskException
{
baseDir = FileUtils.newFileUtils().normalize( baseDir.getAbsolutePath() );
if( !baseDir.exists() )
throw new TaskException( "Basedir " + baseDir.getAbsolutePath() + " does not exist" );
if( !baseDir.isDirectory() )
throw new TaskException( "Basedir " + baseDir.getAbsolutePath() + " is not a directory" );
this.baseDir = baseDir;
setPropertyInternal( "basedir", this.baseDir.getPath() );
String msg = "Project base dir set to: " + this.baseDir;
log( msg, MSG_VERBOSE );
}

/**
* match basedir attribute in xml
*
* @param baseD project base directory.
* @throws TaskException if the directory was invalid
*/
public void setBasedir( String baseD )
throws TaskException
{
setBaseDir( new File( baseD ) );
}

public void setCoreLoader( ClassLoader coreLoader )
{
this.coreLoader = coreLoader;
}

/**
* set the default target of the project XML attribute name.
*
* @param defaultTarget The new Default value
*/
public void setDefault( String defaultTarget )
{
this.defaultTarget = defaultTarget;
}

/**
* set the project description
*
* @param description text
*/
public void setDescription( String description )
{
this.description = description;
}

/** /**
* set the ant.java.version property, also tests for unsupported JVM * set the ant.java.version property, also tests for unsupported JVM
* versions, prints the verbose log messages * versions, prints the verbose log messages
@@ -265,18 +190,6 @@ public class Project
log( "Detected OS: " + System.getProperty( "os.name" ), MSG_VERBOSE ); log( "Detected OS: " + System.getProperty( "os.name" ), MSG_VERBOSE );
} }


/**
* ant xml property. Set the project name as an attribute of this class, and
* of the property ant.project.name
*
* @param name The new Name value
*/
public void setName( String name )
{
setUserProperty( "ant.project.name", name );
this.name = name;
}

/** /**
* set a property. An existing property of the same name will not be * set a property. An existing property of the same name will not be
* overwritten. * overwritten.
@@ -297,65 +210,6 @@ public class Project
properties.put( name, value ); properties.put( name, value );
} }


/**
* set a property. Any existing property of the same name is overwritten,
* unless it is a user property.
*
* @param name name of property
* @param value new value of the property
*/
public void setProperty( String name, String value )
{
// command line properties take precedence
if( null != userProperties.get( name ) )
{
log( "Override ignored for user property " + name, MSG_VERBOSE );
return;
}

if( null != properties.get( name ) )
{
log( "Overriding previous definition of property " + name,
MSG_VERBOSE );
}

log( "Setting project property: " + name + " -> " +
value, MSG_DEBUG );
properties.put( name, value );
}

/**
* turn all the system properties into ant properties. user properties still
* override these values
*/
public void setSystemProperties()
{
Properties systemP = System.getProperties();
Enumeration e = systemP.keys();
while( e.hasMoreElements() )
{
Object name = e.nextElement();
String value = systemP.get( name ).toString();
this.setPropertyInternal( name.toString(), value );
}
}

/**
* set a user property, which can not be overwritten by set/unset property
* calls
*
* @param name The new UserProperty value
* @param value The new UserProperty value
* @see #setProperty(String,String)
*/
public void setUserProperty( String name, String value )
{
log( "Setting ro project property: " + name + " -> " +
value, MSG_DEBUG );
userProperties.put( name, value );
properties.put( name, value );
}

/** /**
* get the base directory of the project as a file object * get the base directory of the project as a file object
* *
@@ -364,25 +218,9 @@ public class Project
*/ */
public File getBaseDir() public File getBaseDir()
{ {
if( baseDir == null )
{
try
{
setBasedir( "." );
}
catch( TaskException ex )
{
ex.printStackTrace();
}
}
return baseDir; return baseDir;
} }


public Vector getBuildListeners()
{
return listeners;
}

public ClassLoader getCoreLoader() public ClassLoader getCoreLoader()
{ {
return coreLoader; return coreLoader;
@@ -398,41 +236,11 @@ public class Project
return dataClassDefinitions; return dataClassDefinitions;
} }


/**
* get the default target of the project
*
* @return default target or null
*/
public String getDefaultTarget()
{
return defaultTarget;
}

/**
* get the project description
*
* @return description or null if no description has been set
*/
public String getDescription()
{
return description;
}

public FilterSet getGlobalFilterSet() public FilterSet getGlobalFilterSet()
{ {
return globalFilterSet; return globalFilterSet;
} }


/**
* get the project name
*
* @return name string
*/
public String getName()
{
return name;
}

/** /**
* get a copy of the property hashtable * get a copy of the property hashtable
* *
@@ -501,314 +309,11 @@ public class Project
return taskClassDefinitions; return taskClassDefinitions;
} }


/**
* get a copy of the user property hashtable
*
* @return the hashtable user properties only
*/
public Hashtable getUserProperties()
{
Hashtable propertiesCopy = new Hashtable();

Enumeration e = userProperties.keys();
while( e.hasMoreElements() )
{
Object name = e.nextElement();
Object value = properties.get( name );
propertiesCopy.put( name, value );
}

return propertiesCopy;
}

/**
* query a user property.
*
* @param name the name of the property
* @return the property value, or null for no match
*/
public String getUserProperty( String name )
{
if( name == null )
return null;
String property = (String)userProperties.get( name );
return property;
}

/**
* Topologically sort a set of Targets.
*
* @param root is the (String) name of the root Target. The sort is created
* in such a way that the sequence of Targets uptil the root target is
* the minimum possible such sequence.
* @param targets is a Hashtable representing a "name to Target" mapping
* @return a Vector of Strings with the names of the targets in sorted
* order.
* @exception TaskException if there is a cyclic dependency among the
* Targets, or if a Target does not exist.
*/
public final Vector topoSort( String root, Hashtable targets )
throws TaskException
{
Vector ret = new Vector();
Hashtable state = new Hashtable();
Stack visiting = new Stack();

// We first run a DFS based sort using the root as the starting node.
// This creates the minimum sequence of Targets to the root node.
// We then do a sort on any remaining unVISITED targets.
// This is unnecessary for doing our build, but it catches
// circular dependencies or missing Targets on the entire
// dependency tree, not just on the Targets that depend on the
// build Target.

tsort( root, targets, state, visiting, ret );
log( "Build sequence for target `" + root + "' is " + ret, MSG_VERBOSE );
for( Enumeration en = targets.keys(); en.hasMoreElements(); )
{
String curTarget = (String)( en.nextElement() );
String st = (String)state.get( curTarget );
if( st == null )
{
tsort( curTarget, targets, state, visiting, ret );
}
else if( st == VISITING )
{
throw new RuntimeException( "Unexpected node in visiting state: " + curTarget );
}
}
log( "Complete build sequence is " + ret, MSG_VERBOSE );
return ret;
}

public void addBuildListener( BuildListener listener ) public void addBuildListener( BuildListener listener )
{ {
listeners.addElement( listener ); listeners.addElement( listener );
} }


/**
* add a new datatype
*
* @param typeName name of the datatype
* @param typeClass full datatype classname
*/
public void addDataTypeDefinition( String typeName, Class typeClass )
{
if( null != dataClassDefinitions.get( typeName ) )
{
log( "Trying to override old definition of datatype " + typeName,
MSG_WARN );
}

String msg = " +User datatype: " + typeName + " " + typeClass.getName();
log( msg, MSG_DEBUG );
dataClassDefinitions.put( typeName, typeClass );
}

/**
* @param target is the Target to be added or replaced in the current
* Project.
*/
public void addOrReplaceTarget( Target target )
{
addOrReplaceTarget( target.getName(), target );
}

/**
* @param target is the Target to be added/replaced in the current Project.
* @param targetName is the name to use for the Target
*/
public void addOrReplaceTarget( String targetName, Target target )
{
String msg = " +Target: " + targetName;
log( msg, MSG_DEBUG );
target.setProject( this );
targets.put( targetName, target );
}

public void addReference( String name, Object value )
{
if( null != references.get( name ) )
{
log( "Overriding previous definition of reference to " + name,
MSG_WARN );
}
log( "Adding reference: " + name + " -> " + value, MSG_DEBUG );
references.put( name, value );
}

/**
* This call expects to add a <em>new</em> Target.
*
* @param target is the Target to be added to the current Project.
* @see Project#addOrReplaceTarget to replace existing Targets.
*/
public void addTarget( Target target )
throws TaskException
{
String name = target.getName();
if( targets.get( name ) != null )
{
throw new TaskException( "Duplicate target: `" + name + "'" );
}
addOrReplaceTarget( name, target );
}

/**
* This call expects to add a <em>new</em> Target.
*
* @param target is the Target to be added to the current Project.
* @param targetName is the name to use for the Target
* @exception TaskException if the Target already exists in the project.
* @see Project#addOrReplaceTarget to replace existing Targets.
*/
public void addTarget( String targetName, Target target )
throws TaskException
{
if( targets.get( targetName ) != null )
{
throw new TaskException( "Duplicate target: `" + targetName + "'" );
}
addOrReplaceTarget( targetName, target );
}

/**
* add a new task definition, complain if there is an overwrite attempt
*
* @param taskName name of the task
* @param taskClass full task classname
* @throws TaskException and logs as Project.MSG_ERR for conditions, that
* will cause the task execution to fail.
*/
public void addTaskDefinition( String taskName, Class taskClass )
throws TaskException
{
Class old = (Class)taskClassDefinitions.get( taskName );
if( null != old )
{
if( old.equals( taskClass ) )
{
log( "Ignoring override for task " + taskName
+ ", it is already defined by the same class.",
MSG_VERBOSE );
return;
}
else
{
log( "Trying to override old definition of task " + taskName,
MSG_WARN );

}
}

String msg = " +User task: " + taskName + " " + taskClass.getName();
log( msg, MSG_DEBUG );
checkTaskClass( taskClass );
taskClassDefinitions.put( taskName, taskClass );
}

/**
* Checks a class, whether it is suitable for serving as ant task.
*
* @param taskClass Description of Parameter
* @throws TaskException and logs as Project.MSG_ERR for conditions, that
* will cause the task execution to fail.
*/
public void checkTaskClass( final Class taskClass )
throws TaskException
{
if( !Modifier.isPublic( taskClass.getModifiers() ) )
{
final String message = taskClass + " is not public";
log( message, Project.MSG_ERR );
throw new TaskException( message );
}
if( Modifier.isAbstract( taskClass.getModifiers() ) )
{
final String message = taskClass + " is abstract";
log( message, Project.MSG_ERR );
throw new TaskException( message );
}
try
{
taskClass.getConstructor( null );
// don't have to check for public, since
// getConstructor finds public constructors only.
}
catch( NoSuchMethodException e )
{
final String message = "No public default constructor in " + taskClass;
log( message, Project.MSG_ERR );
throw new TaskException( message );
}
if( !Task.class.isAssignableFrom( taskClass ) )
TaskAdapter.checkTaskClass( taskClass, this );
}

/**
* create a new DataType instance
*
* @param typeName name of the datatype
* @return null if the datatype name is unknown
* @throws TaskException when datatype creation goes bad
*/
public Object createDataType( String typeName )
throws TaskException
{
Class c = (Class)dataClassDefinitions.get( typeName );

if( c == null )
return null;

try
{
java.lang.reflect.Constructor ctor = null;
boolean noArg = false;
// DataType can have a "no arg" constructor or take a single
// Project argument.
try
{
ctor = c.getConstructor( new Class[ 0 ] );
noArg = true;
}
catch( NoSuchMethodException nse )
{
ctor = c.getConstructor( new Class[]{Project.class} );
noArg = false;
}

Object o = null;
if( noArg )
{
o = ctor.newInstance( new Object[ 0 ] );
}
else
{
o = ctor.newInstance( new Object[]{this} );
}
if( o instanceof ProjectComponent )
{
( (ProjectComponent)o ).setProject( this );
}
String msg = " +DataType: " + typeName;
log( msg, MSG_DEBUG );
return o;
}
catch( java.lang.reflect.InvocationTargetException ite )
{
Throwable t = ite.getTargetException();
String msg = "Could not create datatype of type: "
+ typeName + " due to " + t;
throw new TaskException( msg, t );
}
catch( Throwable t )
{
String msg = "Could not create datatype of type: "
+ typeName + " due to " + t;
throw new TaskException( msg, t );
}
}

/** /**
* create a new task instance * create a new task instance
* *
@@ -819,40 +324,7 @@ public class Project
public Task createTask( String taskType ) public Task createTask( String taskType )
throws TaskException throws TaskException
{ {
Class c = (Class)taskClassDefinitions.get( taskType );

if( c == null )
return null;
try
{
Object o = c.newInstance();
Task task = null;
if( o instanceof Task )
{
task = (Task)o;
}
else
{
// "Generic" Bean - use the setter pattern
// and an Adapter
TaskAdapter taskA = new TaskAdapter();
taskA.setProxy( o );
task = taskA;
}
task.setProject( this );
//task.setTaskType( taskType );

String msg = " +Task: " + taskType;
log( msg, MSG_DEBUG );
addCreatedTask( taskType, task );
return task;
}
catch( Throwable t )
{
String msg = "Could not create task of type: "
+ taskType + " due to " + t;
throw new TaskException( msg, t );
}
throw new TaskException( "Task needs reimplementing" );
} }


public void demuxOutput( String line, boolean isError ) public void demuxOutput( String line, boolean isError )
@@ -860,7 +332,7 @@ public class Project
Task task = (Task)threadTasks.get( Thread.currentThread() ); Task task = (Task)threadTasks.get( Thread.currentThread() );
if( task == null ) if( task == null )
{ {
fireMessageLogged( this, line, isError ? MSG_ERR : MSG_INFO );
//fireMessageLogged( this, line, isError ? MSG_ERR : MSG_INFO );
} }
else else
{ {
@@ -875,113 +347,11 @@ public class Project
} }
} }


/**
* execute the targets and any targets it depends on
*
* @param targetName the target to execute
* @throws TaskException if the build failed
*/
public void executeTarget( String targetName )
throws TaskException
{
}

/**
* Initialise the project. This involves setting the default task
* definitions and loading the system properties.
*
* @exception TaskException Description of Exception
*/
public void init()
throws TaskException
{
setJavaVersionProperty();

String defs = "/org/apache/tools/ant/taskdefs/defaults.properties";

try
{
Properties props = new Properties();
InputStream in = this.getClass().getResourceAsStream( defs );
if( in == null )
{
throw new TaskException( "Can't load default task list" );
}
props.load( in );
in.close();

Enumeration enum = props.propertyNames();
while( enum.hasMoreElements() )
{
String key = (String)enum.nextElement();
String value = props.getProperty( key );
try
{
Class taskClass = Class.forName( value );
addTaskDefinition( key, taskClass );
}
catch( NoClassDefFoundError ncdfe )
{
// ignore...
}
catch( ClassNotFoundException cnfe )
{
// ignore...
}
}
}
catch( IOException ioe )
{
throw new TaskException( "Can't load default task list" );
}

String dataDefs = "/org/apache/tools/ant/types/defaults.properties";

try
{
Properties props = new Properties();
InputStream in = this.getClass().getResourceAsStream( dataDefs );
if( in == null )
{
throw new TaskException( "Can't load default datatype list" );
}
props.load( in );
in.close();

Enumeration enum = props.propertyNames();
while( enum.hasMoreElements() )
{
String key = (String)enum.nextElement();
String value = props.getProperty( key );
try
{
Class dataClass = Class.forName( value );
addDataTypeDefinition( key, dataClass );
}
catch( NoClassDefFoundError ncdfe )
{
// ignore...
}
catch( ClassNotFoundException cnfe )
{
// ignore...
}
}
}
catch( IOException ioe )
{
throw new TaskException( "Can't load default datatype list" );
}

setSystemProperties();
}

/** /**
* Output a message to the log with the default log level of MSG_INFO * Output a message to the log with the default log level of MSG_INFO
* *
* @param msg text to log * @param msg text to log
*/ */

public void log( String msg ) public void log( String msg )
{ {
log( msg, MSG_INFO ); log( msg, MSG_INFO );
@@ -996,7 +366,6 @@ public class Project
*/ */
public void log( String msg, int msgLevel ) public void log( String msg, int msgLevel )
{ {
fireMessageLogged( this, msg, msgLevel );
} }


/** /**
@@ -1009,7 +378,6 @@ public class Project
*/ */
public void log( Task task, String msg, int msgLevel ) public void log( Task task, String msg, int msgLevel )
{ {
fireMessageLogged( task, msg, msgLevel );
} }


/** /**
@@ -1022,12 +390,6 @@ public class Project
*/ */
public void log( Target target, String msg, int msgLevel ) public void log( Target target, String msg, int msgLevel )
{ {
fireMessageLogged( target, msg, msgLevel );
}

public void removeBuildListener( BuildListener listener )
{
listeners.removeElement( listener );
} }


/** /**
@@ -1142,111 +504,6 @@ public class Project
} }
} }


/**
* send build finished event to the listeners
*
* @param exception exception which indicates failure if not null
*/
protected void fireBuildFinished( Throwable exception )
{
BuildEvent event = new BuildEvent( this );
event.setException( exception );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.buildFinished( event );
}
}

/**
* send build started event to the listeners
*/
protected void fireBuildStarted()
{
BuildEvent event = new BuildEvent( this );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.buildStarted( event );
}
}

protected void fireMessageLogged( Project project, String message, int priority )
{
BuildEvent event = new BuildEvent( project );
fireMessageLoggedEvent( event, message, priority );
}

protected void fireMessageLogged( Target target, String message, int priority )
{
BuildEvent event = new BuildEvent( target );
fireMessageLoggedEvent( event, message, priority );
}

protected void fireMessageLogged( Task task, String message, int priority )
{
BuildEvent event = new BuildEvent( task );
fireMessageLoggedEvent( event, message, priority );
}

/**
* send build finished event to the listeners
*
* @param exception exception which indicates failure if not null
* @param target Description of Parameter
*/
protected void fireTargetFinished( Target target, Throwable exception )
{
BuildEvent event = new BuildEvent( target );
event.setException( exception );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.targetFinished( event );
}
}

/**
* send target started event to the listeners
*
* @param target Description of Parameter
*/
protected void fireTargetStarted( Target target )
{
BuildEvent event = new BuildEvent( target );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.targetStarted( event );
}
}

protected void fireTaskFinished( Task task, Throwable exception )
{
threadTasks.remove( Thread.currentThread() );
System.out.flush();
System.err.flush();
BuildEvent event = new BuildEvent( task );
event.setException( exception );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.taskFinished( event );
}
}

protected void fireTaskStarted( Task task )
{
// register this as the current task on the current thread.
threadTasks.put( Thread.currentThread(), task );
BuildEvent event = new BuildEvent( task );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.taskStarted( event );
}
}

/** /**
* Allows Project and subclasses to set a property unless its already * Allows Project and subclasses to set a property unless its already
* defined as a user property. There are a few cases internally to Project * defined as a user property. There are a few cases internally to Project
@@ -1263,105 +520,4 @@ public class Project
} }
properties.put( name, value ); properties.put( name, value );
} }

// one step in a recursive DFS traversal of the Target dependency tree.
// - The Hashtable "state" contains the state (VISITED or VISITING or null)
// of all the target names.
// - The Stack "visiting" contains a stack of target names that are
// currently on the DFS stack. (NB: the target names in "visiting" are
// exactly the target names in "state" that are in the VISITING state.)
// 1. Set the current target to the VISITING state, and push it onto
// the "visiting" stack.
// 2. Throw a TaskException if any child of the current node is
// in the VISITING state (implies there is a cycle.) It uses the
// "visiting" Stack to construct the cycle.
// 3. If any children have not been VISITED, tsort() the child.
// 4. Add the current target to the Vector "ret" after the children
// have been visited. Move the current target to the VISITED state.
// "ret" now contains the sorted sequence of Targets upto the current
// Target.

private final void tsort( String root, Hashtable targets,
Hashtable state, Stack visiting,
Vector ret )
throws TaskException
{
state.put( root, VISITING );
visiting.push( root );

Target target = (Target)( targets.get( root ) );

// Make sure we exist
if( target == null )
{
StringBuffer sb = new StringBuffer( "Target `" );
sb.append( root );
sb.append( "' does not exist in this project. " );
visiting.pop();
if( !visiting.empty() )
{
String parent = (String)visiting.peek();
sb.append( "It is used from target `" );
sb.append( parent );
sb.append( "'." );
}

throw new TaskException( new String( sb ) );
}

for( Enumeration en = target.getDependencies(); en.hasMoreElements(); )
{
String cur = (String)en.nextElement();
String m = (String)state.get( cur );
if( m == null )
{
// Not been visited
tsort( cur, targets, state, visiting, ret );
}
else if( m == VISITING )
{
// Currently visiting this node, so have a cycle
throw makeCircularException( cur, visiting );
}
}

String p = (String)visiting.pop();
if( root != p )
{
throw new RuntimeException( "Unexpected internal error: expected to pop " + root + " but got " + p );
}
state.put( root, VISITED );
ret.addElement( target );
}

/**
* Keep a record of all tasks that have been created so that they can be
* invalidated if a taskdef overrides the definition.
*
* @param type The feature to be added to the CreatedTask attribute
* @param task The feature to be added to the CreatedTask attribute
*/
private void addCreatedTask( String type, Task task )
{
synchronized( createdTasks )
{
Vector v = (Vector)createdTasks.get( type );
if( v == null )
{
v = new Vector();
createdTasks.put( type, v );
}
v.addElement( task );
}
}

private void fireMessageLoggedEvent( BuildEvent event, String message, int priority )
{
event.setMessage( message, priority );
for( int i = 0; i < listeners.size(); i++ )
{
BuildListener listener = (BuildListener)listeners.elementAt( i );
listener.messageLogged( event );
}
}
} }

Loading…
Cancel
Save