peterreilly 2003/08/14 05:46:02 Modified: src/main/org/apache/tools/ant/taskdefs defaults.properties Added: src/main/org/apache/tools/ant/taskdefs MacroDef.java MacroInstance.java PreSetDef.java Log: Adding tasks presetdef and macrodef Revision Changes Path 1.152 +2 -0 ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties Index: defaults.properties =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties,v retrieving revision 1.151 retrieving revision 1.152 diff -u -r1.151 -r1.152 --- defaults.properties 23 Jul 2003 14:12:12 -0000 1.151 +++ defaults.properties 14 Aug 2003 12:46:01 -0000 1.152 @@ -76,6 +76,8 @@ subant=org.apache.tools.ant.taskdefs.SubAnt sync=org.apache.tools.ant.taskdefs.Sync defaultexcludes=org.apache.tools.ant.taskdefs.DefaultExcludes +presetdef=org.apache.tools.ant.taskdefs.PreSetDef +macrodef=org.apache.tools.ant.taskdefs.MacroDef # optional tasks image=org.apache.tools.ant.taskdefs.optional.image.Image 1.1 ant/src/main/org/apache/tools/ant/taskdefs/MacroDef.java Index: MacroDef.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2003 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 "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 [EMAIL PROTECTED] * * 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 * <http://www.apache.org/>. */ package org.apache.tools.ant.taskdefs; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.HashMap; import org.apache.tools.ant.AntTypeDefinition; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.ComponentHelper; import org.apache.tools.ant.Project; import org.apache.tools.ant.ProjectHelper; import org.apache.tools.ant.Task; import org.apache.tools.ant.TaskContainer; import org.apache.tools.ant.UnknownElement; /** * Describe class <code>MacroDef</code> here. * * @author Peter Reilly */ public class MacroDef extends Task implements AntlibInterface, TaskContainer { private UnknownElement nestedTask; private String name; private String componentName; private List params = new ArrayList(); private Map elements = new HashMap(); private String uri; /** * Name of the definition * @param name the name of the definition */ public void setName(String name) { this.name = name; } /** * The URI for this definition. * @param uri the namespace URI * @throws BuildException if uri is not allowed */ public void setURI(String uri) throws BuildException { if (uri.equals(ProjectHelper.ANT_CORE_URI)) { uri = ""; } if (uri.startsWith("ant:") && !uri.startsWith("antlib:")) { throw new BuildException("Attempt to use a reserved URI " + uri); } this.uri = uri; } /** * Set the class loader. * Not used * @param classLoader a <code>ClassLoader</code> value */ public void setAntlibClassLoader(ClassLoader classLoader) { // Ignore } /** * Add a nested task to ExtendType * @param nestedTask Nested task/type to extend */ public void addTask(Task nestedTask) { if (this.nestedTask != null) { throw new BuildException("Only one sequential/Parallel allowed"); } UnknownElement ue = (UnknownElement) nestedTask; if (!ue.getNamespace().equals("") || (!ue.getTag().equals("sequential") && !ue.getTag().equals("parallel"))) { throw new BuildException("Unsupported tag " + ue.getQName()); } this.nestedTask = ue; } /** * @return the nested task */ public UnknownElement getNestedTask() { return nestedTask; } /** * @return the nested Params */ public List getParams() { return params; } /** * @return the nested elements */ public Map getElements() { return elements; } /** * Add a param element. * * @param param a param nested element. */ public void addConfiguredParam(Param param) { if (param.getName() == null) { throw new BuildException( "the param nested element needed a \"name\" attribute"); } params.add(param); } /** * Add an element element. * * @param element an element nested element. */ public void addConfiguredElement(TemplateElement element) { if (element.getName() == null) { throw new BuildException( "the element nested element needed a \"name\" attribute"); } elements.put(element.getName(), element); } /** * Create a new ant type based on the embedded tasks and types. * */ public void execute() { if (nestedTask == null) { throw new BuildException("Missing nested element"); } if (name == null) { throw new BuildException("Name not specified"); } name = ProjectHelper.genComponentName(uri, name); MyAntTypeDefinition def = new MyAntTypeDefinition(this); def.setName(name); def.setClass(MacroInstance.class); ComponentHelper helper = ComponentHelper.getComponentHelper( getProject()); helper.addDataTypeDefinition(def); } /** * A nested element for the MacroDef task. * */ public static class Param { private String name; private String defaultValue; /** * The name of the parameter. * * @param name the name of the parameter */ public void setName(String name) { this.name = name; } /** * @return the name of the parameter. */ public String getName() { return name; } /** * The default value to use if the parameter is not * used in the templated instance. * * @param defaultValue the default value */ public void setDefault(String defaultValue) { this.defaultValue = defaultValue; } /** * @return the default value, null if not set */ public String getDefault() { return defaultValue; } } /** * A nested element for the MacroDef task. * */ public static class TemplateElement { private String name; private boolean optional = false; /** * The name of the element. * * @param name the name of the element. */ public void setName(String name) { this.name = name; } /** * @return the name of the element. */ public String getName() { return name; } /** * is this element optional ? * * @param optional if true this element may be left out, default * is false. */ public void setOptional(boolean optional) { this.optional = optional; } /** * @return the optional attribute */ public boolean isOptional() { return optional; } } /** * extends AntTypeDefinition, on create * of the object, the template macro definition * is given. */ private static class MyAntTypeDefinition extends AntTypeDefinition { private MacroDef template; /** * Creates a new <code>MyAntTypeDefinition</code> instance. * * @param template a <code>MacroDef</code> value */ public MyAntTypeDefinition(MacroDef template) { this.template = template; } /** * create an instance of the definition. * The instance may be wrapped in a proxy class. * @param project the current project * @return the created object */ public Object create(Project project) { Object o = super.create(project); if (o == null) { return null; } ((MacroInstance) o).setTemplate(template); return o; } } } 1.1 ant/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java Index: MacroInstance.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2003 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 "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 [EMAIL PROTECTED] * * 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 * <http://www.apache.org/>. */ package org.apache.tools.ant.taskdefs; import java.util.ArrayList; import java.util.List; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.HashSet; import java.util.HashMap; import java.util.Hashtable; import java.util.Enumeration; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DynamicConfigurator; import org.apache.tools.ant.Task; import org.apache.tools.ant.TaskContainer; import org.apache.tools.ant.UnknownElement; import org.apache.tools.ant.RuntimeConfigurable; /** * The class to be placed in the ant type definition. * It is given a pointer to the template definition, * and makes a copy of the unknown element, substituting * the the parameter values in attributes and text. * @author Peter Reilly */ public class MacroInstance extends Task implements DynamicConfigurator { private MacroDef template; private Map map = new HashMap(); private Map elements = new HashMap(); private Hashtable localProperties = new Hashtable(); /** * Called from MacroDef.MyAntTypeDefinition#create() * * @param template a <code>MacroDef</code> value */ protected void setTemplate(MacroDef template) { this.template = template; } /** * A parameter name value pair as a xml attribute. * * @param name the name of the attribute * @param value the value of the attribute */ public void setDynamicAttribute(String name, String value) { map.put(name, value); } /** * Add an element. * @param name the name of the element * @return an inner Element type * @throws BuildException if the name is not known or if this element * has already been seen */ public Object createDynamicElement(String name) throws BuildException { if (template.getElements().get(name) == null) { throw new BuildException("unsupported element " + name); } if (elements.get(name) != null) { throw new BuildException("Element " + name + " already present"); } Element ret = new Element(); elements.put(name, ret); return ret; } /** * Embedded element in macro instance */ public static class Element implements TaskContainer { private List unknownElements = new ArrayList(); /** * Add an unknown element (to be snipped into the template instance) * * @param nestedTask an unknown element */ public void addTask(Task nestedTask) { unknownElements.add(nestedTask); } /** * @return the list of unknown elements */ public List getUnknownElements() { return unknownElements; } } private static String macroSubs(String s, Map macroMapping) { StringBuffer ret = new StringBuffer(); StringBuffer macroName = new StringBuffer(); boolean inMacro = false; for (int i = 0; i < s.length(); ++i) { if (s.charAt(i) == '$') { inMacro = true; } else { if (inMacro) { if (s.charAt(i) == '{') { continue; } else if (s.charAt(i) == '}') { String name = macroName.toString(); String value = (String) macroMapping.get(name); if (value == null) { ret.append("${" + name + "}"); } else { ret.append(value); } macroName = new StringBuffer(); inMacro = false; } else { macroName.append(s.charAt(i)); } } else { ret.append(s.charAt(i)); } } } return ret.toString(); } private UnknownElement copy(UnknownElement ue) { UnknownElement ret = new UnknownElement(ue.getTag()); ret.setNamespace(ue.getNamespace()); ret.setProject(getProject()); ret.setQName(ue.getQName()); ret.setTaskName(ue.getTaskName()); ret.setLocation(ue.getLocation()); ret.setOwningTarget(getOwningTarget()); RuntimeConfigurable rc = new RuntimeConfigurable( ret, ue.getTaskName()); rc.setPolyType(ue.getWrapper().getPolyType()); Map map = ue.getWrapper().getAttributeMap(); for (Iterator i = map.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); rc.setAttribute( (String) entry.getKey(), macroSubs((String) entry.getValue(), localProperties)); } rc.addText(macroSubs(ue.getWrapper().getText().toString(), localProperties)); Enumeration e = ue.getWrapper().getChildren(); while (e.hasMoreElements()) { RuntimeConfigurable r = (RuntimeConfigurable) e.nextElement(); UnknownElement unknownElement = (UnknownElement) r.getProxy(); String tag = unknownElement.getTag(); MacroDef.TemplateElement templateElement = (MacroDef.TemplateElement) template.getElements().get(tag); if (templateElement == null) { UnknownElement child = copy(unknownElement); rc.addChild(child.getWrapper()); ret.addChild(child); } else { Element element = (Element) elements.get(tag); if (element == null) { if (!templateElement.isOptional()) { throw new BuildException( "Required nested element " + templateElement.getName() + " missing"); } continue; } for (Iterator i = element.getUnknownElements().iterator(); i.hasNext();) { UnknownElement child = (UnknownElement) i.next(); rc.addChild(child.getWrapper()); ret.addChild(child); } } } return ret; } /** * Execute the templates instance. * Copies the unknown element, substitutes the parameters, * and calls perform on the unknown element. * */ public void execute() { localProperties = new Hashtable(); Set copyKeys = new HashSet(map.keySet()); for (int i = 0; i < template.getParams().size(); ++i) { MacroDef.Param param = (MacroDef.Param) template.getParams().get(i); String value = (String) map.get(param.getName()); if (value == null) { value = param.getDefault(); } if (value == null) { throw new BuildException( "required parameter " + param.getName() + " not set"); } localProperties.put(param.getName(), value); copyKeys.remove(param.getName()); } if (copyKeys.size() != 0) { throw new BuildException( "Unknown attribute" + (copyKeys.size() > 1 ? "s " : " ") + copyKeys); } // need to set the project on unknown element UnknownElement c = copy(template.getNestedTask()); c.init(); c.perform(); } } 1.1 ant/src/main/org/apache/tools/ant/taskdefs/PreSetDef.java Index: PreSetDef.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2003 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 "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 [EMAIL PROTECTED] * * 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 * <http://www.apache.org/>. */ package org.apache.tools.ant.taskdefs; import org.apache.tools.ant.AntTypeDefinition; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.ComponentHelper; import org.apache.tools.ant.Project; import org.apache.tools.ant.ProjectHelper; import org.apache.tools.ant.Task; import org.apache.tools.ant.TaskContainer; import org.apache.tools.ant.UnknownElement; /** * The preset definition task generates a new definition * based on a current definition with some attributes or * elements preset. * <pre> * <presetdef name="my.javac"> * <javac deprecation="${deprecation}" debug="${debug}"/> * </presetdef> * <my.javac srcdir="src" destdir="classes"/> * </pre> * * @author Peter Reilly */ public class PreSetDef extends Task implements AntlibInterface, TaskContainer { private UnknownElement nestedTask; private String name; private String componentName; private String uri; /** * Name of the definition * @param name the name of the definition */ public void setName(String name) { this.name = name; } /** * The URI for this definition. * @param uri the namespace URI * @throws BuildException if uri is not allowed */ public void setURI(String uri) throws BuildException { if (uri.equals(ProjectHelper.ANT_CORE_URI)) { uri = ""; } if (uri.startsWith("ant:") && !uri.startsWith("antlib:")) { throw new BuildException("Attempt to use a reserved URI " + uri); } this.uri = uri; } /** * Set the class loader. * Not used * @param classLoader a <code>ClassLoader</code> value */ public void setAntlibClassLoader(ClassLoader classLoader) { // Ignore } /** * Add a nested task to predefine attributes and elements on * @param nestedTask Nested task/type to extend */ public void addTask(Task nestedTask) { if (this.nestedTask != null) { throw new BuildException("Only one nested element allowed"); } if (!(nestedTask instanceof UnknownElement)) { throw new BuildException( "addTask called with a task that is not an unknown element"); } this.nestedTask = (UnknownElement) nestedTask; } /** * make a new definition */ public void execute() { if (nestedTask == null) { throw new BuildException("Missing nested element"); } if (name == null) { throw new BuildException("Name not specified"); } name = ProjectHelper.genComponentName(uri, name); ComponentHelper helper = ComponentHelper.getComponentHelper( getProject()); String componentName = ProjectHelper.genComponentName( nestedTask.getNamespace(), nestedTask.getTag()); AntTypeDefinition def = helper.getDefinition(componentName); if (def == null) { throw new BuildException( "Unable to find typedef " + componentName); } MyAntTypeDefinition newDef = new MyAntTypeDefinition(def, nestedTask); newDef.setName(name); helper.addDataTypeDefinition(newDef); } private static class MyAntTypeDefinition extends AntTypeDefinition { AntTypeDefinition parent; UnknownElement element; public MyAntTypeDefinition(AntTypeDefinition parent, UnknownElement el) { this.parent = parent; this.element = el; } public void setClass(Class clazz) { throw new BuildException("Not supported"); } public void setClassName(String className) { throw new BuildException("Not supported"); } /** * get the classname of the definition * @return the name of the class of this definition */ public String getClassName() { return parent.getClassName(); } /** * set the adapter class for this definition. * NOTE Supported * @param adapterClass the adapterClass */ public void setAdapterClass(Class adapterClass) { throw new BuildException("Not supported"); } /** * set the assignable class for this definition. * NOT SUPPORTED * @param adaptToClass the assignable class */ public void setAdaptToClass(Class adaptToClass) { throw new BuildException("Not supported"); } /** * set the classloader to use to create an instance * of the definition * @param classLoader the classLoader */ public void setClassLoader(ClassLoader classLoader) { throw new BuildException("Not supported"); } /** * get the classloader for this definition * @return the classloader for this definition */ public ClassLoader getClassLoader() { return parent.getClassLoader(); } /** * get the exposed class for this definition. * @return the exposed class */ public Class getExposedClass(Project project) { return parent.getExposedClass(project); } /** * get the definition class * @param project the current project * @return the type of the definition */ public Class getTypeClass(Project project) { return parent.getTypeClass(project); } /** * check if the attributes are correct * @param project the current project */ public void checkClass(Project project) { parent.checkClass(project); } /** * create an instance of the definition. * The instance may be wrapped in a proxy class. * @param project the current project * @return the created object */ public Object create(Project project) { Object o = parent.create(project); if (o == null) { return null; } element.configure(o); return o; } } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]