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.

SoftMessage.java 10.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  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 v 2.0
  7. * which accompanies this distribution and is available at
  8. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  9. *
  10. * Contributors:
  11. * Xerox/PARC initial implementation
  12. * ******************************************************************/
  13. package org.aspectj.testing.xml;
  14. import java.io.File;
  15. import java.util.ArrayList;
  16. //import java.util.Collections;
  17. import java.util.List;
  18. import org.aspectj.bridge.IMessage;
  19. import org.aspectj.bridge.IMessageHolder;
  20. import org.aspectj.bridge.ISourceLocation;
  21. import org.aspectj.bridge.MessageUtil;
  22. import org.aspectj.bridge.SourceLocation;
  23. import org.aspectj.util.LangUtil;
  24. /**
  25. * Implement messages.
  26. * This implementation is immutable if ISourceLocation is immutable,
  27. * except for adding source locations.
  28. */
  29. public class SoftMessage implements IMessage {
  30. public static String XMLNAME = "message";
  31. public static final File NO_FILE = ISourceLocation.NO_FILE;
  32. private String message;
  33. private IMessage.Kind kind;
  34. private Throwable thrown;
  35. private ISourceLocation sourceLocation;
  36. private String details;
  37. private int id;
  38. private int sourceStart,sourceEnd;
  39. private final List extraSourceLocations = new ArrayList();
  40. //private ISourceLocation pseudoSourceLocation; // set directly
  41. // collapse enclosed source location for shorter, property-based xml
  42. private String file;
  43. private int line = Integer.MAX_VALUE;
  44. /** convenience for constructing failure messages */
  45. public static SoftMessage fail(String message, Throwable thrown) {
  46. return new SoftMessage(message, IMessage.FAIL, thrown, null);
  47. }
  48. /**
  49. * Print messages.
  50. * @param messages List of IMessage
  51. */
  52. public static void writeXml(XMLWriter out, IMessageHolder messages) {
  53. if ((null == out)
  54. || (null == messages)
  55. || (0 == messages.numMessages(null, true))) {
  56. return;
  57. }
  58. List list = messages.getUnmodifiableListView();
  59. for (Object o : list) {
  60. writeXml(out, (IMessage) o);
  61. }
  62. }
  63. /**
  64. * Print messages.
  65. * @param messages IMessage[]
  66. */
  67. public static void writeXml(XMLWriter out, IMessage[] messages) {
  68. if ((null == out) || (null == messages)) {
  69. return;
  70. }
  71. for (IMessage iMessage : messages) {
  72. writeXml(out, iMessage);
  73. }
  74. }
  75. /** print message as an element
  76. * XXX has to sync with ajcTests.dtd
  77. * @throws IllegalArgumentException if message.getThrown() is not null
  78. */
  79. public static void writeXml(
  80. XMLWriter out,
  81. IMessage message) { // XXX short form only, no files
  82. if ((null == out) || (null == message)) {
  83. return;
  84. }
  85. Throwable thrown = message.getThrown();
  86. if (null != thrown) {
  87. String m = "unable to write " + message + " thrown not permitted";
  88. throw new IllegalArgumentException(m);
  89. }
  90. final String elementName = XMLNAME;
  91. out.startElement(elementName, false);
  92. out.printAttribute("kind", message.getKind().toString());
  93. String value = message.getMessage();
  94. if (null != value) {
  95. value = XMLWriter.attributeValue(value);
  96. out.printAttribute("text", value);
  97. }
  98. value = message.getDetails();
  99. if (null != value) {
  100. value = XMLWriter.attributeValue(value);
  101. out.printAttribute("details", value);
  102. }
  103. ISourceLocation sl = message.getSourceLocation();
  104. if (null != sl) {
  105. int line = sl.getLine();
  106. if (-1 < line) {
  107. out.printAttribute("line", "" + line);
  108. }
  109. File file = sl.getSourceFile();
  110. if ((null != file) && !ISourceLocation.NO_FILE.equals(file)) {
  111. value = XMLWriter.attributeValue(file.getPath());
  112. out.printAttribute("file", value);
  113. }
  114. }
  115. List extras = message.getExtraSourceLocations();
  116. if (!LangUtil.isEmpty(extras)) {
  117. out.endAttributes();
  118. for (Object extra : extras) {
  119. /*ISourceLocation element = (ISourceLocation)*/
  120. SoftSourceLocation.writeXml(out, sl);
  121. }
  122. }
  123. out.endElement(elementName);
  124. }
  125. public SoftMessage() {
  126. } // XXX programmatic only
  127. /**
  128. * Create a (compiler) error or warning message
  129. * @param message the String used as the underlying message
  130. * @param sourceLocation the ISourceLocation, if any, associated with this message
  131. * @param isError if true, use IMessage.ERROR; else use IMessage.WARNING
  132. */
  133. public SoftMessage(
  134. String message,
  135. ISourceLocation location,
  136. boolean isError) {
  137. this(
  138. message,
  139. (isError ? IMessage.ERROR : IMessage.WARNING),
  140. null,
  141. location);
  142. }
  143. /**
  144. * Create a message, handling null values for message and kind
  145. * if thrown is not null.
  146. * @param message the String used as the underlying message
  147. * @param kind the IMessage.Kind of message - not null
  148. * @param thrown the Throwable, if any, associated with this message
  149. * @param sourceLocation the ISourceLocation, if any, associated with this message
  150. * @throws IllegalArgumentException if message is null and
  151. * thrown is null or has a null message, or if kind is null
  152. * and thrown is null.
  153. */
  154. public SoftMessage(
  155. String message,
  156. IMessage.Kind kind,
  157. Throwable thrown,
  158. ISourceLocation sourceLocation) {
  159. this.message = message;
  160. this.kind = kind;
  161. this.thrown = thrown;
  162. this.sourceLocation = sourceLocation;
  163. if (null == message) {
  164. if (null != thrown) {
  165. message = thrown.getMessage();
  166. }
  167. if (null == message) {
  168. throw new IllegalArgumentException("null message");
  169. }
  170. }
  171. if (null == kind) {
  172. throw new IllegalArgumentException("null kind");
  173. }
  174. }
  175. /** @return the kind of this message */
  176. public IMessage.Kind getKind() {
  177. return kind;
  178. }
  179. /** @return true if kind == IMessage.ERROR */
  180. public boolean isError() {
  181. return kind == IMessage.ERROR;
  182. }
  183. /** @return true if kind == IMessage.WARNING */
  184. public boolean isWarning() {
  185. return kind == IMessage.WARNING;
  186. }
  187. /** @return true if kind == IMessage.DEBUG */
  188. public boolean isDebug() {
  189. return kind == IMessage.DEBUG;
  190. }
  191. /**
  192. * @return true if kind == IMessage.USAGE
  193. */
  194. public boolean isUsage() {
  195. return kind == IMessage.USAGE;
  196. }
  197. /**
  198. * @return true if kind == IMessage.INFO
  199. */
  200. public boolean isInfo() {
  201. return kind == IMessage.INFO;
  202. }
  203. public boolean isTaskTag() {
  204. return kind == IMessage.TASKTAG;
  205. }
  206. /** @return true if kind == IMessage.ABORT */
  207. public boolean isAbort() {
  208. return kind == IMessage.ABORT;
  209. }
  210. /**
  211. * @return true if kind == IMessage.FAIL
  212. */
  213. public boolean isFailed() {
  214. return kind == IMessage.FAIL;
  215. }
  216. public boolean getDeclared() { return false; }
  217. /** @return non-null String with simple message */
  218. final public String getMessage() {
  219. return message;
  220. }
  221. /** @return Throwable associated with this message, or null if none */
  222. final public Throwable getThrown() {
  223. return thrown;
  224. }
  225. /**
  226. * This returns any ISourceLocation set or a mock-up
  227. * if file and/or line were set.
  228. * @return ISourceLocation associated with this message,
  229. * a mock-up if file or line is available, or null if none
  230. */
  231. final public ISourceLocation getSourceLocation() {
  232. if ((null == sourceLocation)
  233. && ((null != file) || (line != Integer.MAX_VALUE))) {
  234. File f = (null == file ? NO_FILE : new File(file));
  235. int line = (this.line == Integer.MAX_VALUE ? 0 : this.line);
  236. sourceLocation = new SourceLocation(f, line);
  237. }
  238. return sourceLocation;
  239. }
  240. /** set the kind of this message */
  241. public void setMessageKind(IMessage.Kind kind) {
  242. this.kind = (null == kind ? IMessage.ERROR : kind);
  243. }
  244. /** set the file for the underlying source location of this message
  245. * @throws IllegalStateException if source location was set directly
  246. * or indirectly by calling getSourceLocation after setting
  247. * file or line.
  248. */
  249. public void setFile(String path) {
  250. LangUtil.throwIaxIfFalse(!LangUtil.isEmpty(path), "empty path");
  251. if (null != sourceLocation) {
  252. throw new IllegalStateException("cannot set line after creating source location");
  253. }
  254. this.file = path;
  255. }
  256. /** set the kind of this message */
  257. public void setKindAsString(String kind) {
  258. setMessageKind(MessageUtil.getKind(kind));
  259. }
  260. public void setSourceLocation(ISourceLocation sourceLocation) {
  261. this.sourceLocation = sourceLocation;
  262. }
  263. /**
  264. * Set the line for the underlying source location.
  265. * @throws IllegalStateException if source location was set directly
  266. * or indirectly by calling getSourceLocation after setting
  267. * file or line.
  268. */
  269. public void setLineAsString(String line) {
  270. if (null != sourceLocation) {
  271. throw new IllegalStateException("cannot set line after creating source location");
  272. }
  273. this.line = Integer.parseInt(line);
  274. SourceLocation.validLine(this.line);
  275. }
  276. public void setText(String text) {
  277. this.message = (null == text ? "" : text);
  278. }
  279. public String toString() {
  280. StringBuilder result = new StringBuilder();
  281. result.append(null == getKind() ? "<null kind>" : getKind().toString());
  282. String messageString = getMessage();
  283. if (!LangUtil.isEmpty(messageString)) {
  284. result.append(messageString);
  285. }
  286. ISourceLocation loc = getSourceLocation();
  287. if ((null != loc) && (loc != ISourceLocation.NO_FILE)) {
  288. result.append(" at " + loc);
  289. }
  290. if (null != thrown) {
  291. result.append(" -- " + LangUtil.renderExceptionShort(thrown));
  292. }
  293. return result.toString();
  294. }
  295. public String getDetails() {
  296. return details;
  297. }
  298. public void setDetails(String string) {
  299. details = string;
  300. }
  301. public int getID() {
  302. return id;
  303. }
  304. public void setID(int id) {
  305. this.id = id;
  306. }
  307. public int getSourceStart() {
  308. return sourceStart;
  309. }
  310. public void setSourceStart(int s) {
  311. sourceStart = s;
  312. }
  313. public int getSourceEnd() {
  314. return sourceStart;
  315. }
  316. public void setSourceEnd(int s) {
  317. sourceEnd = s;
  318. }
  319. /* (non-Javadoc)
  320. * @see org.aspectj.bridge.IMessage#getExtraSourceLocations()
  321. */
  322. public List getExtraSourceLocations() {
  323. return extraSourceLocations;
  324. }
  325. public void addSourceLocation(ISourceLocation location) {
  326. if (null != location) {
  327. extraSourceLocations.add(location);
  328. }
  329. }
  330. }