Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

BridgeUtil.java 19KB

vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 5 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 5 Jahren
vor 5 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 5 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 5 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
vor 21 Jahren
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /* *******************************************************************
  2. * Copyright (c) 1999-2001 Xerox Corporation,
  3. * 2002 Palo Alto Research Center, Incorporated (PARC).
  4. * All rights reserved.
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Public License v1.0
  7. * which accompanies this distribution and is available at
  8. * http://www.eclipse.org/legal/epl-v10.html
  9. *
  10. * Contributors:
  11. * Xerox/PARC initial implementation
  12. * ******************************************************************/
  13. package org.aspectj.testing.util;
  14. import java.io.File;
  15. import java.util.Comparator;
  16. import org.aspectj.bridge.IMessage;
  17. import org.aspectj.bridge.ISourceLocation;
  18. import org.aspectj.bridge.Message;
  19. import org.aspectj.bridge.MessageUtil;
  20. import org.aspectj.bridge.SourceLocation;
  21. import org.aspectj.testing.run.IRunStatus;
  22. import org.aspectj.testing.run.RunValidator;
  23. import org.aspectj.util.FileUtil;
  24. /**
  25. *
  26. */
  27. public class BridgeUtil {
  28. // private static final String INDENT = " ";
  29. /** result value when writeMessage is passed null */
  30. private static final String NULL_MESSAGE_OUTPUT = "<null message output>";
  31. /** result value when readMessage is passed null */
  32. private static final IMessage NULL_MESSAGE_INPUT = null;
  33. private static final String KIND_DELIM = ": \"";
  34. private static final String MESSAGE_DELIM = "\" - ";
  35. public static ISourceLocation makeSourceLocation(UtilLineReader reader) {
  36. LangUtil.throwIaxIfNull(reader, "reader");
  37. int line = reader.getLineNumber();
  38. return new SourceLocation(reader.getFile(), line, line, 0);
  39. }
  40. /**
  41. * Method readSourceLocation.
  42. * @param sourceLocStr
  43. * @return ISourceLocation
  44. */
  45. private static ISourceLocation readSourceLocation(String sourceLocStr) {
  46. return BridgeUtil.makeSourceLocation(sourceLocStr);
  47. }
  48. // public static IMessage makeMessage(String message, IMessage.Kind kind,
  49. // Throwable thrown, LineReader reader) {
  50. // ISourceLocation sl = (null == reader ? null : MessageUtil.makeSourceLocation(reader));
  51. // if (null == kind) kind = IMessage.INFO;
  52. // return new Message(message, kind, thrown, sl);
  53. // }
  54. /**
  55. * Read a message from a string written by writeMessage(IMessage).
  56. * Does not handle exceptions at all or source location well. XXX
  57. * @param message the String representation of a message
  58. * @return IMessage
  59. */
  60. public static IMessage readMessage(String message) {
  61. if (null == message) {
  62. return NULL_MESSAGE_INPUT;
  63. }
  64. if (NULL_MESSAGE_OUTPUT.equals(message)) {
  65. return null;
  66. }
  67. int kindEnd = message.indexOf(KIND_DELIM);
  68. int messageEnd = message.indexOf(MESSAGE_DELIM);
  69. int messageStart = kindEnd+KIND_DELIM.length();
  70. int sourceLocStart = messageEnd+MESSAGE_DELIM.length();
  71. String kindStr = message.substring(0, kindEnd);
  72. String text = message.substring(messageStart, messageEnd);
  73. String sourceLocStr = message.substring(sourceLocStart);
  74. IMessage.Kind kind = MessageUtil.getKind(kindStr);
  75. ISourceLocation loc = readSourceLocation(sourceLocStr);
  76. return new Message(text, kind, null, loc);
  77. }
  78. /**
  79. * Write a message to a string to be read by readMessage(String)
  80. * @param message the String representation of a message
  81. * @return IMessage
  82. */
  83. public static String writeMessage(IMessage message) {
  84. if (null == message) {
  85. return NULL_MESSAGE_OUTPUT;
  86. }
  87. return message.getKind()
  88. + KIND_DELIM
  89. + message.getMessage()
  90. + MESSAGE_DELIM
  91. + message.getSourceLocation(); // XXX implement
  92. }
  93. public static class Comparators {
  94. /**
  95. * Compare based solely on null-inequality:
  96. * -1 if one is not null and two is null,
  97. * 1 if one is null and two is not null,
  98. * 0 otherwise.
  99. */
  100. static int compareNull(Object one, Object two) {
  101. return (null == one
  102. ? (null == two ? 0 : 1)
  103. : (null == two ? -1 : 0));
  104. }
  105. /**
  106. * Soft comparison of String returns 0 if either is empty
  107. * or a substring of the other, and the case-insensitive
  108. * ordering otherwise.
  109. * @param lhs_s
  110. * @param rhs_s
  111. * @return
  112. */
  113. static int compareStringsSoftly(String lhs_s, String rhs_s) {
  114. if (LangUtil.isEmpty(lhs_s)
  115. || LangUtil.isEmpty(rhs_s)) {
  116. return 0;
  117. }
  118. if ((lhs_s.contains(rhs_s))
  119. || (rhs_s.contains(lhs_s))) {
  120. return 0;
  121. }
  122. return String.CASE_INSENSITIVE_ORDER.compare(lhs_s, rhs_s);
  123. }
  124. /**
  125. * This returns 0 if one file path is a suffix of the other
  126. * or a case-insensitive string comparison otherwise.
  127. * WARNING: it returns 0 if either file is
  128. * ISourceLocation.NO_FILE to permit tests to
  129. * not specify file paths.
  130. *
  131. * Use only for sorts, not to maintain maps.
  132. */
  133. public static final Comparator<File> WEAK_File = new Comparator<File>() {
  134. public int compare(File o1, File o2) {
  135. if ((o1 == o2)
  136. || (o1 == ISourceLocation.NO_FILE)
  137. || (o2 == ISourceLocation.NO_FILE) ) {
  138. return 0;
  139. }
  140. int result = compareNull(o1, o2);
  141. if (0 != result) {
  142. return result;
  143. }
  144. File one = (File) o1;
  145. File two = (File) o2;
  146. String s1 = one.getPath();
  147. String s2 = two.getPath();
  148. // check if normalize needed
  149. if (s1.endsWith(s2) || s2.endsWith(s1)) {
  150. return 0;
  151. }
  152. s1 = FileUtil.weakNormalize(s1);
  153. s2 = FileUtil.weakNormalize(s2);
  154. if (s1.endsWith(s2) || s2.endsWith(s1)) {
  155. return 0;
  156. }
  157. return String.CASE_INSENSITIVE_ORDER.compare(s1, s2);
  158. }
  159. };
  160. /**
  161. * Ordering only uses line number.
  162. * Use only for sorts, not to maintain maps.
  163. */
  164. public static final Comparator<ISourceLocation> WEAK_ISourceLocation = new Comparator<ISourceLocation>() {
  165. public int compare(ISourceLocation o1, ISourceLocation o2) {
  166. if (o1 == o2) {
  167. return 0;
  168. }
  169. int result = compareNull(o1, o2);
  170. if (0 != result) {
  171. return result;
  172. }
  173. ISourceLocation one = (ISourceLocation) o1;
  174. ISourceLocation two = (ISourceLocation) o2;
  175. int i1 = one.getLine();
  176. int i2 = two.getLine();
  177. return i1 - i2;
  178. }
  179. };
  180. /**
  181. * Like WEAK_ISourceLocation, except it also
  182. * uses WEAK_FILE on the sourceFile.
  183. * Use only for sorts, not to maintain maps.
  184. */
  185. public static final Comparator<ISourceLocation> MEDIUM_ISourceLocation = new Comparator<ISourceLocation>() {
  186. public int compare(ISourceLocation o1, ISourceLocation o2) {
  187. int result = WEAK_ISourceLocation.compare(o1, o2);
  188. if (0 != result) {
  189. return result;
  190. }
  191. ISourceLocation one = (ISourceLocation) o1;
  192. ISourceLocation two = (ISourceLocation) o2;
  193. result = compareNull(one, two);
  194. if (0 != result) { // one but not other is null
  195. return result;
  196. }
  197. if (null == one) { // both null
  198. return 0;
  199. }
  200. // neither null
  201. return WEAK_File.compare(one.getSourceFile(), two.getSourceFile());
  202. }
  203. };
  204. /**
  205. * Ordering uses kind and weak source location,
  206. * and ignores message
  207. * so use only for sorts, not to maintain maps
  208. */
  209. public static final Comparator<IMessage> WEAK_IMessage = new Comparator<IMessage>() {
  210. public int compare(IMessage o1, IMessage o2) {
  211. if (o1 == o2) {
  212. return 0;
  213. }
  214. int result = compareNull(o1, o2);
  215. if (0 != result) {
  216. return result;
  217. }
  218. IMessage one = (IMessage) o1;
  219. IMessage two = (IMessage) o2;
  220. IMessage.Kind kind1 = one.getKind();
  221. IMessage.Kind kind2= two.getKind();
  222. result = IMessage.Kind.COMPARATOR.compare(kind1, kind2);
  223. if (0 != result) {
  224. return result;
  225. }
  226. ISourceLocation sl1 = one.getSourceLocation();
  227. ISourceLocation sl2 = two.getSourceLocation();
  228. return WEAK_ISourceLocation.compare(sl1, sl2);
  229. }
  230. };
  231. /**
  232. * Ordering uses line and weak filename and message
  233. * (message matches if either is a substring of the other,
  234. * or if either is empty, i.e., none specified).
  235. * so use only for sorts, not to maintain maps
  236. */
  237. public static final Comparator<IMessage> MEDIUM_IMessage = new Comparator<IMessage>() {
  238. public int compare(IMessage o1, IMessage o2) {
  239. int result = WEAK_IMessage.compare(o1, o2);
  240. if (0 != result) {
  241. return result;
  242. }
  243. IMessage rhs_m= (IMessage) o1;
  244. IMessage lhs_m = (IMessage) o2;
  245. ISourceLocation rhs_sl = rhs_m.getSourceLocation();
  246. ISourceLocation lhs_sl = lhs_m.getSourceLocation();
  247. result = MEDIUM_ISourceLocation.compare(lhs_sl, rhs_sl);
  248. if (0 != result) {
  249. return result;
  250. }
  251. String lhs_s =lhs_m.getMessage();
  252. String rhs_s = rhs_m.getMessage();
  253. return compareStringsSoftly(lhs_s, rhs_s);
  254. }
  255. };
  256. }
  257. public static SourceLocation makeSourceLocation(String input) { // XXX only for testing, not production
  258. return makeSourceLocation(input, (File) null);
  259. }
  260. public static SourceLocation makeSourceLocation(String input, String path) {
  261. return makeSourceLocation(input, (null == path ? null : new File(path)));
  262. }
  263. /** attempt to create a source location from the input */
  264. public static SourceLocation makeSourceLocation(String input, File defaultFile) {
  265. /*
  266. * Forms interpreted:
  267. * # - line
  268. * file - file
  269. * file:# - file, line
  270. * #:# - if defaultFile is not null, then file, line, column
  271. * file:#:# - file, line, column
  272. * file:#:#:? - file, line, column, message
  273. */
  274. // SourceLocation result = null;
  275. if ((null == input) || (0 == input.length())) {
  276. if (null == defaultFile) {
  277. return null;
  278. } else {
  279. return new SourceLocation(defaultFile, 0, 0, 0);
  280. }
  281. }
  282. input = input.trim();
  283. String path = null;
  284. int line = 0;
  285. int endLine = 0;
  286. int column = 0;
  287. // String message = null;
  288. // first try line only
  289. line = convert(input);
  290. if (-1 != line) {
  291. return new SourceLocation(defaultFile, line, line, 0);
  292. }
  293. // if not a line - must be > 2 characters
  294. if (3 > input.length()) {
  295. return null; // throw new IllegalArgumentException("too short: " + input);
  296. }
  297. final String fixTag = "FIXFIX";
  298. if (input.charAt(1) == ':') { // windows drive ambiguates ":" file:line:col separator
  299. input = fixTag + input.substring(0,1) + input.substring(2);
  300. }
  301. // expecting max: path:line:column:message
  302. // if 1 colon, delimits line (to second colon or end of string)
  303. // if 2 colon, delimits column (to third colon or end of string)
  304. // if 3 colon, delimits column (to fourth colon or end of string)
  305. // todo: use this instead??
  306. final int colon1 = input.indexOf(":",2); // 2 to get past windows drives...
  307. final int colon2 = (-1 == colon1?-1:input.indexOf(":", colon1+1));
  308. final int colon3 = (-1 == colon2?-1:input.indexOf(":", colon2+1));
  309. String s;
  310. if (-1 == colon1) { // no colon; only path (number handled above)
  311. path = input;
  312. } else { // 1+ colon => file:line // XXX later or line:column
  313. path = input.substring(0, colon1);
  314. s = input.substring(colon1+1,(-1!=colon2?colon2:input.length())).trim();
  315. line = convert(s);
  316. if (-1 == line) {
  317. return null;
  318. //line = "expecting line(number) at \"" + line + "\" in " + input;
  319. //throw new IllegalArgumentException(line);
  320. } else if (-1 != colon2) { // 2+ colon => col
  321. s = input.substring(colon2+1,(-1!=colon3?colon3:input.length())).trim();
  322. column = convert(s);
  323. if (-1 == column) {
  324. return null;
  325. //col = "expecting col(number) at \"" + col + "\" in " + input;
  326. //throw new IllegalArgumentException(col);
  327. } else if (-1 != colon3) { // 3 colon => message
  328. input.substring(colon3+1); // do not trim message
  329. }
  330. }
  331. }
  332. if (path.startsWith(fixTag)) {
  333. int len = fixTag.length();
  334. path = path.substring(len, 1+len) + ":" +
  335. path.substring(1+len);
  336. }
  337. if ((endLine == 0) && (line != 0)) {
  338. endLine = line;
  339. }
  340. // XXX removed message/comment
  341. return new SourceLocation(new File(path), line, endLine, column);
  342. }
  343. // XXX reconsider convert if used in production code
  344. /**
  345. * Convert String to int using ascii and optionally
  346. * tolerating text
  347. * @param s the String to convert
  348. * @param permitText if true, pick a sequence of numbers
  349. * within a possibly non-numeric String
  350. * @param last if permitText, then if this is true the
  351. * last sequence is used - otherwise the first is used
  352. * XXX only default u.s. encodings..
  353. * @return -1 or value if a valid, totally-numeric positive string 0..MAX_WIDTH
  354. */
  355. private static int convert(String s) {
  356. return convert(s, false, false);
  357. }
  358. // XXX reconsider convert if used in production code
  359. /**
  360. * Convert String to int using ascii and optionally
  361. * tolerating text
  362. * @param s the String to convert
  363. * @param permitText if true, pick a sequence of numbers
  364. * within a possibly non-numeric String
  365. * @param last if permitText, then if this is true the
  366. * last sequence is used - otherwise the first is used
  367. * XXX only default u.s. encodings..
  368. * @return -1 or value if a valid, positive string 0..MAX_WIDTH
  369. */
  370. private static int convert(String s, boolean permitText,
  371. boolean first) {
  372. int result = -1;
  373. int last = -1;
  374. int max = s.length();
  375. boolean reading = false;
  376. for (int i = 0; i < max; i++) {
  377. char c = s.charAt(i);
  378. if ((c >= '0') && (c <= '9')) {
  379. if (-1 == result) { // prefix loop
  380. result = 0;
  381. reading = true;
  382. }
  383. result = ((result * 10) + (c - '0'));
  384. } else if (!permitText) {
  385. return -1;
  386. } else if (reading) { // from numeric -> non-numeric
  387. if (first) {
  388. return result;
  389. } else {
  390. last = result;
  391. }
  392. reading = false;
  393. }
  394. }
  395. if (permitText && !first && (-1 != last) && (-1 == result)) {
  396. result = last;
  397. }
  398. return ((0 < result) && (result < ISourceLocation.MAX_LINE) ? result : -1);
  399. }
  400. private BridgeUtil() {}
  401. /** @return String for status header, counting children passed/failed */
  402. public static String childString(IRunStatus runStatus, int numSkips, int numIncomplete) {
  403. if (null == runStatus) {
  404. return "((RunStatus) null)";
  405. }
  406. if (0 > numSkips) {
  407. numSkips = 0;
  408. }
  409. if (0 > numIncomplete) {
  410. numIncomplete = 0;
  411. }
  412. StringBuffer sb = new StringBuffer();
  413. if (RunValidator.NORMAL.runPassed(runStatus)) {
  414. sb.append("PASS ");
  415. } else {
  416. sb.append("FAIL ");
  417. }
  418. Object id = runStatus.getIdentifier();
  419. if (null != id) {
  420. sb.append(id.toString() + " ");
  421. }
  422. IRunStatus[] children = runStatus.getChildren();
  423. final int numChildren = (null == children ? 0 : children.length);
  424. final int numTests = numIncomplete + numChildren + numSkips;
  425. int numFails = 0;
  426. if (!LangUtil.isEmpty(children)) {
  427. for (IRunStatus child : children) {
  428. if (!RunValidator.NORMAL.runPassed(child)) {
  429. numFails++;
  430. }
  431. }
  432. }
  433. final int numPass = children.length - numFails;
  434. sb.append(numTests + " tests");
  435. if (0 < numTests) {
  436. sb.append(" (");
  437. }
  438. if (0 < numSkips) {
  439. sb.append(numSkips + " skipped");
  440. if (0 < (numFails + numPass + numIncomplete)) {
  441. sb.append(", ");
  442. }
  443. }
  444. if (0 < numIncomplete) {
  445. sb.append(numIncomplete + " incomplete");
  446. if (0 < (numFails + numPass)) {
  447. sb.append(", ");
  448. }
  449. }
  450. if (0 < numFails) {
  451. sb.append(numFails + " failed");
  452. if (0 < numPass) {
  453. sb.append(", ");
  454. }
  455. }
  456. if (0 < numPass) {
  457. sb.append(numPass + " passed)");
  458. } else if (0 < numTests) {
  459. sb.append(")");
  460. }
  461. return sb.toString().trim();
  462. }
  463. /** @return String for status header */
  464. public static String toShortString(IRunStatus runStatus) {
  465. if (null == runStatus) {
  466. return "((RunStatus) null)";
  467. }
  468. StringBuffer sb = new StringBuffer();
  469. if (RunValidator.NORMAL.runPassed(runStatus)) {
  470. sb.append("PASS ");
  471. } else {
  472. sb.append("FAIL ");
  473. }
  474. Object id = runStatus.getIdentifier();
  475. if (null != id) {
  476. sb.append(id.toString() + " ");
  477. }
  478. sb.append(MessageUtil.renderCounts(runStatus));
  479. return sb.toString().trim();
  480. }
  481. }