diff --git a/proposal/mutant/bootstrap.sh b/proposal/mutant/bootstrap.sh index 8b192a1cc..fe559c26f 100755 --- a/proposal/mutant/bootstrap.sh +++ b/proposal/mutant/bootstrap.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/sh # Copyright (c) 2000-2001 The Apache Software Foundation. All rights # reserved. @@ -22,7 +22,7 @@ javac -classpath bin/init:bin/bootstrap -d bin/builder src/java/bootstrap/org/ap java -classpath bin/init:bin/bootstrap org.apache.ant.bootstrap.Bootstrap # run full build using bootstrapped version -java -jar bootstrap/lib/start.jar $* +java -jar bootstrap/lib/core/start/start.jar $* # Use the full build as the build used by the build script cp -r dist/lib bootstrap diff --git a/proposal/mutant/build.sh b/proposal/mutant/build.sh index d2cc21394..605550e26 100755 --- a/proposal/mutant/build.sh +++ b/proposal/mutant/build.sh @@ -1,6 +1,6 @@ -#!/bin/sh -x +#!/bin/sh # Copyright (c) 2002 The Apache Software Foundation. All rights # reserved. -java -jar bootstrap/lib/start.jar $@ +java -jar bootstrap/lib/core/start/start.jar $@ diff --git a/proposal/mutant/build.xml b/proposal/mutant/build.xml index 830e89922..a503dd713 100644 --- a/proposal/mutant/build.xml +++ b/proposal/mutant/build.xml @@ -1,117 +1,127 @@ - + + + + + - - + + + + + + + + + + - + - + - + - + - - + + - + + - + - + - + - + - + - + - + - + - - - - + - - + + - + - + @@ -120,11 +130,8 @@ - - - - - + - + - - + + - - + + + - - + + + + - + - + - + - - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -230,6 +276,10 @@ + + + + diff --git a/proposal/mutant/build/ant1compat.xml b/proposal/mutant/build/ant1compat.xml index af1fbac3b..7d44d1559 100644 --- a/proposal/mutant/build/ant1compat.xml +++ b/proposal/mutant/build/ant1compat.xml @@ -1,9 +1,9 @@ - + @@ -16,14 +16,16 @@ - - + + + + @@ -40,11 +42,11 @@ - - - - - + + + + + @@ -561,8 +563,8 @@ - - + + diff --git a/proposal/mutant/build/bootstrap.xsl b/proposal/mutant/build/bootstrap.xsl index c0f99ecfd..55a8723f1 100644 --- a/proposal/mutant/build/bootstrap.xsl +++ b/proposal/mutant/build/bootstrap.xsl @@ -14,7 +14,7 @@ } - + helper.setProperty(" @@ -23,15 +23,33 @@ "); + + { + BuildHelper subHelper = new BuildHelper(); + + subHelper.setProperty(" + + ", helper.resolve(" + + ")); + + subHelper.setParent(helper); + _init(subHelper); + + + (subHelper); + } + + - + helper.createPath(" "); - + helper.addFileSetToPath(" @@ -52,7 +70,7 @@ ); - + helper.addPathElementToPath(" @@ -61,7 +79,7 @@ "); - + helper.addPathToPath(" @@ -76,16 +94,24 @@ protected void (BuildHelper helper) { + helper.runDepends(this, " + + ", " + + "); + System.out.println(" + + : "); } - + helper.mkdir(" "); - + helper.javac(" @@ -150,7 +176,7 @@ ); - + diff --git a/proposal/mutant/src/conf/ant.policy b/proposal/mutant/src/conf/ant.policy new file mode 100644 index 000000000..f5208cdc2 --- /dev/null +++ b/proposal/mutant/src/conf/ant.policy @@ -0,0 +1,49 @@ +// Mutant Policy File +// +// Copyright (c) 2002 The Apache Software Foundation. +// All rights reserved. + +// Need to explicitly grant to java.home to pick up tools.jar classes +grant codeBase "file:${java.home}/../lib/tools.jar" { + permission java.security.AllPermission; +}; + +// full access is granted to the core +grant codeBase "file:${ant.home}/lib/core/-" { + permission java.security.AllPermission; +}; + +// grant full access to the command line front end. +// All operations can be controlled by setting the appropriate +// permissions on the front end. This will also affect core +// functions +grant codeBase "file:${ant.home}/lib/frontend/cli.jar" { + permission java.security.AllPermission; +}; + +// grant for the Ant1 compat jar. Other Ant libraries can be controlled +// individually. +grant codeBase "file:${ant.home}/lib/antlibs/ant1compat.jar" { + permission java.security.AllPermission; + + // For backward compatibility the Ant1 compatabilioty is granted full + // permission. This can be reduced as desired to eliminate the ability to + // access the network. + // + // For example, the following permissions are required to build Mutant. Additional + // permissions are required depending on what tasks you want to enable. +// permission java.io.FilePermission "<>", "read, write, execute, delete"; +// permission java.lang.RuntimePermission "accessDeclaredMembers"; +// permission java.lang.RuntimePermission "createClassLoader"; +// permission java.lang.RuntimePermission "getClassLoader"; +// permission java.util.PropertyPermission "java.class.path", "read, write"; +// permission java.util.PropertyPermission "java.home", "read"; +// permission java.util.PropertyPermission "user.dir", "read"; +// permission java.util.PropertyPermission "user.name", "read"; +// permission java.util.PropertyPermission "sun.*", "read"; +// permission java.util.PropertyPermission "java.*", "read"; +// permission java.util.PropertyPermission "javac.*", "read"; +// permission java.util.PropertyPermission "line.separator", "write"; +// permission java.lang.RuntimePermission "accessClassInPackage.sun.*"; +}; + diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java index ae5d480e4..a170324c7 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java @@ -251,7 +251,7 @@ public class BuildEventSupport implements DemuxOutputReceiver { } } fireMessageLogged(this, line, - isError ? MessageLevel.MSG_ERR : MessageLevel.MSG_INFO); + isError ? MessageLevel.ERROR : MessageLevel.INFO); } } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java index ba4c36f0d..b51c2a5db 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java @@ -299,7 +299,7 @@ public class ComponentManager implements ComponentService { frame.log("Adding referenced component <" + definition.getLocalName() + "> as <" + label + "> from library \"" + definition.getComponentLibrary().getLibraryId() + "\", class: " - + definition.getClassName(), MessageLevel.MSG_DEBUG); + + definition.getClassName(), MessageLevel.DEBUG); imports.put(label, definition); } @@ -631,7 +631,7 @@ public class ComponentManager implements ComponentService { AntLibDefinition libDef = library.getDefinition(defName); frame.log("Adding component <" + defName + "> as <" + label + "> from library \"" + library.getLibraryId() + "\", class: " - + libDef.getClassName(), MessageLevel.MSG_DEBUG); + + libDef.getClassName(), MessageLevel.DEBUG); imports.put(label, new ImportInfo(library, libDef)); } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreDataService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreDataService.java index 1b6f8e699..8daee51b3 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreDataService.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreDataService.java @@ -53,76 +53,184 @@ */ package org.apache.ant.antcore.execution; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import org.apache.ant.common.event.MessageLevel; +import org.apache.ant.common.model.Project; import org.apache.ant.common.service.DataService; -import org.apache.ant.common.util.PropertyUtils; import org.apache.ant.common.util.AntException; +import org.apache.ant.common.util.DataValue; +import org.apache.ant.common.util.PropertyUtils; /** - * This is the core's implementation of the DataService service interface. - * It gives Ant libraries access to property values maintained in the - * Frame. + * This is the core's implementation of the DataService service interface. It + * gives Ant libraries access to property values maintained in the Frame. * * @author Conor MacNeill * @created 31 January 2002 */ public class CoreDataService implements DataService { + /** The Frame this service instance is working for */ private Frame frame; /** all properties to be unset without throwing an exception */ private boolean allowUnsetProperties; + /** + * The context of this execution. This contains all data object's created + * by tasks that have been executed + */ + private Map dataValues = new HashMap(); + + /** + * The property overrides for the referenced frames. This map is indexed + * by the reference names of the frame. Each entry is another Map of + * property values indexed by their relative name. + */ + private Map overrides = new HashMap(); + /** * Constructor * * @param frame the frame containing this context - * @param allowUnsetProperties true if the reference to an unset - * property should not throw an exception + * @param allowUnsetProperties true if the reference to an unset property + * should not throw an exception */ protected CoreDataService(Frame frame, - boolean allowUnsetProperties) { + boolean allowUnsetProperties) { this.frame = frame; this.allowUnsetProperties = allowUnsetProperties; } /** - * Set a data value. If an existing data value exists, associated with - * the given name, the value will not be changed + * Get the Data service of a frame * - * @param valueName the name of the data value - * @param value the value to be associated with the name - * @exception ExecutionException if the value cannot be set + * @param frame the frame whose data service is required. + * @return the frame's data service. + * @exception ExecutionException if the frame's data service cannot be + * retrieved. */ - public void setDataValue(String valueName, Object value) + private DataService getFrameDataService(Frame frame) throws ExecutionException { - frame.setDataValue(valueName, value, false); + return (DataService) frame.getCoreService(DataService.class); + } + + /** + * Update a DataValue in a repository. + * + * The value is only updated if it is a higher priority than any existing + * values or the same priority and the mutable flag is set. + * + * @param repository the repository containing the values. + * @param key the key under which the value is to be stored. + * @param value the data vale instance + * @param mutable true if a value of equal priority can be overwritten. + */ + private void updateValue(Map repository, String key, + DataValue value, boolean mutable) { + int priority = value.getPriority(); + DataValue currentDataValue = (DataValue) repository.get(key); + if (currentDataValue != null) { + int currentPriority = currentDataValue.getPriority(); + if (currentPriority > priority + || (currentPriority == priority && !mutable)) { + frame.log("Ignoring override for data value " + key, + MessageLevel.VERBOSE); + return; + } + } + repository.put(key, value); + } + + /** + * Set a value in this frame or any of its imported frames. + * + * @param name the name of the value + * @param value the actual value + * @param mutable if true, existing values can be changed + * @exception AntException if the value cannot be set. + */ + public void setDataValue(String name, DataValue value, boolean mutable) + throws AntException { + Frame containingFrame = frame.getContainingFrame(name); + + if (containingFrame == null) { + setOverrideProperty(name, value, mutable); + return; + } + + String localName = frame.getNameInFrame(name); + if (containingFrame == frame) { + updateValue(dataValues, localName, value, mutable); + } else { + DataService actualDataService = getFrameDataService(containingFrame); + actualDataService.setDataValue(localName, value, mutable); + } } /** - * Set a data value which can be overwritten + * When a frame has not yet been referenced, this method is used to set + * the initial properties for the frame when it is introduced. * - * @param valueName the name of the data value - * @param value the value to be associated with the name - * @exception ExecutionException if the value cannot be set + * @param name the name of the value + * @param value the actual value + * @param mutable if true, existing values can be changed + * @exception ExecutionException if attempting to override a property in + * the current frame. */ - public void setMutableDataValue(String valueName, Object value) + private void setOverrideProperty(String name, DataValue value, + boolean mutable) throws ExecutionException { - frame.setDataValue(valueName, value, true); + int refIndex = name.indexOf(Project.REF_DELIMITER); + if (refIndex == -1) { + throw new ExecutionException("Property overrides can only be set" + + " for properties in referenced projects - not " + + name); + } + + String firstFrameName = name.substring(0, refIndex); + + String relativeName + = name.substring(refIndex + Project.REF_DELIMITER.length()); + + Map frameOverrides = (Map) overrides.get(firstFrameName); + if (frameOverrides == null) { + frameOverrides = new HashMap(); + overrides.put(firstFrameName, frameOverrides); + } + + updateValue(frameOverrides, relativeName, value, mutable); } + /** * Get a data value * - * @param valueName the name of the data value - * @return the current object associated with the name or null if no - * value is currently associated with the name - * @exception ExecutionException if the value cannot be retrieved. + * @param name the name of the data value + * @return the current object associated with the name or null if no value + * is currently associated with the name + * @exception AntException if the value cannot be retrieved. */ - public Object getDataValue(String valueName) throws ExecutionException { - return frame.getDataValue(valueName); + public Object getDataValue(String name) throws AntException { + Frame containingFrame = frame.getContainingFrame(name); + + if (containingFrame == null) { + return getOverrideProperty(name); + } + if (containingFrame == frame) { + DataValue dataValue = (DataValue) dataValues.get(name); + if (dataValue == null) { + return null; + } + return dataValue.getValue(); + } else { + String localName = frame.getNameInFrame(name); + DataService actualDataService = getFrameDataService(containingFrame); + return actualDataService.getDataValue(localName); + } } /** @@ -131,25 +239,69 @@ public class CoreDataService implements DataService { * @param name the name of the data value - may contain reference * delimiters * @return true if the value exists - * @exception ExecutionException if the containing frame for the value - * does not exist + * @exception AntException if the data value cannot be accessed. */ - public boolean isDataValueSet(String name) throws ExecutionException { - return frame.isDataValueSet(name); + public boolean isDataValueSet(String name) throws AntException { + Frame containingFrame = frame.getContainingFrame(name); + + if (containingFrame == null) { + return isOverrideSet(name); + } + if (containingFrame == frame) { + return dataValues.containsKey(name); + } else { + String localName = frame.getNameInFrame(name); + DataService actualDataService = getFrameDataService(containingFrame); + return actualDataService.isDataValueSet(localName); + } } /** - * Get all the properties from the frame and any references frames. This + * Get all the data values from the frame and any referenced frames. This * is an expensive operation since it must clone all of the property * stores in all frames * - * @return a Map containing the frames properties indexed by their full + * @return a Map containing the frames data values indexed by their full * name. + * @exception AntException if the values cannot be retrieved. */ - public Map getAllProperties() { - return frame.getAllProperties(); + public Map getAllDataValues() throws AntException { + Map allValues = new HashMap(); + mergeDataValues(allValues, dataValues); + + // add in values from sub frames + for (Iterator i = frame.getRefNames(); i.hasNext();) { + String refName = (String) i.next(); + Frame refFrame = frame.getReferencedFrame(refName); + + DataService refDataService = getFrameDataService(refFrame); + Map refValues = refDataService.getAllDataValues(); + Iterator j = refValues.keySet().iterator(); + + while (j.hasNext()) { + String name = (String) j.next(); + DataValue value = (DataValue) refValues.get(name); + updateValue(allValues, refName + Project.REF_DELIMITER + name, + value, false); + } + } + + // add in values from overrides which have not yet been activated + for (Iterator i = overrides.keySet().iterator(); i.hasNext();) { + String refName = (String) i.next(); + Map refOverrides = (Map) overrides.get(refName); + for (Iterator j = refOverrides.keySet().iterator(); j.hasNext();) { + String name = (String) j.next(); + DataValue value = (DataValue) refOverrides.get(name); + updateValue(allValues, refName + Project.REF_DELIMITER + name, + value, false); + } + } + + return allValues; } + /** * Replace ${} style constructions in the given value with the string * value of the corresponding data values in the frame @@ -230,5 +382,144 @@ public class CoreDataService implements DataService { return sb.toString(); } + + /** + * Get the data value overrides associated with a given reference name. + * + * @param refName The name of the reference for which overriding datavalues + * are required. + * @return The map of named DataValue instances. + */ + protected Map getOverrides(String refName) { + return (Map) overrides.get(refName); + } + + /** + * Remove the override values associated with a given reference name. + * + * @param refName The name of the reference for which overriding datavalues + * are required. + */ + protected void removeOverrides(String refName) { + overrides.remove(refName); + } + + /** + * Get a value which exists in the frame property overrides awaiting the + * frame to be introduced. + * + * @param name the name of the value + * @return the value of the property or null if the property does not + * exist. + * @exception ExecutionException if attempting to get an override in the + * current frame. + */ + private Object getOverrideProperty(String name) throws ExecutionException { + int refIndex = name.indexOf(Project.REF_DELIMITER); + if (refIndex == -1) { + throw new ExecutionException("Property overrides can only be" + + " returned for properties in referenced projects - not " + + name); + } + + String firstFrameName = name.substring(0, refIndex); + + String relativeName + = name.substring(refIndex + Project.REF_DELIMITER.length()); + + Map frameOverrides = (Map) overrides.get(firstFrameName); + if (frameOverrides == null) { + return null; + } + + return frameOverrides.get(relativeName); + } + + /** + * Get a value which exists in the frame property overrides awaiting the + * frame to be introduced. + * + * @param name the name of the value + * @return the value of the property or null if the property does not + * exist. + * @exception ExecutionException if attempting to check an override in the + * current frame. + */ + private boolean isOverrideSet(String name) throws ExecutionException { + int refIndex = name.indexOf(Project.REF_DELIMITER); + if (refIndex == -1) { + throw new ExecutionException("Property overrides can only be" + + " returned for properties in referenced projects - not " + + name); + } + + String firstFrameName = name.substring(0, refIndex); + + String relativeName + = name.substring(refIndex + Project.REF_DELIMITER.length()); + + Map frameOverrides = (Map) overrides.get(firstFrameName); + if (frameOverrides == null) { + return false; + } + + return frameOverrides.containsKey(relativeName); + } + + + /** + * Add a collection of properties to this frame with a given priority. + * + * @param properties the collection of property values, indexed by their + * names + * @param priority the priority at which the values are added. + * @exception AntException if the values cannot be added. + */ + protected void addProperties(Map properties, int priority) + throws AntException { + addDataValues(DataValue.makeDataValues(properties, priority)); + } + + /** + * Add a set of data values. + * + * @param dataValues a collection of DataValue instances named + * @exception AntException if the values cannot be added. + */ + protected void addDataValues(Map values) throws AntException { + mergeDataValues(dataValues, values); + } + + /** + * Merge one set of values into another + * + * @param values the values to which the new values are added + * @param newValues the values to be added in. + */ + public void mergeDataValues(Map values, Map newValues) { + mergeDataValues(values, newValues, DataValue.PRIORITY_BASE); + } + + /** + * Merge in values which are of a given priority or higher. + * + * @param values the values to which the new values are added + * @param newValues the values to be added in. + * @param threshold The require data value priority for a value to be + * merged. + */ + public void mergeDataValues(Map values, Map newValues, int threshold) { + if (newValues == null) { + return; + } + + for (Iterator i = newValues.keySet().iterator(); i.hasNext();) { + String name = (String) i.next(); + DataValue value = (DataValue) newValues.get(name); + if (value.getPriority() >= threshold) { + updateValue(values, name, value, false); + } + } + } } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java index 4d0d31d10..f46132523 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java @@ -275,20 +275,20 @@ public class CoreExecService implements ExecService { * Setup a sub-build. * * @param model the project model to be used for the build - * @param properties the initiali properties to be used in the build + * @param dataValues the initial data values to be used in the build * @param addListeners true if the current frame's listeners should be * added to the created Frame * @return Description of the Return Value * @exception AntException if the subbuild cannot be run */ - public Object setupBuild(Project model, Map properties, + public Object setupBuild(Project model, Map dataValues, boolean addListeners) throws AntException { Frame newFrame = frame.createFrame(model); if (addListeners) { frame.addListeners(newFrame); } - newFrame.initialize(properties); + newFrame.initialize(dataValues); return newFrame; } @@ -297,15 +297,15 @@ public class CoreExecService implements ExecService { /** * Setup a sub-build using the current frame's project model * - * @param properties the initiali properties to be used in the build + * @param dataValues the initial properties to be used in the build * @param addListeners true if the current frame's listeners should be * added to the created Frame * @return Description of the Return Value * @exception AntException if the subbuild cannot be run */ - public Object setupBuild(Map properties, boolean addListeners) + public Object setupBuild(Map dataValues, boolean addListeners) throws AntException { - return setupBuild(frame.getProject(), properties, addListeners); + return setupBuild(frame.getProject(), dataValues, addListeners); } } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java index 9d404864f..d74b25d0b 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java @@ -54,7 +54,6 @@ package org.apache.ant.antcore.execution; import java.io.File; import java.net.URL; -import java.net.MalformedURLException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -81,6 +80,7 @@ import org.apache.ant.common.service.FileService; import org.apache.ant.common.service.InputService; import org.apache.ant.common.service.MagicProperties; import org.apache.ant.common.util.DemuxOutputReceiver; +import org.apache.ant.common.util.DataValue; import org.apache.ant.common.util.FileUtils; import org.apache.ant.common.util.Location; import org.apache.ant.common.util.AntException; @@ -112,19 +112,6 @@ public class Frame implements DemuxOutputReceiver { */ private Map aspectContextsMap = new HashMap(); - /** - * The property overrides for the referenced frames. This map is indexed - * by the reference names of the frame. Each entry is another Map of - * property values indexed by their relative name. - */ - private Map overrides = new HashMap(); - - /** - * The context of this execution. This contains all data object's created - * by tasks that have been executed - */ - private Map dataValues = new HashMap(); - /** * Ant's initialization configuration with information on the location of * Ant and its libraries. @@ -242,153 +229,22 @@ public class Frame implements DemuxOutputReceiver { /** - * Set a value in this frame or any of its imported frames. - * - * @param name the name of the value - * @param value the actual value - * @param mutable if true, existing values can be changed - * @exception ExecutionException if the value name is invalid - */ - protected void setDataValue(String name, Object value, boolean mutable) - throws ExecutionException { - Frame frame = getContainingFrame(name); - - if (frame == null) { - setOverrideProperty(name, value, mutable); - return; - } - - if (frame == this) { - if (dataValues.containsKey(name) && !mutable) { - log("Ignoring override for data value " + name, - MessageLevel.MSG_VERBOSE); - } else { - dataValues.put(name, value); - } - } else { - frame.setDataValue(getNameInFrame(name), value, mutable); - } - } - - /** - * When a frame has not yet been referenced, this method is used - * to set the initial properties for the frame when it is introduced. + * Initialize the frame. * - * @param name the name of the value - * @param value the actual value - * @param mutable if true, existing values can be changed - * @exception ExecutionException if attempting to override a property in - * the current frame. - */ - private void setOverrideProperty(String name, Object value, - boolean mutable) - throws ExecutionException { - int refIndex = name.indexOf(Project.REF_DELIMITER); - if (refIndex == -1) { - throw new ExecutionException("Property overrides can only be set" - + " for properties in referenced projects - not " - + name); - } - - String firstFrameName = name.substring(0, refIndex); - - String relativeName - = name.substring(refIndex + Project.REF_DELIMITER.length()); - - Map frameOverrides = (Map) overrides.get(firstFrameName); - if (frameOverrides == null) { - frameOverrides = new HashMap(); - overrides.put(firstFrameName, frameOverrides); - } - - if (mutable || !frameOverrides.containsKey(relativeName)) { - frameOverrides.put(relativeName, value); - } - } - - /** - * Get a value which exists in the frame property overrides awaiting - * the frame to be introduced. - * - * @param name the name of the value - * @return the value of the property or null if the property does not - * exist. - * @exception ExecutionException if attempting to get an override in - * the current frame. - */ - private Object getOverrideProperty(String name) throws ExecutionException { - int refIndex = name.indexOf(Project.REF_DELIMITER); - if (refIndex == -1) { - throw new ExecutionException("Property overrides can only be" - + " returned for properties in referenced projects - not " - + name); - } - - String firstFrameName = name.substring(0, refIndex); - - String relativeName - = name.substring(refIndex + Project.REF_DELIMITER.length()); - - Map frameOverrides = (Map) overrides.get(firstFrameName); - if (frameOverrides == null) { - return null; - } - - return frameOverrides.get(relativeName); - } - - /** - * Get a value which exists in the frame property overrides awaiting - * the frame to be introduced. - * - * @param name the name of the value - * @return the value of the property or null if the property does not - * exist. - * @exception ExecutionException if attempting to check an override in - * the current frame. - */ - private boolean isOverrideSet(String name) throws ExecutionException { - int refIndex = name.indexOf(Project.REF_DELIMITER); - if (refIndex == -1) { - throw new ExecutionException("Property overrides can only be" - + " returned for properties in referenced projects - not " - + name); - } - - String firstFrameName = name.substring(0, refIndex); - - String relativeName - = name.substring(refIndex + Project.REF_DELIMITER.length()); - - Map frameOverrides = (Map) overrides.get(firstFrameName); - if (frameOverrides == null) { - return false; - } - - return frameOverrides.containsKey(relativeName); - } - - - /** - * Initialize the frame setting any initial properties. - * - * @param properties a Map of named properties which may in fact be any - * object - * @exception AntException if the properties cannot be set + * @param initialDataValues a Map of named DataValue instances. + * @exception AntException if the frame cannot be initialized. */ - public void initialize(Map properties) - throws AntException { + public void initialize(Map initialDataValues) throws AntException { configureServices(); - if (properties != null) { - addProperties(properties); - } - // add in system properties - addProperties(System.getProperties()); + dataService.addProperties(System.getProperties(), + DataValue.PRIORITY_BASE); + if (initialDataValues != null) { + dataService.addDataValues(initialDataValues); + } setMagicProperties(); } - /** * Set the values of various magic properties * @@ -406,14 +262,19 @@ public class Frame implements DemuxOutputReceiver { } else { antHomeString = antHomeURL.toString(); } - setDataValue(MagicProperties.ANT_HOME, antHomeString, false); + DataValue antHomeValue + = new DataValue(antHomeString, DataValue.PRIORITY_USER); + dataService.setDataValue(MagicProperties.ANT_HOME, antHomeValue, + false); // ant.file URL projectSource = project.getSourceURL(); if (projectSource != null && projectSource.getProtocol().equals("file")) { - setDataValue(MagicProperties.ANT_FILE, projectSource.getFile(), - true); + DataValue antFileValue = new DataValue(projectSource.getFile(), + DataValue.PRIORITY_USER); + dataService.setDataValue(MagicProperties.ANT_FILE, + antFileValue, true); } // basedir @@ -422,7 +283,9 @@ public class Frame implements DemuxOutputReceiver { // ant.project.name String projectName = project.getName(); if (projectName != null) { - setDataValue(MagicProperties.ANT_PROJECT_NAME, projectName, true); + dataService.setDataValue(MagicProperties.ANT_PROJECT_NAME, + new DataValue(projectName, DataValue.PRIORITY_USER), + true); } } @@ -464,36 +327,6 @@ public class Frame implements DemuxOutputReceiver { } - /** - * Get all the properties from the frame and any references frames. This - * is an expensive operation since it must clone all of the property - * stores in all frames - * - * @return a Map containing the frames properties indexed by their full - * name. - */ - protected Map getAllProperties() { - Map allProperties = new HashMap(dataValues); - Iterator i = referencedFrames.keySet().iterator(); - - while (i.hasNext()) { - String refName = (String) i.next(); - Frame refFrame = getReferencedFrame(refName); - Map refProperties = refFrame.getAllProperties(); - Iterator j = refProperties.keySet().iterator(); - - while (j.hasNext()) { - String name = (String) j.next(); - Object value = refProperties.get(name); - - allProperties.put(refName + Project.REF_DELIMITER + name, - value); - } - } - - return allProperties; - } - /** * Get the Ant initialization configuration for this frame. @@ -572,12 +405,20 @@ public class Frame implements DemuxOutputReceiver { /** * Get the frames representing referenced projects. * - * @return an iterator which returns the referenced ExeuctionFrames.. + * @return an iterator which returns the referenced ExeuctionFrames. */ protected Iterator getReferencedFrames() { return referencedFrames.values().iterator(); } + /** + * Get the names used for referenced projects + * + * @return an iterator which returns the referenced frame names. + */ + protected Iterator getRefNames() { + return referencedFrames.keySet().iterator(); + } /** * Get the name of an object in its frame @@ -595,51 +436,6 @@ public class Frame implements DemuxOutputReceiver { } - /** - * Get a value from this frame or any imported frame - * - * @param name the name of the data value - may contain reference - * delimiters - * @return the data value fetched from the appropriate frame - * @exception ExecutionException if the value is not defined - */ - protected Object getDataValue(String name) throws ExecutionException { - Frame frame = getContainingFrame(name); - - if (frame == null) { - return getOverrideProperty(name); - } - if (frame == this) { - return dataValues.get(name); - } else { - return frame.getDataValue(getNameInFrame(name)); - } - } - - - /** - * Indicate if a data value has been set - * - * @param name the name of the data value - may contain reference - * delimiters - * @return true if the value exists - * @exception ExecutionException if the containing frame for the value - * does not exist - */ - protected boolean isDataValueSet(String name) throws ExecutionException { - Frame frame = getContainingFrame(name); - - if (frame == null) { - return isOverrideSet(name); - } - if (frame == this) { - return dataValues.containsKey(name); - } else { - return frame.isDataValueSet(getNameInFrame(name)); - } - } - - /** * Get the execution frame which contains, directly, the named element * where the name is relative to this frame @@ -672,23 +468,6 @@ public class Frame implements DemuxOutputReceiver { return currentFrame; } - - /** - * Add a collection of properties to this frame - * - * @param properties the collection of property values, indexed by their - * names - * @exception ExecutionException if the frame cannot be created. - */ - protected void addProperties(Map properties) throws ExecutionException { - for (Iterator i = properties.keySet().iterator(); i.hasNext();) { - String name = (String) i.next(); - Object value = properties.get(name); - - setDataValue(name, value, false); - } - } - /** * Create a project reference. * @@ -701,19 +480,20 @@ public class Frame implements DemuxOutputReceiver { protected void createProjectReference(String name, Project project, Map initialData) throws AntException { - Frame referencedFrame = createFrame(project); - addListeners(referencedFrame); + Frame referencedFrame = createFrame(project); + addListeners(referencedFrame); - referencedFrame.initialize(initialData); - // does the frame have any overrides? - Map initialProperties = (Map) overrides.get(name); - referencedFrame.initialize(initialProperties); - overrides.remove(name); + Map overrideProperties = dataService.getOverrides(name); + Map values = new HashMap(); + dataService.mergeDataValues(values, initialData); + dataService.mergeDataValues(values, overrideProperties); + referencedFrame.initialize(values); + dataService.removeOverrides(name); - referencedFrames.put(name, referencedFrame); - referencedFrame.importStandardComponents(); - referencedFrame.runGlobalTasks(); + referencedFrames.put(name, referencedFrame); + referencedFrame.importStandardComponents(); + referencedFrame.runGlobalTasks(); } /** @@ -807,6 +587,7 @@ public class Frame implements DemuxOutputReceiver { * @exception AntException if there is a problem in the build */ protected void runBuild(List targets) throws AntException { + log("Running build.", MessageLevel.DEBUG); importStandardComponents(); runGlobalTasks(); if (targets.isEmpty()) { @@ -815,14 +596,14 @@ public class Frame implements DemuxOutputReceiver { if (defaultTarget != null) { log("Executing default target: " + defaultTarget, - MessageLevel.MSG_DEBUG); + MessageLevel.DEBUG); executeTarget(defaultTarget); } } else { for (Iterator i = targets.iterator(); i.hasNext();) { String targetName = (String) i.next(); - log("Executing target: " + targetName, MessageLevel.MSG_DEBUG); + log("Executing target: " + targetName, MessageLevel.DEBUG); executeTarget(targetName); } } @@ -1108,7 +889,7 @@ public class Frame implements DemuxOutputReceiver { if (ifCondition != null) { ifCondition = dataService.replacePropertyRefs(ifCondition.trim()); - if (!isDataValueSet(ifCondition)) { + if (!dataService.isDataValueSet(ifCondition)) { return; } } @@ -1116,7 +897,7 @@ public class Frame implements DemuxOutputReceiver { if (unlessCondition != null) { unlessCondition = dataService.replacePropertyRefs(unlessCondition.trim()); - if (isDataValueSet(unlessCondition)) { + if (dataService.isDataValueSet(unlessCondition)) { return; } } @@ -1161,29 +942,32 @@ public class Frame implements DemuxOutputReceiver { Throwable buildFailureCause = null; try { // load system ant lib - URL systemLibs - = new URL(antEnv.getLibraryURL(), "syslibs/"); - componentManager.loadLib(systemLibs, false); + log("Loading system antlibs.", MessageLevel.DEBUG); + URL systemLibsURL = antEnv.getSyslibsURL(); + componentManager.loadLib(systemLibsURL, false); + log("Importing standard components.", MessageLevel.DEBUG); importStandardComponents(); + log("Executing global configuration tasks", MessageLevel.DEBUG); executeTasks(config.getGlobalTasks()); // now load other system libraries - URL antLibs = new URL(antEnv.getLibraryURL(), "antlibs/"); - componentManager.loadLib(antLibs, false); + log("Loading standard antlibs.", MessageLevel.DEBUG); + URL antLibsURL = antEnv.getAntlibsURL(); + componentManager.loadLib(antLibsURL, false); runBuild(targets); - } catch (MalformedURLException e) { - ExecutionException ee = - new ExecutionException("Unable to initialize antlibs", e); - buildFailureCause = ee; - throw ee; } catch (RuntimeException e) { buildFailureCause = e; throw e; } catch (AntException e) { buildFailureCause = e; throw e; + } catch (Throwable e) { + ExecutionException ee = + new ExecutionException("Unable to initialize antlibs", e); + buildFailureCause = ee; + throw ee; } finally { eventSupport.fireBuildFinished(project, buildFailureCause); } @@ -1220,9 +1004,11 @@ public class Frame implements DemuxOutputReceiver { + " is not a directory"); } this.baseDir = baseDir; - setDataValue(MagicProperties.BASEDIR, baseDir.getPath(), false); + dataService.setDataValue(MagicProperties.BASEDIR, + new DataValue(baseDir.getPath(), DataValue.PRIORITY_USER), + false); log("Project base dir set to: " + this.baseDir, - MessageLevel.MSG_VERBOSE); + MessageLevel.VERBOSE); } @@ -1233,9 +1019,9 @@ public class Frame implements DemuxOutputReceiver { * determined */ private void determineBaseDir() throws AntException { - if (isDataValueSet(MagicProperties.BASEDIR)) { + if (dataService.isDataValueSet(MagicProperties.BASEDIR)) { String baseDirString - = getDataValue(MagicProperties.BASEDIR).toString(); + = dataService.getDataValue(MagicProperties.BASEDIR).toString(); setBaseDir(new File(baseDirString)); } else { URL projectURL = project.getSourceURL(); diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskAdapter.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskAdapter.java index 6b8d6b0c1..f6431dc63 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskAdapter.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskAdapter.java @@ -106,7 +106,7 @@ public class TaskAdapter extends AbstractTask { try { executeMethod.invoke(worker, null); } catch (InvocationTargetException e) { - log("Error in " + worker.getClass(), MessageLevel.MSG_ERR); + log("Error in " + worker.getClass(), MessageLevel.ERROR); Throwable t = e.getTargetException(); if (t instanceof ExecutionException) { throw (ExecutionException) t; @@ -114,7 +114,7 @@ public class TaskAdapter extends AbstractTask { throw new ExecutionException(t); } } catch (Throwable t) { - log("Error in " + worker.getClass(), MessageLevel.MSG_ERR); + log("Error in " + worker.getClass(), MessageLevel.ERROR); throw new ExecutionException(t); } } diff --git a/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendException.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/frontend/FrontendException.java similarity index 99% rename from proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendException.java rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/frontend/FrontendException.java index 54a17024f..f4c3e8acd 100644 --- a/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendException.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/frontend/FrontendException.java @@ -51,7 +51,7 @@ * information on the Apache Software Foundation, please see * . */ -package org.apache.ant.frontend; +package org.apache.ant.antcore.frontend; import org.apache.ant.common.util.AntException; import org.apache.ant.common.util.Location; diff --git a/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendUtils.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/frontend/FrontendUtils.java similarity index 95% rename from proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendUtils.java rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/frontend/FrontendUtils.java index 9cc94fa4d..5869dc6dd 100644 --- a/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendUtils.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/frontend/FrontendUtils.java @@ -51,7 +51,7 @@ * information on the Apache Software Foundation, please see * . */ -package org.apache.ant.frontend; +package org.apache.ant.antcore.frontend; import java.io.File; import java.io.FileNotFoundException; @@ -114,10 +114,6 @@ public class FrontendUtils { URL configFileURL = InitUtils.getFileURL(configFile); ParseContext context = new ParseContext(); - context.declareNamespace(Namespace.ANT_META_PREFIX, - Namespace.ANT_META_URI); - context.declareNamespace(Namespace.XSI_PREFIX, - Namespace.XSI_URI); AntConfigHandler configHandler = new AntConfigHandler(); diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java index 5a8f59d1d..d534ee8e0 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java @@ -75,10 +75,7 @@ public class ProjectHandler extends ModelElementHandler { /** The default attribute name */ public static final String DEFAULT_ATTR = "default"; - /** The name of the element used to define references */ - public static final String REF_ELEMENT = "ant:ref"; - - /** The name of the element used to define references */ + /** The name of the element used to define includes */ public static final String INCLUDE_ELEMENT = "ant:include"; /** The name of the element used to define references */ diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/XMLProjectParser.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/XMLProjectParser.java index 26da99ddf..7564ba0c9 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/XMLProjectParser.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/XMLProjectParser.java @@ -79,10 +79,6 @@ public class XMLProjectParser { throws XMLParseException { try { ParseContext context = new ParseContext(); - context.declareNamespace(Namespace.ANT_META_PREFIX, - Namespace.ANT_META_URI); - context.declareNamespace(Namespace.XSI_PREFIX, - Namespace.XSI_URI); ProjectHandler projectHandler = new ProjectHandler(); diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java index d2b26b5be..2fa0fa2f2 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java @@ -56,22 +56,22 @@ import java.net.URL; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import org.apache.ant.common.util.AttributeCollection; import org.apache.ant.common.util.Location; -import org.apache.ant.common.util.AttributeCollection; +import org.apache.ant.common.util.PropertyUtils; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; -import org.apache.ant.common.util.PropertyUtils; /** - * An Element Handler is a handler which handles a single element by - * becoming the handler for the parser while processing the element. Any sub - * elements must be delegated to separate handlers. When this element is - * finished, control returns to the parent handler. + * An Element Handler is a handler which handles a single element by becoming + * the handler for the parser while processing the element. Any sub elements + * must be delegated to separate handlers. When this element is finished, + * control returns to the parent handler. * * @author Conor MacNeill * @created 9 January 2002 @@ -81,8 +81,8 @@ public abstract class ElementHandler extends DefaultHandler { private ParseContext context; /** - * Locator used to identify where in the build source particular - * elements occur. + * Locator used to identify where in the build source particular elements + * occur. */ private Locator locator; @@ -133,10 +133,9 @@ public abstract class ElementHandler extends DefaultHandler { * Get the collection of namespace attributes for a given namespace. * * @param uri the URI of the namespace from which the attribute collection - * is required. - * + * is required. * @return an attribute collection if any attributes of the requested - * namespace have beebn encountered - otherwise null. + * namespace have beebn encountered - otherwise null. */ public AttributeCollection getNamespaceAttributes(String uri) { return (AttributeCollection) namespaces.get(uri); @@ -193,10 +192,8 @@ public abstract class ElementHandler extends DefaultHandler { * @param source the URL from which the XML source is being parsed. * @param xmlReader the parser being used * @param context the parser context for this element - * @param elementName the actual element Name for this element in the - * XML - * @exception SAXParseException if there is a problem parsing the - * element + * @param elementName the actual element Name for this element in the XML + * @exception SAXParseException if there is a problem parsing the element */ public final void start(ParseContext context, XMLReader xmlReader, ContentHandler parent, Locator locator, @@ -216,8 +213,8 @@ public abstract class ElementHandler extends DefaultHandler { /** - * Process an element. This resolves any namespaces against - * prefixes declared in the ParseContext. + * Process an element. This resolves any namespaces against prefixes + * declared in the ParseContext. * * @param uri The Namespace URI. * @param localName The local name (without prefix). @@ -225,7 +222,7 @@ public abstract class ElementHandler extends DefaultHandler { * @param attributes The attributes attached to the element. * @throws SAXParseException if there is a problem parsng the subelement */ - final public void startElement(String uri, String localName, + public final void startElement(String uri, String localName, String qualifiedName, Attributes attributes) throws SAXParseException { addNestedElement(uri, localName, qualifiedName, attributes); @@ -233,8 +230,8 @@ public abstract class ElementHandler extends DefaultHandler { /** * By default an element handler does not support nested elements. This - * method will always throw an exception. Subclasses should override - * this method to support their own nested elements + * method will always throw an exception. Subclasses should override this + * method to support their own nested elements * * @param uri The Namespace URI. * @param localName The local name (without prefix). @@ -252,8 +249,8 @@ public abstract class ElementHandler extends DefaultHandler { /** - * Handle the end of this element by making the parent element handler - * the current content handler + * Handle the end of this element by making the parent element handler the + * current content handler * * @param localName The local name (without prefix). * @param namespaceURI The Namespace URI. @@ -330,15 +327,14 @@ public abstract class ElementHandler extends DefaultHandler { * Process the element. * * @param elementName the name of the element - * @exception SAXParseException if there is a problem parsing the - * element + * @exception SAXParseException if there is a problem parsing the element */ protected abstract void processElement(String elementName) throws SAXParseException; /** - * Process all of the attributes of the element into maps, one for - * aspects and one for other attributes + * Process all of the attributes of the element into maps, one for aspects + * and one for other attributes * * @param attributes The SAX attributes collection for the element * @exception SAXParseException if there is a problem reading the @@ -357,21 +353,10 @@ public abstract class ElementHandler extends DefaultHandler { uri = null; } - - if (uri == null) { - if (qName.indexOf(":") != -1) { - // try to resolve through known namespaces - uri = context.resolveNamespace(qName); - localName = qName.substring(qName.indexOf(":") + 1); - } else { - localName = qName; - } - } - String attributeValue = attributes.getValue(i); if (uri != null) { AttributeCollection namespaceAttributes - = (AttributeCollection) namespaces.get(uri); + = (AttributeCollection) namespaces.get(uri); if (namespaceAttributes == null) { namespaceAttributes = new AttributeCollection(); namespaces.put(uri, namespaceAttributes); @@ -417,8 +402,8 @@ public abstract class ElementHandler extends DefaultHandler { /** * This method is called when this element is finished being processed. - * This is a template method allowing subclasses to complete any - * necessary processing. + * This is a template method allowing subclasses to complete any necessary + * processing. */ protected void finish() { } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java index 40cc6dc15..48df853d4 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java @@ -88,6 +88,12 @@ public class ParseContext { /** The factory used to create SAX parsers. */ private SAXParserFactory parserFactory; + /** + * Initialize a parse context. + * + * This method creates the Parser Factory for which it sets the + * context classloader. + */ public ParseContext() { Thread thread = Thread.currentThread(); ClassLoader currentContextLoader = thread.getContextClassLoader(); @@ -173,29 +179,5 @@ public class ParseContext { throw new XMLParseException(e); } } - - /** - * Given an XML qName, this method tries to resolve a name into a URI - * using the map of well known namespaces. - * - * @param qName the XML qName - * @return the namespace URI for the given name. If the namespace - * prefix is unknown the prefix is returned. - */ - public String resolveNamespace(String qName) { - String namespaceId = qName.substring(0, qName.indexOf(":")); - String namespaceURI = (String) knownNamespaces.get(namespaceId); - return namespaceURI == null ? namespaceId : namespaceURI; - } - - /** - * Declare a namespace - * - * @param prefix the prefix that is used in the XML for the namespace. - * @param uri the namespace's unique URI. - */ - public void declareNamespace(String prefix, String uri) { - knownNamespaces.put(prefix, uri); - } } diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java index 8ff27de8e..9c106d477 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java @@ -57,11 +57,11 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Enumeration; +import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.HashMap; import java.util.Properties; import java.util.Stack; import java.util.Vector; @@ -74,6 +74,7 @@ import org.apache.ant.common.service.ExecService; import org.apache.ant.common.service.FileService; import org.apache.ant.common.service.InputService; import org.apache.ant.common.util.AntException; +import org.apache.ant.common.util.DataValue; import org.apache.ant.common.util.PropertyUtils; import org.apache.tools.ant.input.InputHandler; import org.apache.tools.ant.types.FilterSet; @@ -88,8 +89,8 @@ import org.apache.tools.ant.util.FileUtils; */ public class Project implements org.apache.ant.common.event.BuildListener { /** - * A Property key which identifies the Project actiong as proxy for a - * a project. + * A Property key which identifies the Project actiong as proxy for a a + * project. */ private static final String PROXY_KEY = "_ant.proxy"; @@ -105,29 +106,35 @@ public class Project implements org.apache.ant.common.event.BuildListener { public static final String JAVA_1_4 = "1.4"; /** - * @see MessageLevel.MSG_ERR + * @see MessageLevel.ERR */ - public static final int MSG_ERR = MessageLevel.MSG_ERR; + public static final int MSG_ERR = MessageLevel.ERROR; /** - * @see MessageLevel.MSG_WARN + * @see MessageLevel.WARN */ - public static final int MSG_WARN = MessageLevel.MSG_WARN; + public static final int MSG_WARN = MessageLevel.WARNING; /** - * @see MessageLevel.MSG_INFO + * @see MessageLevel.INFO */ - public static final int MSG_INFO = MessageLevel.MSG_INFO; + public static final int MSG_INFO = MessageLevel.INFO; /** - * @see MessageLevel.MSG_VERBOSE + * @see MessageLevel.VERBOSE */ - public static final int MSG_VERBOSE = MessageLevel.MSG_VERBOSE; + public static final int MSG_VERBOSE = MessageLevel.VERBOSE; /** - * @see MessageLevel.MSG_DEBUG + * @see MessageLevel.DEBUG */ - public static final int MSG_DEBUG = MessageLevel.MSG_DEBUG; + public static final int MSG_DEBUG = MessageLevel.DEBUG; /** The java version detected that Ant is running on */ private static String javaVersion; + /** + * A static copy of a context used fro Projects which have been created on + * the fly. It is used to access the required core services + */ + private static AntContext sharedContext = null; + /** Called to handle any input requests. */ private InputHandler inputHandler = null; @@ -163,12 +170,6 @@ public class Project implements org.apache.ant.common.event.BuildListener { /** The core's Component Service instance */ private ComponentService componentService; - /** - * A static copy of a context used fro Projects which have been created on - * the fly. It is used to access the required core services - */ - private static AntContext sharedContext = null; - /** Ant1 FileUtils instance for manipulating files */ private FileUtils fileUtils; /** The collection of global filters */ @@ -182,30 +183,24 @@ public class Project implements org.apache.ant.common.event.BuildListener { private Stack targetStack = new Stack(); /** - * Flag which indicates if this project object is proxing for a subordinate - * project which has not yet been created. + * Flag which indicates if this project object is proxing for a + * subordinate project which has not yet been created. */ private boolean proxying; /** - * The properties which will be passed to the project instance for which we - * are proxing. + * The properties which will be passed to the project instance for which + * we are proxing. */ private Map proxyProperties = new HashMap(); - /** - * The build key used to control the proxied build. - */ + /** The build key used to control the proxied build. */ private Object proxyBuildKey; - /** - * The subordinate project if proxying - */ + /** The subordinate project if proxying */ private Project subordinate; - /** - * The requested base dir - */ + /** The requested base dir */ private File baseDir = null; static { @@ -251,33 +246,11 @@ public class Project implements org.apache.ant.common.event.BuildListener { public Project() { if (sharedContext == null) { throw new BuildException("Project object can no longer be " - + "constructed outside Ant execution"); + + "constructed outside Ant execution"); } proxying = true; } - /** - * Configure a new project - * - * @param buildFile the file containing the XML build definition. - */ - protected void configure(File buildFile) { - try { - // we create an execution frame and link ourselves to the Project - // object created in that frame - ExecService sharedExec - = (ExecService) sharedContext.getCoreService(ExecService.class); - org.apache.ant.common.model.Project subProject - = sharedExec.parseXMLBuildFile(buildFile); - proxyProperties.put(PROXY_KEY, this); - proxyBuildKey - = sharedExec.setupBuild(subProject, proxyProperties, false); - sharedExec.initializeBuildLibrary(proxyBuildKey, "ant.ant1compat"); - } catch (AntException e) { - throw new BuildException(e.getMessage(), e); - } - } - /** * static query of the java version * @@ -330,6 +303,29 @@ public class Project implements org.apache.ant.common.event.BuildListener { return path.toString(); } + /** + * Configure a new project + * + * @param buildFile the file containing the XML build definition. + */ + protected void configure(File buildFile) { + try { + // we create an execution frame and link ourselves to the Project + // object created in that frame + ExecService sharedExec = (ExecService) + sharedContext.getCoreService(ExecService.class); + org.apache.ant.common.model.Project subProject + = sharedExec.parseXMLBuildFile(buildFile); + proxyProperties.put(PROXY_KEY, + new DataValue(this, DataValue.PRIORITY_USER)); + proxyBuildKey + = sharedExec.setupBuild(subProject, proxyProperties, false); + sharedExec.initializeBuildLibrary(proxyBuildKey, "ant.ant1compat"); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); + } + } + /** * The old initialisation method for Projects. Not used now * @@ -418,8 +414,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { targets.add(i.next()); } - ExecService execService - = (ExecService) sharedContext.getCoreService(ExecService.class); + ExecService sharedExec = (ExecService) + sharedContext.getCoreService(ExecService.class); execService.runBuild(proxyBuildKey, targets); } catch (AntException e) { throw new BuildException(e.getMessage(), e); @@ -429,8 +425,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { /** * Executes the specified target and any targets it depends on. * - * @param targetName The name of the target to execute. - * Must not be null. + * @param targetName The name of the target to execute. Must not be + * null. * * @exception BuildException if the build failed */ @@ -452,8 +448,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { List targets = new ArrayList(); targets.add(targetName); - ExecService execService - = (ExecService) sharedContext.getCoreService(ExecService.class); + ExecService sharedExec = (ExecService) + sharedContext.getCoreService(ExecService.class); execService.runBuild(proxyBuildKey, targets); } catch (AntException e) { throw new BuildException(e.getMessage(), e); @@ -469,6 +465,38 @@ public class Project implements org.apache.ant.common.event.BuildListener { this.description = description; } + + /** + * Set a DataValue with the given name. + * + * @param name the name of the datavalue + * @param value the datavalue itself + * @param mutable true if a value at the same priority can be overwritten. + */ + private synchronized void setDataValue(String name, DataValue value, + boolean mutable) { + if (dataService == null) { + if (proxyProperties.containsKey(name)) { + int priority = value.getPriority(); + DataValue current = (DataValue) proxyProperties.get(name); + int currentPriority = current.getPriority(); + if (currentPriority > priority + || (currentPriority == priority && !mutable)) { + log("Ignoring override for data value " + name, + MessageLevel.VERBOSE); + return; + } + } + proxyProperties.put(name, value); + } else { + try { + dataService.setDataValue(name, value, true); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); + } + } + } + /** * Set a project property * @@ -476,11 +504,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @param value the property value */ public void setProperty(String name, String value) { - try { - dataService.setMutableDataValue(name, value); - } catch (AntException e) { - throw new BuildException(e.getMessage(), e); - } + setDataValue(name, new DataValue(value, DataValue.PRIORITY_BASE), + true); } /** @@ -489,51 +514,41 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @param name the property name * @param value the property value */ - public void setNewProperty(String name, String value) { - if (dataService == null) { - if (!proxyProperties.containsKey(name)) { - proxyProperties.put(name, value); - } - return; - } - try { - dataService.setDataValue(name, value); - } catch (AntException e) { - throw new BuildException(e.getMessage(), e); - } + public synchronized void setNewProperty(String name, String value) { + setDataValue(name, new DataValue(value, DataValue.PRIORITY_BASE), + false); } /** - * Sets a userProperty of the Project. Note under Ant2, there is no - * distinction between user and system properties + * Sets an inherited property of the Project. * * @param name the property name * @param value the property value */ - public void setUserProperty(String name, String value) { - if (dataService == null) { - proxyProperties.put(name, value); - return; - } + public synchronized void setInheritedProperty(String name, String value) { + setDataValue(name, new DataValue(value, DataValue.PRIORITY_INHERIT), + false); + } - try { - dataService.setMutableDataValue(name, value); - } catch (AntException e) { - throw new BuildException(e.getMessage(), e); - } + /** + * Sets a userProperty of the Project. + * + * @param name the property name + * @param value the property value + */ + public synchronized void setUserProperty(String name, String value) { + setDataValue(name, new DataValue(value, DataValue.PRIORITY_USER), + false); } /** - * Returns a description of the type of the given element, with - * special handling for instances of tasks and data types. - *

