/plugins/ErrorList/tags/release-1-2-2/errorlist/DefaultErrorSource.java

# · Java · 542 lines · 298 code · 67 blank · 177 comment · 55 complexity · 85a14b4524199569edbef6fef7144e96 MD5 · raw file

  1. /*
  2. * DefaultErrorSource.java - Default error source
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 1999, 2000, 2001 Slava Pestov
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package errorlist;
  23. //{{{ Imports
  24. import javax.swing.text.Position;
  25. import javax.swing.SwingUtilities;
  26. import java.io.File;
  27. import java.util.*;
  28. import org.gjt.sp.jedit.msg.*;
  29. import org.gjt.sp.jedit.*;
  30. import org.gjt.sp.util.Log;
  31. //}}}
  32. /**
  33. * @author Slava Pestov
  34. */
  35. public class DefaultErrorSource extends ErrorSource
  36. {
  37. //{{{ DefaultErrorSource constructor
  38. /**
  39. * Creates a new default error source.
  40. */
  41. public DefaultErrorSource(String name)
  42. {
  43. errors = new Hashtable();
  44. this.name = name;
  45. } //}}}
  46. //{{{ getName() method
  47. /**
  48. * Returns a string description of this error source.
  49. */
  50. public String getName()
  51. {
  52. return name;
  53. } //}}}
  54. //{{{ getErrorCount() method
  55. /**
  56. * Returns the number of errors in this source.
  57. */
  58. public int getErrorCount()
  59. {
  60. return errorCount;
  61. } //}}}
  62. //{{{ getAllErrors() method
  63. /**
  64. * Returns all errors.
  65. */
  66. public ErrorSource.Error[] getAllErrors()
  67. {
  68. if(errors.size() == 0)
  69. return null;
  70. Vector errorList = new Vector(errorCount);
  71. Enumeration enum = errors.elements();
  72. while(enum.hasMoreElements())
  73. {
  74. Vector list = (Vector)enum.nextElement();
  75. for(int i = 0; i < list.size(); i++)
  76. {
  77. errorList.addElement(list.elementAt(i));
  78. }
  79. }
  80. ErrorSource.Error[] array = new ErrorSource.Error[errorList.size()];
  81. errorList.copyInto(array);
  82. return array;
  83. } //}}}
  84. //{{{ getFileErrorCount() method
  85. /**
  86. * Returns the number of errors in the specified file.
  87. * @param path The full path name
  88. */
  89. public int getFileErrorCount(String path)
  90. {
  91. Vector list = (Vector)errors.get(path);
  92. if(list == null)
  93. return 0;
  94. else
  95. return list.size();
  96. } //}}}
  97. //{{{ getFileErrors() method
  98. /**
  99. * Returns all errors in the specified file.
  100. * @param path The full path name
  101. */
  102. public ErrorSource.Error[] getFileErrors(String path)
  103. {
  104. Vector list = (Vector)errors.get(path);
  105. if(list == null || list.size() == 0)
  106. return null;
  107. ErrorSource.Error[] array = new ErrorSource.Error[list.size()];
  108. list.copyInto(array);
  109. return array;
  110. } //}}}
  111. //{{{ getLineErrors() method
  112. /**
  113. * Returns all errors on the specified line.
  114. * @param lineIndex The line number
  115. */
  116. public ErrorSource.Error[] getLineErrors(Buffer buffer, int lineIndex)
  117. {
  118. if(errors.size() == 0)
  119. return null;
  120. Vector list = (Vector)errors.get(buffer.getPath());
  121. if(list == null)
  122. return null;
  123. Vector errorList = null;
  124. for(int i = 0; i < list.size(); i++)
  125. {
  126. DefaultError error = (DefaultError)list.elementAt(i);
  127. if(error.getLineNumber() == lineIndex)
  128. {
  129. if(errorList == null)
  130. errorList = new Vector();
  131. errorList.addElement(error);
  132. }
  133. }
  134. if(errorList == null)
  135. return null;
  136. ErrorSource.Error[] array = new ErrorSource.Error[errorList.size()];
  137. errorList.copyInto(array);
  138. return array;
  139. } //}}}
  140. //{{{ clear() method
  141. /**
  142. * Removes all errors from this error source. This method is not thread
  143. * safe.
  144. */
  145. public void clear()
  146. {
  147. if(errorCount == 0)
  148. return;
  149. errors.clear();
  150. errorCount = 0;
  151. ErrorSourceUpdate message = new ErrorSourceUpdate(this,
  152. ErrorSourceUpdate.ERRORS_CLEARED,this,null);
  153. EditBus.send(message);
  154. } //}}}
  155. //{{{ addError() method
  156. /**
  157. * Adds an error to this error source. This method is thread-safe.
  158. * @param error The error
  159. */
  160. public synchronized void addError(DefaultError error)
  161. {
  162. Vector list = (Vector)errors.get(error.getFilePath());
  163. if(list == null)
  164. {
  165. list = new Vector();
  166. errors.put(error.getFilePath(),list);
  167. }
  168. list.addElement(error);
  169. errorCount++;
  170. final ErrorSourceUpdate message = new ErrorSourceUpdate(this,
  171. ErrorSourceUpdate.ERROR_ADDED,this,error);
  172. SwingUtilities.invokeLater(new Runnable()
  173. {
  174. public void run()
  175. {
  176. EditBus.send(message);
  177. }
  178. });
  179. } //}}}
  180. //{{{ addError() method
  181. /**
  182. * Adds an error to this error source. This method is thread-safe.
  183. * @param errorType The error type (ErrorSource.ERROR or
  184. * ErrorSource.WARNING)
  185. * @param path The path name
  186. * @param lineIndex The line number
  187. * @param start The start offset
  188. * @param end The end offset
  189. * @param error The error message
  190. */
  191. public void addError(int type, String path,
  192. int lineIndex, int start, int end, String error)
  193. {
  194. DefaultError newError = new DefaultError(this,type,path,lineIndex,
  195. start,end,error);
  196. addError(newError);
  197. } //}}}
  198. //{{{ handleMessage() method
  199. public void handleMessage(EBMessage message)
  200. {
  201. if(message instanceof BufferUpdate)
  202. handleBufferMessage((BufferUpdate)message);
  203. } //}}}
  204. //{{{ toString() method
  205. public String toString()
  206. {
  207. return getClass().getName() + "[" + name + "]";
  208. } //}}}
  209. //{{{ Protected members
  210. protected String name;
  211. protected int errorCount;
  212. protected Hashtable errors;
  213. //}}}
  214. //{{{ Private members
  215. //{{{ handleBufferMessage() method
  216. private void handleBufferMessage(BufferUpdate message)
  217. {
  218. Buffer buffer = message.getBuffer();
  219. if(message.getWhat() == BufferUpdate.LOADED)
  220. {
  221. Vector list = (Vector)errors.get(buffer.getPath());
  222. if(list != null)
  223. {
  224. for(int i = 0; i < list.size(); i++)
  225. {
  226. ((DefaultError)list.elementAt(i))
  227. .openNotify(buffer);
  228. }
  229. }
  230. }
  231. else if(message.getWhat() == BufferUpdate.CLOSED)
  232. {
  233. Vector list = (Vector)errors.get(buffer.getPath());
  234. if(list != null)
  235. {
  236. for(int i = 0; i < list.size(); i++)
  237. {
  238. ((DefaultError)list.elementAt(i))
  239. .closeNotify(buffer);
  240. }
  241. }
  242. }
  243. } //}}}
  244. //}}}
  245. //{{{ DefaultError class
  246. /**
  247. * An error.
  248. */
  249. public static class DefaultError implements ErrorSource.Error
  250. {
  251. //{{{ DefaultError constructor
  252. /**
  253. * Creates a new default error.
  254. * @param type The error type
  255. * @param path The path
  256. * @param start The start offset
  257. * @param end The end offset
  258. * @param error The error message
  259. */
  260. public DefaultError(ErrorSource source, int type, String path,
  261. int lineIndex, int start, int end, String error)
  262. {
  263. this.source = source;
  264. this.type = type;
  265. // Create absolute path
  266. if(MiscUtilities.isURL(path))
  267. this.path = path;
  268. else
  269. {
  270. this.path = MiscUtilities.constructPath(System
  271. .getProperty("user.dir"),path);
  272. }
  273. this.lineIndex = lineIndex;
  274. this.start = start;
  275. this.end = end;
  276. this.error = error;
  277. // Shortened name used in display
  278. name = MiscUtilities.getFileName(path);
  279. // If the buffer is open and loaded, this creates
  280. // a floating position
  281. Buffer buffer = jEdit.getBuffer(this.path);
  282. if(buffer != null && buffer.isLoaded())
  283. openNotify(buffer);
  284. } //}}}
  285. //{{{ getErrorSource() method
  286. /**
  287. * Returns the error source.
  288. */
  289. public ErrorSource getErrorSource()
  290. {
  291. return source;
  292. } //}}}
  293. //{{{ getErrorType() method
  294. /**
  295. * Returns the error type.
  296. */
  297. public int getErrorType()
  298. {
  299. return type;
  300. } //}}}
  301. //{{{ getBuffer() method
  302. /**
  303. * Returns the buffer involved, or null if it is not open.
  304. */
  305. public Buffer getBuffer()
  306. {
  307. return buffer;
  308. } //}}}
  309. //{{{ getFilePath() method
  310. /**
  311. * Returns the file name involved.
  312. */
  313. public String getFilePath()
  314. {
  315. return path;
  316. } //}}}
  317. //{{{ getFileName() method
  318. /**
  319. * Returns the name portion of the file involved.
  320. */
  321. public String getFileName()
  322. {
  323. return name;
  324. } //}}}
  325. //{{{ getLineNumber() method
  326. /**
  327. * Returns the line number.
  328. */
  329. public int getLineNumber()
  330. {
  331. if(startPos != null)
  332. {
  333. return buffer.getLineOfOffset(startPos.getOffset());
  334. }
  335. else
  336. return lineIndex;
  337. } //}}}
  338. //{{{ getStartOffset() method
  339. /**
  340. * Returns the start offset.
  341. */
  342. public int getStartOffset()
  343. {
  344. // the if(endPos) is intentional, don't float unless
  345. // both end and start are set
  346. if(endPos != null)
  347. {
  348. return startPos.getOffset()
  349. - buffer.getLineStartOffset(
  350. getLineNumber());
  351. }
  352. else
  353. return start;
  354. } //}}}
  355. //{{{ getEndOffset() method
  356. /**
  357. * Returns the end offset.
  358. */
  359. public int getEndOffset()
  360. {
  361. if(endPos != null)
  362. {
  363. return endPos.getOffset()
  364. - buffer.getLineStartOffset(
  365. getLineNumber());
  366. }
  367. else
  368. return end;
  369. } //}}}
  370. //{{{ getErrorMessage() method
  371. /**
  372. * Returns the error message.
  373. */
  374. public String getErrorMessage()
  375. {
  376. return error;
  377. } //}}}
  378. //{{{ addExtraMessage() method
  379. /**
  380. * Adds an additional message to the error. This must be called
  381. * before the error is added to the error source, otherwise it
  382. * will have no effect.
  383. * @param message The message
  384. */
  385. public void addExtraMessage(String message)
  386. {
  387. if(extras == null)
  388. extras = new Vector();
  389. extras.addElement(message);
  390. } //}}}
  391. //{{{ getExtraMessages() method
  392. /**
  393. * Returns the error message.
  394. */
  395. public String[] getExtraMessages()
  396. {
  397. if(extras == null)
  398. return new String[0];
  399. String[] retVal = new String[extras.size()];
  400. extras.copyInto(retVal);
  401. return retVal;
  402. } //}}}
  403. //{{{ toString() method
  404. /**
  405. * Returns a string representation of this error.
  406. */
  407. public String toString()
  408. {
  409. return getFileName() + ":" + (getLineNumber() + 1)
  410. + ":" + getErrorMessage();
  411. } //}}}
  412. //{{{ Package-private members
  413. DefaultError next;
  414. //{{{ openNotify() method
  415. /*
  416. * Notifies the compiler error that a buffer has been opened.
  417. * This creates the floating position if necessary.
  418. *
  419. * I could make every CompilerError listen for buffer open
  420. * events, but it's too much effort remembering to unregister
  421. * the listeners, etc.
  422. */
  423. void openNotify(Buffer buffer)
  424. {
  425. if(!buffer.getPath().equals(path))
  426. return;
  427. this.buffer = buffer;
  428. if(lineIndex < buffer.getLineCount())
  429. {
  430. int lineStart = buffer.getLineStartOffset(lineIndex);
  431. startPos = buffer.createPosition(
  432. lineStart + start);
  433. if(end != 0)
  434. {
  435. endPos = buffer.createPosition(
  436. lineStart + end);
  437. }
  438. }
  439. } //}}}
  440. //{{{ closeNotify() method
  441. /*
  442. * Notifies the error that a buffer has been closed.
  443. * This clears the floating position if necessary.
  444. *
  445. * I could make every error listen for buffer closed
  446. * events, but it's too much effort remembering to unregister
  447. * the listeners, etc.
  448. */
  449. void closeNotify(Buffer buffer)
  450. {
  451. if(!buffer.getPath().equals(path))
  452. return;
  453. this.buffer = null;
  454. linePos = null;
  455. startPos = null;
  456. endPos = null;
  457. } //}}}
  458. //}}}
  459. //{{{ Private members
  460. private ErrorSource source;
  461. private int type;
  462. private String path;
  463. private String name;
  464. private Buffer buffer;
  465. private int lineIndex;
  466. private int start;
  467. private int end;
  468. private Position linePos;
  469. private Position startPos;
  470. private Position endPos;
  471. private String error;
  472. private Vector extras;
  473. //}}}
  474. } //}}}
  475. }