git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275082 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -0,0 +1,319 @@ | |||
| /* | |||
| * 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 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 | |||
| * <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; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,267 @@ | |||
| /* | |||
| * 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 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 | |||
| * <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(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,267 @@ | |||
| /* | |||
| * 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 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 | |||
| * <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; | |||
| } | |||
| } | |||
| } | |||
| @@ -76,6 +76,8 @@ whichresource=org.apache.tools.ant.taskdefs.WhichResource | |||
| 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 | |||