diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java new file mode 100644 index 00000000..ac9eb88e --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java @@ -0,0 +1,397 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.tools.ant.taskdefs.optional.script; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.apache.tools.ant.AntTypeDefinition; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.ComponentHelper; +import org.apache.tools.ant.MagicNames; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectHelper; +import org.apache.tools.ant.taskdefs.DefBase; +import org.apache.tools.ant.types.ResourceCollection; +import org.apache.tools.ant.util.ClasspathUtils; +import org.apache.tools.ant.util.ScriptRunnerBase; +import org.apache.tools.ant.util.ScriptRunnerHelper; + +/** + * Define a task using a script + * + * @since Ant 1.6 + */ +public class ScriptDef extends DefBase { + /** + * script runner helper + */ + private ScriptRunnerHelper helper = new ScriptRunnerHelper(); + + /** the name by which this script will be activated */ + private String name; + + /** Attributes definitions of this script */ + private List attributes = new ArrayList(); + + /** Nested Element definitions of this script */ + private List nestedElements = new ArrayList(); + + /** The attribute names as a set */ + private Set attributeSet; + + /** The nested element definitions indexed by their names */ + private Map nestedElementMap; + + /** + * Set the project. + * @param project the project that this def belows to. + */ + public void setProject(Project project) { + super.setProject(project); + helper.setProjectComponent(this); + helper.setSetBeans(false); + } + + /** + * set the name under which this script will be activated in a build + * file + * + * @param name the name of the script + */ + public void setName(String name) { + this.name = name; + } + + /** + * Indicates whether the task supports a given attribute name + * + * @param attributeName the name of the attribute. + * + * @return true if the attribute is supported by the script. + */ + public boolean isAttributeSupported(String attributeName) { + return attributeSet.contains(attributeName); + } + + /** + * Class representing an attribute definition + */ + public static class Attribute { + /** The attribute name */ + private String name; + + /** + * Set the attribute name + * + * @param name the attribute name + */ + public void setName(String name) { + this.name = name.toLowerCase(Locale.ENGLISH); + } + } + + /** + * Add an attribute definition to this script. + * + * @param attribute the attribute definition. + */ + public void addAttribute(Attribute attribute) { + attributes.add(attribute); + } + + /** + * Class to represent a nested element definition + */ + public static class NestedElement { + /** The name of the nested element */ + private String name; + + /** The Ant type to which this nested element corresponds. */ + private String type; + + /** The class to be created for this nested element */ + private String className; + + /** + * set the tag name for this nested element + * + * @param name the name of this nested element + */ + public void setName(String name) { + this.name = name.toLowerCase(Locale.ENGLISH); + } + + /** + * Set the type of this element. This is the name of an + * Ant task or type which is to be used when this element is to be + * created. This is an alternative to specifying the class name directly + * + * @param type the name of an Ant type, or task, to use for this nested + * element. + */ + public void setType(String type) { + this.type = type; + } + + /** + * Set the classname of the class to be used for the nested element. + * This specifies the class directly and is an alternative to specifying + * the Ant type name. + * + * @param className the name of the class to use for this nested + * element. + */ + public void setClassName(String className) { + this.className = className; + } + } + + /** + * Add a nested element definition. + * + * @param nestedElement the nested element definition. + */ + public void addElement(NestedElement nestedElement) { + nestedElements.add(nestedElement); + } + + /** + * Define the script. + */ + public void execute() { + if (name == null) { + throw new BuildException("scriptdef requires a name attribute to " + + "name the script"); + } + + if (helper.getLanguage() == null) { + throw new BuildException("<scriptdef> requires a language attribute " + + "to specify the script language"); + } + + // Check if need to set the loader + if (getAntlibClassLoader() != null || hasCpDelegate()) { + helper.setClassLoader(createLoader()); + } + + attributeSet = new HashSet(); + for (Iterator i = attributes.iterator(); i.hasNext();) { + Attribute attribute = (Attribute) i.next(); + if (attribute.name == null) { + throw new BuildException("scriptdef <attribute> elements " + + "must specify an attribute name"); + } + + if (attributeSet.contains(attribute.name)) { + throw new BuildException("scriptdef <" + name + "> declares " + + "the " + attribute.name + " attribute more than once"); + } + attributeSet.add(attribute.name); + } + + nestedElementMap = new HashMap(); + for (Iterator i = nestedElements.iterator(); i.hasNext();) { + NestedElement nestedElement = (NestedElement) i.next(); + if (nestedElement.name == null) { + throw new BuildException("scriptdef <element> elements " + + "must specify an element name"); + } + if (nestedElementMap.containsKey(nestedElement.name)) { + throw new BuildException("scriptdef <" + name + "> declares " + + "the " + nestedElement.name + " nested element more " + + "than once"); + } + + if (nestedElement.className == null + && nestedElement.type == null) { + throw new BuildException("scriptdef <element> elements " + + "must specify either a classname or type attribute"); + } + if (nestedElement.className != null + && nestedElement.type != null) { + throw new BuildException("scriptdef <element> elements " + + "must specify only one of the classname and type " + + "attributes"); + } + + + nestedElementMap.put(nestedElement.name, nestedElement); + } + + // find the script repository - it is stored in the project + Map scriptRepository = lookupScriptRepository(); + name = ProjectHelper.genComponentName(getURI(), name); + scriptRepository.put(name, this); + AntTypeDefinition def = new AntTypeDefinition(); + def.setName(name); + def.setClass(ScriptDefBase.class); + ComponentHelper.getComponentHelper( + getProject()).addDataTypeDefinition(def); + } + + /** + * Find or create the script repository - it is stored in the project. + * This method is synchronized on the project under {@link MagicNames#SCRIPT_REPOSITORY} + * @return the current script repository registered as a reference. + */ + private Map lookupScriptRepository() { + Map scriptRepository = null; + Project p = getProject(); + synchronized (p) { + scriptRepository = + (Map) p.getReference(MagicNames.SCRIPT_REPOSITORY); + if (scriptRepository == null) { + scriptRepository = new HashMap(); + p.addReference(MagicNames.SCRIPT_REPOSITORY, + scriptRepository); + } + } + return scriptRepository; + } + + /** + * Create a nested element to be configured. + * + * @param elementName the name of the nested element. + * @return object representing the element name. + */ + public Object createNestedElement(String elementName) { + NestedElement definition + = (NestedElement) nestedElementMap.get(elementName); + if (definition == null) { + throw new BuildException("<" + name + "> does not support " + + "the <" + elementName + "> nested element"); + } + + Object instance = null; + String classname = definition.className; + if (classname == null) { + instance = getProject().createTask(definition.type); + if (instance == null) { + instance = getProject().createDataType(definition.type); + } + } else { + /* + // try the context classloader + ClassLoader loader + = Thread.currentThread().getContextClassLoader(); + */ + ClassLoader loader = createLoader(); + + try { + instance = ClasspathUtils.newInstance(classname, loader); + } catch (BuildException e) { + instance = ClasspathUtils.newInstance(classname, ScriptDef.class.getClassLoader()); + } + + getProject().setProjectReference(instance); + } + + if (instance == null) { + throw new BuildException("<" + name + "> is unable to create " + + "the <" + elementName + "> nested element"); + } + return instance; + } + + /** + * Execute the script. + * + * @param attributes collection of attributes + * @param elements a list of nested element values. + * @deprecated since 1.7. + * Use executeScript(attribute, elements, instance) instead. + */ + public void executeScript(Map attributes, Map elements) { + executeScript(attributes, elements, null); + } + + /** + * Execute the script. + * This is called by the script instance to execute the script for this + * definition. + * + * @param attributes collection of attributes + * @param elements a list of nested element values. + * @param instance the script instance; can be null + */ + public void executeScript(Map attributes, Map elements, ScriptDefBase instance) { + ScriptRunnerBase runner = helper.getScriptRunner(); + runner.addBean("attributes", attributes); + runner.addBean("elements", elements); + runner.addBean("project", getProject()); + if (instance != null) { + runner.addBean("self", instance); + } + runner.executeScript("scriptdef_" + name); + } + + /** + * Defines the manager. + * + * @param manager the scripting manager. + */ + public void setManager(String manager) { + helper.setManager(manager); + } + + /** + * Defines the language (required). + * + * @param language the scripting language name for the script. + */ + public void setLanguage(String language) { + helper.setLanguage(language); + } + + /** + * Load the script from an external file ; optional. + * + * @param file the file containing the script source. + */ + public void setSrc(File file) { + helper.setSrc(file); + } + + /** + * Set the script text. + * + * @param text a component of the script text to be added. + */ + public void addText(String text) { + helper.addText(text); + } + + /** + * Add any source resource. + * @since Ant1.7.1 + * @param resource source of script + */ + public void add(ResourceCollection resource) { + helper.add(resource); + } +} + |