import java.io.File;\r
import java.io.IOException;\r
import java.io.InputStream;\r
+import java.text.MessageFormat;\r
import java.text.ParseException;\r
import java.util.ArrayList;\r
import java.util.Arrays;\r
Document doc = searcher.doc(docId);\r
SearchResult result = createSearchResult(doc, hits[i].score);\r
String content = doc.get(FIELD_CONTENT);\r
- result.fragment = getHighlightedFragment(analyzer, query, content);\r
+ \r
+ result.fragment = getHighlightedFragment(analyzer, query, content, result);\r
results.add(result);\r
}\r
} catch (Exception e) {\r
}\r
\r
private static String getHighlightedFragment(Analyzer analyzer, Query query,\r
- String content) throws IOException, InvalidTokenOffsetsException {\r
- content = content == null ? "":StringUtils.escapeForHtml(content, false); \r
+ String content, SearchResult result) throws IOException, InvalidTokenOffsetsException {\r
+ content = content == null ? "":StringUtils.escapeForHtml(content, false);\r
+ \r
TokenStream stream = TokenSources.getTokenStream("content", content, analyzer);\r
QueryScorer scorer = new QueryScorer(query, "content");\r
- Fragmenter fragmenter = new SimpleSpanFragmenter(scorer, 150);\r
-\r
- SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<span class=\"highlight\">", "</span>");\r
- Highlighter highlighter = new Highlighter(formatter, scorer);\r
+ Fragmenter fragmenter;\r
\r
+ if (ObjectType.commit == result.type) {\r
+ fragmenter = new SimpleSpanFragmenter(scorer, 1024); \r
+ } else {\r
+ fragmenter = new SimpleSpanFragmenter(scorer, 150);\r
+ }\r
+\r
+ // use an artificial delimiter for the token\r
+ String termTag = "<!--[";\r
+ String termTagEnd = "]-->";\r
+ SimpleHTMLFormatter formatter = new SimpleHTMLFormatter(termTag, termTagEnd);\r
+ Highlighter highlighter = new Highlighter(formatter, scorer); \r
highlighter.setTextFragmenter(fragmenter);\r
+ \r
String [] fragments = highlighter.getBestFragments(stream, content, 5);\r
if (ArrayUtils.isEmpty(fragments)) {\r
- return content;\r
- }\r
- if (fragments.length == 1) {\r
- return "<pre>" + fragments[0] + "</pre>";\r
+ if (ObjectType.blob == result.type) {\r
+ return "";\r
+ }\r
+ return "<pre class=\"text\">" + content + "</pre>";\r
}\r
StringBuilder sb = new StringBuilder();\r
for (int i = 0, len = fragments.length; i < len; i++) {\r
- String fragment = fragments[i].trim(); \r
- sb.append("<pre>");\r
- sb.append(fragment);\r
+ String fragment = fragments[i];\r
+ \r
+ // resurrect the raw fragment from removing the artificial delimiters\r
+ String raw = fragment.replace(termTag, "").replace(termTagEnd, ""); \r
+ sb.append(getPreTag(result, raw, content));\r
+ \r
+ // replace the artificial delimiter with html tags\r
+ String html = fragment.replace(termTag, "<span class=\"highlight\">").replace(termTagEnd, "</span>");\r
+ sb.append(html);\r
sb.append("</pre>");\r
if (i < len - 1) {\r
sb.append("<span class=\"ellipses\">...</span><br/>");\r
}\r
return sb.toString();\r
}\r
+ \r
+ private static String getPreTag(SearchResult result, String fragment, String content) {\r
+ String pre = "<pre class=\"text\">";\r
+ if (ObjectType.blob == result.type) {\r
+ int line = StringUtils.countLines(content.substring(0, content.indexOf(fragment))); \r
+ int lastDot = result.path.lastIndexOf('.');\r
+ if (lastDot > -1) {\r
+ String ext = result.path.substring(lastDot + 1).toLowerCase();\r
+ pre = MessageFormat.format("<pre class=\"prettyprint linenums:{0,number,0} lang-{1}\">", line, ext); \r
+ } else {\r
+ pre = MessageFormat.format("<pre class=\"prettyprint linenums:{0,number,0}\">", line);\r
+ }\r
+ }\r
+ return pre;\r
+ }\r
\r
/**\r
* Close all the index writers and searchers\r
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd" \r
xml:lang="en" \r
lang="en"> \r
-<body onload="document.getElementById('fragment').focus();">\r
+\r
+<!-- contribute google-code-prettify resources to the page header -->\r
+<wicket:head>\r
+ <wicket:link>\r
+ <link href="prettify/prettify.css" type="text/css" rel="stylesheet" />\r
+ <script type="text/javascript" src="prettify/prettify.js"></script>\r
+ </wicket:link>\r
+</wicket:head>\r
+ \r
<wicket:extend>\r
+<body onload="document.getElementById('query').focus(); prettyPrint();">\r
<div class="pageTitle">\r
<h2><wicket:message key="gb.search"></wicket:message></h2>\r
</div>\r
<div class="span9">\r
<div>\r
<h3><wicket:message key="gb.query"></wicket:message></h3>\r
- <input class="span8" wicket:id="query" placeholder="enter search text"></input>\r
+ <input class="span8" id="query" wicket:id="query" placeholder="enter search text"></input>\r
<button class="btn btn-primary" type="submit" value="Search"><wicket:message key="gb.search"></wicket:message></button>\r
</div>\r
<div style="margin-top:10px;">\r
<div><i wicket:id="type"></i><span class="summary" wicket:id="summary"></span></div>\r
<div class="body">\r
<div class="fragment" wicket:id="fragment"></div>\r
- <span class="author" wicket:id="author"></span> committed to <span class="repository" wicket:id="repository"></span>:<span class="branch" wicket:id="branch"></span><br/>\r
- <span class="date" wicket:id="date"></span>\r
- <hr/>\r
+ <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>\r
+ <span class="repository" wicket:id="repository"></span>:<span class="branch" wicket:id="branch"></span> \r
</div>\r
</div>\r
</div>\r
-</wicket:extend>\r
</body>\r
+</wicket:extend>\r
</html>
\ No newline at end of file
\r
import com.gitblit.Constants.SearchType;\r
import com.gitblit.GitBlit;\r
+import com.gitblit.models.RepositoryModel;\r
import com.gitblit.models.SearchResult;\r
+import com.gitblit.models.UserModel;\r
import com.gitblit.utils.ArrayUtils;\r
import com.gitblit.utils.LuceneUtils;\r
import com.gitblit.utils.StringUtils;\r
+import com.gitblit.wicket.GitBlitWebSession;\r
+import com.gitblit.wicket.StringChoiceRenderer;\r
import com.gitblit.wicket.WicketUtils;\r
import com.gitblit.wicket.panels.LinkPanel;\r
\r
setResponsePage(LucenePage.class, params);\r
}\r
};\r
- ListMultipleChoice<String> selections = new ListMultipleChoice<String>("repositories", repositoriesModel, GitBlit.self().getRepositoryList());\r
+ \r
+ UserModel user = GitBlitWebSession.get().getUser();\r
+ List<String> availableRepositories = new ArrayList<String>();\r
+ for (RepositoryModel model : GitBlit.self().getRepositoryModels(user)) {\r
+ availableRepositories.add(model.name);\r
+ }\r
+ ListMultipleChoice<String> selections = new ListMultipleChoice<String>("repositories", \r
+ repositoriesModel, availableRepositories, new StringChoiceRenderer());\r
selections.setMaxRows(10);\r
form.add(selections);\r
form.add(new TextField<String>("query", queryModel));\r
item.add(new LinkPanel("repository", null, sr.repository, SummaryPage.class, WicketUtils.newRepositoryParameter(sr.repository)));\r
item.add(new LinkPanel("branch", "branch", StringUtils.getRelativePath(Constants.R_HEADS, sr.branch), LogPage.class, WicketUtils.newObjectParameter(sr.repository, sr.branch)));\r
item.add(new Label("author", sr.author));\r
- item.add(WicketUtils.createTimestampLabel("date", sr.date, getTimeZone()));\r
+ item.add(WicketUtils.createDatestampLabel("date", sr.date, getTimeZone()));\r
}\r
};\r
add(resultsView.setVisible(results.size() > 0));\r