James Moger
2012-08-01 65f55eee1c41a9cdfec96dc4310efcc6e57df97f
src/com/gitblit/LuceneExecutor.java
@@ -73,6 +73,7 @@
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
@@ -104,7 +105,7 @@
public class LuceneExecutor implements Runnable {
   
      
   private static final int INDEX_VERSION = 2;
   private static final int INDEX_VERSION = 4;
   private static final String FIELD_OBJECT_TYPE = "type";
   private static final String FIELD_ISSUE = "issue";
@@ -300,7 +301,6 @@
         throw new RuntimeException(e);
      }
   }
   
   /**
    * Returns the author for the commit, if this information is available.
@@ -412,7 +412,8 @@
      if (!deleteIndex(model.name)) {
         return result;
      }
      try {
      try {
         String [] encodings = storedSettings.getStrings(Keys.web.blobEncodings).toArray(new String[0]);
         FileBasedConfig config = getConfig(repository);
         Set<String> indexedCommits = new TreeSet<String>();
         IndexWriter writer = getIndexWriter(model.name);
@@ -562,7 +563,7 @@
                     }
                     in.close();
                     byte[] content = os.toByteArray();
                     String str = new String(content, Constants.CHARACTER_ENCODING);
                     String str = StringUtils.decodeString(content, encodings);
                     doc.add(new Field(FIELD_CONTENT, str, Store.YES, Index.ANALYZED));
                     os.reset();
                  }                     
@@ -641,6 +642,7 @@
         String branch, RevCommit commit) {
      IndexResult result = new IndexResult();
      try {
         String [] encodings = storedSettings.getStrings(Keys.web.blobEncodings).toArray(new String[0]);
         List<PathChangeModel> changedPaths = JGitUtils.getFilesInCommit(repository, commit);
         String revDate = DateTools.timeToString(commit.getCommitTime() * 1000L,
               Resolution.MINUTE);
@@ -673,7 +675,7 @@
               if (StringUtils.isEmpty(ext) || !excludedExtensions.contains(ext)) {
                  // read the blob content
                  String str = JGitUtils.getStringContent(repository, commit.getTree(),
                        path.path);
                        path.path, encodings);
                  doc.add(new Field(FIELD_CONTENT, str, Store.YES, Index.ANALYZED));
                  writer.addDocument(doc);
               }
@@ -726,8 +728,9 @@
    * @param repositoryName
    * @param issueId
    * @throws Exception
    * @return true, if deleted, false if no record was deleted
    */
   private void deleteIssue(String repositoryName, String issueId) throws Exception {
   private boolean deleteIssue(String repositoryName, String issueId) throws Exception {
      BooleanQuery query = new BooleanQuery();
      Term objectTerm = new Term(FIELD_OBJECT_TYPE, SearchObjectType.issue.name());
      query.add(new TermQuery(objectTerm), Occur.MUST);
@@ -735,8 +738,17 @@
      query.add(new TermQuery(issueidTerm), Occur.MUST);
      
      IndexWriter writer = getIndexWriter(repositoryName);
      int numDocsBefore = writer.numDocs();
      writer.deleteDocuments(query);
      writer.commit();
      int numDocsAfter = writer.numDocs();
      if (numDocsBefore == numDocsAfter) {
         logger.debug(MessageFormat.format("no records found to delete {0}", query.toString()));
         return false;
      } else {
         logger.debug(MessageFormat.format("deleted {0} records with {1}", numDocsBefore - numDocsAfter, query.toString()));
         return true;
      }
   }
   
   /**
@@ -746,19 +758,29 @@
    * @param branch
    * @param path
    * @throws Exception
    * @return true, if deleted, false if no record was deleted
    */
   private void deleteBlob(String repositoryName, String branch, String path) throws Exception {
      BooleanQuery query = new BooleanQuery();
      Term objectTerm = new Term(FIELD_OBJECT_TYPE, SearchObjectType.blob.name());
      query.add(new TermQuery(objectTerm), Occur.MUST);
      Term branchTerm = new Term(FIELD_BRANCH, branch);
      query.add(new TermQuery(branchTerm), Occur.MUST);
      Term pathTerm = new Term(FIELD_PATH, path);
      query.add(new TermQuery(pathTerm), Occur.MUST);
   public boolean deleteBlob(String repositoryName, String branch, String path) throws Exception {
      String pattern = MessageFormat.format("{0}:'{'0} AND {1}:\"'{'1'}'\" AND {2}:\"'{'2'}'\"", FIELD_OBJECT_TYPE, FIELD_BRANCH, FIELD_PATH);
      String q = MessageFormat.format(pattern, SearchObjectType.blob.name(), branch, path);
      
      BooleanQuery query = new BooleanQuery();
      StandardAnalyzer analyzer = new StandardAnalyzer(LUCENE_VERSION);
      QueryParser qp = new QueryParser(LUCENE_VERSION, FIELD_SUMMARY, analyzer);
      query.add(qp.parse(q), Occur.MUST);
      IndexWriter writer = getIndexWriter(repositoryName);
      writer.deleteDocuments(query);
      int numDocsBefore = writer.numDocs();
      writer.deleteDocuments(query);
      writer.commit();
      int numDocsAfter = writer.numDocs();
      if (numDocsBefore == numDocsAfter) {
         logger.debug(MessageFormat.format("no records found to delete {0}", query.toString()));
         return false;
      } else {
         logger.debug(MessageFormat.format("deleted {0} records with {1}", numDocsBefore - numDocsAfter, query.toString()));
         return true;
      }
   }
   /**
@@ -879,7 +901,9 @@
                  IssueModel issue = IssueUtils.getIssue(repository, issueId);
                  if (issue == null) {
                     // issue was deleted, remove from index
                     deleteIssue(model.name, issueId);
                     if (!deleteIssue(model.name, issueId)) {
                        logger.error(MessageFormat.format("Failed to delete issue {0} from Lucene index!", issueId));
                     }
                  } else {
                     // issue was updated
                     index(model.name, issue);
@@ -1042,8 +1066,8 @@
    * @throws IOException
    */
   private IndexWriter getIndexWriter(String repository) throws IOException {
      IndexWriter indexWriter = writers.get(repository);
      File repositoryFolder = new File(repositoriesFolder, repository);
      IndexWriter indexWriter = writers.get(repository);
      File repositoryFolder = FileKey.resolve(new File(repositoriesFolder, repository), FS.DETECTED);
      File indexFolder = new File(repositoryFolder, LUCENE_DIR);
      Directory directory = FSDirectory.open(indexFolder);      
@@ -1117,7 +1141,7 @@
         qp = new QueryParser(LUCENE_VERSION, FIELD_CONTENT, analyzer);
         qp.setAllowLeadingWildcard(true);
         query.add(qp.parse(text), Occur.SHOULD);
         IndexSearcher searcher;
         if (repositories.length == 1) {
            // single repository search
@@ -1133,7 +1157,10 @@
            MultiSourceReader reader = new MultiSourceReader(rdrs);
            searcher = new IndexSearcher(reader);
         }
         Query rewrittenQuery = searcher.rewrite(query);
         logger.debug(rewrittenQuery.toString());
         TopScoreDocCollector collector = TopScoreDocCollector.create(5000, true);
         searcher.search(rewrittenQuery, collector);
         int offset = Math.max(0, (page - 1) * pageSize);
@@ -1203,7 +1230,13 @@
         return "<pre class=\"text\">" + StringUtils.escapeForHtml(fragment, true) + "</pre>";
      }
      
      int contentPos = 0;
      // make sure we have unique fragments
      Set<String> uniqueFragments = new LinkedHashSet<String>();
      for (String fragment : fragments) {
         uniqueFragments.add(fragment);
      }
      fragments = uniqueFragments.toArray(new String[uniqueFragments.size()]);
      StringBuilder sb = new StringBuilder();
      for (int i = 0, len = fragments.length; i < len; i++) {
         String fragment = fragments[i];
@@ -1213,7 +1246,7 @@
         String raw = fragment.replace(termTag, "").replace(termTagEnd, "");
         // determine position of the raw fragment in the content
         int pos = content.indexOf(raw, contentPos);
         int pos = content.indexOf(raw);
            
         // restore complete first line of fragment
         int c = pos;
@@ -1241,8 +1274,6 @@
            }
            tag = MessageFormat.format("<pre class=\"prettyprint linenums:{0,number,0}{1}\">", line, lang);
                        
            // update offset into content
            contentPos = pos + raw.length() + 1;
         }
         
         sb.append(tag);