1 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 ; 29 import java.util.HashMap ; 30 import java.util.List ; 31 import java.util.Locale ; 32 import java.util.ArrayList ; 33 import java.util.Iterator ; 34 import java.util.Set ; 35 import java.util.HashSet ; 36 import java.io.File ; 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 47 public class ScriptDef extends DefBase { 48 51 private ScriptRunnerHelper helper = new ScriptRunnerHelper(); 52 55 56 private ScriptRunnerBase runner = null; 57 58 59 private String name; 60 61 62 private List attributes = new ArrayList (); 63 64 65 private List nestedElements = new ArrayList (); 66 67 68 private Set attributeSet; 69 70 71 private Map nestedElementMap; 72 73 77 public void setProject(Project project) { 78 super.setProject(project); 79 helper.setProjectComponent(this); 80 helper.setSetBeans(false); 81 } 82 83 89 public void setName(String name) { 90 this.name = name; 91 } 92 93 100 public boolean isAttributeSupported(String attributeName) { 101 return attributeSet.contains(attributeName); 102 } 103 104 107 public static class Attribute { 108 109 private String name; 110 111 116 public void setName(String name) { 117 this.name = name.toLowerCase(Locale.US); 118 } 119 } 120 121 126 public void addAttribute(Attribute attribute) { 127 attributes.add(attribute); 128 } 129 130 133 public static class NestedElement { 134 135 private String name; 136 137 138 private String type; 139 140 141 private String className; 142 143 148 public void setName(String name) { 149 this.name = name.toLowerCase(Locale.US); 150 } 151 152 160 public void setType(String type) { 161 this.type = type; 162 } 163 164 172 public void setClassName(String className) { 173 this.className = className; 174 } 175 } 176 177 182 public void addElement(NestedElement nestedElement) { 183 nestedElements.add(nestedElement); 184 } 185 186 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 if (getAntlibClassLoader() != null || hasCpDelegate()) { 202 helper.setClassLoader(createLoader()); 203 } 204 205 runner = helper.getScriptRunner(); 207 208 attributeSet = new HashSet (); 209 for (Iterator 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 (); 224 for (Iterator 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 Map scriptRepository = null; 254 Project p = getProject(); 255 synchronized (p) { 256 scriptRepository = 257 (Map ) p.getReference(MagicNames.SCRIPT_REPOSITORY); 258 if (scriptRepository == null) { 259 scriptRepository = new HashMap (); 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 280 public Object createNestedElement(String 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 instance = null; 289 String 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 301 ClassLoader 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 327 public void executeScript(Map attributes, Map elements) { 328 executeScript(attributes, elements, null); 329 } 330 331 340 public void executeScript(Map attributes, Map 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 355 public void setManager(String manager) { 356 helper.setManager(manager); 357 } 358 359 364 public void setLanguage(String language) { 365 helper.setLanguage(language); 366 } 367 368 373 public void setSrc(File file) { 374 helper.setSrc(file); 375 } 376 377 382 public void addText(String text) { 383 helper.addText(text); 384 } 385 } 386 387 | Popular Tags |