You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Result.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /* *******************************************************************
  2. * Copyright (c) 2005 Contributors.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * Wes Isberg initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.internal.tools.build;
  13. import java.io.File;
  14. import java.util.ArrayList;
  15. import java.util.Arrays;
  16. import java.util.Collections;
  17. import java.util.HashMap;
  18. import java.util.List;
  19. import java.util.ListIterator;
  20. /**
  21. * Represents a prospective build result and any requirements for it. Used for
  22. * [testing|normal][jar|assembled-jar|classesDir?].
  23. */
  24. public class Result {
  25. public static final boolean NORMAL = true;
  26. public static final boolean ASSEMBLE = true;
  27. static final Kind RELEASE = new Kind("RELEASE", NORMAL, !ASSEMBLE);
  28. static final Kind RELEASE_ALL = new Kind("RELEASE_ALL", NORMAL, ASSEMBLE);
  29. static final Kind TEST = new Kind("TEST", !NORMAL, !ASSEMBLE);
  30. static final Kind TEST_ALL = new Kind("TEST_ALL", !NORMAL, ASSEMBLE);
  31. private static final Kind[] KINDS = { RELEASE, TEST, RELEASE_ALL, TEST_ALL };
  32. private static final HashMap<String,Result> nameToResult = new HashMap<>();
  33. public static boolean isTestingJar(String name) {
  34. name = name.toLowerCase();
  35. return "junit.jar".equals(name);
  36. }
  37. public static boolean isTestingDir(String name) {
  38. name = name.toLowerCase();
  39. return (Util.Constants.TESTSRC.equals(name) || Util.Constants.JAVA5_TESTSRC
  40. .equals(name));
  41. }
  42. public static boolean isTestingModule(Module module) {
  43. String name = module.name.toLowerCase();
  44. return name.startsWith("testing") || "tests".equals(name);
  45. }
  46. public static synchronized Result getResult(String name) {
  47. if (null == name) {
  48. throw new IllegalArgumentException("null name");
  49. }
  50. return nameToResult.get(name);
  51. }
  52. public static Result[] getResults(String[] names) {
  53. if (null == names) {
  54. return new Result[0];
  55. }
  56. Result[] results = new Result[names.length];
  57. for (int i = 0; i < results.length; i++) {
  58. String name = names[i];
  59. if (null == name) {
  60. String m = "no name at " + i + ": " + Arrays.asList(names);
  61. throw new IllegalArgumentException(m);
  62. }
  63. Result r = Result.getResult(name);
  64. if (null == r) {
  65. String m = "no result [" + i + "]: " + name + ": "
  66. + Arrays.asList(names);
  67. throw new IllegalArgumentException(m);
  68. }
  69. results[i] = r;
  70. }
  71. return results;
  72. }
  73. public static Kind[] KINDS() {
  74. Kind[] result = new Kind[KINDS.length];
  75. System.arraycopy(KINDS, 0, result, 0, result.length);
  76. return result;
  77. }
  78. public static void iaxUnlessNormal(Result result) {
  79. if ((null == result) || !result.getKind().normal) {
  80. throw new IllegalArgumentException("not normal: " + result);
  81. }
  82. }
  83. public static void iaxUnlessAssembly(Result result) {
  84. if ((null == result) || !result.getKind().assemble) {
  85. throw new IllegalArgumentException("not assembly: " + result);
  86. }
  87. }
  88. public static Kind kind(boolean normal, boolean assemble) {
  89. return (normal == NORMAL ? (assemble == ASSEMBLE ? RELEASE_ALL
  90. : RELEASE) : (assemble == ASSEMBLE ? TEST_ALL : TEST));
  91. }
  92. public static class Kind {
  93. final String name;
  94. final boolean normal;
  95. final boolean assemble;
  96. private Kind(String name, boolean normal, boolean assemble) {
  97. this.name = name;
  98. this.normal = normal;
  99. this.assemble = assemble;
  100. }
  101. public final boolean isAssembly() {
  102. return assemble;
  103. }
  104. public final boolean isNormal() {
  105. return normal;
  106. }
  107. public final String toString() {
  108. return name;
  109. }
  110. }
  111. /** path to output jar - may not exist */
  112. private final File outputFile;
  113. /** List of required Result */
  114. private final List<Result> requiredResults;
  115. /** List of library jars */
  116. private final List<File> libJars;
  117. /** List of classpath variables */
  118. private final List<String> classpathVariables;
  119. transient String toLongString;
  120. /**
  121. * List of library jars exported to clients (duplicates some libJars
  122. * entries)
  123. */
  124. private final List<File> exportedLibJars;
  125. /** List of source directories */
  126. private final List<File> srcDirs;
  127. /** true if this has calculated List fields. */
  128. private boolean requiredDone;
  129. /** true if this has been found to be out of date */
  130. private boolean outOfDate;
  131. /** true if we have calculated whether this is out of date */
  132. private boolean outOfDateSet;
  133. private final Kind kind;
  134. private final Module module;
  135. private final String name;
  136. Result(Kind kind, Module module, File jarDir) {
  137. this.kind = kind;
  138. this.module = module;
  139. this.libJars = new ArrayList<>();
  140. this.exportedLibJars = new ArrayList<>();
  141. this.srcDirs = new ArrayList<>();
  142. this.classpathVariables = new ArrayList<>();
  143. this.requiredResults = new ArrayList<>();
  144. String name = module.name;
  145. if (!kind.normal) {
  146. name += "-test";
  147. }
  148. if (kind.assemble) {
  149. name += "-all";
  150. }
  151. this.name = name;
  152. this.outputFile = new File(jarDir, name + ".jar");
  153. nameToResult.put(name, this);
  154. }
  155. public String getName() {
  156. return name;
  157. }
  158. public File getOutputFile() {
  159. return outputFile;
  160. }
  161. public void clearOutOfDate() {
  162. outOfDateSet = false;
  163. outOfDate = false;
  164. }
  165. public boolean outOfDate() {
  166. if (!outOfDateSet) {
  167. outOfDate = Module.outOfDate(this);
  168. outOfDateSet = true;
  169. }
  170. return outOfDate;
  171. }
  172. /** @return List (File) of jar's required */
  173. public List<File> findJarRequirements() {
  174. ArrayList<File> result = new ArrayList<>();
  175. Module.doFindJarRequirements(this, result);
  176. return result;
  177. }
  178. /** @return unmodifiable List of String classpath variables */
  179. public List<String> getClasspathVariables() {
  180. return safeList(classpathVariables);
  181. }
  182. //
  183. /** @return unmodifiable List of required modules String names */
  184. public Result[] getRequired() {
  185. return safeResults(requiredResults);
  186. }
  187. /**
  188. * @return unmodifiable list of exported library files, guaranteed readable
  189. */
  190. public List<File> getExportedLibJars() {
  191. return safeList(exportedLibJars);
  192. }
  193. /**
  194. * @return unmodifiable list of required library files, guaranteed readable
  195. */
  196. public List<File> getLibJars() {
  197. requiredDone();
  198. return safeList(libJars);
  199. }
  200. /**
  201. * @return unmodifiable list of required library files, guaranteed readable
  202. */
  203. // public List getMerges() {
  204. // requiredDone();
  205. // return safeList(merges);
  206. // }
  207. /** @return unmodifiable list of source directories, guaranteed readable */
  208. public List<File> getSrcDirs() {
  209. return safeList(srcDirs);
  210. }
  211. public Module getModule() {
  212. return module;
  213. }
  214. public Kind getKind() {
  215. return kind;
  216. }
  217. public String toLongString() {
  218. if (null == toLongString) {
  219. toLongString = name + "[outputFile=" + outputFile
  220. + ", requiredResults=" + requiredResults + ", srcDirs="
  221. + srcDirs + ", libJars=" + libJars + "]";
  222. }
  223. return toLongString;
  224. }
  225. public String toString() {
  226. return name;
  227. }
  228. private <T> List<T> safeList(List<T> l) {
  229. requiredDone();
  230. return Collections.unmodifiableList(l);
  231. }
  232. private Result[] safeResults(List<Result> list) {
  233. requiredDone();
  234. if (null == list) {
  235. return new Result[0];
  236. }
  237. return list.toArray(new Result[0]);
  238. }
  239. private void initSrcDirs() {
  240. srcDirs.addAll(getModule().srcDirs(this));
  241. if (getKind().normal) {
  242. // trim testing source directories
  243. for (ListIterator<File> iter = srcDirs.listIterator(); iter.hasNext();) {
  244. File srcDir = iter.next();
  245. if (isTestingDir(srcDir.getName())) {
  246. iter.remove();
  247. }
  248. }
  249. }
  250. }
  251. private void initLibJars() {
  252. libJars.addAll(getModule().libJars(this));
  253. if (getKind().normal && !isTestingModule(getModule())) {
  254. // trim testing libraries
  255. for (ListIterator<File> iter = libJars.listIterator(); iter.hasNext();) {
  256. File libJar = iter.next();
  257. if (isTestingJar(libJar.getName())) {
  258. iter.remove();
  259. }
  260. }
  261. }
  262. }
  263. private void assertKind(Kind kind) {
  264. if (kind != getKind()) {
  265. throw new IllegalArgumentException("expected " + getKind()
  266. + " got " + kind);
  267. }
  268. }
  269. private void initRequiredResults() {
  270. final Module module = getModule();
  271. final Kind kind = getKind();
  272. if (kind.assemble) {
  273. if (kind.normal) {
  274. assertKind(RELEASE_ALL);
  275. requiredResults.add(module.getResult(RELEASE));
  276. } else {
  277. assertKind(TEST_ALL);
  278. requiredResults.add(module.getResult(TEST));
  279. requiredResults.add(module.getResult(RELEASE));
  280. }
  281. } else if (!kind.normal) {
  282. assertKind(TEST);
  283. requiredResults.add(module.getResult(RELEASE));
  284. } else {
  285. assertKind(RELEASE);
  286. }
  287. // externally-required:
  288. List<Module> modules = module.requiredModules(this);
  289. final boolean adoptTests = !kind.normal || isTestingModule(module);
  290. for (Module required: modules) {
  291. if (adoptTests) {
  292. // testing builds can rely on other release and test results
  293. requiredResults.add(required.getResult(TEST));
  294. requiredResults.add(required.getResult(RELEASE));
  295. } else if (!isTestingModule(required)){
  296. // release builds can only rely on non-testing results
  297. // from non-testing modules
  298. requiredResults.add(required.getResult(RELEASE));
  299. } // else skip release dependencies on testing-* (testing-util)
  300. }
  301. }
  302. private void initClasspathVariables() {
  303. // no difference
  304. classpathVariables.addAll(getModule().classpathVariables(this));
  305. }
  306. private void initExportedLibJars() {
  307. // no difference
  308. exportedLibJars.addAll(getModule().exportedLibJars(this));
  309. }
  310. private synchronized void requiredDone() {
  311. if (!requiredDone) {
  312. initSrcDirs();
  313. initLibJars();
  314. initRequiredResults();
  315. initClasspathVariables();
  316. initExportedLibJars();
  317. requiredDone = true;
  318. }
  319. }
  320. }