resources/gitblit.css | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/utils/LuceneUtils.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/utils/StringUtils.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/pages/LucenePage.html | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/pages/LucenePage.java | ●●●●● patch | view | raw | blame | history |
resources/gitblit.css
@@ -267,7 +267,7 @@ } div.searchResult { padding:5px; padding: 10px 5px 10px 5px; } div.searchResult .summary { @@ -300,18 +300,24 @@ 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 { src/com/gitblit/utils/LuceneUtils.java
@@ -21,6 +21,7 @@ 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 @@ 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 @@ } 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 @@ } 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 src/com/gitblit/utils/StringUtils.java
@@ -485,4 +485,11 @@ } return value; } public static int countLines(String value) { if (isEmpty(value)) { return 0; } return value.split("\n").length; } } 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> src/com/gitblit/wicket/pages/LucenePage.java
@@ -32,10 +32,14 @@ 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 @@ 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 @@ 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));