PageRenderTime 54ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/bundles/plugins-trunk/LucenePlugin/src/gatchan/jedit/lucene/MarkerListQueryProcessor.java

#
Java | 196 lines | 153 code | 11 blank | 32 comment | 23 complexity | f495d55435fd22fc2ec4ad070ad55764 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * :tabSize=8:indentSize=8:noTabs=false:
  3. * :folding=explicit:collapseFolds=1:
  4. *
  5. * Copyright (C) 2009, 2011 Matthieu Casanova
  6. * Copyright (C) 2009, 2011 Shlomy Reinstein
  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. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20. */
  21. package gatchan.jedit.lucene;
  22. import java.io.*;
  23. import java.util.ArrayList;
  24. import java.util.Collections;
  25. import java.util.List;
  26. import marker.FileMarker;
  27. import org.apache.lucene.search.Query;
  28. import org.apache.lucene.search.highlight.Highlighter;
  29. import org.apache.lucene.search.highlight.QueryScorer;
  30. import org.apache.lucene.search.highlight.Formatter;
  31. import org.apache.lucene.analysis.TokenStream;
  32. import org.gjt.sp.jedit.Buffer;
  33. import org.gjt.sp.jedit.View;
  34. import org.gjt.sp.jedit.jEdit;
  35. import org.gjt.sp.jedit.io.VFS;
  36. import org.gjt.sp.jedit.io.VFSFile;
  37. import org.gjt.sp.jedit.io.VFSManager;
  38. import org.gjt.sp.jedit.syntax.DefaultTokenHandler;
  39. import org.gjt.sp.jedit.syntax.Token;
  40. import org.gjt.sp.util.IOUtilities;
  41. import org.gjt.sp.util.IntegerArray;
  42. import org.gjt.sp.util.Log;
  43. /*
  44. * A query result processor that collects the lines containing results,
  45. * using the highlighter to find matches within the files.
  46. */
  47. public class MarkerListQueryProcessor implements ResultProcessor
  48. {
  49. private final Index index;
  50. private final List<Object> results;
  51. private final int max;
  52. private final TokenFilter tokenFilter;
  53. public MarkerListQueryProcessor(Index index, List<Object> results, int max, TokenFilter tokenFilter)
  54. {
  55. this.index = index;
  56. this.results = results;
  57. this.max = max;
  58. this.tokenFilter = tokenFilter;
  59. }
  60. @Override
  61. public boolean process(Query query, float score, Result result)
  62. {
  63. String s = result.getPath();
  64. addLinesMatching(query, s, max - results.size());
  65. return results.size() < max;
  66. }
  67. private boolean isFiltered(int offsetInLine, String file, int line, String lineText, int lineStart)
  68. {
  69. if (! tokenFilter.isFiltering())
  70. return false;
  71. Buffer b = jEdit.openTemporary(jEdit.getActiveView(), new File(file).getParent(), file, false);
  72. b.setMode();
  73. // Mark the tokens on the line, to filter out comments and strings
  74. DefaultTokenHandler tokenHandler = new DefaultTokenHandler();
  75. b.markTokens(line, tokenHandler);
  76. Token token = tokenHandler.getTokens();
  77. int start = lineStart;
  78. int indexPos = lineStart + offsetInLine;
  79. while(token.id != Token.END)
  80. {
  81. int next = start + token.length;
  82. if (start <= indexPos && next > indexPos)
  83. break;
  84. start = next;
  85. token = token.next;
  86. }
  87. return tokenFilter.isFiltered(token);
  88. }
  89. private void addLinesMatching(Query query, String file, int max)
  90. {
  91. IntegerArray positions = new IntegerArray(30);
  92. Formatter sf = new SearchFormatter(positions, max);
  93. QueryScorer scorer = new QueryScorer(query);
  94. StringBuilder sb = new StringBuilder();
  95. List<Integer> lineStart = new ArrayList<Integer>(500);
  96. BufferedReader br = null;
  97. try
  98. {
  99. br = getReader(file);
  100. if (br == null)
  101. {
  102. Log.log(Log.WARNING, this, "Cannot read file " + file +
  103. " maybe it doesn't exist anymore");
  104. return;
  105. }
  106. String s;
  107. char sep = '\n';
  108. while ((s = br.readLine()) != null)
  109. {
  110. if (sb.length() > 0)
  111. sb.append(sep);
  112. lineStart.add(sb.length());
  113. sb.append(s);
  114. }
  115. Highlighter h = new Highlighter(sf, scorer);
  116. h.setMaxDocCharsToAnalyze(sb.length());
  117. String text = sb.toString();
  118. TokenStream tokenStream = index.getAnalyzer().tokenStream("field", new StringReader(text));
  119. h.getBestFragments(tokenStream, text, 0);
  120. }
  121. catch (Exception e)
  122. {
  123. Log.log(Log.ERROR, this, e);
  124. }
  125. finally
  126. {
  127. IOUtilities.closeQuietly(br);
  128. }
  129. for (int i = 0; i < positions.getSize(); i += 2)
  130. {
  131. int tokenStart = positions.get(i), tokenEnd = positions.get(i + 1);
  132. int start = tokenStart, stop = tokenEnd;
  133. // Find beginning and end of line
  134. while ((start >= 0) && (sb.charAt(start) != '\n'))
  135. start--;
  136. start++;
  137. while ((stop < sb.length()) && (sb.charAt(stop) != '\n'))
  138. stop++;
  139. String lineText = sb.substring(start, stop);
  140. int line = Collections.binarySearch(lineStart, tokenStart);
  141. if (line < 0)
  142. line = -line - 2;
  143. int startOffset = tokenStart - start;
  144. if (isFiltered(startOffset, file, line, lineText, start))
  145. continue;
  146. FileMarker marker = new FileMarker(file, line, lineText);
  147. int endOffset = startOffset + tokenEnd - tokenStart;
  148. if (endOffset > lineText.length())
  149. endOffset = lineText.length();
  150. marker.addSelection(marker.new Selection(startOffset,
  151. startOffset + tokenEnd - tokenStart));
  152. results.add(marker);
  153. }
  154. }
  155. /**
  156. * Return a reader for the given file
  157. * @param file the file
  158. * @return a reader or null of the reader cannot be opened or if
  159. * the file do not exist anymore
  160. */
  161. private static BufferedReader getReader(String file)
  162. {
  163. VFS vfs = VFSManager.getVFSForPath(file);
  164. View view = jEdit.getActiveView();
  165. Object session = vfs.createVFSSession(file, view);
  166. BufferedReader reader = null;
  167. try
  168. {
  169. VFSFile vfsFile = vfs._getFile(session, file, view);
  170. if (vfsFile != null)
  171. {
  172. InputStream inputStream = vfs._createInputStream(session,
  173. vfsFile.getPath(), false, view);
  174. if (inputStream != null)
  175. reader = new BufferedReader(new InputStreamReader(
  176. inputStream));
  177. }
  178. }
  179. catch (IOException e)
  180. {
  181. Log.log(Log.ERROR, MarkerListQueryProcessor.class, e);
  182. }
  183. return reader;
  184. }
  185. }