/plugins/XSearch/tags/release-1-0-0/XSearch/xsearch/HyperSearchRequest.java

# · Java · 419 lines · 266 code · 60 blank · 93 comment · 41 complexity · eea1f9ebe7ab605fb09a7c002b4fe010 MD5 · raw file

  1. /*
  2. * HyperSearchRequest.java - HyperSearch request, run in I/O thread
  3. * :tabSize=2:indentSize=2:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 1998, 1999, 2000, 2001, 2002 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 org.gjt.sp.jedit.search;
  23. package xsearch;
  24. //{{{ Imports
  25. import javax.swing.text.Segment;
  26. import javax.swing.tree.*;
  27. import javax.swing.JTree;
  28. import javax.swing.SwingUtilities;
  29. import org.gjt.sp.jedit.textarea.Selection;
  30. import org.gjt.sp.jedit.io.VFSManager;
  31. import org.gjt.sp.jedit.Buffer;
  32. import org.gjt.sp.jedit.GUIUtilities;
  33. import org.gjt.sp.jedit.jEdit;
  34. import org.gjt.sp.jedit.View;
  35. import org.gjt.sp.jedit.search.*;
  36. import org.gjt.sp.util.*;
  37. //import bsh.BshMethod;
  38. import org.gjt.sp.util.Log; // for debugging
  39. import org.gjt.sp.jedit.BeanShell;
  40. //}}}
  41. class HyperSearchRequest extends WorkRequest
  42. {
  43. //{{{ HyperSearchRequest constructor
  44. public HyperSearchRequest(View view, SearchMatcher matcher,
  45. HyperSearchResults results, Selection[] selection)
  46. {
  47. this( view, matcher, results, selection, 0, 0);
  48. }
  49. public HyperSearchRequest(View view, SearchMatcher matcher,
  50. HyperSearchResults results, Selection[] selection,
  51. int lineRangeUp, int lineRangeDown)
  52. {
  53. //Log.log(Log.DEBUG, BeanShell.class,"HyperSearchRequest.54: lineRangeUp = "+lineRangeUp+", lineRangeDown = "+lineRangeDown);
  54. this.view = view;
  55. this.matcher = matcher;
  56. this.results = results;
  57. // this.resultTreeModel = results.getTreeModel();
  58. // this.resultTreeRoot = (DefaultMutableTreeNode)resultTreeModel
  59. // .getRoot();
  60. this.searchString = XSearchAndReplace.getSearchString();
  61. this.rootSearchNode = new DefaultMutableTreeNode(searchString);
  62. this.selection = selection;
  63. this.lineRangeUp = lineRangeUp;
  64. this.lineRangeDown = lineRangeDown;
  65. } //}}}
  66. //{{{ run() method
  67. public void run()
  68. {
  69. setStatus(jEdit.getProperty("hypersearch-status")); // added 4.1pre5
  70. SearchFileSet fileset = XSearchAndReplace.getSearchFileSet();
  71. String[] files = fileset.getFiles(view);
  72. if(files == null || files.length == 0)
  73. {
  74. SwingUtilities.invokeLater(new Runnable()
  75. {
  76. public void run()
  77. {
  78. GUIUtilities.error(view,"empty-fileset",null);
  79. }
  80. });
  81. return;
  82. }
  83. setProgressMaximum(fileset.getFileCount(view));
  84. // to minimise synchronization and stuff like that, we only
  85. // show a status message at most twice a second
  86. // initially zero, so that we always show the first message
  87. long lastStatusTime = 0;
  88. try
  89. {
  90. if(selection != null)
  91. {
  92. Buffer buffer = view.getBuffer();
  93. searchInSelection(buffer);
  94. }
  95. else
  96. {
  97. int current = 0;
  98. loop: for(int i = 0; i < files.length; i++)
  99. {
  100. String file = files[i];
  101. current++;
  102. long currentTime = System.currentTimeMillis();
  103. if(currentTime - lastStatusTime > 500)
  104. {
  105. setStatus(jEdit.getProperty("hypersearch.status",
  106. new String[] { file }));
  107. setProgressValue(current);
  108. lastStatusTime = currentTime;
  109. }
  110. Buffer buffer = jEdit.openTemporary(null,null,file,false);
  111. if(buffer == null)
  112. continue loop;
  113. // int thisResultCount = doHyperSearch(buffer,
  114. // 0,buffer.getLength());
  115. // if(thisResultCount != 0)
  116. // {
  117. // bufferCount++;
  118. // resultCount += thisResultCount;
  119. // }
  120. doHyperSearch(buffer);
  121. };
  122. }
  123. }
  124. catch(final Exception e)
  125. {
  126. Log.log(Log.ERROR,this,e);
  127. SwingUtilities.invokeLater(new Runnable()
  128. {
  129. public void run()
  130. {
  131. GUIUtilities.error(view,"searcherror",
  132. new String[] { e.toString() });
  133. }
  134. });
  135. }
  136. catch(WorkThread.Abort a)
  137. {
  138. }
  139. finally
  140. {
  141. VFSManager.runInAWTThread(new Runnable()
  142. {
  143. public void run()
  144. {
  145. results.searchDone(rootSearchNode);
  146. if (lineRangeUp != 0 || lineRangeDown != 0) {
  147. // expand hyperrange result
  148. SwingUtilities.invokeLater(new Runnable()
  149. {
  150. public void run()
  151. {
  152. JTree tree = results.getTree();
  153. final int searchChildCount = rootSearchNode.getChildCount();
  154. if (searchChildCount != 0) {
  155. DefaultMutableTreeNode fileNode =
  156. (DefaultMutableTreeNode)rootSearchNode.getFirstChild();
  157. for(int j = 0; j < searchChildCount; j++)
  158. {
  159. //TreePath filePath = new TreePath(fileNode.getPath());
  160. //tree.expandPath(filePath);
  161. // check if the childs of a fileNode have children
  162. // ==> expand hyper range
  163. int fileChildCount = fileNode.getChildCount();
  164. if (fileChildCount != 0) {
  165. DefaultMutableTreeNode lineNode =
  166. (DefaultMutableTreeNode)fileNode.getFirstChild();
  167. for(int k = 0; k < fileChildCount; k++)
  168. {
  169. TreePath linePath = new TreePath(lineNode.getPath());
  170. tree.expandPath(linePath);
  171. lineNode = lineNode.getNextSibling();
  172. }
  173. }
  174. fileNode = fileNode.getNextSibling();
  175. }
  176. }
  177. // resultTree.scrollPathToVisible(
  178. // new TreePath(new Object[] {
  179. // resultTreeRoot,searchNode }));
  180. }
  181. });
  182. }
  183. }
  184. });
  185. }
  186. } //}}}
  187. //{{{ Private members
  188. //{{{ Instance variables
  189. private View view;
  190. private SearchMatcher matcher;
  191. private HyperSearchResults results;
  192. // private DefaultTreeModel resultTreeModel;
  193. // private DefaultMutableTreeNode resultTreeRoot;
  194. private DefaultMutableTreeNode rootSearchNode;
  195. private Selection[] selection;
  196. private String searchString;
  197. private int lineRangeUp, lineRangeDown;
  198. //}}}
  199. //{{{ searchInSelection() method
  200. private int searchInSelection(Buffer buffer) throws Exception
  201. {
  202. setAbortable(false);
  203. int resultCount = 0;
  204. try
  205. {
  206. buffer.readLock();
  207. //final DefaultMutableTreeNode bufferNode = new DefaultMutableTreeNode(
  208. // buffer.getPath());
  209. for(int i = 0; i < selection.length; i++)
  210. {
  211. Selection s = selection[i];
  212. if(s instanceof Selection.Rect)
  213. {
  214. for(int j = s.getStartLine();
  215. j <= s.getEndLine(); j++)
  216. {
  217. resultCount += doHyperSearch(buffer,
  218. s.getStart(buffer,j),
  219. s.getEnd(buffer,j));
  220. }
  221. }
  222. else
  223. {
  224. resultCount += doHyperSearch(buffer,
  225. s.getStart(),s.getEnd());
  226. }
  227. }
  228. }
  229. finally
  230. {
  231. buffer.readUnlock();
  232. }
  233. setAbortable(true);
  234. return resultCount;
  235. } //}}}
  236. //{{{ doHyperSearch() method
  237. private int doHyperSearch(Buffer buffer)
  238. throws Exception
  239. {
  240. return doHyperSearch(buffer, 0, buffer.getLength());
  241. } //}}}
  242. //{{{ doHyperSearch() method
  243. private int doHyperSearch(Buffer buffer, int start, int end)
  244. throws Exception
  245. {
  246. setAbortable(false);
  247. final DefaultMutableTreeNode bufferNode = new DefaultMutableTreeNode(
  248. //buffer.getPath());
  249. new HyperSearchPath(buffer, 0, 0, 0));
  250. int resultCount = doHyperSearch(buffer,start,end,bufferNode);
  251. if(resultCount != 0)
  252. {
  253. // resultTreeRoot.insert(bufferNode,resultTreeRoot.getChildCount());
  254. //
  255. // SwingUtilities.invokeLater(new Runnable()
  256. // {
  257. // public void run()
  258. // {
  259. // resultTreeModel.reload(resultTreeRoot);
  260. // }
  261. // });
  262. // }
  263. rootSearchNode.insert(bufferNode,rootSearchNode.getChildCount());
  264. }
  265. setAbortable(true);
  266. return resultCount;
  267. } //}}}
  268. //{{{ doHyperSearch() method
  269. private int doHyperSearch(Buffer buffer, int start, int end,
  270. DefaultMutableTreeNode bufferNode)
  271. {
  272. int resultCount = 0;
  273. try
  274. {
  275. buffer.readLock();
  276. boolean endOfLine = (buffer.getLineEndOffset(
  277. buffer.getLineOfOffset(end)) - 1 == end);
  278. Segment text = new Segment();
  279. int offset = start;
  280. int line = -1;
  281. loop: for(int counter = 0; ; counter++)
  282. {
  283. boolean startOfLine = (buffer.getLineStartOffset(
  284. buffer.getLineOfOffset(offset)) == offset);
  285. buffer.getText(offset,end - offset,text);
  286. int[] match = matcher.nextMatch(
  287. new CharIndexedSegment(text,false),
  288. startOfLine,endOfLine,counter == 0,
  289. false);
  290. if(match == null)
  291. break loop;
  292. int matchStart = offset + match[0];
  293. int matchEnd = offset + match[1];
  294. offset += match[1];
  295. // Log.log(Log.DEBUG, BeanShell.class,"tp275: matchStart = "+matchStart+", matchEnd = "+matchEnd+", offset = "+offset+
  296. // " ,found: "+buffer.getText(matchStart, matchEnd - matchStart));
  297. // rwchg: check extended parameters
  298. if (!XSearchAndReplace.checkXSearchParameters(view.getTextArea(), buffer, matchStart, matchEnd, true)) {
  299. // Log.log(Log.DEBUG, BeanShell.class,"tp281: match invalid");
  300. // this match was not valid: skip
  301. continue loop;
  302. }
  303. resultCount++; // this line has been moved: count match, even if on same line
  304. int newLine = buffer.getLineOfOffset(offset);
  305. if(line >= newLine+lineRangeDown)
  306. {
  307. // already had a result on this
  308. // line, skip
  309. continue loop;
  310. }
  311. if(lineRangeUp > 0 || lineRangeDown > 0) {
  312. //Log.log(Log.DEBUG, BeanShell.class,"HyperSearchRequest.330: lineRangeUp = "+lineRangeUp+", lineRangeDown = "+lineRangeDown);
  313. // create subnode to separate hyper ranges
  314. DefaultMutableTreeNode subNode = new DefaultMutableTreeNode(
  315. new HyperSearchResult(buffer,newLine,
  316. matchStart,matchEnd));
  317. bufferNode.add(subNode);
  318. for (int i = newLine-lineRangeUp;
  319. i<=newLine+lineRangeDown && i < buffer.getLineCount(); i++) {
  320. if (i < 0) i = 0; // cannot display before startOfBuffer
  321. /* if (i > line) { // skip if already displayed !?
  322. int startOfI = buffer.getLineStartOffset(i);
  323. int endOfI = buffer.getLineEndOffset(i);
  324. bufferNode.add(new DefaultMutableTreeNode(
  325. new HyperSearchResult(
  326. buffer,i,
  327. i == newLine ? matchStart : startOfI,
  328. i == newLine ? matchEnd : endOfI
  329. )
  330. ,false));
  331. }
  332. */
  333. int startOfI = buffer.getLineStartOffset(i);
  334. int endOfI = buffer.getLineEndOffset(i);
  335. subNode.add(new DefaultMutableTreeNode(
  336. new HyperSearchResult(
  337. buffer,i,
  338. i == newLine ? matchStart : startOfI,
  339. i == newLine ? matchEnd : endOfI
  340. )
  341. ,false));
  342. }
  343. }
  344. else {
  345. bufferNode.add(new DefaultMutableTreeNode(
  346. new HyperSearchResult(buffer,newLine,
  347. matchStart,matchEnd),false));
  348. }
  349. line = newLine+lineRangeDown;
  350. }
  351. }
  352. finally
  353. {
  354. buffer.readUnlock();
  355. }
  356. return resultCount;
  357. } //}}}
  358. //}}}
  359. }