diff --git a/proposal/sandbox/embed/ProjectHelperImpl2.java b/proposal/sandbox/embed/ProjectHelperImpl2.java
index b72fe3f92..8f86e0d54 100644
--- a/proposal/sandbox/embed/ProjectHelperImpl2.java
+++ b/proposal/sandbox/embed/ProjectHelperImpl2.java
@@ -129,7 +129,7 @@ public class ProjectHelperImpl2 extends ProjectHelper {
ex.printStackTrace();
}
}
-
+
/**
* Parses the project file, configuring the project as it goes.
*
@@ -835,7 +835,7 @@ public class ProjectHelperImpl2 extends ProjectHelper {
}
} else {
task.init();
- RuntimeConfigurable2.configure(task, attrs, context.project);
+ PropertyHelper.getPropertyHelper(context.project).configure(task, attrs, context.project);
}
}
@@ -999,7 +999,7 @@ public class ProjectHelperImpl2 extends ProjectHelper {
childWrapper.setAttributes2(attrs);
parentWrapper.addChild(childWrapper);
} else {
- RuntimeConfigurable2.configure(child, attrs, context.project);
+ PropertyHelper.getPropertyHelper(context.project).configure(child, attrs, context.project);
ih.storeElement(context.project, parent, child, elementName);
}
} catch (BuildException exc) {
@@ -1117,7 +1117,7 @@ public class ProjectHelperImpl2 extends ProjectHelper {
wrapper.setAttributes2(attrs);
target.addDataType(wrapper);
} else {
- RuntimeConfigurable2.configure(element, attrs, context.project);
+ PropertyHelper.getPropertyHelper(context.project).configure(element, attrs, context.project);
context.configureId(element, attrs);
}
} catch (BuildException exc) {
diff --git a/proposal/sandbox/embed/PropertyHelper.java b/proposal/sandbox/embed/PropertyHelper.java
new file mode 100644
index 000000000..47d0e7f46
--- /dev/null
+++ b/proposal/sandbox/embed/PropertyHelper.java
@@ -0,0 +1,219 @@
+/*
+ * 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.apache.tools.ant.helper.*;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+import java.util.Hashtable;
+import org.xml.sax.AttributeList;
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.AttributeListImpl;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * Deals with properties - substitution, dynamic properties, etc.
+ *
+ * Eventually the static methods from ProjectHelper should be
+ * moved here ( with a wrapper for backward compat ).
+ *
+ * Also the property store ( Hashtable ) and all property manipulation
+ * logic could be moved here.
+ *
+ * @author Stefan Bodewig
+ * @author Costin Manolache
+ */
+public class PropertyHelper {
+ Project project;
+ Vector propertyInterceptors=new Vector();
+
+ protected PropertyHelper() {
+ }
+
+ public void setProject(Project p ) {
+ this.project=p;
+ }
+
+ /** Factory method to create a property processor.
+ * Right now returns the singleton instance of PropertyHelper,
+ * in future it may use discovery of config to return a
+ * customized version, for integration in other apps.
+ */
+ public static PropertyHelper getPropertyHelper(Project project) {
+ PropertyHelper ph=(PropertyHelper)project.getReference( "ant.PropertyHelper" );
+ if( ph!=null ) return ph;
+ ph=new PropertyHelper();
+ ph.setProject( project );
+
+ project.addReference( "ant.PropertyHelper",ph );
+ return ph;
+ }
+
+ public void addPropertyInterceptor( PropertyInterceptor pi ) {
+ propertyInterceptors.addElement( pi );
+ }
+
+// public Vector getPropertyInterceptors() {
+// return propertyInterceptors;
+// }
+
+ /** Process an value, doing the replacements.
+ */
+ public String replaceProperties( String value ) {
+ if (value == null) {
+ return null;
+ }
+
+ Vector fragments = new Vector();
+ Vector propertyRefs = new Vector();
+
+ // XXX Move the static method here - if this is accepted in the main
+ // branch.
+ ProjectHelper.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 repl=processDynamic( project, propertyName);
+
+ if( repl==null) {
+ // default to the static property.
+ repl=project.getProperty( propertyName );
+ }
+
+ if (repl==null ) {
+ project.log("Property ${" + propertyName
+ + "} has not been set", Project.MSG_VERBOSE);
+ fragment="${" + propertyName + "}";
+ } else {
+ fragment = (String) repl;
+ }
+ }
+ sb.append(fragment);
+ }
+
+ return sb.toString();
+ }
+
+ /** Use the reference table to generate values for ${} substitution.
+ * To preserve backward compat ( as much as possible ) we'll only process
+ * ids with a 'namespace-like' syntax.
+ *
+ * Currently we support:
+ * dom:idName:/xpath/like/syntax - the referenced node must be a DOM, we'll use
+ * XPath to extract a node. ( a simplified syntax is handled
+ * directly, XXX used for 'real' xpaths ).
+ * toString:idName - we use toString on the referenced object
+ * bean:idName.propertyName - we get the idName and call the getter for the property.
+ */
+ Object processDynamic( Project project, String name ) {
+ for(int i=0; i.
+ */
+
+package org.apache.tools.ant;
+
+import org.apache.tools.ant.helper.*;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Vector;
+import java.util.Hashtable;
+import org.xml.sax.AttributeList;
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.AttributeListImpl;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * The new XML processor will use this interface to support
+ * dynamic properties.
+ *
+ * Any task/type that implements this interface will be registered
+ * and will receive notification of each property get operations
+ * executed by the processor.
+ *
+ * XXX In ant1.6+, tasks implementing the interface will also
+ * receive notification when a property is set.
+ *
+ * @author Costin Manolache
+ */
+public interface PropertyInterceptor {
+
+ /**
+ * Called for each ${} property. If the result is null the
+ * next PropertyInterceptor will be called. If all interceptors
+ * return null, the properties stored in Project are used.
+ */
+ public Object getProperty( Project p, String ns, String name );
+
+ /**
+ * Called when a property/reference is recorded.
+ * XXX Not implemented yet.
+ */
+ // public boolean setProperty( String ns, String name, Object value );
+
+}
diff --git a/proposal/sandbox/embed/RuntimeConfigurable2.java b/proposal/sandbox/embed/RuntimeConfigurable2.java
index 1e594d1cc..89540823e 100644
--- a/proposal/sandbox/embed/RuntimeConfigurable2.java
+++ b/proposal/sandbox/embed/RuntimeConfigurable2.java
@@ -176,7 +176,7 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable {
* @return The child wrapper at position index
within the
* list.
*/
- RuntimeConfigurable getChild(int index) {
+ public RuntimeConfigurable getChild(int index) {
return (RuntimeConfigurable) children.elementAt(index);
}
@@ -234,7 +234,8 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable {
String id = null;
if (attributes != null) {
- configure(wrappedObject, attributes, p);
+ PropertyHelper ph=PropertyHelper.getPropertyHelper(p);
+ ph.configure(wrappedObject, attributes, p);
id = attributes.getValue("id");
attributes = null;
}
@@ -255,125 +256,11 @@ public class RuntimeConfigurable2 extends RuntimeConfigurable {
child.maybeConfigure(p);
}
ProjectHelper.storeChild(p, wrappedObject, child.wrappedObject,
- child.getElementTag().toLowerCase(Locale.US));
+ child.getElementTag().toLowerCase(Locale.US));
}
if (id != null) {
p.addReference(id, wrappedObject);
}
}
-
-
- public static void configure( Object target, Attributes attrs, Project project )
- throws BuildException
- {
- if (target instanceof TaskAdapter) {
- target = ((TaskAdapter) target).getProxy();
- }
-
- IntrospectionHelper ih =
- IntrospectionHelper.getHelper(target.getClass());
-
- project.addBuildListener(ih);
-
- for (int i = 0; i < attrs.getLength(); i++) {
- // reflect these into the target
- String value = RuntimeConfigurable2.replaceProperties(project, attrs.getValue(i));
-
- try {
- ih.setAttribute(project, target,
- attrs.getQName(i).toLowerCase(Locale.US), value);
- } catch (BuildException be) {
- // id attribute must be set externally
- if (!attrs.getQName(i).equals("id")) {
- throw be;
- }
- }
- }
- }
-
- public static String replaceProperties( Project project ,String value ) {
- if (value == null) {
- return null;
- }
-
- Vector fragments = new Vector();
- Vector propertyRefs = new Vector();
-
- ProjectHelper.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 repl=project.getProperty( propertyName );
-
- if( repl==null) {
- // Try a dynamic substitiution using ref
- repl=processReference( project, propertyName );
- }
-
- if (repl==null ) {
- project.log("Property ${" + propertyName
- + "} has not been set", Project.MSG_VERBOSE);
- fragment="${" + propertyName + "}";
- } else {
- fragment = (String) repl;
- }
- }
- sb.append(fragment);
- }
-
- return sb.toString();
-
- }
-
- static Hashtable propertySources=new Hashtable();
-
- public static interface ProjectPropertySource {
-
- public String getProperty( Project project, String key );
-
- }
-
- public static void addPropertySource( String ns, ProjectPropertySource src ) {
- propertySources.put( ns, src );
- }
-
-
- /** Use the reference table to generate values for ${} substitution.
- * To preserve backward compat ( as much as possible ) we'll only process
- * ids with a 'namespace-like' syntax.
- *
- * Currently we support:
- * dom:idName:/xpath/like/syntax - the referenced node must be a DOM, we'll use
- * XPath to extract a node. ( a simplified syntax is handled
- * directly, XXX used for 'real' xpaths ).
- * toString:idName - we use toString on the referenced object
- * bean:idName.propertyName - we get the idName and call the getter for the property.
- */
- static String processReference( Project project, String name ) {
- if( name.startsWith( "toString:" )) {
- name=name.substring( "toString:".length());
- Object v=project.getReference( name );
- if( v==null ) return null;
- return v.toString();
- }
-
- int idx=name.indexOf(":");
- if( idx<0 ) return null;
-
- String ns=name.substring( 0, idx );
- String path=name.substring( idx );
-
- ProjectPropertySource ps=(ProjectPropertySource)propertySources.get( ns );
- if( ps == null )
- return null;
-
- return ps.getProperty( project, path );
- }
}
diff --git a/proposal/sandbox/embed/ant-sax2.jar b/proposal/sandbox/embed/ant-sax2.jar
index 780565122..e8ca89583 100644
Binary files a/proposal/sandbox/embed/ant-sax2.jar and b/proposal/sandbox/embed/ant-sax2.jar differ
diff --git a/proposal/sandbox/embed/build.xml b/proposal/sandbox/embed/build.xml
index 3fcebe6a8..7c391694a 100644
--- a/proposal/sandbox/embed/build.xml
+++ b/proposal/sandbox/embed/build.xml
@@ -8,6 +8,10 @@
todir="${ant.src}/src/main/org/apache/tools/ant/helper" />
+
+
@@ -16,6 +20,8 @@
destdir="${ant.build}/classes" >
+
+
@@ -28,6 +34,8 @@
+
+