|
|
@@ -70,6 +70,7 @@ import org.apache.tools.ant.types.FilterSetCollection; |
|
|
|
import org.apache.tools.ant.util.FileUtils; |
|
|
|
import org.apache.tools.ant.util.JavaEnvUtils; |
|
|
|
import org.apache.tools.ant.util.WeakishReference; |
|
|
|
import org.apache.tools.ant.util.LazyHashtable; |
|
|
|
|
|
|
|
/** |
|
|
|
* Central representation of an Ant project. This class defines an |
|
|
@@ -168,14 +169,14 @@ public class Project { |
|
|
|
*/ |
|
|
|
private Hashtable inheritedProperties = new Hashtable(); |
|
|
|
/** Map of references within the project (paths etc) (String to Object). */ |
|
|
|
private Hashtable references = new Hashtable(); |
|
|
|
private Hashtable references = new AntRefTable(this); |
|
|
|
|
|
|
|
/** Name of the project's default target. */ |
|
|
|
private String defaultTarget; |
|
|
|
/** Map from data type names to implementing classes (String to Class). */ |
|
|
|
private Hashtable dataClassDefinitions = new Hashtable(); |
|
|
|
private Hashtable dataClassDefinitions = new AntTaskTable(this, false); |
|
|
|
/** Map from task names to implementing classes (String to Class). */ |
|
|
|
private Hashtable taskClassDefinitions = new Hashtable(); |
|
|
|
private Hashtable taskClassDefinitions = new AntTaskTable(this, true); |
|
|
|
/** |
|
|
|
* Map from task names to vectors of created tasks |
|
|
|
* (String to Vector of Task). This is used to invalidate tasks if |
|
|
@@ -260,22 +261,9 @@ public class Project { |
|
|
|
} |
|
|
|
props.load(in); |
|
|
|
in.close(); |
|
|
|
((AntTaskTable)taskClassDefinitions).addDefinitions( props ); |
|
|
|
|
|
|
|
|
|
|
|
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) { |
|
|
|
log("Could not load a dependent class (" |
|
|
|
+ ncdfe.getMessage() + ") for task " + key, MSG_DEBUG); |
|
|
|
} catch (ClassNotFoundException cnfe) { |
|
|
|
log("Could not load class (" + value |
|
|
|
+ ") for task " + key, MSG_DEBUG); |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (IOException ioe) { |
|
|
|
throw new BuildException("Can't load default task list"); |
|
|
|
} |
|
|
@@ -291,19 +279,9 @@ public class Project { |
|
|
|
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... |
|
|
|
} |
|
|
|
} |
|
|
|
((AntTaskTable)dataClassDefinitions).addDefinitions(props); |
|
|
|
|
|
|
|
|
|
|
|
} catch (IOException ioe) { |
|
|
|
throw new BuildException("Can't load default datatype list"); |
|
|
|
} |
|
|
@@ -790,7 +768,7 @@ public class Project { |
|
|
|
this.baseDir = baseDir; |
|
|
|
setPropertyInternal("basedir", this.baseDir.getPath()); |
|
|
|
String msg = "Project base dir set to: " + this.baseDir; |
|
|
|
log(msg, MSG_VERBOSE); |
|
|
|
log(msg, MSG_VERBOSE); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -1793,7 +1771,7 @@ public class Project { |
|
|
|
*/ |
|
|
|
public void addReference(String name, Object value) { |
|
|
|
synchronized (references) { |
|
|
|
Object old = references.get(name); |
|
|
|
Object old = ((AntRefTable)references).getReal(name); |
|
|
|
if (old == value) { |
|
|
|
// no warning, this is not changing anything |
|
|
|
return; |
|
|
@@ -2075,4 +2053,126 @@ public class Project { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Should move to a separate public class - and have API to add |
|
|
|
// listeners, etc. |
|
|
|
private static class AntRefTable extends Hashtable { |
|
|
|
Project project; |
|
|
|
public AntRefTable(Project project) { |
|
|
|
super(); |
|
|
|
this.project=project; |
|
|
|
} |
|
|
|
|
|
|
|
/** Returns the unmodified original object. |
|
|
|
* This method should be called internally to |
|
|
|
* get the 'real' object. |
|
|
|
* The normal get method will do the replacement |
|
|
|
* of UnknownElement ( this is similar with the JDNI |
|
|
|
* refs behavior ) |
|
|
|
*/ |
|
|
|
public Object getReal(Object key ) { |
|
|
|
return super.get( key ); |
|
|
|
} |
|
|
|
|
|
|
|
/** Get method for the reference table. |
|
|
|
* It can be used to hook dynamic references and to modify |
|
|
|
* some references on the fly - for example for delayed |
|
|
|
* evaluation. |
|
|
|
* |
|
|
|
* It is important to make sure that the processing that is |
|
|
|
* done inside is not calling get indirectly. |
|
|
|
* |
|
|
|
* @param key |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
public Object get(Object key) { |
|
|
|
//System.out.println("AntRefTable.get " + key); |
|
|
|
Object o=super.get(key); |
|
|
|
if( o instanceof UnknownElement ) { |
|
|
|
// Make sure that |
|
|
|
((UnknownElement)o).maybeConfigure(); |
|
|
|
o=((UnknownElement)o).getTask(); |
|
|
|
} |
|
|
|
return o; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private static class AntTaskTable extends LazyHashtable { |
|
|
|
Project project; |
|
|
|
Properties props; |
|
|
|
boolean tasks=false; |
|
|
|
|
|
|
|
public AntTaskTable( Project p, boolean tasks ) { |
|
|
|
this.project=p; |
|
|
|
this.tasks=tasks; |
|
|
|
} |
|
|
|
|
|
|
|
public void addDefinitions( Properties props ) { |
|
|
|
this.props=props; |
|
|
|
} |
|
|
|
|
|
|
|
protected void initAll( ) { |
|
|
|
if( initAllDone ) return; |
|
|
|
project.log("InitAll", Project.MSG_DEBUG); |
|
|
|
if( props==null ) return; |
|
|
|
Enumeration enum = props.propertyNames(); |
|
|
|
while (enum.hasMoreElements()) { |
|
|
|
String key = (String) enum.nextElement(); |
|
|
|
Class taskClass=getTask( key ); |
|
|
|
if( taskClass!=null ) { |
|
|
|
// This will call a get() and a put() |
|
|
|
if( tasks ) |
|
|
|
project.addTaskDefinition(key, taskClass); |
|
|
|
else |
|
|
|
project.addDataTypeDefinition(key, taskClass ); |
|
|
|
} |
|
|
|
} |
|
|
|
initAllDone=true; |
|
|
|
} |
|
|
|
|
|
|
|
protected Class getTask(String key) { |
|
|
|
if( props==null ) return null; // for tasks loaded before init() |
|
|
|
String value=props.getProperty(key); |
|
|
|
if( value==null) { |
|
|
|
//project.log( "No class name for " + key, Project.MSG_VERBOSE ); |
|
|
|
return null; |
|
|
|
} |
|
|
|
try { |
|
|
|
Class taskClass=null; |
|
|
|
if( project.getCoreLoader() != null && |
|
|
|
!("only".equals(project.getProperty("build.sysclasspath")))) { |
|
|
|
try { |
|
|
|
taskClass=project.getCoreLoader().loadClass(value); |
|
|
|
if( taskClass != null ) return taskClass; |
|
|
|
} catch( Exception ex ) { |
|
|
|
} |
|
|
|
} |
|
|
|
taskClass = Class.forName(value); |
|
|
|
return taskClass; |
|
|
|
} catch (NoClassDefFoundError ncdfe) { |
|
|
|
project.log("Could not load a dependent class (" |
|
|
|
+ ncdfe.getMessage() + ") for task " + key, Project.MSG_DEBUG); |
|
|
|
} catch (ClassNotFoundException cnfe) { |
|
|
|
project.log("Could not load class (" + value |
|
|
|
+ ") for task " + key, Project.MSG_DEBUG); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
// Hashtable implementation |
|
|
|
public Object get( Object key ) { |
|
|
|
Object orig=super.get( key ); |
|
|
|
if( orig!= null ) return orig; |
|
|
|
if( ! (key instanceof String) ) return null; |
|
|
|
project.log("Get task " + key, Project.MSG_DEBUG ); |
|
|
|
Object taskClass=getTask( (String) key); |
|
|
|
if( taskClass != null) |
|
|
|
super.put( key, taskClass ); |
|
|
|
return taskClass; |
|
|
|
} |
|
|
|
|
|
|
|
public boolean contains( Object key ) { |
|
|
|
return get( key ) != null; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |