1 18 19 package org.apache.tools.ant; 20 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.io.EOFException ; 24 import java.io.InputStream ; 25 import java.lang.reflect.Method ; 26 import java.lang.reflect.Modifier ; 27 import java.util.Collections ; 28 import java.util.Enumeration ; 29 import java.util.Hashtable ; 30 import java.util.Iterator ; 31 import java.util.Properties ; 32 import java.util.Stack ; 33 import java.util.Vector ; 34 import java.util.Set ; 35 import java.util.HashSet ; 36 import java.util.HashMap ; 37 import java.util.Map ; 38 import java.util.WeakHashMap ; 39 import org.apache.tools.ant.input.DefaultInputHandler; 40 import org.apache.tools.ant.input.InputHandler; 41 import org.apache.tools.ant.helper.DefaultExecutor; 42 import org.apache.tools.ant.types.FilterSet; 43 import org.apache.tools.ant.types.FilterSetCollection; 44 import org.apache.tools.ant.types.Description; 45 import org.apache.tools.ant.types.Path; 46 import org.apache.tools.ant.types.Resource; 47 import org.apache.tools.ant.types.ResourceFactory; 48 import org.apache.tools.ant.types.resources.FileResource; 49 import org.apache.tools.ant.util.FileUtils; 50 import org.apache.tools.ant.util.JavaEnvUtils; 51 import org.apache.tools.ant.util.StringUtils; 52 53 64 public class Project implements ResourceFactory { 65 private static final String LINE_SEP = System.getProperty("line.separator"); 66 67 68 public static final int MSG_ERR = 0; 69 70 public static final int MSG_WARN = 1; 71 72 public static final int MSG_INFO = 2; 73 74 public static final int MSG_VERBOSE = 3; 75 76 public static final int MSG_DEBUG = 4; 77 78 82 private static final String VISITING = "VISITING"; 83 87 private static final String VISITED = "VISITED"; 88 89 95 public static final String JAVA_1_0 = JavaEnvUtils.JAVA_1_0; 96 102 public static final String JAVA_1_1 = JavaEnvUtils.JAVA_1_1; 103 109 public static final String JAVA_1_2 = JavaEnvUtils.JAVA_1_2; 110 116 public static final String JAVA_1_3 = JavaEnvUtils.JAVA_1_3; 117 123 public static final String JAVA_1_4 = JavaEnvUtils.JAVA_1_4; 124 125 126 public static final String TOKEN_START = FilterSet.DEFAULT_TOKEN_START; 127 128 public static final String TOKEN_END = FilterSet.DEFAULT_TOKEN_END; 129 130 131 private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); 132 133 134 private String name; 135 136 private String description; 137 138 139 140 private Hashtable references = new AntRefTable(); 141 142 143 private HashMap idReferences = new HashMap (); 144 145 146 private Project parentIdProject = null; 147 148 149 private String defaultTarget; 150 151 152 private Hashtable targets = new Hashtable (); 153 154 private FilterSet globalFilterSet = new FilterSet(); 155 { 156 globalFilterSet.setProject(this); 158 } 159 160 165 private FilterSetCollection globalFilters 166 = new FilterSetCollection(globalFilterSet); 167 168 169 private File baseDir; 170 171 172 private Vector listeners = new Vector (); 173 174 178 private ClassLoader coreLoader = null; 179 180 181 private Map threadTasks = Collections.synchronizedMap(new WeakHashMap ()); 182 183 184 private Map threadGroupTasks 185 = Collections.synchronizedMap(new WeakHashMap ()); 186 187 190 private InputHandler inputHandler = null; 191 192 195 private InputStream defaultInputStream = null; 196 197 200 private boolean keepGoingMode = false; 201 202 205 private boolean loggingMessage = false; 206 207 212 public void setInputHandler(InputHandler handler) { 213 inputHandler = handler; 214 } 215 216 225 public void setDefaultInputStream(InputStream defaultInputStream) { 226 this.defaultInputStream = defaultInputStream; 227 } 228 229 235 public InputStream getDefaultInputStream() { 236 return defaultInputStream; 237 } 238 239 245 public InputHandler getInputHandler() { 246 return inputHandler; 247 } 248 249 252 public Project() { 253 inputHandler = new DefaultInputHandler(); 254 } 255 256 263 public Project createSubProject() { 264 Project subProject = null; 265 try { 266 subProject = (Project) (getClass().newInstance()); 267 } catch (Exception e) { 268 subProject = new Project(); 269 } 270 initSubProject(subProject); 271 return subProject; 272 } 273 274 278 public void initSubProject(Project subProject) { 279 ComponentHelper.getComponentHelper(subProject) 280 .initSubProject(ComponentHelper.getComponentHelper(this)); 281 subProject.setDefaultInputStream(getDefaultInputStream()); 282 subProject.setKeepGoingMode(this.isKeepGoingMode()); 283 subProject.setExecutor(getExecutor().getSubProjectExecutor()); 284 } 285 286 294 public void init() throws BuildException { 295 initProperties(); 296 297 ComponentHelper.getComponentHelper(this).initDefaultDefinitions(); 298 } 299 300 305 public void initProperties() throws BuildException { 306 setJavaVersionProperty(); 307 setSystemProperties(); 308 setPropertyInternal(MagicNames.ANT_VERSION, Main.getAntVersion()); 309 setAntLib(); 310 } 311 312 private void setAntLib() { 313 File antlib = org.apache.tools.ant.launch.Locator.getClassSource( 314 Project.class); 315 if (antlib != null) { 316 setPropertyInternal(MagicNames.ANT_LIB, antlib.getAbsolutePath()); 317 } 318 } 319 327 public AntClassLoader createClassLoader(Path path) { 328 return new AntClassLoader( 329 getClass().getClassLoader(), this, path); 330 } 331 332 341 public AntClassLoader createClassLoader( 342 ClassLoader parent, Path path) { 343 return new AntClassLoader(parent, this, path); 344 } 345 346 353 public void setCoreLoader(ClassLoader coreLoader) { 354 this.coreLoader = coreLoader; 355 } 356 357 365 public ClassLoader getCoreLoader() { 366 return coreLoader; 367 } 368 369 376 public synchronized void addBuildListener(BuildListener listener) { 377 if (listeners.contains(listener)) { 379 return; 380 } 381 Vector newListeners = getBuildListeners(); 384 newListeners.addElement(listener); 385 listeners = newListeners; 386 } 387 388 395 public synchronized void removeBuildListener(BuildListener listener) { 396 Vector newListeners = getBuildListeners(); 399 newListeners.removeElement(listener); 400 listeners = newListeners; 401 } 402 403 408 public Vector getBuildListeners() { 409 return (Vector ) listeners.clone(); 410 } 411 412 417 418 public void log(String message) { 419 log(message, MSG_INFO); 420 } 421 422 427 public void log(String message, int msgLevel) { 428 log(message, null, msgLevel); 429 } 430 431 438 public void log(String message, Throwable throwable, int msgLevel) { 439 fireMessageLogged(this, message, throwable, msgLevel); 440 } 441 442 448 public void log(Task task, String message, int msgLevel) { 449 fireMessageLogged(task, message, null, msgLevel); 450 } 451 452 460 public void log(Task task, String message, Throwable throwable, int msgLevel) { 461 fireMessageLogged(task, message, throwable, msgLevel); 462 } 463 464 471 public void log(Target target, String message, int msgLevel) { 472 log(target, message, null, msgLevel); 473 } 474 475 484 public void log(Target target, String message, Throwable throwable, 485 int msgLevel) { 486 fireMessageLogged(target, message, throwable, msgLevel); 487 } 488 489 494 public FilterSet getGlobalFilterSet() { 495 return globalFilterSet; 496 } 497 498 506 public void setProperty(String name, String value) { 507 PropertyHelper.getPropertyHelper(this). 508 setProperty(null, name, value, true); 509 } 510 511 522 public void setNewProperty(String name, String value) { 523 PropertyHelper.getPropertyHelper(this).setNewProperty(null, name, 524 value); 525 } 526 527 536 public void setUserProperty(String name, String value) { 537 PropertyHelper.getPropertyHelper(this).setUserProperty(null, name, 538 value); 539 } 540 541 553 public void setInheritedProperty(String name, String value) { 554 PropertyHelper ph = PropertyHelper.getPropertyHelper(this); 555 ph.setInheritedProperty(null, name, value); 556 } 557 558 566 private void setPropertyInternal(String name, String value) { 567 PropertyHelper ph = PropertyHelper.getPropertyHelper(this); 568 ph.setProperty(null, name, value, false); 569 } 570 571 580 public String getProperty(String propertyName) { 581 PropertyHelper ph = PropertyHelper.getPropertyHelper(this); 582 return (String ) ph.getProperty(null, propertyName); 583 } 584 585 599 public String replaceProperties(String value) 600 throws BuildException { 601 PropertyHelper ph = PropertyHelper.getPropertyHelper(this); 602 return ph.replaceProperties(null, value, null); 603 } 604 605 614 public String getUserProperty(String propertyName) { 615 PropertyHelper ph = PropertyHelper.getPropertyHelper(this); 616 return (String ) ph.getUserProperty(null, propertyName); 617 } 618 619 624 public Hashtable getProperties() { 625 PropertyHelper ph = PropertyHelper.getPropertyHelper(this); 626 return ph.getProperties(); 627 } 628 629 633 public Hashtable getUserProperties() { 634 PropertyHelper ph = PropertyHelper.getPropertyHelper(this); 635 return ph.getUserProperties(); 636 } 637 638 650 public void copyUserProperties(Project other) { 651 PropertyHelper ph = PropertyHelper.getPropertyHelper(this); 652 ph.copyUserProperties(other); 653 } 654 655 667 public void copyInheritedProperties(Project other) { 668 PropertyHelper ph = PropertyHelper.getPropertyHelper(this); 669 ph.copyInheritedProperties(other); 670 } 671 672 683 public void setDefaultTarget(String defaultTarget) { 684 this.defaultTarget = defaultTarget; 685 } 686 687 692 public String getDefaultTarget() { 693 return defaultTarget; 694 } 695 696 703 public void setDefault(String defaultTarget) { 704 this.defaultTarget = defaultTarget; 705 } 706 707 714 public void setName(String name) { 715 setUserProperty("ant.project.name", name); 716 this.name = name; 717 } 718 719 724 public String getName() { 725 return name; 726 } 727 728 734 public void setDescription(String description) { 735 this.description = description; 736 } 737 738 744 public String getDescription() { 745 if (description == null) { 746 description = Description.getDescription(this); 747 } 748 return description; 749 } 750 751 764 public void addFilter(String token, String value) { 765 if (token == null) { 766 return; 767 } 768 globalFilterSet.addFilter(new FilterSet.Filter(token, value)); 769 } 770 771 783 public Hashtable getFilters() { 784 return globalFilterSet.getFilterHash(); 786 } 787 788 797 public void setBasedir(String baseD) throws BuildException { 798 setBaseDir(new File (baseD)); 799 } 800 801 810 public void setBaseDir(File baseDir) throws BuildException { 811 baseDir = FILE_UTILS.normalize(baseDir.getAbsolutePath()); 812 if (!baseDir.exists()) { 813 throw new BuildException("Basedir " + baseDir.getAbsolutePath() 814 + " does not exist"); 815 } 816 if (!baseDir.isDirectory()) { 817 throw new BuildException("Basedir " + baseDir.getAbsolutePath() 818 + " is not a directory"); 819 } 820 this.baseDir = baseDir; 821 setPropertyInternal(MagicNames.PROJECT_BASEDIR, this.baseDir.getPath()); 822 String msg = "Project base dir set to: " + this.baseDir; 823 log(msg, MSG_VERBOSE); 824 } 825 826 832 public File getBaseDir() { 833 if (baseDir == null) { 834 try { 835 setBasedir("."); 836 } catch (BuildException ex) { 837 ex.printStackTrace(); 838 } 839 } 840 return baseDir; 841 } 842 843 852 public void setKeepGoingMode(boolean keepGoingMode) { 853 this.keepGoingMode = keepGoingMode; 854 } 855 856 863 public boolean isKeepGoingMode() { 864 return this.keepGoingMode; 865 } 866 867 874 public static String getJavaVersion() { 875 return JavaEnvUtils.getJavaVersion(); 876 } 877 878 888 public void setJavaVersionProperty() throws BuildException { 889 String javaVersion = JavaEnvUtils.getJavaVersion(); 890 setPropertyInternal(MagicNames.ANT_JAVA_VERSION, javaVersion); 891 892 if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_0) 894 || JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) { 895 throw new BuildException("Ant cannot work on Java 1.0 / 1.1"); 896 } 897 log("Detected Java version: " + javaVersion + " in: " 898 + System.getProperty("java.home"), MSG_VERBOSE); 899 900 log("Detected OS: " + System.getProperty("os.name"), MSG_VERBOSE); 901 } 902 903 907 public void setSystemProperties() { 908 Properties systemP = System.getProperties(); 909 Enumeration e = systemP.propertyNames(); 910 while (e.hasMoreElements()) { 911 String propertyName = (String ) e.nextElement(); 912 String value = systemP.getProperty(propertyName); 913 this.setPropertyInternal(propertyName, value); 914 } 915 } 916 917 937 public void addTaskDefinition(String taskName, Class taskClass) 938 throws BuildException { 939 ComponentHelper.getComponentHelper(this).addTaskDefinition(taskName, 940 taskClass); 941 } 942 943 955 public void checkTaskClass(final Class taskClass) throws BuildException { 956 ComponentHelper.getComponentHelper(this).checkTaskClass(taskClass); 957 958 if (!Modifier.isPublic(taskClass.getModifiers())) { 959 final String message = taskClass + " is not public"; 960 log(message, Project.MSG_ERR); 961 throw new BuildException(message); 962 } 963 if (Modifier.isAbstract(taskClass.getModifiers())) { 964 final String message = taskClass + " is abstract"; 965 log(message, Project.MSG_ERR); 966 throw new BuildException(message); 967 } 968 try { 969 taskClass.getConstructor((Class []) null); 970 } catch (NoSuchMethodException e) { 973 final String message = "No public no-arg constructor in " 974 + taskClass; 975 log(message, Project.MSG_ERR); 976 throw new BuildException(message); 977 } catch (LinkageError e) { 978 String message = "Could not load " + taskClass + ": " + e; 979 log(message, Project.MSG_ERR); 980 throw new BuildException(message, e); 981 } 982 if (!Task.class.isAssignableFrom(taskClass)) { 983 TaskAdapter.checkTaskClass(taskClass, this); 984 } 985 } 986 987 994 public Hashtable getTaskDefinitions() { 995 return ComponentHelper.getComponentHelper(this).getTaskDefinitions(); 996 } 997 998 1011 public void addDataTypeDefinition(String typeName, Class typeClass) { 1012 ComponentHelper.getComponentHelper(this).addDataTypeDefinition(typeName, 1013 typeClass); 1014 } 1015 1016 1023 public Hashtable getDataTypeDefinitions() { 1024 return ComponentHelper.getComponentHelper(this).getDataTypeDefinitions(); 1025 } 1026 1027 1037 public void addTarget(Target target) throws BuildException { 1038 addTarget(target.getName(), target); 1039 } 1040 1041 1053 public void addTarget(String targetName, Target target) 1054 throws BuildException { 1055 if (targets.get(targetName) != null) { 1056 throw new BuildException("Duplicate target: `" + targetName + "'"); 1057 } 1058 addOrReplaceTarget(targetName, target); 1059 } 1060 1061 1068 public void addOrReplaceTarget(Target target) { 1069 addOrReplaceTarget(target.getName(), target); 1070 } 1071 1072 1081 public void addOrReplaceTarget(String targetName, Target target) { 1082 String msg = " +Target: " + targetName; 1083 log(msg, MSG_DEBUG); 1084 target.setProject(this); 1085 targets.put(targetName, target); 1086 } 1087 1088 1093 public Hashtable getTargets() { 1094 return targets; 1095 } 1096 1097 1110 public Task createTask(String taskType) throws BuildException { 1111 return ComponentHelper.getComponentHelper(this).createTask(taskType); 1112 } 1113 1114 1126 public Object createDataType(String typeName) throws BuildException { 1127 return ComponentHelper.getComponentHelper(this).createDataType(typeName); 1128 } 1129 1130 1134 public void setExecutor(Executor e) { 1135 addReference(MagicNames.ANT_EXECUTOR_REFERENCE, e); 1136 } 1137 1138 1142 public Executor getExecutor() { 1143 Object o = getReference(MagicNames.ANT_EXECUTOR_REFERENCE); 1144 if (o == null) { 1145 String classname = getProperty(MagicNames.ANT_EXECUTOR_CLASSNAME); 1146 if (classname == null) { 1147 classname = DefaultExecutor.class.getName(); 1148 } 1149 log("Attempting to create object of type " + classname, MSG_DEBUG); 1150 try { 1151 o = Class.forName(classname, true, coreLoader).newInstance(); 1152 } catch (ClassNotFoundException seaEnEfEx) { 1153 try { 1155 o = Class.forName(classname).newInstance(); 1156 } catch (Exception ex) { 1157 log(ex.toString(), MSG_ERR); 1158 } 1159 } catch (Exception ex) { 1160 log(ex.toString(), MSG_ERR); 1161 } 1162 if (o == null) { 1163 throw new BuildException( 1164 "Unable to obtain a Target Executor instance."); 1165 } 1166 setExecutor((Executor) o); 1167 } 1168 return (Executor) o; 1169 } 1170 1171 1180 public void executeTargets(Vector names) throws BuildException { 1181 getExecutor().executeTargets(this, 1182 (String []) (names.toArray(new String [names.size()]))); 1183 } 1184 1185 1194 public void demuxOutput(String output, boolean isWarning) { 1195 Task task = getThreadTask(Thread.currentThread()); 1196 if (task == null) { 1197 log(output, isWarning ? MSG_WARN : MSG_INFO); 1198 } else { 1199 if (isWarning) { 1200 task.handleErrorOutput(output); 1201 } else { 1202 task.handleOutput(output); 1203 } 1204 } 1205 } 1206 1207 1220 public int defaultInput(byte[] buffer, int offset, int length) 1221 throws IOException { 1222 if (defaultInputStream != null) { 1223 System.out.flush(); 1224 return defaultInputStream.read(buffer, offset, length); 1225 } else { 1226 throw new EOFException ("No input provided for project"); 1227 } 1228 } 1229 1230 1242 public int demuxInput(byte[] buffer, int offset, int length) 1243 throws IOException { 1244 Task task = getThreadTask(Thread.currentThread()); 1245 if (task == null) { 1246 return defaultInput(buffer, offset, length); 1247 } else { 1248 return task.handleInput(buffer, offset, length); 1249 } 1250 } 1251 1252 1263 public void demuxFlush(String output, boolean isError) { 1264 Task task = getThreadTask(Thread.currentThread()); 1265 if (task == null) { 1266 fireMessageLogged(this, output, isError ? MSG_ERR : MSG_INFO); 1267 } else { 1268 if (isError) { 1269 task.handleErrorFlush(output); 1270 } else { 1271 task.handleFlush(output); 1272 } 1273 } 1274 } 1275 1276 1284 public void executeTarget(String targetName) throws BuildException { 1285 1286 1289 if (targetName == null) { 1290 String msg = "No target specified"; 1291 throw new BuildException(msg); 1292 } 1293 1294 executeSortedTargets(topoSort(targetName, targets, false)); 1299 } 1300 1301 1306 public void executeSortedTargets(Vector sortedTargets) 1307 throws BuildException { 1308 Set succeededTargets = new HashSet (); 1309 BuildException buildException = null; for (Enumeration iter = sortedTargets.elements(); 1311 iter.hasMoreElements();) { 1312 Target curtarget = (Target) iter.nextElement(); 1313 boolean canExecute = true; 1314 for (Enumeration depIter = curtarget.getDependencies(); 1315 depIter.hasMoreElements();) { 1316 String dependencyName = ((String ) depIter.nextElement()); 1317 if (!succeededTargets.contains(dependencyName)) { 1318 canExecute = false; 1319 log(curtarget, 1320 "Cannot execute '" + curtarget.getName() + "' - '" 1321 + dependencyName + "' failed or was not executed.", 1322 MSG_ERR); 1323 break; 1324 } 1325 } 1326 if (canExecute) { 1327 Throwable thrownException = null; 1328 try { 1329 curtarget.performTasks(); 1330 succeededTargets.add(curtarget.getName()); 1331 } catch (RuntimeException ex) { 1332 if (!(keepGoingMode)) { 1333 throw ex; } 1335 thrownException = ex; 1336 } catch (Throwable ex) { 1337 if (!(keepGoingMode)) { 1338 throw new BuildException(ex); 1339 } 1340 thrownException = ex; 1341 } 1342 if (thrownException != null) { 1343 if (thrownException instanceof BuildException) { 1344 log(curtarget, 1345 "Target '" + curtarget.getName() 1346 + "' failed with message '" 1347 + thrownException.getMessage() + "'.", MSG_ERR); 1348 if (buildException == null) { 1350 buildException = (BuildException) thrownException; 1351 } 1352 } else { 1353 log(curtarget, 1354 "Target '" + curtarget.getName() 1355 + "' failed with message '" 1356 + thrownException.getMessage() + "'.", MSG_ERR); 1357 thrownException.printStackTrace(System.err); 1358 if (buildException == null) { 1359 buildException = 1360 new BuildException(thrownException); 1361 } 1362 } 1363 } 1364 } 1365 } 1366 if (buildException != null) { 1367 throw buildException; 1368 } 1369 } 1370 1371 1388 public File resolveFile(String fileName, File rootDir) { 1389 return FILE_UTILS.resolveFile(rootDir, fileName); 1390 } 1391 1392 1404 public File resolveFile(String fileName) { 1405 return FILE_UTILS.resolveFile(baseDir, fileName); 1406 } 1407 1408 1427 public static String translatePath(String toProcess) { 1428 return FileUtils.translatePath(toProcess); 1429 } 1430 1431 1444 public void copyFile(String sourceFile, String destFile) 1445 throws IOException { 1446 FILE_UTILS.copyFile(sourceFile, destFile); 1447 } 1448 1449 1464 public void copyFile(String sourceFile, String destFile, boolean filtering) 1465 throws IOException { 1466 FILE_UTILS.copyFile(sourceFile, destFile, 1467 filtering ? globalFilters : null); 1468 } 1469 1470 1488 public void copyFile(String sourceFile, String destFile, boolean filtering, 1489 boolean overwrite) throws IOException { 1490 FILE_UTILS.copyFile(sourceFile, destFile, 1491 filtering ? globalFilters : null, overwrite); 1492 } 1493 1494 1517 public void copyFile(String sourceFile, String destFile, boolean filtering, 1518 boolean overwrite, boolean preserveLastModified) 1519 throws IOException { 1520 FILE_UTILS.copyFile(sourceFile, destFile, 1521 filtering ? globalFilters : null, overwrite, preserveLastModified); 1522 } 1523 1524 1537 public void copyFile(File sourceFile, File destFile) throws IOException { 1538 FILE_UTILS.copyFile(sourceFile, destFile); 1539 } 1540 1541 1556 public void copyFile(File sourceFile, File destFile, boolean filtering) 1557 throws IOException { 1558 FILE_UTILS.copyFile(sourceFile, destFile, 1559 filtering ? globalFilters : null); 1560 } 1561 1562 1580 public void copyFile(File sourceFile, File destFile, boolean filtering, 1581 boolean overwrite) throws IOException { 1582 FILE_UTILS.copyFile(sourceFile, destFile, 1583 filtering ? globalFilters : null, overwrite); 1584 } 1585 1586 1609 public void copyFile(File sourceFile, File destFile, boolean filtering, 1610 boolean overwrite, boolean preserveLastModified) 1611 throws IOException { 1612 FILE_UTILS.copyFile(sourceFile, destFile, 1613 filtering ? globalFilters : null, overwrite, preserveLastModified); 1614 } 1615 1616 1631 public void setFileLastModified(File file, long time) 1632 throws BuildException { 1633 FILE_UTILS.setFileLastModified(file, time); 1634 log("Setting modification time for " + file, MSG_VERBOSE); 1635 } 1636 1637 1648 public static boolean toBoolean(String s) { 1649 return ("on".equalsIgnoreCase(s) 1650 || "true".equalsIgnoreCase(s) 1651 || "yes".equalsIgnoreCase(s)); 1652 } 1653 1654 1668 public final Vector topoSort(String root, Hashtable targetTable) 1669 throws BuildException { 1670 return topoSort(new String [] {root}, targetTable, true); 1671 } 1672 1673 1690 public final Vector topoSort(String root, Hashtable targetTable, 1691 boolean returnAll) throws BuildException { 1692 return topoSort(new String [] {root}, targetTable, returnAll); 1693 } 1694 1695 1712 public final Vector topoSort(String [] root, Hashtable targetTable, 1713 boolean returnAll) throws BuildException { 1714 Vector ret = new Vector (); 1715 Hashtable state = new Hashtable (); 1716 Stack visiting = new Stack (); 1717 1718 1726 for (int i = 0; i < root.length; i++) { 1727 String st = (String ) (state.get(root[i])); 1728 if (st == null) { 1729 tsort(root[i], targetTable, state, visiting, ret); 1730 } else if (st == VISITING) { 1731 throw new RuntimeException ("Unexpected node in visiting state: " 1732 + root[i]); 1733 } 1734 } 1735 StringBuffer buf = new StringBuffer ("Build sequence for target(s)"); 1736 1737 for (int j = 0; j < root.length; j++) { 1738 buf.append((j == 0) ? " `" : ", `").append(root[j]).append('\''); 1739 } 1740 buf.append(" is " + ret); 1741 log(buf.toString(), MSG_VERBOSE); 1742 1743 Vector complete = (returnAll) ? ret : new Vector (ret); 1744 for (Enumeration en = targetTable.keys(); en.hasMoreElements();) { 1745 String curTarget = (String ) en.nextElement(); 1746 String st = (String ) state.get(curTarget); 1747 if (st == null) { 1748 tsort(curTarget, targetTable, state, visiting, complete); 1749 } else if (st == VISITING) { 1750 throw new RuntimeException ("Unexpected node in visiting state: " 1751 + curTarget); 1752 } 1753 } 1754 log("Complete build sequence is " + complete, MSG_VERBOSE); 1755 return ret; 1756 } 1757 1758 1798 private void tsort(String root, Hashtable targetTable, 1799 Hashtable state, Stack visiting, 1800 Vector ret) 1801 throws BuildException { 1802 state.put(root, VISITING); 1803 visiting.push(root); 1804 1805 Target target = (Target) targetTable.get(root); 1806 1807 if (target == null) { 1809 StringBuffer sb = new StringBuffer ("Target \""); 1810 sb.append(root); 1811 sb.append("\" does not exist in the project \""); 1812 sb.append(name); 1813 sb.append("\". "); 1814 visiting.pop(); 1815 if (!visiting.empty()) { 1816 String parent = (String ) visiting.peek(); 1817 sb.append("It is used from target \""); 1818 sb.append(parent); 1819 sb.append("\"."); 1820 } 1821 throw new BuildException(new String (sb)); 1822 } 1823 for (Enumeration en = target.getDependencies(); en.hasMoreElements();) { 1824 String cur = (String ) en.nextElement(); 1825 String m = (String ) state.get(cur); 1826 if (m == null) { 1827 tsort(cur, targetTable, state, visiting, ret); 1829 } else if (m == VISITING) { 1830 throw makeCircularException(cur, visiting); 1832 } 1833 } 1834 String p = (String ) visiting.pop(); 1835 if (root != p) { 1836 throw new RuntimeException ("Unexpected internal error: expected to " 1837 + "pop " + root + " but got " + p); 1838 } 1839 state.put(root, VISITED); 1840 ret.addElement(target); 1841 } 1842 1843 1852 private static BuildException makeCircularException(String end, Stack stk) { 1853 StringBuffer sb = new StringBuffer ("Circular dependency: "); 1854 sb.append(end); 1855 String c; 1856 do { 1857 c = (String ) stk.pop(); 1858 sb.append(" <- "); 1859 sb.append(c); 1860 } while (!c.equals(end)); 1861 return new BuildException(new String (sb)); 1862 } 1863 1864 1868 public void inheritIDReferences(Project parent) { 1869 parentIdProject = parent; 1870 } 1871 1872 1876 private Object resolveIdReference(String key, Project callerProject) { 1877 UnknownElement origUE = (UnknownElement) idReferences.get(key); 1878 if (origUE == null) { 1879 return parentIdProject == null 1880 ? null 1881 : parentIdProject.resolveIdReference(key, callerProject); 1882 } 1883 callerProject.log( 1884 "Warning: Reference " + key + " has not been set at runtime," 1885 + " but was found during" + LINE_SEP 1886 + "build file parsing, attempting to resolve." 1887 + " Future versions of Ant may support" + LINE_SEP 1888 + " referencing ids defined in non-executed targets.", MSG_WARN); 1889 UnknownElement copyUE = origUE.copy(callerProject); 1890 copyUE.maybeConfigure(); 1891 return copyUE.getRealThing(); 1892 } 1893 1894 1900 public void addIdReference(String id, Object value) { 1901 idReferences.put(id, value); 1902 } 1903 1904 1910 public void addReference(String referenceName, Object value) { 1911 synchronized (references) { 1912 Object old = ((AntRefTable) references).getReal(referenceName); 1913 if (old == value) { 1914 return; 1916 } 1917 if (old != null && !(old instanceof UnknownElement)) { 1918 log("Overriding previous definition of reference to " + referenceName, 1919 MSG_VERBOSE); 1920 } 1921 log("Adding reference: " + referenceName, MSG_DEBUG); 1922 references.put(referenceName, value); 1923 } 1924 } 1925 1926 1932 public Hashtable getReferences() { 1933 return references; 1934 } 1935 1936 1945 public Object getReference(String key) { 1946 Object ret = references.get(key); 1947 if (ret != null) { 1948 return ret; 1949 } 1950 ret = resolveIdReference(key, this); 1952 if (ret == null && !key.equals(MagicNames.REFID_PROPERTY_HELPER)) { 1953 Vector p = new Vector (); 1954 PropertyHelper.getPropertyHelper(this).parsePropertyString( 1955 key, new Vector (), p); 1956 if (p.size() == 1) { 1957 log("Unresolvable reference " + key 1958 + " might be a misuse of property expansion syntax.", 1959 MSG_WARN); 1960 } 1961 } 1962 return ret; 1963 } 1964 1965 1978 public String getElementName(Object element) { 1979 return ComponentHelper.getComponentHelper(this).getElementName(element); 1980 } 1981 1982 1986 public void fireBuildStarted() { 1987 BuildEvent event = new BuildEvent(this); 1988 Iterator iter = listeners.iterator(); 1989 while (iter.hasNext()) { 1990 BuildListener listener = (BuildListener) iter.next(); 1991 listener.buildStarted(event); 1992 } 1993 } 1994 1995 2002 public void fireBuildFinished(Throwable exception) { 2003 BuildEvent event = new BuildEvent(this); 2004 event.setException(exception); 2005 Iterator iter = listeners.iterator(); 2006 while (iter.hasNext()) { 2007 BuildListener listener = (BuildListener) iter.next(); 2008 listener.buildFinished(event); 2009 } 2010 IntrospectionHelper.clearCache(); 2012 } 2013 2014 2020 public void fireSubBuildStarted() { 2021 BuildEvent event = new BuildEvent(this); 2022 Iterator iter = listeners.iterator(); 2023 while (iter.hasNext()) { 2024 Object listener = iter.next(); 2025 if (listener instanceof SubBuildListener) { 2026 ((SubBuildListener) listener).subBuildStarted(event); 2027 } 2028 } 2029 } 2030 2031 2040 public void fireSubBuildFinished(Throwable exception) { 2041 BuildEvent event = new BuildEvent(this); 2042 event.setException(exception); 2043 Iterator iter = listeners.iterator(); 2044 while (iter.hasNext()) { 2045 Object listener = iter.next(); 2046 if (listener instanceof SubBuildListener) { 2047 ((SubBuildListener) listener).subBuildFinished(event); 2048 } 2049 } 2050 } 2051 2052 2059 protected void fireTargetStarted(Target target) { 2060 BuildEvent event = new BuildEvent(target); 2061 Iterator iter = listeners.iterator(); 2062 while (iter.hasNext()) { 2063 BuildListener listener = (BuildListener) iter.next(); 2064 listener.targetStarted(event); 2065 } 2066 } 2067 2068 2078 protected void fireTargetFinished(Target target, Throwable exception) { 2079 BuildEvent event = new BuildEvent(target); 2080 event.setException(exception); 2081 Iterator iter = listeners.iterator(); 2082 while (iter.hasNext()) { 2083 BuildListener listener = (BuildListener) iter.next(); 2084 listener.targetFinished(event); 2085 } 2086 } 2087 2088 2095 protected void fireTaskStarted(Task task) { 2096 registerThreadTask(Thread.currentThread(), task); 2098 BuildEvent event = new BuildEvent(task); 2099 Iterator iter = listeners.iterator(); 2100 while (iter.hasNext()) { 2101 BuildListener listener = (BuildListener) iter.next(); 2102 listener.taskStarted(event); 2103 } 2104 } 2105 2106 2116 protected void fireTaskFinished(Task task, Throwable exception) { 2117 registerThreadTask(Thread.currentThread(), null); 2118 System.out.flush(); 2119 System.err.flush(); 2120 BuildEvent event = new BuildEvent(task); 2121 event.setException(exception); 2122 Iterator iter = listeners.iterator(); 2123 while (iter.hasNext()) { 2124 BuildListener listener = (BuildListener) iter.next(); 2125 listener.taskFinished(event); 2126 } 2127 } 2128 2129 2140 private void fireMessageLoggedEvent(BuildEvent event, String message, 2141 int priority) { 2142 2143 if (message.endsWith(StringUtils.LINE_SEP)) { 2144 int endIndex = message.length() - StringUtils.LINE_SEP.length(); 2145 event.setMessage(message.substring(0, endIndex), priority); 2146 } else { 2147 event.setMessage(message, priority); 2148 } 2149 synchronized (this) { 2150 if (loggingMessage) { 2151 2164 return; 2165 } 2166 try { 2167 loggingMessage = true; 2168 Iterator iter = listeners.iterator(); 2169 while (iter.hasNext()) { 2170 BuildListener listener = (BuildListener) iter.next(); 2171 listener.messageLogged(event); 2172 } 2173 } finally { 2174 loggingMessage = false; 2175 } 2176 } 2177 } 2178 2179 2188 protected void fireMessageLogged(Project project, String message, 2189 int priority) { 2190 fireMessageLogged(project, message, null, priority); 2191 } 2192 2193 2204 protected void fireMessageLogged(Project project, String message, 2205 Throwable throwable, int priority) { 2206 BuildEvent event = new BuildEvent(project); 2207 event.setException(throwable); 2208 fireMessageLoggedEvent(event, message, priority); 2209 } 2210 2211 2220 protected void fireMessageLogged(Target target, String message, 2221 int priority) { 2222 fireMessageLogged(target, message, null, priority); 2223 } 2224 2225 2236 protected void fireMessageLogged(Target target, String message, 2237 Throwable throwable, int priority) { 2238 BuildEvent event = new BuildEvent(target); 2239 event.setException(throwable); 2240 fireMessageLoggedEvent(event, message, priority); 2241 } 2242 2243 2252 protected void fireMessageLogged(Task task, String message, int priority) { 2253 fireMessageLogged(task, message, null, priority); 2254 } 2255 2256 2267 protected void fireMessageLogged(Task task, String message, 2268 Throwable throwable, int priority) { 2269 BuildEvent event = new BuildEvent(task); 2270 event.setException(throwable); 2271 fireMessageLoggedEvent(event, message, priority); 2272 } 2273 2274 2282 public synchronized void registerThreadTask(Thread thread, Task task) { 2283 if (task != null) { 2284 threadTasks.put(thread, task); 2285 threadGroupTasks.put(thread.getThreadGroup(), task); 2286 } else { 2287 threadTasks.remove(thread); 2288 threadGroupTasks.remove(thread.getThreadGroup()); 2289 } 2290 } 2291 2292 2299 public Task getThreadTask(Thread thread) { 2300 Task task = (Task) threadTasks.get(thread); 2301 if (task == null) { 2302 ThreadGroup group = thread.getThreadGroup(); 2303 while (task == null && group != null) { 2304 task = (Task) threadGroupTasks.get(group); 2305 group = group.getParent(); 2306 } 2307 } 2308 return task; 2309 } 2310 2311 2312 private static class AntRefTable extends Hashtable { 2315 2316 AntRefTable() { 2317 super(); 2318 } 2319 2320 2327 private Object getReal(Object key) { 2328 return super.get(key); 2329 } 2330 2331 2342 public Object get(Object key) { 2343 Object o = getReal(key); 2345 if (o instanceof UnknownElement) { 2346 UnknownElement ue = (UnknownElement) o; 2348 ue.maybeConfigure(); 2349 o = ue.getRealThing(); 2350 } 2351 return o; 2352 } 2353 } 2354 2355 2361 public final void setProjectReference(final Object obj) { 2362 if (obj instanceof ProjectComponent) { 2363 ((ProjectComponent) obj).setProject(this); 2364 return; 2365 } 2366 try { 2367 Method method = 2368 obj.getClass().getMethod( 2369 "setProject", new Class [] {Project.class}); 2370 if (method != null) { 2371 method.invoke(obj, new Object [] {this}); 2372 } 2373 } catch (Throwable e) { 2374 } 2378 } 2379 2380 2387 public Resource getResource(String name) { 2388 return new FileResource(getBaseDir(), name); 2389 } 2390} 2391 | Popular Tags |