1 46 package groovy.util; 47 48 49 import java.lang.reflect.Constructor ; 50 import java.lang.reflect.InvocationTargetException ; 51 import java.lang.reflect.Method ; 52 import java.util.Collections ; 53 import java.util.Iterator ; 54 import java.util.Map ; 55 import java.util.logging.Level ; 56 import java.util.logging.Logger ; 57 58 import org.apache.tools.ant.*; 59 import org.apache.tools.ant.types.DataType; 60 import org.codehaus.groovy.ant.FileScanner; 61 import org.codehaus.groovy.runtime.InvokerHelper; 62 63 69 public class AntBuilder extends BuilderSupport { 70 71 private static final Class [] addTaskParamTypes = { String .class }; 72 73 private Logger log = Logger.getLogger(getClass().getName()); 74 private Project project; 75 76 public AntBuilder() { 77 this.project = createProject(); 78 } 79 80 public AntBuilder(Project project) { 81 this.project = project; 82 } 83 84 protected Project getProject() { 86 return project; 87 } 88 89 92 protected Project createProject() { 93 Project project = new Project(); 94 BuildLogger logger = new NoBannerLogger(); 95 96 logger.setMessageOutputLevel(org.apache.tools.ant.Project.MSG_INFO); 97 logger.setOutputPrintStream(System.out); 98 logger.setErrorPrintStream(System.err); 99 100 project.addBuildListener(logger); 101 102 project.init(); 103 project.getBaseDir(); 104 return project; 105 } 106 107 protected void setParent(Object parent, Object child) { 108 } 109 110 119 protected void nodeCompleted(Object parent, Object node) { 120 if (parent instanceof TaskContainer) { 121 log.finest("parent is TaskContainer: no perform on nodeCompleted"); 122 return; } 124 if (node instanceof Task) { 125 Task task = (Task) node; 126 task.perform(); 127 } 128 } 129 130 protected Object createNode(Object tagName) { 131 return createNode(tagName.toString(), Collections.EMPTY_MAP); 132 } 133 134 protected Object createNode(Object name, Object value) { 135 Object task = createNode(name); 136 setText(task, value.toString()); 137 return task; 138 } 139 140 protected Object createNode(Object name, Map attributes, Object value) { 141 Object task = createNode(name, attributes); 142 setText(task, value.toString()); 143 return task; 144 } 145 146 protected Object createNode(Object name, Map attributes) { 147 148 if (name.equals("fileScanner")) { 149 return new FileScanner(project); 150 } 151 152 String tagName = name.toString(); 153 Object answer = null; 154 155 Object parentObject = getCurrent(); 156 Object parentTask = getParentTask(); 157 158 165 Object nested = null; 166 if (parentObject != null && !(parentTask instanceof TaskContainer)) { 167 nested = createNestedObject(parentObject, tagName); 168 } 169 170 Task task = null; 171 if (nested == null) { 172 task = createTask(tagName); 173 if (task != null) { 174 if (log.isLoggable(Level.FINE)) { 175 log.fine("Creating an ant Task for name: " + tagName); 176 } 177 178 182 if (task instanceof TaskAdapter) { 184 answer = ((TaskAdapter) task).getProxy(); 185 } 186 else { 187 answer = task; 188 } 189 190 Object id = attributes.remove("id"); 192 if (id != null) { 193 project.addReference((String ) id, task); 194 } 195 196 task.init(); 198 199 setBeanProperties(task, attributes); 201 202 if (parentObject instanceof TaskContainer){ 204 ((TaskContainer)parentObject).addTask(task); 205 } 206 } 207 } 208 209 if (task == null) { 210 if (nested == null) { 211 if (log.isLoggable(Level.FINE)) { 212 log.fine("Trying to create a data type for tag: " + tagName); 213 } 214 nested = createDataType(tagName); 215 } 216 else { 217 if (log.isLoggable(Level.FINE)) { 218 log.fine("Created nested property tag: " + tagName); 219 } 220 } 221 222 if (nested != null) { 223 answer = nested; 224 225 Object id = attributes.remove("id"); 227 if (id != null) { 228 project.addReference((String ) id, nested); 229 } 230 231 try { 232 InvokerHelper.setProperty(nested, "name", tagName); 233 } 234 catch (Exception e) { 235 } 236 237 setBeanProperties(nested, attributes); 239 240 if (parentObject != null) { 242 IntrospectionHelper ih = IntrospectionHelper.getHelper(parentObject.getClass()); 243 try { 244 if (log.isLoggable(Level.FINE)) { 245 log.fine( 246 "About to set the: " 247 + tagName 248 + " property on: " 249 + parentObject 250 + " to value: " 251 + nested 252 + " with type: " 253 + nested.getClass()); 254 } 255 256 ih.storeElement(project, parentObject, nested, tagName); 257 } 258 catch (Exception e) { 259 log.log(Level.WARNING, "Caught exception setting nested: " + tagName, e); 260 } 261 262 try { 266 InvokerHelper.setProperty(parentObject, tagName, nested); 267 } 268 catch (Exception e) { 269 log.fine("Caught exception trying to set property: " + tagName + " on: " + parentObject); 270 } 271 } 272 } 273 else { 274 log.log(Level.WARNING, "Could not convert tag: " + tagName + " into an Ant task, data type or property. Maybe the task is not on the classpath?"); 275 } 276 } 277 278 return answer; 279 } 280 281 protected void setText(Object task, String text) { 282 Method method = getAccessibleMethod(task.getClass(), "addText", addTaskParamTypes); 284 if (method != null) { 285 Object [] args = { text }; 286 try { 287 method.invoke(task, args); 288 } 289 catch (Exception e) { 290 log.log(Level.WARNING, "Cannot call addText on: " + task + ". Reason: " + e, e); 291 } 292 } 293 } 294 295 protected Method getAccessibleMethod(Class theClass, String name, Class [] paramTypes) { 296 while (true) { 297 try { 298 Method answer = theClass.getDeclaredMethod(name, paramTypes); 299 if (answer != null) { 300 return answer; 301 } 302 } 303 catch (Exception e) { 304 } 306 theClass = theClass.getSuperclass(); 307 if (theClass == null) { 308 return null; 309 } 310 } 311 } 312 313 public Project getAntProject() { 314 return project; 315 } 316 317 protected void setBeanProperties(Object object, Map map) { 320 for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { 321 Map.Entry entry = (Map.Entry ) iter.next(); 322 String name = (String ) entry.getKey(); 323 Object value = entry.getValue(); 324 setBeanProperty(object, name, ((value == null) ? null : value.toString())); 325 } 326 } 327 328 protected void setBeanProperty(Object object, String name, Object value) { 329 if (log.isLoggable(Level.FINE)) { 330 log.fine("Setting bean property on: " + object + " name: " + name + " value: " + value); 331 } 332 333 IntrospectionHelper ih = IntrospectionHelper.getHelper(object.getClass()); 334 335 if (value instanceof String ) { 336 try { 337 ih.setAttribute(getAntProject(), object, name.toLowerCase(), (String ) value); 338 return; 339 } 340 catch (Exception e) { 341 } 343 } 344 345 try { 346 347 ih.storeElement(getAntProject(), object, value, name); 348 } 349 catch (Exception e) { 350 351 InvokerHelper.setProperty(object, name, value); 352 } 353 } 354 355 358 protected Object createNestedObject(Object object, String name) { 359 Object dataType = null; 360 if (object != null) { 361 IntrospectionHelper ih = IntrospectionHelper.getHelper(object.getClass()); 362 363 if (ih != null) { 364 try { 365 String namespaceUri = ""; UnknownElement unknownElement = null; dataType = ih.getElementCreator(getAntProject(), namespaceUri, object, name.toLowerCase(), unknownElement).create(); 370 } 371 catch (BuildException be) { 372 log.log(Level.SEVERE, "Caught: " + be, be); 373 } 374 } 375 } 376 if (dataType == null) { 377 dataType = createDataType(name); 378 } 379 return dataType; 380 } 381 382 protected Object createDataType(String name) { 383 Object dataType = null; 384 385 Class type = (Class ) getAntProject().getDataTypeDefinitions().get(name); 386 387 if (type != null) { 388 389 Constructor ctor = null; 390 boolean noArg = false; 391 392 try { 395 ctor = type.getConstructor(new Class [0]); 396 noArg = true; 397 } 398 catch (NoSuchMethodException nse) { 399 try { 400 ctor = type.getConstructor(new Class [] { Project.class }); 401 noArg = false; 402 } 403 catch (NoSuchMethodException nsme) { 404 log.log(Level.INFO, "datatype '" + name + "' didn't have a constructor with an Ant Project", nsme); 405 } 406 } 407 408 if (noArg) { 409 dataType = createDataType(ctor, new Object [0], name, "no-arg constructor"); 410 } 411 else { 412 dataType = createDataType(ctor, new Object [] { getAntProject()}, name, "an Ant project"); 413 } 414 if (dataType != null) { 415 ((DataType) dataType).setProject(getAntProject()); 416 } 417 } 418 419 return dataType; 420 } 421 422 429 protected Object createDataType(Constructor ctor, Object [] args, String name, String argDescription) { 430 try { 431 Object datatype = ctor.newInstance(args); 432 return datatype; 433 } 434 catch (InstantiationException ie) { 435 log.log(Level.SEVERE, "datatype '" + name + "' couldn't be created with " + argDescription, ie); 436 } 437 catch (IllegalAccessException iae) { 438 log.log(Level.SEVERE, "datatype '" + name + "' couldn't be created with " + argDescription, iae); 439 } 440 catch (InvocationTargetException ite) { 441 log.log(Level.SEVERE, "datatype '" + name + "' couldn't be created with " + argDescription, ite); 442 } 443 return null; 444 } 445 446 450 protected Task createTask(String taskName) { 451 return createTask(taskName, (Class ) getAntProject().getTaskDefinitions().get(taskName)); 452 } 453 454 protected Task createTask(String taskName, Class taskType) { 455 if (taskType == null) { 456 return null; 457 } 458 try { 459 Object o = taskType.newInstance(); 460 Task task = null; 461 if (o instanceof Task) { 462 task = (Task) o; 463 } 464 else { 465 TaskAdapter taskA = new TaskAdapter(); 466 taskA.setProxy(o); 467 task = taskA; 468 } 469 470 task.setProject(getAntProject()); 471 task.setTaskName(taskName); 472 473 return task; 474 } 475 catch (Exception e) { 476 log.log(Level.WARNING, "Could not create task: " + taskName + ". Reason: " + e, e); 477 return null; 478 } 479 } 480 481 protected Task getParentTask() { 482 Object current = getCurrent(); 483 if (current instanceof Task) { 484 return (Task) current; 485 } 486 return null; 487 } 488 } 489 | Popular Tags |