summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Moger <james.moger@gitblit.com>2012-03-14 16:31:28 -0400
committerJames Moger <james.moger@gitblit.com>2012-03-14 16:31:28 -0400
commit6722961db100d58f8290d51768943fc6b416f7a9 (patch)
tree352c62494bb28e778a25e9739b732d419c44f2cc
parentd1c49a7dd7dc4dfd852fb2bca4533609432ea26a (diff)
downloadgitblit-6722961db100d58f8290d51768943fc6b416f7a9.tar.gz
gitblit-6722961db100d58f8290d51768943fc6b416f7a9.zip
A bunch more Lucene work
* Only list user-accessible repositories * Syntax-highlight matched blob fragments * Improve look and layout of search results
-rw-r--r--resources/gitblit.css24
-rw-r--r--src/com/gitblit/utils/LuceneUtils.java61
-rw-r--r--src/com/gitblit/utils/StringUtils.java7
-rw-r--r--src/com/gitblit/wicket/pages/LucenePage.html20
-rw-r--r--src/com/gitblit/wicket/pages/LucenePage.java15
5 files changed, 96 insertions, 31 deletions
diff --git a/resources/gitblit.css b/resources/gitblit.css
index 0e8e7532..0701a7cf 100644
--- a/resources/gitblit.css
+++ b/resources/gitblit.css
@@ -267,7 +267,7 @@ img.gravatar {
}
div.searchResult {
- padding:5px;
+ padding: 10px 5px 10px 5px;
}
div.searchResult .summary {
@@ -300,18 +300,24 @@ div.searchResult .highlight {
padding: 0 2px;
}
-div.searchResult .ellipses {
- font-family: sans-serif;
- font-size: 9px;
- font-weight: normal;
- background-color: #eee;
- border: 1px solid #ccc;
- padding: 0 3px;
- margin: 0px;
+div.searchResult .ellipses {
+ padding-left:25px;
+ color: #aaa;
}
div.searchResult pre {
margin: 1px 0px;
+ border: 0px;
+}
+
+div.searchResult .text {
+ border-left: 5px solid #EEEEEE;
+
+ padding: 0 0 0 15px;
+}
+
+div.searchResult ol {
+ margin-bottom: 0px !important;
}
div.header, div.commitHeader, table.repositories th {
diff --git a/src/com/gitblit/utils/LuceneUtils.java b/src/com/gitblit/utils/LuceneUtils.java
index 1c24f287..ca1bbf1d 100644
--- a/src/com/gitblit/utils/LuceneUtils.java
+++ b/src/com/gitblit/utils/LuceneUtils.java
@@ -21,6 +21,7 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.text.MessageFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -903,7 +904,8 @@ public class LuceneUtils {
Document doc = searcher.doc(docId);
SearchResult result = createSearchResult(doc, hits[i].score);
String content = doc.get(FIELD_CONTENT);
- result.fragment = getHighlightedFragment(analyzer, query, content);
+
+ result.fragment = getHighlightedFragment(analyzer, query, content, result);
results.add(result);
}
} catch (Exception e) {
@@ -913,28 +915,44 @@ public class LuceneUtils {
}
private static String getHighlightedFragment(Analyzer analyzer, Query query,
- String content) throws IOException, InvalidTokenOffsetsException {
- content = content == null ? "":StringUtils.escapeForHtml(content, false);
+ String content, SearchResult result) throws IOException, InvalidTokenOffsetsException {
+ content = content == null ? "":StringUtils.escapeForHtml(content, false);
+
TokenStream stream = TokenSources.getTokenStream("content", content, analyzer);
QueryScorer scorer = new QueryScorer(query, "content");
- Fragmenter fragmenter = new SimpleSpanFragmenter(scorer, 150);
-
- SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<span class=\"highlight\">", "</span>");
- Highlighter highlighter = new Highlighter(formatter, scorer);
+ Fragmenter fragmenter;
+ if (ObjectType.commit == result.type) {
+ fragmenter = new SimpleSpanFragmenter(scorer, 1024);
+ } else {
+ fragmenter = new SimpleSpanFragmenter(scorer, 150);
+ }
+
+ // use an artificial delimiter for the token
+ String termTag = "<!--[";
+ String termTagEnd = "]-->";
+ SimpleHTMLFormatter formatter = new SimpleHTMLFormatter(termTag, termTagEnd);
+ Highlighter highlighter = new Highlighter(formatter, scorer);
highlighter.setTextFragmenter(fragmenter);
+
String [] fragments = highlighter.getBestFragments(stream, content, 5);
if (ArrayUtils.isEmpty(fragments)) {
- return content;
- }
- if (fragments.length == 1) {
- return "<pre>" + fragments[0] + "</pre>";
+ if (ObjectType.blob == result.type) {
+ return "";
+ }
+ return "<pre class=\"text\">" + content + "</pre>";
}
StringBuilder sb = new StringBuilder();
for (int i = 0, len = fragments.length; i < len; i++) {
- String fragment = fragments[i].trim();
- sb.append("<pre>");
- sb.append(fragment);
+ String fragment = fragments[i];
+
+ // resurrect the raw fragment from removing the artificial delimiters
+ String raw = fragment.replace(termTag, "").replace(termTagEnd, "");
+ sb.append(getPreTag(result, raw, content));
+
+ // replace the artificial delimiter with html tags
+ String html = fragment.replace(termTag, "<span class=\"highlight\">").replace(termTagEnd, "</span>");
+ sb.append(html);
sb.append("</pre>");
if (i < len - 1) {
sb.append("<span class=\"ellipses\">...</span><br/>");
@@ -942,6 +960,21 @@ public class LuceneUtils {
}
return sb.toString();
}
+
+ private static String getPreTag(SearchResult result, String fragment, String content) {
+ String pre = "<pre class=\"text\">";
+ if (ObjectType.blob == result.type) {
+ int line = StringUtils.countLines(content.substring(0, content.indexOf(fragment)));
+ int lastDot = result.path.lastIndexOf('.');
+ if (lastDot > -1) {
+ String ext = result.path.substring(lastDot + 1).toLowerCase();
+ pre = MessageFormat.format("<pre class=\"prettyprint linenums:{0,number,0} lang-{1}\">", line, ext);
+ } else {
+ pre = MessageFormat.format("<pre class=\"prettyprint linenums:{0,number,0}\">", line);
+ }
+ }
+ return pre;
+ }
/**
* Close all the index writers and searchers
diff --git a/src/com/gitblit/utils/StringUtils.java b/src/com/gitblit/utils/StringUtils.java
index a465e0d7..adede1fa 100644
--- a/src/com/gitblit/utils/StringUtils.java
+++ b/src/com/gitblit/utils/StringUtils.java
@@ -485,4 +485,11 @@ public class StringUtils {
}
return value;
}
+
+ public static int countLines(String value) {
+ if (isEmpty(value)) {
+ return 0;
+ }
+ return value.split("\n").length;
+ }
} \ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/LucenePage.html b/src/com/gitblit/wicket/pages/LucenePage.html
index 0abe3d15..e6a9b932 100644
--- a/src/com/gitblit/wicket/pages/LucenePage.html
+++ b/src/com/gitblit/wicket/pages/LucenePage.html
@@ -3,8 +3,17 @@
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"
xml:lang="en"
lang="en">
-<body onload="document.getElementById('fragment').focus();">
+
+<!-- contribute google-code-prettify resources to the page header -->
+<wicket:head>
+ <wicket:link>
+ <link href="prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="prettify/prettify.js"></script>
+ </wicket:link>
+</wicket:head>
+
<wicket:extend>
+<body onload="document.getElementById('query').focus(); prettyPrint();">
<div class="pageTitle">
<h2><wicket:message key="gb.search"></wicket:message></h2>
</div>
@@ -17,7 +26,7 @@
<div class="span9">
<div>
<h3><wicket:message key="gb.query"></wicket:message></h3>
- <input class="span8" wicket:id="query" placeholder="enter search text"></input>
+ <input class="span8" id="query" wicket:id="query" placeholder="enter search text"></input>
<button class="btn btn-primary" type="submit" value="Search"><wicket:message key="gb.search"></wicket:message></button>
</div>
<div style="margin-top:10px;">
@@ -45,12 +54,11 @@
<div><i wicket:id="type"></i><span class="summary" wicket:id="summary"></span></div>
<div class="body">
<div class="fragment" wicket:id="fragment"></div>
- <span class="author" wicket:id="author"></span> committed to <span class="repository" wicket:id="repository"></span>:<span class="branch" wicket:id="branch"></span><br/>
- <span class="date" wicket:id="date"></span>
- <hr/>
+ <div><span class="author" wicket:id="author"></span> <span class="date" ><wicket:message key="gb.authored"></wicket:message> <span class="date" wicket:id="date"></span></span></div>
+ <span class="repository" wicket:id="repository"></span>:<span class="branch" wicket:id="branch"></span>
</div>
</div>
</div>
-</wicket:extend>
</body>
+</wicket:extend>
</html> \ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/LucenePage.java b/src/com/gitblit/wicket/pages/LucenePage.java
index dc740125..39d33b34 100644
--- a/src/com/gitblit/wicket/pages/LucenePage.java
+++ b/src/com/gitblit/wicket/pages/LucenePage.java
@@ -32,10 +32,14 @@ import org.eclipse.jgit.lib.Repository;
import com.gitblit.Constants.SearchType;
import com.gitblit.GitBlit;
+import com.gitblit.models.RepositoryModel;
import com.gitblit.models.SearchResult;
+import com.gitblit.models.UserModel;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.LuceneUtils;
import com.gitblit.utils.StringUtils;
+import com.gitblit.wicket.GitBlitWebSession;
+import com.gitblit.wicket.StringChoiceRenderer;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.LinkPanel;
@@ -110,7 +114,14 @@ public class LucenePage extends RootPage {
setResponsePage(LucenePage.class, params);
}
};
- ListMultipleChoice<String> selections = new ListMultipleChoice<String>("repositories", repositoriesModel, GitBlit.self().getRepositoryList());
+
+ UserModel user = GitBlitWebSession.get().getUser();
+ List<String> availableRepositories = new ArrayList<String>();
+ for (RepositoryModel model : GitBlit.self().getRepositoryModels(user)) {
+ availableRepositories.add(model.name);
+ }
+ ListMultipleChoice<String> selections = new ListMultipleChoice<String>("repositories",
+ repositoriesModel, availableRepositories, new StringChoiceRenderer());
selections.setMaxRows(10);
form.add(selections);
form.add(new TextField<String>("query", queryModel));
@@ -153,7 +164,7 @@ public class LucenePage extends RootPage {
item.add(new LinkPanel("repository", null, sr.repository, SummaryPage.class, WicketUtils.newRepositoryParameter(sr.repository)));
item.add(new LinkPanel("branch", "branch", StringUtils.getRelativePath(Constants.R_HEADS, sr.branch), LogPage.class, WicketUtils.newObjectParameter(sr.repository, sr.branch)));
item.add(new Label("author", sr.author));
- item.add(WicketUtils.createTimestampLabel("date", sr.date, getTimeZone()));
+ item.add(WicketUtils.createDatestampLabel("date", sr.date, getTimeZone()));
}
};
add(resultsView.setVisible(results.size() > 0));