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 | subant=org.apache.tools.ant.taskdefs.SubAnt | ||||
sync=org.apache.tools.ant.taskdefs.Sync | sync=org.apache.tools.ant.taskdefs.Sync | ||||
defaultexcludes=org.apache.tools.ant.taskdefs.DefaultExcludes | defaultexcludes=org.apache.tools.ant.taskdefs.DefaultExcludes | ||||
presetdef=org.apache.tools.ant.taskdefs.PreSetDef | |||||
macrodef=org.apache.tools.ant.taskdefs.MacroDef | |||||
# optional tasks | # optional tasks | ||||
image=org.apache.tools.ant.taskdefs.optional.image.Image | image=org.apache.tools.ant.taskdefs.optional.image.Image | ||||