PropertyHelperpublic class PropertyHelper extends Object NOT FINAL. API MAY CHANGE
Deals with properties - substitution, dynamic properties, etc.
This is the same code as in Ant1.5. The main addition is the ability
to chain multiple PropertyHelpers and to replace the default. |
Fields Summary |
---|
private Project | project | private PropertyHelper | next | private Hashtable | propertiesProject properties map (usually String to String). | private Hashtable | userPropertiesMap of "user" properties (as created in the Ant task, for example).
Note that these key/value pairs are also always put into the
project properties, so only the project properties need to be queried.
Mapping is String to String. | private Hashtable | inheritedPropertiesMap of inherited "user" properties - that are those "user"
properties that have been created by tasks and not been set
from the command line or a GUI tool.
Mapping is String to String. |
Constructors Summary |
---|
protected PropertyHelper()Default constructor.
|
Methods Summary |
---|
public void | copyInheritedProperties(Project other)Copies all user properties that have not been set on the
command line or a GUI tool from this instance to the Project
instance given as the argument.
To copy all "user" properties, you will also have to call
{@link #copyUserProperties copyUserProperties}.
Enumeration e = inheritedProperties.keys();
while (e.hasMoreElements()) {
String arg = e.nextElement().toString();
if (other.getUserProperty(arg) != null) {
continue;
}
Object value = inheritedProperties.get(arg);
other.setInheritedProperty(arg, value.toString());
}
| public void | copyUserProperties(Project other)Copies all user properties that have been set on the command
line or a GUI tool from this instance to the Project instance
given as the argument.
To copy all "user" properties, you will also have to call
{@link #copyInheritedProperties copyInheritedProperties}.
Enumeration e = userProperties.keys();
while (e.hasMoreElements()) {
Object arg = e.nextElement();
if (inheritedProperties.containsKey(arg)) {
continue;
}
Object value = userProperties.get(arg);
other.setUserProperty(arg.toString(), value.toString());
}
| protected java.util.Hashtable | getInternalInheritedProperties()special back door for subclasses, internal access to
the hashtables
return inheritedProperties;
| protected java.util.Hashtable | getInternalProperties()special back door for subclasses, internal access to
the hashtables
return properties;
| protected java.util.Hashtable | getInternalUserProperties()special back door for subclasses, internal access to
the hashtables
return userProperties;
| public org.apache.tools.ant.PropertyHelper | getNext()Get the next property helper in the chain.
return next;
| public java.util.Hashtable | getProperties()Returns a copy of the properties table.
return new Hashtable(properties);
// There is a better way to save the context. This shouldn't
// delegate to next, it's for backward compatibility only.
| public synchronized java.lang.Object | getProperty(java.lang.String ns, java.lang.String name)Returns the value of a property, if it is set. You can override
this method in order to plug your own storage.
if (name == null) {
return null;
}
Object o = getPropertyHook(ns, name, false);
if (o != null) {
return o;
}
return properties.get(name);
| public static synchronized org.apache.tools.ant.PropertyHelper | getPropertyHelper(Project project)Factory method to create a property processor.
Users can provide their own or replace it using "ant.PropertyHelper"
reference. User tasks can also add themselves to the chain, and provide
dynamic properties.
PropertyHelper helper
= (PropertyHelper) project.getReference(MagicNames.REFID_PROPERTY_HELPER);
if (helper != null) {
return helper;
}
helper = new PropertyHelper();
helper.setProject(project);
project.addReference(MagicNames.REFID_PROPERTY_HELPER, helper);
return helper;
| public java.lang.Object | getPropertyHook(java.lang.String ns, java.lang.String name, boolean user)Get a property. If all hooks return null, the default
tables will be used.
if (getNext() != null) {
Object o = getNext().getPropertyHook(ns, name, user);
if (o != null) {
return o;
}
}
// Experimental/Testing, will be removed
if (name.startsWith("toString:")) {
name = name.substring("toString:".length());
Object v = project.getReference(name);
return (v == null) ? null : v.toString();
}
return null;
| public java.util.Hashtable | getUserProperties()Returns a copy of the user property hashtable
return new Hashtable(userProperties);
| public synchronized java.lang.Object | getUserProperty(java.lang.String ns, java.lang.String name)Returns the value of a user property, if it is set.
if (name == null) {
return null;
}
Object o = getPropertyHook(ns, name, true);
if (o != null) {
return o;
}
return userProperties.get(name);
| public void | parsePropertyString(java.lang.String value, java.util.Vector fragments, java.util.Vector propertyRefs)Parses a string containing ${xxx} style property
references into two lists. The first list is a collection
of text fragments, while the other is a set of string property names.
null entries in the first list indicate a property
reference from the second list.
It can be overridden with a more efficient or customized version.
parsePropertyStringDefault(value, fragments, propertyRefs);
| static void | parsePropertyStringDefault(java.lang.String value, java.util.Vector fragments, java.util.Vector propertyRefs)Default parsing method. It is here only to support backward compatibility
for the static ProjectHelper.parsePropertyString().
int prev = 0;
int pos;
//search for the next instance of $ from the 'prev' position
while ((pos = value.indexOf("$", prev)) >= 0) {
//if there was any text before this, add it as a fragment
//TODO, this check could be modified to go if pos>prev;
//seems like this current version could stick empty strings
//into the list
if (pos > 0) {
fragments.addElement(value.substring(prev, pos));
}
//if we are at the end of the string, we tack on a $
//then move past it
if (pos == (value.length() - 1)) {
fragments.addElement("$");
prev = pos + 1;
} else if (value.charAt(pos + 1) != '{") {
//peek ahead to see if the next char is a property or not
//not a property: insert the char as a literal
/*
fragments.addElement(value.substring(pos + 1, pos + 2));
prev = pos + 2;
*/
if (value.charAt(pos + 1) == '$") {
//backwards compatibility two $ map to one mode
fragments.addElement("$");
prev = pos + 2;
} else {
//new behaviour: $X maps to $X for all values of X!='$'
fragments.addElement(value.substring(pos, pos + 2));
prev = pos + 2;
}
} else {
//property found, extract its name or bail on a typo
int endName = value.indexOf('}", pos);
if (endName < 0) {
throw new BuildException("Syntax error in property: "
+ value);
}
String propertyName = value.substring(pos + 2, endName);
fragments.addElement(null);
propertyRefs.addElement(propertyName);
prev = endName + 1;
}
}
//no more $ signs found
//if there is any tail to the file, append it
if (prev < value.length()) {
fragments.addElement(value.substring(prev));
}
| public java.lang.String | replaceProperties(java.lang.String ns, java.lang.String value, java.util.Hashtable keys)Replaces ${xxx} style constructions in the given value
with the string value of the corresponding data types.
if (value == null || value.indexOf('$") == -1) {
return value;
}
Vector fragments = new Vector();
Vector propertyRefs = new Vector();
parsePropertyString(value, fragments, propertyRefs);
StringBuffer sb = new StringBuffer();
Enumeration i = fragments.elements();
Enumeration j = propertyRefs.elements();
while (i.hasMoreElements()) {
String fragment = (String) i.nextElement();
if (fragment == null) {
String propertyName = (String) j.nextElement();
Object replacement = null;
// try to get it from the project or keys
// Backward compatibility
if (keys != null) {
replacement = keys.get(propertyName);
}
if (replacement == null) {
replacement = getProperty(ns, propertyName);
}
if (replacement == null) {
project.log("Property \"" + propertyName
+ "\" has not been set", Project.MSG_VERBOSE);
}
fragment = (replacement != null)
? replacement.toString()
: "${" + propertyName + "}";
}
sb.append(fragment);
}
return sb.toString();
| public synchronized void | setInheritedProperty(java.lang.String ns, java.lang.String name, java.lang.Object value)Sets an inherited user property, which cannot be overwritten by set/unset
property calls. Any previous value is overwritten. Also marks
these properties as properties that have not come from the
command line.
inheritedProperties.put(name, value);
project.log("Setting ro project property: " + name + " -> "
+ value, Project.MSG_DEBUG);
userProperties.put(name, value);
boolean done = setPropertyHook(ns, name, value, true, false, false);
if (done) {
return;
}
properties.put(name, value);
| public synchronized void | setNewProperty(java.lang.String ns, java.lang.String name, java.lang.Object value)Sets a property if no value currently exists. If the property
exists already, a message is logged and the method returns with
no other effect.
if (null != properties.get(name)) {
project.log("Override ignored for property \"" + name
+ "\"", Project.MSG_VERBOSE);
return;
}
boolean done = setPropertyHook(ns, name, value, false, false, true);
if (done) {
return;
}
project.log("Setting project property: " + name + " -> "
+ value, Project.MSG_DEBUG);
if (name != null && value != null) {
properties.put(name, value);
}
| public void | setNext(org.apache.tools.ant.PropertyHelper next)There are 2 ways to hook into property handling:
- you can replace the main PropertyHelper. The replacement is required
to support the same semantics (of course :-)
- you can chain a property helper capable of storing some properties.
Again, you are required to respect the immutability semantics (at
least for non-dynamic properties)
this.next = next;
| public void | setProject(Project p)Set the project for which this helper is performing property resolution
this.project = p;
| public synchronized boolean | setProperty(java.lang.String ns, java.lang.String name, java.lang.Object value, boolean verbose)Default implementation of setProperty. Will be called from Project.
This is the original 1.5 implementation, with calls to the hook
added.
// user (CLI) properties take precedence
if (null != userProperties.get(name)) {
if (verbose) {
project.log("Override ignored for user property \"" + name
+ "\"", Project.MSG_VERBOSE);
}
return false;
}
boolean done = setPropertyHook(ns, name, value, false, false, false);
if (done) {
return true;
}
if (null != properties.get(name) && verbose) {
project.log("Overriding previous definition of property \"" + name
+ "\"", Project.MSG_VERBOSE);
}
if (verbose) {
project.log("Setting project property: " + name + " -> "
+ value, Project.MSG_DEBUG);
}
properties.put(name, value);
return true;
| public boolean | setPropertyHook(java.lang.String ns, java.lang.String name, java.lang.Object value, boolean inherited, boolean user, boolean isNew)Sets a property. Any existing property of the same name
is overwritten, unless it is a user property. Will be called
from setProperty().
If all helpers return false, the property will be saved in
the default properties table by setProperty.
if (getNext() != null) {
boolean subst = getNext().setPropertyHook(ns, name, value,
inherited, user, isNew);
// If next has handled the property
if (subst) {
return true;
}
}
return false;
| public synchronized void | setUserProperty(java.lang.String ns, java.lang.String name, java.lang.Object value)Sets a user property, which cannot be overwritten by
set/unset property calls. Any previous value is overwritten.
project.log("Setting ro project property: " + name + " -> "
+ value, Project.MSG_DEBUG);
userProperties.put(name, value);
boolean done = setPropertyHook(ns, name, value, false, true, false);
if (done) {
return;
}
properties.put(name, value);
|
|