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 10KB

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