- * This is useful for logging purposes. + * Returns a description of the type of the given element, with special + * handling for instances of tasks and data types.

* - * @param element The element to describe. - * Must not be null. + * This is useful for logging purposes. * + * @param element The element to describe. Must not be null. * @return a description of the element type - * * @since 1.95, Ant 1.5 */ public String getElementName(Object element) { @@ -608,7 +623,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @return A Vector of BuildListener instances */ public Vector getBuildListeners() { - return listeners; + return (Vector) listeners.clone(); } /** @@ -718,17 +733,21 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @return the hashtable containing all properties, user included */ public Hashtable getProperties() { - Map properties = dataService.getAllProperties(); - Hashtable result = new Hashtable(); - for (Iterator i = properties.keySet().iterator(); i.hasNext();) { - String name = (String) i.next(); - Object value = properties.get(name); - if (value instanceof String) { - result.put(name, value); + try { + Map dataValues = dataService.getAllDataValues(); + Hashtable result = new Hashtable(); + for (Iterator i = dataValues.keySet().iterator(); i.hasNext();) { + String name = (String) i.next(); + DataValue dataValue = (DataValue) dataValues.get(name); + if (dataValue.getValue() instanceof String) { + result.put(name, dataValue.getValue()); + } } - } - return result; + return result; + } catch (AntException e) { + throw new BuildException(e); + } } /** @@ -746,17 +765,21 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @return the hashtable containing all references */ public Hashtable getReferences() { - Map properties = dataService.getAllProperties(); - Hashtable result = new Hashtable(); - for (Iterator i = properties.keySet().iterator(); i.hasNext();) { - String name = (String) i.next(); - Object value = properties.get(name); - if (!(value instanceof String)) { - result.put(name, value); + try { + Map dataValues = dataService.getAllDataValues(); + Hashtable result = new Hashtable(); + for (Iterator i = dataValues.keySet().iterator(); i.hasNext();) { + String name = (String) i.next(); + DataValue dataValue = (DataValue) dataValues.get(name); + if (!(dataValue.getValue() instanceof String)) { + result.put(name, dataValue.getValue()); + } } - } - return result; + return result; + } catch (AntException e) { + throw new BuildException(e); + } } /** @@ -866,10 +889,10 @@ public class Project implements org.apache.ant.common.event.BuildListener { Object source = event.getSource(); if (source instanceof Task) { fireMessageLogged((Task) source, event.getMessage(), - event.getPriority()); + event.getPriority()); } else { fireMessageLogged(this, event.getMessage(), - event.getPriority()); + event.getPriority()); } } @@ -896,18 +919,15 @@ public class Project implements org.apache.ant.common.event.BuildListener { } /** - * Add a reference to an object. NOte that in Ant2 objects and properties + * Add a reference to an object. Note that in Ant2 objects and properties * occupy the same namespace. * * @param name the reference name - * @param value the object to be associated with the given name. + * @param reference the reference to be added. */ - public void addReference(String name, Object value) { - try { - dataService.setDataValue(name, value); - } catch (AntException e) { - throw new BuildException(e.getMessage(), e); - } + public void addReference(String name, Object reference) { + DataValue value = new DataValue(reference, DataValue.PRIORITY_BASE); + setDataValue(name, value, false); } @@ -962,8 +982,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { /** * Convienence method to copy a file from a source to a destination * specifying if token filtering must be used, if source files may - * overwrite newer destination files and the last modified time - * of destFile file should be made equal to the last + * overwrite newer destination files and the last modified time of + * destFile file should be made equal to the last * modified time of sourceFile. * * @param sourceFile the source file to be copied @@ -1034,8 +1054,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { * Convienence method to copy a file from a source to a destination * specifying if token filtering must be used, if source files may * overwrite newer destination files and the last modified time of - * destFile file should be made equal to the last - * modified time of sourceFile. + * destFile file should be made equal to the last modified + * time of sourceFile. * * @param sourceFile the source file to be copied * @param destFile the destination to which the file is copied @@ -1054,7 +1074,6 @@ public class Project implements org.apache.ant.common.event.BuildListener { } - /** * Initialise this project * @@ -1072,16 +1091,14 @@ public class Project implements org.apache.ant.common.event.BuildListener { } /** - * Connect this project to its subordinate. - * - * When the subordinate project is created it will call this method to - * inform this project. The core services are then initialised using the - * context of the subordinate project + * Connect this project to its subordinate. When the subordinate project + * is created it will call this method to inform this project. The core + * services are then initialised using the context of the subordinate + * project * * @param subordinate the subordinate project - * - * @exception AntException if there is a problem configuring this project to - * use the subordinate's context. + * @exception AntException if there is a problem configuring this project + * to use the subordinate's context. */ private void setSubordinate(Project subordinate) throws AntException { initContext(subordinate.getContext()); @@ -1097,12 +1114,11 @@ public class Project implements org.apache.ant.common.event.BuildListener { } /** - * Sets the base directory for the project, checking that - * the given filename exists and is a directory. - * - * @param baseDir The project base directory. - * Must not be null. + * Sets the base directory for the project, checking that the given + * filename exists and is a directory. * + * @param baseDir The project base directory. Must not be null + * . * @exception BuildException if the directory if invalid */ public void setBasedir(String baseDir) throws BuildException { @@ -1110,13 +1126,13 @@ public class Project implements org.apache.ant.common.event.BuildListener { } /** - * Sets the base directory for the project, checking that - * the given file exists and is a directory. + * Sets the base directory for the project, checking that the given file + * exists and is a directory. * - * @param baseDir The project base directory. - * Must not be null. - * @exception BuildException if the specified file doesn't exist or - * isn't a directory + * @param baseDir The project base directory. Must not be null + * . + * @exception BuildException if the specified file doesn't exist or isn't + * a directory */ public void setBaseDir(File baseDir) throws BuildException { try { @@ -1214,20 +1230,17 @@ public class Project implements org.apache.ant.common.event.BuildListener { /** - * Returns the canonical form of a filename. - *

- * If the specified file name is relative it is resolved - * with respect to the given root directory. - * - * @param fileName The name of the file to resolve. - * Must not be null. + * Returns the canonical form of a filename.

* - * @param rootDir The directory to resolve relative file names with - * respect to. May be null, in which case - * the current directory is used. + * If the specified file name is relative it is resolved with respect to + * the given root directory. * + * @param fileName The name of the file to resolve. Must not be + * null. + * @param rootDir The directory to resolve relative file names with + * respect to. May be null, in which case the current + * directory is used. * @return the resolved File. - * * @deprecated */ public File resolveFile(String fileName, File rootDir) { @@ -1356,6 +1369,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { /** send build started event to the listeners */ protected void fireBuildStarted() { BuildEvent event = new BuildEvent(this); + Vector listeners = getBuildListeners(); for (int i = 0; i < listeners.size(); i++) { BuildListener listener = (BuildListener) listeners.elementAt(i); listener.buildStarted(event); @@ -1370,6 +1384,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { protected void fireBuildFinished(Throwable exception) { BuildEvent event = new BuildEvent(this); event.setException(exception); + Vector listeners = getBuildListeners(); for (int i = 0; i < listeners.size(); i++) { BuildListener listener = (BuildListener) listeners.elementAt(i); listener.buildFinished(event); @@ -1384,6 +1399,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { */ protected void fireTargetStarted(Target target) { BuildEvent event = new BuildEvent(target); + Vector listeners = getBuildListeners(); for (int i = 0; i < listeners.size(); i++) { BuildListener listener = (BuildListener) listeners.elementAt(i); listener.targetStarted(event); @@ -1399,6 +1415,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { protected void fireTargetFinished(Target target, Throwable exception) { BuildEvent event = new BuildEvent(target); event.setException(exception); + Vector listeners = getBuildListeners(); for (int i = 0; i < listeners.size(); i++) { BuildListener listener = (BuildListener) listeners.elementAt(i); listener.targetFinished(event); @@ -1414,6 +1431,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { // register this as the current task on the current thread. // threadTasks.put(Thread.currentThread(), task); BuildEvent event = new BuildEvent(task); + Vector listeners = getBuildListeners(); for (int i = 0; i < listeners.size(); i++) { BuildListener listener = (BuildListener) listeners.elementAt(i); listener.taskStarted(event); @@ -1432,6 +1450,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { // System.err.flush(); BuildEvent event = new BuildEvent(task); event.setException(exception); + Vector listeners = getBuildListeners(); for (int i = 0; i < listeners.size(); i++) { BuildListener listener = (BuildListener) listeners.elementAt(i); listener.taskFinished(event); @@ -1487,6 +1506,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { private void fireMessageLoggedEvent(BuildEvent event, String message, int priority) { event.setMessage(message, priority); + Vector listeners = getBuildListeners(); for (int i = 0; i < listeners.size(); i++) { BuildListener listener = (BuildListener) listeners.elementAt(i); listener.messageLogged(event); diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/RuntimeConfigurable.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/RuntimeConfigurable.java new file mode 100644 index 000000000..9769905be --- /dev/null +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/RuntimeConfigurable.java @@ -0,0 +1,191 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant; + +import org.xml.sax.AttributeList; + +/** + * Implementation shell of the corresponding Ant1 class + * + * @author Conor MacNeill + * @created 26 June 2002 + */ +public class RuntimeConfigurable { + + /** + * Sole constructor creating a wrapper for the specified object. + * + * @param proxy The element to configure. Must not be null. + * @param elementTag The tag name generating this element. Should not be + * null. + */ + public RuntimeConfigurable(Object proxy, String elementTag) { + } + + /** + * Sets the element to configure. This is used when the real type of an + * element isn't known at the time of wrapper creation. + * + * @param proxy The element to configure. Must not be null. + */ + void setProxy(Object proxy) { + } + + /** + * Sets the attributes for the wrapped element. + * + * @param attributes List of attributes defined in the XML for this + * element. May be null. + */ + public void setAttributes(AttributeList attributes) { + } + + /** + * Returns the list of attributes for the wrapped element. + * + * @return An AttributeList representing the attributes defined in the XML + * for this element. May be null. + */ + public AttributeList getAttributes() { + return null; + } + + /** + * Adds a child element to the wrapped element. + * + * @param child The child element wrapper to add to this one. Must not be + * null. + */ + public void addChild(RuntimeConfigurable child) { + } + + /** + * Returns the child wrapper at the specified position within the list. + * + * @param index The index of the child to return. + * @return The child wrapper at position index within the + * list. + */ + RuntimeConfigurable getChild(int index) { + return null; + } + + /** + * Adds characters from #PCDATA areas to the wrapped element. + * + * @param data Text to add to the wrapped element. Should not + * be null. + */ + public void addText(String data) { + } + + /** + * Adds characters from #PCDATA areas to the wrapped element. + * + * @param buf A character array of the text within the element. Must not + * be null. + * @param start The start element in the array. + * @param count The number of characters to read from the array. + */ + public void addText(char[] buf, int start, int count) { + } + + /** + * Returns the tag name of the wrapped element. + * + * @return The tag name of the wrapped element. This is unlikely to be + * null, but may be. + */ + public String getElementTag() { + return null; + } + + /** + * Configures the wrapped element and all its children. The attributes and + * text for the wrapped element are configured, and then each child is + * configured and added. Each time the wrapper is configured, the + * attributes and text for it are reset. If the element has an + * id attribute, a reference is added to the project as well. + * + * @param p The project containing the wrapped element. Must not be + * null. + * @exception BuildException if the configuration fails, for instance due + * to invalid attributes or children, or text being added to an + * element which doesn't accept it. + */ + public void maybeConfigure(Project p) throws BuildException { + maybeConfigure(p, true); + } + + /** + * Configures the wrapped element. The attributes and text for the wrapped + * element are configured. Each time the wrapper is configured, the + * attributes and text for it are reset. If the element has an + * id attribute, a reference is added to the project as well. + * + * @param p The project containing the wrapped element. Must not be + * null. + * @param configureChildren Whether to configure child elements as well. + * if true, child elements will be configured after the wrapped + * element. + * @exception BuildException if the configuration fails, for instance due + * to invalid attributes or children, or text being added to an + * element which doesn't accept it. + */ + public void maybeConfigure(Project p, boolean configureChildren) + throws BuildException { + } + +} + diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java index e4039a421..05a69ae31 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java @@ -106,6 +106,33 @@ public abstract class Task extends ProjectComponent this.target = target; } + + /** + * Has this task been marked invalid? + * + * @since Ant 1.5 + */ + protected final boolean isInvalid() { + return false; + } + + public void maybeConfigure() throws BuildException { + // XXX + throw new BuildException("Not supported"); + } + + /** + * Returns the wrapper used for runtime configuration. + * + * @return the wrapper used for runtime configuration. This + * method will generate a new wrapper (and cache it) + * if one isn't set already. + */ + public RuntimeConfigurable getRuntimeConfigurableWrapper() { + // XXX + throw new BuildException("Not supported"); + } + /** * Sets a description of the current action. It will be usefull in * commenting what we are doing. diff --git a/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorAspect.java b/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorAspect.java index 0c11fcfb2..f8a34c2ba 100644 --- a/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorAspect.java +++ b/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorAspect.java @@ -87,7 +87,7 @@ public class MonitorAspect extends AbstractAspect { = new PrintStream(new FileOutputStream("monitor.log")); monitorLog.println("Logging started at " + new Date()); } catch (IOException e) { - log("Unable to open monitor log", MessageLevel.MSG_WARN); + log("Unable to open monitor log", MessageLevel.WARNING); } } } diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java index 5e62557ed..ace4cc2fb 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java @@ -136,7 +136,7 @@ public class Ant extends AntBase { ExecService execService = getExecService(); Project model = execService.parseXMLBuildFile(antFile); - Object key = execService.setupBuild(model, getProperties(), true); + Object key = execService.setupBuild(model, getDataValues(), true); setSubBuildKey(key); @@ -154,13 +154,13 @@ public class Ant extends AntBase { PrintStream out = new PrintStream(new FileOutputStream(outfile)); DefaultLogger logger = new DefaultLogger(); - logger.setMessageOutputLevel(MessageLevel.MSG_INFO); + logger.setMessageOutputLevel(MessageLevel.INFO); logger.setOutputPrintStream(out); logger.setErrorPrintStream(out); execService.addBuildListener(key, logger); } catch (IOException ex) { log("Ant: Can't set output to " + output, - MessageLevel.MSG_INFO); + MessageLevel.INFO); } } diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java index 9102e7747..f68a13e74 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java @@ -64,6 +64,7 @@ import org.apache.ant.common.model.BuildElement; import org.apache.ant.common.model.NamespaceValueCollection; import org.apache.ant.common.util.AttributeCollection; import org.apache.ant.common.constants.Namespace; +import org.apache.ant.common.util.DataValue; /** * The Ant aspect - handles all ant aspects @@ -144,7 +145,8 @@ public class AntAspect extends AbstractAspect { = model.getNamespaceAttributeValue(Namespace.ANT_META_URI, "id"); if (typeId != null) { - dataService.setMutableDataValue(typeId, component); + dataService.setDataValue(typeId, + new DataValue(component, DataValue.PRIORITY_BASE), true); } return super.postCreateComponent(component, model); diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java index 44afc828c..3c7849f9c 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java @@ -53,9 +53,12 @@ */ package org.apache.ant.antlib.system; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.ant.common.service.DataService; import org.apache.ant.common.util.AntException; +import org.apache.ant.common.util.DataValue; /** * Common Base class for the Ant and AntCall tasks @@ -89,17 +92,18 @@ public abstract class AntBase extends SubBuild { * Get the properties to be used with the sub-build * * @return the properties the sub-build will start with + * @exception AntException if the data values cannot be combined with + * existing values. */ - protected Map getProperties() { - if (!inheritAll) { - return super.getProperties(); - } - - // need to combine existing properties with new ones - Map subBuildProperties = getDataService().getAllProperties(); - - subBuildProperties.putAll(super.getProperties()); - return subBuildProperties; + protected Map getDataValues() throws AntException { + DataService dataService = getDataService(); + int priority = inheritAll ? DataValue.PRIORITY_BASE + : DataValue.PRIORITY_INHERIT; + + Map values = new HashMap(super.getDataValues()); + dataService.mergeDataValues(values, dataService.getAllDataValues(), + priority); + return values; } diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java index f3abb82f8..d7b2d7b6e 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java @@ -71,7 +71,7 @@ public class AntCall extends AntBase { setProperty(MagicProperties.BASEDIR, getExecService().getBaseDir().getAbsolutePath()); - Object key = getExecService().setupBuild(getProperties(), true); + Object key = getExecService().setupBuild(getDataValues(), true); setSubBuildKey(key); getExecService().runBuild(key, getTargets()); setSubBuildKey(null); diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LibPath.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LibPath.java index 97ac0858e..f6f17fd1e 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LibPath.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LibPath.java @@ -156,7 +156,7 @@ public class LibPath extends AbstractTask { ComponentService componentService = (ComponentService) context.getCoreService(ComponentService.class); log("Adding lib path " + url + " for " + libraryId, - MessageLevel.MSG_DEBUG); + MessageLevel.DEBUG); componentService.addLibPath(libraryId, url); } diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ref.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ref.java index 2f7e865f0..b37950c74 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ref.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ref.java @@ -53,9 +53,13 @@ */ package org.apache.ant.antlib.system; import java.io.File; +import java.util.HashMap; +import java.util.Map; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.model.Project; +import org.apache.ant.common.service.DataService; import org.apache.ant.common.util.AntException; +import org.apache.ant.common.util.DataValue; /** * A Task to create a project reference. @@ -106,6 +110,21 @@ public class Ref extends SubBuild { } + /** + * Get the properties to be used with the references + * + * @return the properties the sub-build will start with + * @exception AntException if the data values cannot be retrieved. + */ + protected Map getDataValues() throws AntException { + DataService dataService = getDataService(); + + Map values = new HashMap(super.getDataValues()); + dataService.mergeDataValues(values, dataService.getAllDataValues(), + DataValue.PRIORITY_USER); + return values; + } + /** * Create the project reference * @@ -114,7 +133,7 @@ public class Ref extends SubBuild { public void execute() throws AntException { Project model = getExecService().parseXMLBuildFile(projectFile); - getExecService().createProjectReference(name, model, getProperties()); + getExecService().createProjectReference(name, model, getDataValues()); } } diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/SubBuild.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/SubBuild.java index 5a58d5885..bc8efa64d 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/SubBuild.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/SubBuild.java @@ -61,6 +61,7 @@ import org.apache.ant.common.antlib.ValidationException; import org.apache.ant.common.service.DataService; import org.apache.ant.common.service.ExecService; import org.apache.ant.common.util.AntException; +import org.apache.ant.common.util.DataValue; /** * Common Base class all tasks that can pass references and property overrides @@ -217,8 +218,8 @@ public abstract class SubBuild extends AbstractTask { /** The core's ExecutionService for running builds and external programs */ private ExecService execService; - /** The properties which will be passed to the sub-build */ - private Map properties = new HashMap(); + /** The data values which will be passed to the sub-build */ + private Map dataValues = new HashMap(); /** @@ -227,7 +228,9 @@ public abstract class SubBuild extends AbstractTask { * @param property descriptor for the property to be passed */ public void addProperty(Property property) { - properties.put(property.getName(), property.getValue()); + DataValue value + = new DataValue(property.getValue(), DataValue.PRIORITY_INHERIT); + dataValues.put(property.getName(), value); } @@ -235,8 +238,8 @@ public abstract class SubBuild extends AbstractTask { * Add a reference to be passed * * @param reference the descriptor of the reference to be passed - * @exception AntException if the reference does not reference a - * valid object + * @exception AntException if the reference does not reference a valid + * object */ public void addReference(Reference reference) throws AntException { String refId = reference.getRefId(); @@ -251,7 +254,7 @@ public abstract class SubBuild extends AbstractTask { toId = refId; } - properties.put(toId, value); + dataValues.put(toId, new DataValue(value, DataValue.PRIORITY_INHERIT)); } @@ -278,10 +281,11 @@ public abstract class SubBuild extends AbstractTask { /** * Get the properties to be used with the sub-build * - * @return the properties the sub-build will start with + * @return the data values the sub-build will start with + * @exception AntException if the datavalues cannot be retrieved. */ - protected Map getProperties() { - return properties; + protected Map getDataValues() throws AntException { + return dataValues; } @@ -308,7 +312,9 @@ public abstract class SubBuild extends AbstractTask { * @param propertyValue the value of the property */ protected void setProperty(String propertyName, Object propertyValue) { - properties.put(propertyName, propertyValue); + DataValue value + = new DataValue(propertyValue, DataValue.PRIORITY_INHERIT); + dataValues.put(propertyName, value); } } diff --git a/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Ant1CompatBuilder.java b/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Ant1CompatBuilder.java index 4d73a07a6..c03ef7331 100644 --- a/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Ant1CompatBuilder.java +++ b/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Ant1CompatBuilder.java @@ -1,45 +1,106 @@ package org.apache.ant.builder; public class Ant1CompatBuilder { protected void _init(BuildHelper helper) { - helper.setProperty("src.dir", "src"); - helper.setProperty("lib.dir", "lib"); - helper.setProperty("java.dir", "${src.dir}/java"); - helper.setProperty("bin.dir", "bin"); - helper.setProperty("dist.dir", "dist"); - helper.setProperty("javadocs.dir", "${dist.dir}/javadocs"); - helper.setProperty("distlib.dir", "${dist.dir}/lib"); + helper.setProperty("debug", "true"); + helper.setProperty("deprecation", "false"); + helper.setProperty("optimize", "true"); + helper.setProperty("junit.fork", "false"); + helper.setProperty("junit.filtertrace", "off"); + helper.setProperty("junit.summary", "no"); helper.setProperty("ant1base.dir", "../.."); helper.setProperty("ant1src.dir", "${ant1base.dir}/src"); helper.setProperty("ant1java.dir", "${ant1src.dir}/main"); helper.setProperty("ant1etc.dir", "${ant1src.dir}/etc"); - helper.setProperty("debug", "true"); + helper.setProperty("ant1.tests.dir", "${ant1src.dir}/etc/testcases"); + helper.setProperty("src.dir", "src"); + helper.setProperty("java.dir", "${src.dir}/java"); + helper.setProperty("lib.dir", "lib"); + helper.setProperty("tests.dir", "${ant1src.dir}/testcases"); + helper.setProperty("tests.etc.dir", "${src.dir}/etc/testcases"); + helper.setProperty("bin.dir", "bin"); + helper.setProperty("dist.dir", "dist"); + helper.setProperty("dist.lib.dir", "${dist.dir}/lib"); + helper.setProperty("dist.core.dir", "${dist.lib.dir}/core"); + helper.setProperty("dist.antlibs.dir", "${dist.lib.dir}/antlibs"); + helper.setProperty("dist.syslibs.dir", "${dist.core.dir}/syslibs"); helper.setProperty("ant.package", "org/apache/tools/ant"); helper.setProperty("optional.package", "${ant.package}/taskdefs/optional"); helper.setProperty("optional.type.package", "${ant.package}/types/optional"); helper.setProperty("util.package", "${ant.package}/util"); helper.setProperty("regexp.package", "${util.package}/regexp"); + helper.setProperty("build.tests", "${bin.dir}/testcases"); helper.createPath("classpath"); helper.addFileSetToPath("classpath", - "${lib.dir}/parser", "*.jar"); - helper.addFileSetToPath("classpath", - "${lib.dir}/ant1compat", "*.jar"); - helper.addPathElementToPath("classpath", "${distlib.dir}/init.jar"); - helper.addPathElementToPath("classpath", "${distlib.dir}/common/common.jar"); - helper.addPathElementToPath("classpath", "${distlib.dir}/syslibs/system.jar"); + "${dist.core.dir}/parser", "*.jar"); + helper.addPathElementToPath("classpath", "${dist.core.dir}/start/init.jar"); + helper.addPathElementToPath("classpath", "${dist.core.dir}/common/common.jar"); + helper.addPathElementToPath("classpath", "${dist.syslibs.dir}/system.jar"); + helper.createPath("tests-classpath"); + helper.addPathElementToPath("tests-classpath", "${build.classes}"); + helper.addPathElementToPath("tests-classpath", "${build.tests}"); + helper.addPathElementToPath("tests-classpath", "${tests.dir}"); + helper.addPathElementToPath("tests-classpath", "${tests.etc.dir}"); + helper.addPathToPath("tests-classpath", "classpath"); } protected void check_for_optional_packages(BuildHelper helper) { + helper.runDepends(this, "check_for_optional_packages", ""); + System.out.println("check_for_optional_packages: "); + helper.setProperty("build.tests.resolved", ""); } protected void ant1compat(BuildHelper helper) { + helper.runDepends(this, "ant1compat", "check_for_optional_packages"); + System.out.println("ant1compat: "); helper.mkdir("${bin.dir}/ant1src_copy"); helper.mkdir("${bin.dir}/ant1compat"); helper.copyFilesetRef("ant1src_tocopy", "${bin.dir}/ant1src_copy"); helper.javac("${bin.dir}/ant1src_copy:${java.dir}/antlibs/ant1compat", "${bin.dir}/ant1compat", "classpath"); helper.copyFileset("${bin.dir}/ant1src_copy", "${bin.dir}/ant1compat"); helper.copyFileset("${ant1etc.dir}", "${bin.dir}/ant1compat/${optional.package}/junit/xsl"); - helper.mkdir("${distlib.dir}/antlibs/"); - helper.jar("${bin.dir}/ant1compat", "${distlib.dir}/antlibs/ant1compat.jar", + helper.mkdir("${dist.antlibs.dir}"); + helper.jar("${bin.dir}/ant1compat", "${dist.antlibs.dir}/ant1compat.jar", "${java.dir}/antlibs/ant1compat", "antlib.xml", null, null); } + protected void compile_tests(BuildHelper helper) { + helper.runDepends(this, "compile_tests", "check_for_optional_packages"); + System.out.println("compile-tests: "); + helper.mkdir("${build.tests}"); + helper.javac("${tests.dir}", "${build.tests}", "tests-classpath"); + helper.copyFilesetRef("ant1testcases_tocopy", "${tests.etc.dir}"); + } + protected void dump_info(BuildHelper helper) { + helper.runDepends(this, "dump_info", "dump_sys_properties,run_which"); + System.out.println("dump-info: "); + } + protected void dump_sys_properties(BuildHelper helper) { + helper.runDepends(this, "dump_sys_properties", "xml_check"); + System.out.println("dump-sys-properties: "); + } + protected void xml_check(BuildHelper helper) { + helper.runDepends(this, "xml_check", "check_for_optional_packages"); + System.out.println("xml-check: "); + } + protected void run_which(BuildHelper helper) { + helper.runDepends(this, "run_which", "check_for_optional_packages"); + System.out.println("run-which: "); + } + protected void probe_offline(BuildHelper helper) { + helper.runDepends(this, "probe_offline", ""); + System.out.println("probe-offline: "); + } + protected void test(BuildHelper helper) { + helper.runDepends(this, "test", "run_tests"); + System.out.println("test: "); + } + protected void run_tests(BuildHelper helper) { + helper.runDepends(this, "run_tests", "dump_info,compile_tests,probe_offline"); + System.out.println("run-tests: "); + } + protected void run_single_test(BuildHelper helper) { + helper.runDepends(this, "run_single_test", "compile_tests"); + System.out.println("run-single-test: "); + } protected void clean(BuildHelper helper) { + helper.runDepends(this, "clean", ""); + System.out.println("clean: "); } } diff --git a/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/BuildHelper.java b/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/BuildHelper.java index 673669b32..221108025 100644 --- a/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/BuildHelper.java +++ b/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/BuildHelper.java @@ -60,9 +60,11 @@ import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.StringTokenizer; import java.util.jar.Attributes; import java.util.jar.JarOutputStream; @@ -102,6 +104,8 @@ public class BuildHelper { /** Filesets created in the build */ private Map filesets = new HashMap(); + /** The targets which have been run */ + private Set runTargets = new HashSet(); /** * Set a property for the build @@ -117,6 +121,21 @@ public class BuildHelper { } } + /** + * Set the parent helper when creating a new build context + * + * @param parentHelper the parent helper + */ + protected void setParent(BuildHelper parentHelper) { + // grab the parent's properties + Map parentProperties = parentHelper.properties; + for (Iterator i = parentProperties.keySet().iterator(); i.hasNext();) { + String propertyName = (String) i.next(); + String propertyValue = (String) parentProperties.get(propertyName); + setProperty(propertyName, propertyValue); + } + } + /** * Create a Jar @@ -136,6 +155,8 @@ public class BuildHelper { try { File base = new File(resolve(basedir)); File jar = new File(resolve(jarFile)); + System.out.println(" [jar] Creating jar " + jar); + Manifest manifest = new Manifest(); Attributes attributes = manifest.getMainAttributes(); attributes.putValue("Manifest-Version", "1.0"); @@ -206,6 +227,11 @@ public class BuildHelper { args[index++] = ((File) i.next()).getPath(); } + // System.out.println("Javac Arguments"); + // for (int i = 0; i < args.length; ++i) { + // System.out.println(" " + args[i]); + // } + try { Class c = Class.forName("com.sun.tools.javac.Main"); Object compiler = c.newInstance(); @@ -303,12 +329,14 @@ public class BuildHelper { File[] files = buildFileSet(filesetDir, filesetIncludes); String currentPath = (String) paths.get(pathName); - for (int i = 0; i < files.length; ++i) { - if (currentPath == null || currentPath.length() == 0) { - currentPath = files[i].getPath(); - } else { - currentPath = currentPath + File.pathSeparator - + files[i].getPath(); + if (files != null) { + for (int i = 0; i < files.length; ++i) { + if (currentPath == null || currentPath.length() == 0) { + currentPath = files[i].getPath(); + } else { + currentPath = currentPath + File.pathSeparator + + files[i].getPath(); + } } } paths.put(pathName, currentPath); @@ -549,6 +577,47 @@ public class BuildHelper { } + /** + * Run a target in the build + * + * @param builder The builder object created from the original XML build + * file. + * @param target The target to run. + */ + private void runTarget(Object builder, String target) { + try { + // use reflection to get a method with the given name + Method targetMethod + = builder.getClass().getDeclaredMethod(target, + new Class[]{BuildHelper.class}); + targetMethod.invoke(builder, new Object[]{this}); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Unable to run target \"" + + target + "\""); + } + } + + /** + * Run the dependencies of the given target. + * + * @param builder The builder object created from the original XML build + * file. + * @param targetName the target whose dependencies should be run + * @param depends the comma separated list of dependencies. + */ + public void runDepends(Object builder, String targetName, String depends) { + StringTokenizer tokenizer = new StringTokenizer(depends, ", "); + while (tokenizer.hasMoreTokens()) { + String target = tokenizer.nextToken(); + // has this target been run + if (!runTargets.contains(target)) { + runTarget(builder, target); + } + } + runTargets.add(targetName); + } + /** * Resolve the property references in a string * @@ -556,7 +625,7 @@ public class BuildHelper { * @return the string with property references replaced by their current * value. */ - private String resolve(String propertyValue) { + protected String resolve(String propertyValue) { String newValue = propertyValue; while (newValue.indexOf("${") != -1) { diff --git a/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Builder.java b/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Builder.java index 63f99ba1e..97d199840 100644 --- a/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Builder.java +++ b/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Builder.java @@ -90,7 +90,7 @@ public class Builder { private static final File INPUT_ROOT = new File(PACKAGE_ROOT, "input"); /** the input root */ - + /** the root forthe depend task's support classes */ private static final File DEPEND_ROOT = new File(TASKDEFS_ROOT, "optional/depend"); @@ -114,7 +114,7 @@ public class Builder { */ private void addJavaFiles(List files, File dir, boolean recurse) { File[] javaFiles = dir.listFiles(); - + if (javaFiles != null) { for (int i = 0; i < javaFiles.length; ++i) { if (javaFiles[i].isDirectory() && recurse) { @@ -125,7 +125,7 @@ public class Builder { } } } - + /** * Get the Ant1 files currently required to build a bootstrap build. * @@ -157,7 +157,7 @@ public class Builder { files.add(new File(PACKAGE_ROOT, "TaskAdapter.java")); files.add(new File(PACKAGE_ROOT, "MatchingTask.java")); files.add(new File(PACKAGE_ROOT, "defaultManifest.mf")); - + files.add(new File(TASKDEFS_ROOT, "defaults.properties")); files.add(new File(TYPES_ROOT, "defaults.properties")); @@ -166,7 +166,7 @@ public class Builder { files.add(new File(UTIL_ROOT, "regexp/RegexpFactory.java")); files.add(new File(UTIL_ROOT, "regexp/RegexpMatcherFactory.java")); files.add(new File(FILTERS_ROOT, "util/ChainReaderHelper.java")); - + // these should not be included files.remove(new File(TYPES_ROOT, "DataType.java")); files.remove(new File(TASKDEFS_ROOT, "Ant.java")); @@ -177,7 +177,7 @@ public class Builder { files.remove(new File(TASKDEFS_ROOT, "SendEmail.java")); files.remove(new File(TASKDEFS_ROOT, "Do.java")); files.remove(new File(INPUT_ROOT, "InputRequest.java")); - + // not needed for bootstrap files.remove(new File(TASKDEFS_ROOT, "Java.java")); files.remove(new File(TASKDEFS_ROOT, "Tar.java")); @@ -186,8 +186,8 @@ public class Builder { files.remove(new File(TASKDEFS_ROOT, "BUnzip2.java")); files.remove(new File(TASKDEFS_ROOT, "Rmic.java")); files.remove(new File(TASKDEFS_ROOT, "SendEmail.java")); - - + + return (File[]) files.toArray(new File[0]); } @@ -202,13 +202,7 @@ public class Builder { mainBuild.setProperty("dist.dir", "bootstrap"); MutantBuilder mutantBuilder = new MutantBuilder(); mutantBuilder._init(mainBuild); - mutantBuilder.buildsetup(mainBuild); - mutantBuilder.init(mainBuild); - mutantBuilder.common(mainBuild); - mutantBuilder.antcore(mainBuild); - mutantBuilder.start(mainBuild); - mutantBuilder.frontend(mainBuild); - mutantBuilder.systemlib(mainBuild); + mutantBuilder.dist_lite(mainBuild); Ant1CompatBuilder ant1Builder = new Ant1CompatBuilder(); BuildHelper ant1Build = new BuildHelper(); diff --git a/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/MutantBuilder.java b/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/MutantBuilder.java index c7b2a7792..6c076bd54 100644 --- a/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/MutantBuilder.java +++ b/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/MutantBuilder.java @@ -4,96 +4,163 @@ public class MutantBuilder { helper.setProperty("src.dir", "src"); helper.setProperty("lib.dir", "lib"); helper.setProperty("java.dir", "${src.dir}/java"); + helper.setProperty("script.dir", "${src.dir}/script"); + helper.setProperty("conf.dir", "${src.dir}/conf"); helper.setProperty("bin.dir", "bin"); helper.setProperty("dist.dir", "dist"); - helper.setProperty("javadocs.dir", "${dist.dir}/javadocs"); - helper.setProperty("distlib.dir", "${dist.dir}/lib"); + helper.setProperty("dist.bin", "${dist.dir}/bin"); + helper.setProperty("dist.conf", "${dist.dir}/conf"); + helper.setProperty("javadocs.dir", "${dist.dir}/docs/manual/api"); + helper.setProperty("dist.lib.dir", "${dist.dir}/lib"); + helper.setProperty("dist.core.dir", "${dist.lib.dir}/core"); + helper.setProperty("dist.frontend.dir", "${dist.lib.dir}/frontend"); + helper.setProperty("dist.antlibs.dir", "${dist.lib.dir}/antlibs"); + helper.setProperty("dist.syslibs.dir", "${dist.core.dir}/syslibs"); helper.setProperty("debug", "true"); + helper.setProperty("chmod.fail", "true"); helper.createPath("classpath.parser"); helper.addFileSetToPath("classpath.parser", "${lib.dir}/parser", "*.jar"); helper.createPath("classpath.common"); - helper.addPathElementToPath("classpath.common", "${distlib.dir}/init.jar"); + helper.addPathElementToPath("classpath.common", "${dist.core.dir}/start/init.jar"); helper.createPath("classpath.antcore"); - helper.addPathElementToPath("classpath.antcore", "${distlib.dir}/common/common.jar"); + helper.addPathElementToPath("classpath.antcore", "${dist.core.dir}/common/common.jar"); helper.addPathToPath("classpath.antcore", "classpath.common"); helper.addPathToPath("classpath.antcore", "classpath.parser"); helper.createPath("classpath.frontend"); - helper.addPathElementToPath("classpath.frontend", "${distlib.dir}/antcore/antcore.jar"); + helper.addPathElementToPath("classpath.frontend", "${dist.core.dir}/antcore/antcore.jar"); helper.addPathToPath("classpath.frontend", "classpath.antcore"); helper.createPath("classpath.start"); - helper.addPathElementToPath("classpath.start", "${distlib.dir}/init.jar"); + helper.addPathElementToPath("classpath.start", "${dist.core.dir}/start/init.jar"); } protected void buildsetup(BuildHelper helper) { + helper.runDepends(this, "buildsetup", ""); + System.out.println("buildsetup: "); helper.mkdir("${bin.dir}"); - helper.mkdir("${distlib.dir}"); - helper.copyFileset("${lib.dir}/parser", "${distlib.dir}/parser"); + helper.mkdir("${dist.core.dir}"); + helper.copyFileset("${lib.dir}/parser", "${dist.core.dir}/parser"); } - protected void init(BuildHelper helper) { + protected void initjar(BuildHelper helper) { + helper.runDepends(this, "initjar", "buildsetup"); + System.out.println("initjar: "); helper.mkdir("${bin.dir}/init"); + helper.mkdir("${dist.core.dir}/start"); helper.javac("${java.dir}/init", "${bin.dir}/init", null); - helper.jar("${bin.dir}/init", "${distlib.dir}/init.jar", + helper.jar("${bin.dir}/init", "${dist.core.dir}/start/init.jar", null, null, null, null); } protected void common(BuildHelper helper) { + helper.runDepends(this, "common", "initjar"); + System.out.println("common: "); helper.mkdir("${bin.dir}/common"); - helper.mkdir("${distlib.dir}/common"); + helper.mkdir("${dist.core.dir}/common"); helper.javac("${java.dir}/common", "${bin.dir}/common", "classpath.common"); - helper.jar("${bin.dir}/common", "${distlib.dir}/common/common.jar", + helper.jar("${bin.dir}/common", "${dist.core.dir}/common/common.jar", null, null, null, null); } protected void antcore(BuildHelper helper) { + helper.runDepends(this, "antcore", "common"); + System.out.println("antcore: "); helper.mkdir("${bin.dir}/antcore"); - helper.mkdir("${distlib.dir}/antcore"); + helper.mkdir("${dist.core.dir}/antcore"); helper.javac("${java.dir}/antcore", "${bin.dir}/antcore", "classpath.antcore"); - helper.jar("${bin.dir}/antcore", "${distlib.dir}/antcore/antcore.jar", + helper.jar("${bin.dir}/antcore", "${dist.core.dir}/antcore/antcore.jar", null, null, null, null); } protected void frontend(BuildHelper helper) { + helper.runDepends(this, "frontend", "antcore, startjar"); + System.out.println("frontend: "); helper.mkdir("${bin.dir}/frontend"); - helper.mkdir("${distlib.dir}/frontend"); + helper.mkdir("${dist.frontend.dir}"); helper.javac("${java.dir}/frontend", "${bin.dir}/frontend", "classpath.frontend"); - helper.jar("${bin.dir}/frontend", "${distlib.dir}/frontend/frontend.jar", - null, null, null, null); - helper.jar("${bin.dir}/frontend", "${distlib.dir}/frontend/cli.jar", - null, null, "frontend.jar", "org.apache.ant.cli.Commandline"); + helper.jar("${bin.dir}/frontend", "${dist.frontend.dir}/cli.jar", + null, null, null, "org.apache.ant.cli.Commandline"); } - protected void start(BuildHelper helper) { + protected void startjar(BuildHelper helper) { + helper.runDepends(this, "startjar", "initjar"); + System.out.println("startjar: "); helper.mkdir("${bin.dir}/start"); + helper.mkdir("${dist.core.dir}/start"); helper.javac("${java.dir}/start", "${bin.dir}/start", "classpath.start"); - helper.jar("${bin.dir}/start", "${distlib.dir}/start.jar", + helper.jar("${bin.dir}/start", "${dist.core.dir}/start/start.jar", null, null, "init.jar", "org.apache.ant.start.Main"); - helper.jar("${bin.dir}/start", "${distlib.dir}/ant.jar", + helper.jar("${bin.dir}/start", "${dist.core.dir}/start/ant.jar", null, null, "start.jar", "org.apache.tools.ant.Main"); } - protected void ant1compat(BuildHelper helper) { - } - protected void remote(BuildHelper helper) { - helper.mkdir("${bin.dir}/remote"); - helper.javac("${java.dir}/remote", "${bin.dir}/remote", "classpath.start"); - helper.jar("${bin.dir}/remote", "${distlib.dir}/remote.jar", - null, null, null, "org.apache.ant.remote.RemoteMain"); - } - protected void clean(BuildHelper helper) { - } protected void antlibs(BuildHelper helper) { + helper.runDepends(this, "antlibs", "common"); + System.out.println("antlibs: "); + { + BuildHelper subHelper = new BuildHelper(); + subHelper.setProperty("libname", helper.resolve("system")); + subHelper.setProperty("antlibdir", helper.resolve("${dist.syslibs.dir}")); + subHelper.setParent(helper); + _init(subHelper); + buildlib(subHelper); + } + { + BuildHelper subHelper = new BuildHelper(); + subHelper.setProperty("libname", helper.resolve("monitor")); + subHelper.setProperty("antlibdir", helper.resolve("${dist.syslibs.dir}")); + subHelper.setParent(helper); + _init(subHelper); + buildlib(subHelper); + } } - protected void systemlib(BuildHelper helper) { - helper.mkdir("${bin.dir}/antlibs/system"); - helper.mkdir("${distlib.dir}/syslibs"); + protected void buildlib(BuildHelper helper) { + helper.runDepends(this, "buildlib", ""); + System.out.println("buildlib: "); + helper.setProperty("antlib.build.dir", "${bin.dir}/antlibs/${libname}"); + helper.setProperty("antlib.src.dir", "${java.dir}/antlibs/${libname}"); + helper.mkdir("${antlib.build.dir}"); + helper.mkdir("${antlibdir}"); helper.createPath("classpath.antlibs"); - helper.addPathElementToPath("classpath.antlibs", "${distlib.dir}/common/common.jar"); + helper.addPathElementToPath("classpath.antlibs", "${dist.core.dir}/common/common.jar"); helper.addPathToPath("classpath.antlibs", "classpath.common"); - helper.javac("${java.dir}/antlibs/system", "${bin.dir}/antlibs/system", "classpath.antlibs"); - helper.jar("${bin.dir}/antlibs/system", "${distlib.dir}/syslibs/system.jar", - "${java.dir}/antlibs/system", "antlib.xml", null, null); + helper.javac("${antlib.src.dir}", "${antlib.build.dir}", "classpath.antlibs"); + helper.jar("${antlib.build.dir}", "${antlibdir}/${libname}.jar", + "${antlib.src.dir}", "antlib.xml", null, null); + } + protected void setup_bin(BuildHelper helper) { + helper.runDepends(this, "setup_bin", ""); + System.out.println("setup-bin: "); + helper.mkdir("${dist.bin}"); + helper.copyFileset("${script.dir}/", "${dist.bin}"); } - protected void main(BuildHelper helper) { + protected void setup_conf(BuildHelper helper) { + helper.runDepends(this, "setup_conf", ""); + System.out.println("setup-conf: "); + helper.mkdir("${dist.conf}"); + helper.copyFileset("${conf.dir}/", "${dist.conf}"); + } + protected void clean(BuildHelper helper) { + helper.runDepends(this, "clean", ""); + System.out.println("clean: "); } protected void checkstyle(BuildHelper helper) { + helper.runDepends(this, "checkstyle", ""); + System.out.println("checkstyle: "); helper.mkdir("${bin.dir}/check"); } protected void javadocs(BuildHelper helper) { + helper.runDepends(this, "javadocs", ""); + System.out.println("javadocs: "); helper.mkdir("${javadocs.dir}"); } + protected void test(BuildHelper helper) { + helper.runDepends(this, "test", ""); + System.out.println("test: "); + } + protected void jars(BuildHelper helper) { + helper.runDepends(this, "jars", "initjar, startjar, antcore, frontend, antlibs"); + System.out.println("jars: "); + } + protected void dist_lite(BuildHelper helper) { + helper.runDepends(this, "dist_lite", "jars, setup_bin, setup_conf"); + System.out.println("dist-lite: "); + } + protected void dist(BuildHelper helper) { + helper.runDepends(this, "dist", "dist_lite, javadocs"); + System.out.println("dist: "); + } } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java index ea1c8e043..57a69c793 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java @@ -94,7 +94,7 @@ public abstract class AbstractTask extends AbstractComponent implements Task { */ public void handleSystemOut(String line) throws AntException { // default behaviout is to log at INFO level - log(line, MessageLevel.MSG_INFO); + log(line, MessageLevel.INFO); } /** @@ -108,7 +108,7 @@ public abstract class AbstractTask extends AbstractComponent implements Task { */ public void handleSystemErr(String line) throws AntException { // default behaviout is to log at WARN level - log(line, MessageLevel.MSG_WARN); + log(line, MessageLevel.WARNING); } } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/constants/Namespace.java b/proposal/mutant/src/java/common/org/apache/ant/common/constants/Namespace.java index 76ee4e69d..7a2c1bd47 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/constants/Namespace.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/constants/Namespace.java @@ -62,16 +62,10 @@ package org.apache.ant.common.constants; public class Namespace { /** The Ant namespace used to identify Ant metadata */ public static final String ANT_META_URI - = "http://jakarta.apache.org/ant/meta"; - - /** The namespace id that is predeclared for the Ant metadata namespace */ - public static final String ANT_META_PREFIX = "ant"; + = "http://jakarta.apache.org/ant"; /** The XML Schema namespace */ public static final String XSI_URI = "http://www.w3.org/2001/XMLSchema-instance"; - - /** The namespace id that is predeclared for the Ant metadata namespace */ - public static final String XSI_PREFIX = "xsi"; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/event/MessageLevel.java b/proposal/mutant/src/java/common/org/apache/ant/common/event/MessageLevel.java index ac7b2aad0..27176d55e 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/event/MessageLevel.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/event/MessageLevel.java @@ -61,14 +61,14 @@ package org.apache.ant.common.event; */ public class MessageLevel { /** Error message level */ - public static final int MSG_ERR = 0; + public static final int ERROR = 0; /** Warnign message level */ - public static final int MSG_WARN = 1; + public static final int WARNING = 1; /** Informational message level */ - public static final int MSG_INFO = 2; + public static final int INFO = 2; /** Verbose message level */ - public static final int MSG_VERBOSE = 3; + public static final int VERBOSE = 3; /** Debug Message level */ - public static final int MSG_DEBUG = 4; + public static final int DEBUG = 4; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/logger/DefaultLogger.java b/proposal/mutant/src/java/common/org/apache/ant/common/logger/DefaultLogger.java index 4dbd387cd..18069bfdf 100755 --- a/proposal/mutant/src/java/common/org/apache/ant/common/logger/DefaultLogger.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/logger/DefaultLogger.java @@ -82,7 +82,7 @@ public class DefaultLogger extends BuildListenerAdapter implements BuildLogger { /** The stream to where errors should be written */ private PrintStream err; /** The level of messages which should be let through */ - private int messageOutputLevel = MessageLevel.MSG_ERR; + private int messageOutputLevel = MessageLevel.ERROR; /** Controls whether adornments are added */ private boolean emacsMode = false; @@ -171,7 +171,7 @@ public class DefaultLogger extends BuildListenerAdapter implements BuildLogger { } out.println(e.getMessage()); - if (messageOutputLevel >= MessageLevel.MSG_VERBOSE) { + if (messageOutputLevel >= MessageLevel.VERBOSE) { t.printStackTrace(out); } @@ -218,7 +218,7 @@ public class DefaultLogger extends BuildListenerAdapter implements BuildLogger { * @param event Description of Parameter */ public void targetStarted(BuildEvent event) { - if (MessageLevel.MSG_INFO <= messageOutputLevel) { + if (MessageLevel.INFO <= messageOutputLevel) { Target target = (Target) event.getSource(); out.println(lSep + target.getName() + ":"); } @@ -255,7 +255,7 @@ public class DefaultLogger extends BuildListenerAdapter implements BuildLogger { */ public void messageLogged(BuildEvent event) { PrintStream logTo - = event.getPriority() == MessageLevel.MSG_ERR ? err : out; + = event.getPriority() == MessageLevel.ERROR ? err : out; // Filter out messages based on priority if (event.getPriority() <= messageOutputLevel) { diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/DataService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/DataService.java index e497cef21..4e7e79179 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/service/DataService.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/DataService.java @@ -55,6 +55,7 @@ package org.apache.ant.common.service; import java.util.Map; import org.apache.ant.common.util.AntException; +import org.apache.ant.common.util.DataValue; /** * Service interface for Data value manipulation operations provided by the @@ -64,12 +65,13 @@ import org.apache.ant.common.util.AntException; * @created 31 January 2002 */ public interface DataService { + /** * Get a data value * * @param valueName the name of the data value - * @return the current object associated with the name or null if no - * value is currently associated with the name + * @return the current object associated with the name or null if no value + * is currently associated with the name * @exception AntException if the value cannot be retrieved. */ Object getDataValue(String valueName) throws AntException; @@ -80,29 +82,21 @@ public interface DataService { * @param name the name of the data value - may contain reference * delimiters * @return true if the value exists - * @exception AntException if the containing frame for the value - * does not exist + * @exception AntException if the containing frame for the value does not + * exist */ boolean isDataValueSet(String name) throws AntException; /** - * Set a data value. If an existing data value exists, associated with - * the given name, the value will not be changed + * Set a data value. If an existing data value exists, associated with the + * given name, the value will not be changed * * @param valueName the name of the data value * @param value the value to be associated with the name + * @param mutable if true, existing values can be changed * @exception AntException if the value cannot be set */ - void setDataValue(String valueName, Object value) throws AntException; - - /** - * Set a data value which can be overwritten - * - * @param valueName the name of the data value - * @param value the value to be associated with the name - * @exception AntException if the value cannot be set - */ - void setMutableDataValue(String valueName, Object value) + void setDataValue(String valueName, DataValue value, boolean mutable) throws AntException; /** @@ -133,9 +127,29 @@ public interface DataService { * is an expensive operation since it must clone all of the property * stores in all frames * - * @return a Map containing the frames properties indexed by their full + * @return a Map containing the frames data values indexed by their full * name. + * @exception AntExceptionif the values cannot be retrieved. */ - Map getAllProperties(); + Map getAllDataValues() throws AntException; + + /** + * Merge one set of values into another + * + * @param values the values to which the new values are added + * @param newValues the values to be added in. + */ + void mergeDataValues(Map values, Map newValues); + + /** + * Merge in values which are of a given priority or higher. + * + * @param values the values to which the new values are added + * @param newValues the values to be added in. + * @param threshold The require data value priority for a value to be + * merged. + */ + void mergeDataValues(Map values, Map newValues, int threshold); + } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java index 13175b6e7..0feed6576 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java @@ -95,26 +95,26 @@ public interface ExecService { * Setup a sub-build. * * @param model the project model to be used for the build - * @param properties the initiali properties to be used in the build + * @param dataValue the initial properties to be used in the build * @param addListeners true if the current frame's listeners should be * added to the created Frame * @return a key to the build allowing it to be executed and managed * @exception AntException if the subbuild cannot be setup */ - Object setupBuild(Project model, Map properties, boolean addListeners) + Object setupBuild(Project model, Map dataValue, boolean addListeners) throws AntException; /** * Setup a sub-build using the current frame's project model * - * @param properties the initiali properties to be used in the build + * @param dataValue the initial properties to be used in the build * @param addListeners true if the current frame's listeners should be * added to the created Frame * @return a key to the build allowing it to be executed and managed * @exception AntException if the subbuild cannot be setup */ - Object setupBuild(Map properties, boolean addListeners) + Object setupBuild(Map dataValue, boolean addListeners) throws AntException; diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/util/DataValue.java b/proposal/mutant/src/java/common/org/apache/ant/common/util/DataValue.java new file mode 100644 index 000000000..b9af44f31 --- /dev/null +++ b/proposal/mutant/src/java/common/org/apache/ant/common/util/DataValue.java @@ -0,0 +1,127 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.common.util; +import java.util.HashMap; +import java.util.Iterator; + +import java.util.Map; + +/** + * A DataValue is an arbitrary value with an associated priority. + * + * @author Conor MacNeill + * @created 26 June 2002 + */ +public class DataValue { + /** Base priority level */ + public static final int PRIORITY_BASE = 0; + /** Prioirty of values inherited from a super build. */ + public static final int PRIORITY_INHERIT = 10; + /** Priority of values specified by the user. */ + public static final int PRIORITY_USER = 20; + + /** The DataValue's priority */ + private int priority; + /** The actual data. */ + private Object value; + + /** + * Create a DataValue with the given data and priority. + * + * @param value the actual value + * @param priority the priority associated with this value. + */ + public DataValue(Object value, int priority) { + this.priority = priority; + this.value = value; + } + + /** + * Convert plain named values into a collection of DataValues with the + * given priority + * + * @param values A collection of values named by String keys + * @param priority The required data value to be applied to the values. + * @return A collection of datavalues corresponding to the input collection + * and having the specified priority. + */ + public static Map makeDataValues(Map values, int priority) { + Map dataValues = new HashMap(); + for (Iterator i = values.keySet().iterator(); i.hasNext();) { + Object key = i.next(); + Object value = values.get(key); + dataValues.put(key, new DataValue(value, priority)); + } + return dataValues; + } + + /** + * Gets the priority of the DataValue object + * + * @return the priority value + */ + public int getPriority() { + return priority; + } + + /** + * Gets the value of the DataValue object + * + * @return the value value + */ + public Object getValue() { + return value; + } +} + diff --git a/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java b/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java index 77b5407d3..701fed8e6 100755 --- a/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java +++ b/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java @@ -55,8 +55,8 @@ package org.apache.ant.cli; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.io.PrintStream; import java.io.OutputStream; +import java.io.PrintStream; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; @@ -66,19 +66,21 @@ import java.util.List; import java.util.Map; import org.apache.ant.antcore.config.AntConfig; import org.apache.ant.antcore.execution.Frame; +import org.apache.ant.antcore.frontend.FrontendException; +import org.apache.ant.antcore.frontend.FrontendUtils; import org.apache.ant.antcore.modelparser.XMLProjectParser; import org.apache.ant.antcore.xml.XMLParseException; import org.apache.ant.common.event.BuildEvent; import org.apache.ant.common.event.BuildListener; import org.apache.ant.common.event.MessageLevel; +import org.apache.ant.common.logger.BuildLogger; +import org.apache.ant.common.logger.DefaultLogger; import org.apache.ant.common.model.Project; +import org.apache.ant.common.util.DataValue; import org.apache.ant.common.util.DemuxOutputStream; -import org.apache.ant.common.logger.DefaultLogger; -import org.apache.ant.common.logger.BuildLogger; import org.apache.ant.init.AntEnvironment; +import org.apache.ant.init.Frontend; import org.apache.ant.init.InitUtils; -import org.apache.ant.frontend.FrontendUtils; -import org.apache.ant.frontend.FrontendException; /** * This is the command line front end. It drives the core. @@ -86,7 +88,7 @@ import org.apache.ant.frontend.FrontendException; * @author Conor MacNeill * @created 9 January 2002 */ -public class Commandline { +public class Commandline implements Frontend { /** The initialisation configuration for Ant */ private AntEnvironment antEnv; @@ -103,16 +105,13 @@ public class Commandline { private List targets = new ArrayList(4); /** The command line properties */ - private Map definedProperties = new HashMap(); + private Map definedValues = new HashMap(); /** The Config files to use in this run */ private List configFiles = new ArrayList(); - /** - * This is the build file to run. By default it is a file: type URL but - * other URL protocols can be used. - */ - private URL buildFileURL; + /** This is the build to run. */ + private String buildSource; /** * The Ant logger class. There may be only one logger. It will have the @@ -122,29 +121,17 @@ public class Commandline { private String loggerClassname = null; /** Our current message output status. Follows MessageLevel values */ - private int messageOutputLevel = MessageLevel.MSG_INFO; + private int messageOutputLevel = MessageLevel.INFO; /** The logger that will be used for the build */ private BuildLogger logger = null; - /** - * Start the command line front end for mutant. - * - * @param args the commandline arguments - * @param config the initialisation configuration - */ - public static void start(String[] args, AntEnvironment config) { - // create a command line and use it to run ant - Commandline commandline = new Commandline(); - commandline.process(args, config); - } - /** * Adds a feature to the BuildListeners attribute of the Commandline * object * - * @param eventSource the build event source to which listeners - * will be added. + * @param eventSource the build event source to which listeners will be + * added. * @exception FrontendException if the necessary listener instances could * not be created */ @@ -205,14 +192,15 @@ public class Commandline { * @param args the commandline arguments * @param antEnv Ant's initialization configuration */ - private void process(String[] args, AntEnvironment antEnv) { + public void start(final String[] args, final AntEnvironment antEnv) { this.antEnv = antEnv; + Frame mainFrame = null; Project project = null; try { parseArguments(args); createLogger(); - determineBuildFile(); + URL buildSourceURL = determineBuildFile(); AntConfig config = new AntConfig(); AntConfig userConfig = @@ -230,27 +218,32 @@ public class Commandline { for (Iterator i = configFiles.iterator(); i.hasNext();) { File configFile = (File) i.next(); AntConfig runConfig - = FrontendUtils.getAntConfigFile(configFile); + = FrontendUtils.getAntConfigFile(configFile); config.merge(runConfig); } - if (!buildFileURL.getProtocol().equals("file") - && !config.isRemoteProjectAllowed()) { + if (buildSourceURL.getProtocol().equals("file")) { + System.out.println("Buildfile: " + buildSource); + } else if (!config.isRemoteProjectAllowed()) { throw new FrontendException("Remote Projects are not allowed: " - + buildFileURL); + + buildSourceURL); + } else { + System.out.println("Build: " + buildSourceURL); } - project = parseProject(); + project = parseProject(buildSourceURL); // create the execution manager to execute the build mainFrame = new Frame(antEnv, config); OutputStream demuxOut - = new DemuxOutputStream(mainFrame, false); + = new DemuxOutputStream(mainFrame, false); OutputStream demuxErr - = new DemuxOutputStream(mainFrame, true); + = new DemuxOutputStream(mainFrame, true); System.setOut(new PrintStream(demuxOut)); System.setErr(new PrintStream(demuxErr)); addBuildListeners(mainFrame); + mainFrame.setProject(project); + mainFrame.initialize(definedValues); } catch (Throwable e) { if (logger != null) { BuildEvent finishedEvent @@ -263,9 +256,6 @@ public class Commandline { } try { - mainFrame.setProject(project); - mainFrame.initialize(definedProperties); - mainFrame.startBuild(targets); System.exit(0); } catch (Throwable t) { @@ -274,35 +264,26 @@ public class Commandline { } /** - * Use the XML parser to parse the build file into a project model + * Use the XML parser to parse the build into a project model * + * @param buildSourceURL the location of the build XML source. * @return a project model representation of the project file * @exception XMLParseException if the project cannot be parsed */ - private Project parseProject() + private Project parseProject(URL buildSourceURL) throws XMLParseException { XMLProjectParser parser = new XMLProjectParser(); - Project project = parser.parseBuildFile(buildFileURL); + Project project = parser.parseBuildFile(buildSourceURL); return project; } /** - * Handle build file argument + * Handle build argument * - * @param url the build file's URL - * @exception FrontendException if the build file location is not valid + * @param buildSource the build to process */ - private void argBuildFile(String url) throws FrontendException { - try { - if (url.indexOf(":") == -1) { - // We convert any hash characters to their URL escape. - buildFileURL = InitUtils.getFileURL(new File(url)); - } else { - buildFileURL = new URL(url); - } - } catch (MalformedURLException e) { - throw new FrontendException("Build file is not valid", e); - } + private void argBuild(String buildSource) { + this.buildSource = buildSource; } /** @@ -339,26 +320,50 @@ public class Commandline { /** - * Determine the build file to use + * Determine the build to use * - * @exception FrontendException if the build file cannot be found + * @return the URL of the build source. + * @exception FrontendException if the build cannot be found */ - private void determineBuildFile() throws FrontendException { - if (buildFileURL == null) { - File defaultBuildFile - = new File(FrontendUtils.DEFAULT_BUILD_FILENAME); - if (!defaultBuildFile.exists()) { - File ant1BuildFile - = new File(FrontendUtils.DEFAULT_ANT1_FILENAME); - if (ant1BuildFile.exists()) { - defaultBuildFile = ant1BuildFile; + private URL determineBuildFile() throws FrontendException { + + URL buildSourceURL = null; + try { + if (buildSource == null) { + buildSource = FrontendUtils.DEFAULT_BUILD_FILENAME; + File defaultBuildFile = new File(buildSource); + if (!defaultBuildFile.exists()) { + String ant1File = FrontendUtils.DEFAULT_ANT1_FILENAME; + File ant1BuildFile = new File(ant1File); + if (ant1BuildFile.exists()) { + buildSource = ant1File; + defaultBuildFile = ant1BuildFile; + } else { + throw new FrontendException("No build file " + + FrontendUtils.DEFAULT_BUILD_FILENAME + " or " + + FrontendUtils.DEFAULT_ANT1_FILENAME + " found."); + } + } + buildSourceURL = InitUtils.getFileURL(defaultBuildFile); + } else { + // we have been given a file as a string - try to figure out if + // it is a URL or just a file + try { + buildSourceURL = new URL(buildSource); + } catch (MalformedURLException e) { + // must be a file + File buildFile = new File(buildSource); + if (!buildFile.exists()) { + throw new FrontendException("Cannot find build: " + + buildSource); + } + buildSourceURL = InitUtils.getFileURL(buildFile); } } - try { - buildFileURL = InitUtils.getFileURL(defaultBuildFile); - } catch (MalformedURLException e) { - throw new FrontendException("Build file is not valid", e); - } + return buildSourceURL; + } catch (MalformedURLException e) { + throw new FrontendException("Build file " + buildSource + + " is not valid", e); } } @@ -378,17 +383,17 @@ public class Commandline { if (arg.equals("-buildfile") || arg.equals("-file") || arg.equals("-f")) { - argBuildFile(getOption(args, i++, arg)); + argBuild(getOption(args, i++, arg)); } else if (arg.equals("-logfile") || arg.equals("-l")) { argLogFile(getOption(args, i++, arg)); } else if (arg.equals("-quiet") || arg.equals("-q")) { - messageOutputLevel = MessageLevel.MSG_WARN; + messageOutputLevel = MessageLevel.WARNING; } else if (arg.equals("-verbose") || arg.equals("-v")) { // printVersion(); - messageOutputLevel = MessageLevel.MSG_VERBOSE; + messageOutputLevel = MessageLevel.VERBOSE; } else if (arg.equals("-debug")) { // printVersion(); - messageOutputLevel = MessageLevel.MSG_DEBUG; + messageOutputLevel = MessageLevel.DEBUG; } else if (arg.equals("-config") || arg.equals("-c")) { configFiles.add(new File(getOption(args, i++, arg))); } else if (arg.equals("-listener")) { @@ -405,7 +410,8 @@ public class Commandline { } else { value = getOption(args, i++, arg); } - definedProperties.put(name, value); + definedValues.put(name, + new DataValue(value, DataValue.PRIORITY_USER)); } else if (arg.startsWith("-")) { // we don't have any more args to recognize! System.out.println("Unknown option: " + arg); diff --git a/proposal/mutant/src/java/init/org/apache/ant/init/AntEnvironment.java b/proposal/mutant/src/java/init/org/apache/ant/init/AntEnvironment.java index 5479035e2..ca333d5a3 100644 --- a/proposal/mutant/src/java/init/org/apache/ant/init/AntEnvironment.java +++ b/proposal/mutant/src/java/init/org/apache/ant/init/AntEnvironment.java @@ -59,14 +59,47 @@ import java.net.URL; import java.net.URLClassLoader; /** - * AntEnvironment describes the environment in which Ant is operating. - * It provides the locations of a number of key Ant components. + * AntEnvironment describes the environment in which Ant is operating. It + * provides the locations of a number of key Ant components. * * @author Conor MacNeill * @created 9 January 2002 */ public class AntEnvironment { + /** + * How to navigate from a URL retrieved from a core class to + * the Ant Home area + */ + public static final String CORECLASS_TO_ANTHOME = "../../.."; + + /** The configuration directory */ + public static final String SYSTEM_CONFDIR = "conf"; + + /** The User's configuration directory */ + public static final String USER_CONFDIR = ".ant/conf"; + + /** The library diurectory */ + public static final String LIB_DIR = "lib/"; + + /** Common libraries directory */ + public static final String COMMON_DIR = "core/common/"; + + /** Parser library directory */ + public static final String PARSER_DIR = "core/parser/"; + + /** Core libraries directory */ + public static final String ANTCORE_DIR = "core/antcore/"; + + /** System Ant libraries directory */ + public static final String SYSLIBS_DIR = "core/syslibs/"; + + /** Standard Ant Libraries directory */ + public static final String ANTLIBS_DIR = "antlibs/"; + + /** The Ant Home property */ + public static final String ANTHOME_PROPERTY = "ant.home"; + /** The default name of the jar containing the XML parser */ public static final String DEFAULT_PARSER_JAR = "crimson.jar"; @@ -74,14 +107,14 @@ public class AntEnvironment { private ClassLoader systemLoader; /** - * The common class loader loads components which are common to tasks - * and the core + * The common class loader loads components which are common to tasks and + * the core */ private ClassLoader commonLoader; /** - * The core loader is the loader which loads classes which are - * exclusively used by the Ant core + * The core loader is the loader which loads classes which are exclusively + * used by the Ant core */ private ClassLoader coreLoader; @@ -93,8 +126,8 @@ public class AntEnvironment { /** * The URLs to the Ant XML parser. These are available to allow tasks - * which require XML support to use the standard parser rather than - * having to supply their own + * which require XML support to use the standard parser rather than having + * to supply their own */ private URL[] parserURLs; @@ -123,22 +156,39 @@ public class AntEnvironment { /** * Create and automatically configure the Ant Environment * - * @param libraryClass - a class loaded from the Ant library area. + * @param coreClass - a core Ant class * @exception InitException if the configuration cannot be initialized */ - public AntEnvironment(Class libraryClass) throws InitException { + public AntEnvironment(Class coreClass) throws InitException { try { - URL antLibURL = getAntLibURL(libraryClass); - setLibraryURL(antLibURL); + // is Ant Home set? + String antHomeProperty = System.getProperty(ANTHOME_PROPERTY); + if (antHomeProperty == null) { + URL classURL = getAntLibURL(coreClass); + antHome = new URL(classURL, CORECLASS_TO_ANTHOME); + } else { + try { + antHome = new URL(antHomeProperty); + } catch (MalformedURLException e) { + // try as a file + File antHomeDir = new File(antHomeProperty); + if (!antHomeDir.exists()) { + throw new InitException("ant.home value \"" + + antHomeProperty + "\" is not valid."); + } + antHome = InitUtils.getFileURL(antHomeDir); + } + } + + setLibraryURL(new URL(antHome, LIB_DIR)); - URL antHome = new URL(antLibURL, ".."); - setAntHome(antHome); if (antHome.getProtocol().equals("file")) { - File systemConfigArea = new File(antHome.getFile(), "conf"); + File systemConfigArea + = new File(antHome.getFile(), SYSTEM_CONFDIR); setSystemConfigArea(systemConfigArea); } File userConfigArea - = new File(System.getProperty("user.home"), ".ant/conf"); + = new File(System.getProperty("user.home"), USER_CONFDIR); setUserConfigArea(userConfigArea); // set up the class loaders that will be used when running Ant @@ -147,21 +197,21 @@ public class AntEnvironment { URL toolsJarURL = ClassLocator.getToolsJarURL(); setToolsJarURL(toolsJarURL); - URL commonJarLib = new URL(libraryURL, "common/"); + URL commonJarLib = new URL(libraryURL, COMMON_DIR); ClassLoader commonLoader = new URLClassLoader(LoaderUtils.getLocationURLs(commonJarLib, "common.jar"), systemLoader); setCommonLoader(commonLoader); // core needs XML parser for parsing various XML components. - URL parserBase = new URL(libraryURL, "parser/"); + URL parserBase = new URL(libraryURL, PARSER_DIR); URL[] parserURLs = LoaderUtils.getLocationURLs(parserBase, DEFAULT_PARSER_JAR); setParserURLs(parserURLs); + URL antcoreBase = new URL(libraryURL, ANTCORE_DIR); URL[] coreURLs - = LoaderUtils.getLocationURLs(new URL(libraryURL, "antcore/"), - "antcore.jar"); + = LoaderUtils.getLocationURLs(antcoreBase, "antcore.jar"); URL[] combinedURLs = new URL[parserURLs.length + coreURLs.length]; System.arraycopy(coreURLs, 0, combinedURLs, 0, coreURLs.length); System.arraycopy(parserURLs, 0, combinedURLs, coreURLs.length, @@ -336,6 +386,26 @@ public class AntEnvironment { return libraryURL; } + /** + * Get the location of the antlibs directory + * + * @return a URL giving the location of the antlibs directory + * @exception MalformedURLException if the URL cannot be formed. + */ + public URL getSyslibsURL() throws MalformedURLException { + return new URL(libraryURL, SYSLIBS_DIR); + } + + /** + * Get the location of the syslibs directory + * + * @return a URL giving the location of the syslibs directory + * @exception MalformedURLException if the URL cannot be formed. + */ + public URL getAntlibsURL() throws MalformedURLException { + return new URL(libraryURL, ANTLIBS_DIR); + } + /** * Get a URL to the Ant Library directory. * @@ -353,7 +423,7 @@ public class AntEnvironment { initURLString = initURLString.substring(0, index + 1); } - return new URL(initURLString); + return new URL(initURLString); } } diff --git a/proposal/mutant/src/java/init/org/apache/ant/init/Frontend.java b/proposal/mutant/src/java/init/org/apache/ant/init/Frontend.java new file mode 100644 index 000000000..585edb3e2 --- /dev/null +++ b/proposal/mutant/src/java/init/org/apache/ant/init/Frontend.java @@ -0,0 +1,72 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.init; + +/** + * Interface which all front ends implement and is used to launch the front + * end. + * + * @author Conor MacNeill + * @created 26 June 2002 + */ +public interface Frontend { + /** + * Start a frontend. + * + * @param args the command line arguments is any + * @param antEnv the AntEnvironment describing the operating environment. + */ + void start(String[] args, AntEnvironment antEnv); +} + diff --git a/proposal/mutant/src/java/start/org/apache/ant/start/Main.java b/proposal/mutant/src/java/start/org/apache/ant/start/Main.java index e264f8a50..3e4a6d386 100755 --- a/proposal/mutant/src/java/start/org/apache/ant/start/Main.java +++ b/proposal/mutant/src/java/start/org/apache/ant/start/Main.java @@ -54,7 +54,6 @@ package org.apache.ant.start; import java.io.IOException; -import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.util.jar.Attributes; @@ -62,6 +61,7 @@ import java.util.jar.JarInputStream; import java.util.jar.Manifest; import org.apache.ant.init.AntEnvironment; import org.apache.ant.init.InitException; +import org.apache.ant.init.Frontend; import java.io.File; /** @@ -72,10 +72,6 @@ import java.io.File; * @created 9 January 2002 */ public class Main { - /** The actual class that implements the command line front end. */ - public static final String DEFAULT_COMMANDLINE_CLASS - = "org.apache.ant.cli.Commandline"; - /** The default front end name */ public static final String DEFAULT_FRONTEND = "cli"; @@ -98,6 +94,7 @@ public class Main { } } + String[] mainArgs = args; if (frontendIndex != -1) { try { frontend = args[frontendIndex + 1]; @@ -106,42 +103,36 @@ public class Main { + "-frontend argument"); } - String[] newArgs = new String[args.length - 2]; + mainArgs = new String[args.length - 2]; - System.arraycopy(args, 0, newArgs, 0, frontendIndex); + System.arraycopy(args, 0, mainArgs, 0, frontendIndex); if (args.length > (frontendIndex + 2)) { - System.arraycopy(args, frontendIndex + 2, newArgs, + System.arraycopy(args, frontendIndex + 2, mainArgs, frontendIndex, args.length - frontendIndex - 2); } - args = newArgs; } - String defaultClass = frontend.equals(DEFAULT_FRONTEND) - ? DEFAULT_COMMANDLINE_CLASS : null; - - main.start(frontend, defaultClass, args); + main.start(frontend, mainArgs); } /** * Internal start method used to initialise front end * - * @param frontend the frontend jar to launch + * @param frontendName the frontend jar to launch * @param args commandline arguments - * @param defaultClass the default class to use if it cannot be determined - * from the jar itself * @exception InitException if the front end cannot be started */ - public void start(String frontend, String defaultClass, String[] args) + public void start(String frontendName, String[] args) throws InitException { try { - AntEnvironment config = new AntEnvironment(getClass()); + AntEnvironment antEnv = new AntEnvironment(getClass()); - URL frontendJar = new URL(config.getLibraryURL(), - "frontend/" + frontend + ".jar"); + URL frontendJar = new URL(antEnv.getLibraryURL(), + "frontend/" + frontendName + ".jar"); URL[] frontendJars = new URL[]{frontendJar}; ClassLoader frontEndLoader - = new URLClassLoader(frontendJars, config.getCoreLoader()); + = new URLClassLoader(frontendJars, antEnv.getCoreLoader()); //System.out.println("Front End Loader config"); //LoaderUtils.dumpLoader(System.out, frontEndLoader); @@ -150,31 +141,22 @@ public class Main { File jarFile = new File(frontendJar.getFile()); if (!jarFile.exists()) { throw new InitException("Could not find jar for frontend \"" - + frontend + "\" - expected at " + frontendJar); + + frontendName + "\" - expected at " + frontendJar); } } String mainClass = getMainClass(frontendJar); - if (mainClass == null) { - mainClass = defaultClass; - } - if (mainClass == null) { throw new InitException("Unable to determine main class " - + " for \"" + frontend + "\" frontend"); + + " for \"" + frontendName + "\" frontend"); } // Now start the front end by reflection. Class frontendClass = Class.forName(mainClass, true, frontEndLoader); - final Class[] param = {Class.forName("[Ljava.lang.String;"), - AntEnvironment.class}; - final Method startMethod - = frontendClass.getMethod("start", param); - final Object[] argument = {args, config}; - - startMethod.invoke(null, argument); + Frontend frontend = (Frontend) frontendClass.newInstance(); + frontend.start(args, antEnv); } catch (Exception e) { throw new InitException(e); } diff --git a/proposal/mutant/src/script/mutant b/proposal/mutant/src/script/mutant new file mode 100644 index 000000000..d759f4b18 --- /dev/null +++ b/proposal/mutant/src/script/mutant @@ -0,0 +1,172 @@ +#! /bin/sh +# Copyright (c) 2002 The Apache Software Foundation. All rights +# reserved. + +# load system-wide ant configuration +if [ -f "/etc/mutant.conf" ] ; then + . /etc/mutant.conf +fi + +# provide default values for people who don't use RPMs +if [ -z "$rpm_mode" ] ; then + rpm_mode=false; +fi +if [ -z "$usejikes" ] ; then + usejikes=false; +fi + +# load user ant configuration +if [ -f "$HOME/.antrc" ] ; then + . $HOME/.antrc +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +case "`uname`" in + CYGWIN*) cygwin=true ;; + Darwin*) darwin=true + if [ -z "$JAVA_HOME" ] ; then + JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home + fi + ;; +esac + +if [ -z "$MUTANT_HOME" ] ; then + # try to find MUTANT + if [ -d /opt/mutant ] ; then + MUTANT_HOME=/opt/mutant + fi + + if [ -d ${HOME}/opt/mutant ] ; then + MUTANT_HOME=${HOME}/opt/mutant + fi + + ## resolve links - $0 may be a link to ant's home + PRG=$0 + progname=`basename $0` + saveddir=`pwd` + + # need this for relative symlinks + cd `dirname $PRG` + + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '.*/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname $PRG`/$link" + fi + done + + MUTANT_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + MUTANT_HOME=`cd "$MUTANT_HOME" && pwd` + + cd $saveddir +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$MUTANT_HOME" ] && + MUTANT_HOME=`cygpath --unix "$MUTANT_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD=java + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." + echo " We cannot execute $JAVACMD" + exit 1 +fi + +# in rpm_mode get ant/optional/xml parser&api from JAVALIBDIR +if $rpm_mode; then + JAVALIBDIR=/usr/share/java + # TODO - RPM structure for Mutant needs to be determined +else + # add in the dependency .jar files in non-RPM mode (the default) + STARTJARPATH="${MUTANT_HOME}"/lib/core/start/start.jar +fi + +if [ -n "$JAVA_HOME" ] ; then + if [ -f "$JAVA_HOME/lib/tools.jar" ] ; then + TOOLSJARPATH="$JAVA_HOME/lib/tools.jar" + fi + + # OSX hack to make Ant work with jikes + if $darwin ; then + OSXHACK="/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Classes" + if [ -d ${OSXHACK} ] ; then + for i in ${OSXHACK}/*.jar + do + JIKESPATH=$JIKESPATH:$i + done + fi + fi +else + echo "Warning: JAVA_HOME environment variable is not set." + echo " If build fails because sun.* classes could not be found" + echo " you will need to set the JAVA_HOME environment variable" + echo " to the installation directory of java." +fi + +# supply JIKESPATH to Ant as jikes.class.path +if [ -n "$JIKESPATH" ] ; then + if $cygwin ; then + JIKESPATH=`cygpath --path --windows "$JIKESPATH"` + fi + ANT_OPTS="$ANT_OPTS -Djikes.class.path=$JIKESPATH" +fi + +# Allow Jikes support (off by default) +if $usejikes; then + ANT_OPTS="$ANT_OPTS -Dbuild.compiler=jikes" +fi + +LOCALCLASSPATH=$STARTJARPATH + +if [ -n "$CLASSPATH" ] ; then + LOCALCLASSPATH="$LOCALCLASSPATH:$CLASSPATH" +fi + +#Setup policy file +if [ -z $ANT_POLICY ] ; then + if [ -f $MUTANT_HOME/conf/ant.policy ] ; then + ANT_POLICY=file:$MUTANT_HOME/conf/ant.policy + fi +fi + +if [ -n $ANT_POLICY ] ; then + ANT_OPTS="$ANT_OPTS -Djava.security.manager -Djava.security.policy=$ANT_POLICY" +fi + + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + MUTANT_HOME=`cygpath --path --windows "$MUTANT_HOME"` + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + STARTJARPATH=`cygpath --path --windows "$STARTJARPATH"` + TOOLSJARPATH=`cygpath --path --windows "$TOOLSJARPATH"` + LOCALCLASSPATH=`cygpath --path --windows "$LOCALCLASSPATH"` + ANT_OPTS="$ANT_OPTS -Dcygwin.user.home="`cygpath --path --windows "$HOME"` +fi + +"$JAVACMD" -classpath "$LOCALCLASSPATH" $ANT_OPTS -Dant.home=$MUTANT_HOME org.apache.ant.start.Main $ANT_ARGS "$@"