KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > script > ScriptDef


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package org.apache.tools.ant.taskdefs.optional.script;
19
20 import org.apache.tools.ant.AntTypeDefinition;
21 import org.apache.tools.ant.ComponentHelper;
22 import org.apache.tools.ant.Project;
23 import org.apache.tools.ant.MagicNames;
24 import org.apache.tools.ant.BuildException;
25 import org.apache.tools.ant.ProjectHelper;
26 import org.apache.tools.ant.taskdefs.DefBase;
27
28 import java.util.Map JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Locale JavaDoc;
32 import java.util.ArrayList JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.Set JavaDoc;
35 import java.util.HashSet JavaDoc;
36 import java.io.File JavaDoc;
37
38 import org.apache.tools.ant.util.ClasspathUtils;
39 import org.apache.tools.ant.util.ScriptRunnerBase;
40 import org.apache.tools.ant.util.ScriptRunnerHelper;
41
42 /**
43  * Define a task using a script
44  *
45  * @since Ant 1.6
46  */

47 public class ScriptDef extends DefBase {
48     /**
49      * script runner helper
50      */

51     private ScriptRunnerHelper helper = new ScriptRunnerHelper();
52     /**
53      * script runner.
54      */

55     /** Used to run the script */
56     private ScriptRunnerBase runner = null;
57
58     /** the name by which this script will be activated */
59     private String JavaDoc name;
60
61     /** Attributes definitions of this script */
62     private List JavaDoc attributes = new ArrayList JavaDoc();
63
64     /** Nested Element definitions of this script */
65     private List JavaDoc nestedElements = new ArrayList JavaDoc();
66
67     /** The attribute names as a set */
68     private Set JavaDoc attributeSet;
69
70     /** The nested element definitions indexed by their names */
71     private Map JavaDoc nestedElementMap;
72
73     /**
74      * Set the project.
75      * @param project the project that this def belows to.
76      */

77     public void setProject(Project project) {
78         super.setProject(project);
79         helper.setProjectComponent(this);
80         helper.setSetBeans(false);
81     }
82
83     /**
84      * set the name under which this script will be activated in a build
85      * file
86      *
87      * @param name the name of the script
88      */

89     public void setName(String JavaDoc name) {
90         this.name = name;
91     }
92
93     /**
94      * Indicates whether the task supports a given attribute name
95      *
96      * @param attributeName the name of the attribute.
97      *
98      * @return true if the attribute is supported by the script.
99      */

100     public boolean isAttributeSupported(String JavaDoc attributeName) {
101         return attributeSet.contains(attributeName);
102     }
103
104     /**
105      * Class representing an attribute definition
106      */

107     public static class Attribute {
108         /** The attribute name */
109         private String JavaDoc name;
110
111         /**
112          * Set the attribute name
113          *
114          * @param name the attribute name
115          */

116         public void setName(String JavaDoc name) {
117             this.name = name.toLowerCase(Locale.US);
118         }
119     }
120
121     /**
122      * Add an attribute definition to this script.
123      *
124      * @param attribute the attribute definition.
125      */

126     public void addAttribute(Attribute attribute) {
127         attributes.add(attribute);
128     }
129
130     /**
131      * Class to represent a nested element definition
132      */

133     public static class NestedElement {
134         /** The name of the neseted element */
135         private String JavaDoc name;
136
137         /** The Ant type to which this nested element corresponds. */
138         private String JavaDoc type;
139
140         /** The class to be created for this nested element */
141         private String JavaDoc className;
142
143         /**
144          * set the tag name for this nested element
145          *
146          * @param name the name of this nested element
147          */

148         public void setName(String JavaDoc name) {
149             this.name = name.toLowerCase(Locale.US);
150         }
151
152         /**
153          * Set the type of this element. This is the name of an
154          * Ant task or type which is to be used when this element is to be
155          * created. This is an alternative to specifying the class name directly
156          *
157          * @param type the name of an Ant type, or task, to use for this nested
158          * element.
159          */

160         public void setType(String JavaDoc type) {
161             this.type = type;
162         }
163
164         /**
165          * Set the classname of the class to be used for the nested element.
166          * This specifies the class directly and is an alternative to specifying
167          * the Ant type name.
168          *
169          * @param className the name of the class to use for this nested
170          * element.
171          */

172         public void setClassName(String JavaDoc className) {
173             this.className = className;
174         }
175     }
176
177     /**
178      * Add a nested element definition.
179      *
180      * @param nestedElement the nested element definition.
181      */

182     public void addElement(NestedElement nestedElement) {
183         nestedElements.add(nestedElement);
184     }
185
186     /**
187      * Define the script.
188      */

189     public void execute() {
190         if (name == null) {
191             throw new BuildException("scriptdef requires a name attribute to "
192                 + "name the script");
193         }
194
195         if (helper.getLanguage() == null) {
196             throw new BuildException("<scriptdef> requires a language attribute "
197                 + "to specify the script language");
198         }
199
200         // Check if need to set the loader
201
if (getAntlibClassLoader() != null || hasCpDelegate()) {
202             helper.setClassLoader(createLoader());
203         }
204
205         // Now create the scriptRunner
206
runner = helper.getScriptRunner();
207
208         attributeSet = new HashSet JavaDoc();
209         for (Iterator JavaDoc i = attributes.iterator(); i.hasNext();) {
210             Attribute attribute = (Attribute) i.next();
211             if (attribute.name == null) {
212                 throw new BuildException("scriptdef <attribute> elements "
213                     + "must specify an attribute name");
214             }
215
216             if (attributeSet.contains(attribute.name)) {
217                 throw new BuildException("scriptdef <" + name + "> declares "
218                     + "the " + attribute.name + " attribute more than once");
219             }
220             attributeSet.add(attribute.name);
221         }
222
223         nestedElementMap = new HashMap JavaDoc();
224         for (Iterator JavaDoc i = nestedElements.iterator(); i.hasNext();) {
225             NestedElement nestedElement = (NestedElement) i.next();
226             if (nestedElement.name == null) {
227                 throw new BuildException("scriptdef <element> elements "
228                     + "must specify an element name");
229             }
230             if (nestedElementMap.containsKey(nestedElement.name)) {
231                 throw new BuildException("scriptdef <" + name + "> declares "
232                     + "the " + nestedElement.name + " nested element more "
233                     + "than once");
234             }
235
236             if (nestedElement.className == null
237                 && nestedElement.type == null) {
238                 throw new BuildException("scriptdef <element> elements "
239                     + "must specify either a classname or type attribute");
240             }
241             if (nestedElement.className != null
242                 && nestedElement.type != null) {
243                 throw new BuildException("scriptdef <element> elements "
244                     + "must specify only one of the classname and type "
245                     + "attributes");
246             }
247
248
249             nestedElementMap.put(nestedElement.name, nestedElement);
250         }
251
252         // find the script repository - it is stored in the project
253
Map JavaDoc scriptRepository = null;
254         Project p = getProject();
255         synchronized (p) {
256             scriptRepository =
257                 (Map JavaDoc) p.getReference(MagicNames.SCRIPT_REPOSITORY);
258             if (scriptRepository == null) {
259                 scriptRepository = new HashMap JavaDoc();
260                 p.addReference(MagicNames.SCRIPT_REPOSITORY,
261                     scriptRepository);
262             }
263         }
264
265         name = ProjectHelper.genComponentName(getURI(), name);
266         scriptRepository.put(name, this);
267         AntTypeDefinition def = new AntTypeDefinition();
268         def.setName(name);
269         def.setClass(ScriptDefBase.class);
270         ComponentHelper.getComponentHelper(
271             getProject()).addDataTypeDefinition(def);
272     }
273
274     /**
275      * Create a nested element to be configured.
276      *
277      * @param elementName the name of the nested element.
278      * @return object representing the element name.
279      */

280     public Object JavaDoc createNestedElement(String JavaDoc elementName) {
281         NestedElement definition
282             = (NestedElement) nestedElementMap.get(elementName);
283         if (definition == null) {
284             throw new BuildException("<" + name + "> does not support "
285                 + "the <" + elementName + "> nested element");
286         }
287
288         Object JavaDoc instance = null;
289         String JavaDoc classname = definition.className;
290         if (classname == null) {
291             instance = getProject().createTask(definition.type);
292             if (instance == null) {
293                 instance = getProject().createDataType(definition.type);
294             }
295         } else {
296             /*
297             // try the context classloader
298             ClassLoader loader
299                 = Thread.currentThread().getContextClassLoader();
300             */

301             ClassLoader JavaDoc loader = createLoader();
302
303             try {
304                 instance = ClasspathUtils.newInstance(classname, loader);
305             } catch (BuildException e) {
306                 instance = ClasspathUtils.newInstance(classname, ScriptDef.class.getClassLoader());
307             }
308
309             getProject().setProjectReference(instance);
310         }
311
312         if (instance == null) {
313             throw new BuildException("<" + name + "> is unable to create "
314                 + "the <" + elementName + "> nested element");
315         }
316         return instance;
317     }
318
319     /**
320      * Execute the script.
321      *
322      * @param attributes collection of attributes
323      * @param elements a list of nested element values.
324      * @deprecated since 1.7.
325      * Use executeScript(attribute, elements, instance) instead.
326      */

327     public void executeScript(Map JavaDoc attributes, Map JavaDoc elements) {
328         executeScript(attributes, elements, null);
329     }
330
331     /**
332      * Execute the script.
333      * This is called by the script instance to execute the script for this
334      * definition.
335      *
336      * @param attributes collection of attributes
337      * @param elements a list of nested element values.
338      * @param instance the script instance; can be null
339      */

340     public void executeScript(Map JavaDoc attributes, Map JavaDoc elements, ScriptDefBase instance) {
341         runner.addBean("attributes", attributes);
342         runner.addBean("elements", elements);
343         runner.addBean("project", getProject());
344         if (instance != null) {
345             runner.addBean("self", instance);
346         }
347         runner.executeScript("scriptdef_" + name);
348     }
349
350     /**
351      * Defines the manager.
352      *
353      * @param manager the scripting manager.
354      */

355     public void setManager(String JavaDoc manager) {
356         helper.setManager(manager);
357     }
358
359     /**
360      * Defines the language (required).
361      *
362      * @param language the scripting language name for the script.
363      */

364     public void setLanguage(String JavaDoc language) {
365         helper.setLanguage(language);
366     }
367
368     /**
369      * Load the script from an external file ; optional.
370      *
371      * @param file the file containing the script source.
372      */

373     public void setSrc(File JavaDoc file) {
374         helper.setSrc(file);
375     }
376
377     /**
378      * Set the script text.
379      *
380      * @param text a component of the script text to be added.
381      */

382     public void addText(String JavaDoc text) {
383         helper.addText(text);
384     }
385 }
386
387
Popular Tags