]> source.dussan.org Git - gitblit.git/commitdiff
Restore the leading hunk of the first line of a fragment
authorJames Moger <james.moger@gitblit.com>
Thu, 22 Mar 2012 00:01:30 +0000 (20:01 -0400)
committerJames Moger <james.moger@gitblit.com>
Thu, 22 Mar 2012 00:01:30 +0000 (20:01 -0400)
Also correctly determine the line number of a fragment.

src/com/gitblit/LuceneExecutor.java
src/com/gitblit/utils/StringUtils.java

index 65e1b2be70162e86cc2684c32db8b870ca4b4eb7..12f230508295b1c743437011fa03d9237cb98e5f 100644 (file)
@@ -1114,17 +1114,14 @@ public class LuceneExecutor implements Runnable {
         */\r
        private String getHighlightedFragment(Analyzer analyzer, Query query,\r
                        String content, SearchResult result) throws IOException, InvalidTokenOffsetsException {\r
-               content = content == null ? "":StringUtils.escapeForHtml(content, false);\r
-               \r
+               if (content == null) {\r
+                       content = "";\r
+               }               \r
+\r
+               int fragmentLength = SearchObjectType.commit == result.type ? 512 : 150;\r
+\r
                QueryScorer scorer = new QueryScorer(query, "content");\r
-               Fragmenter fragmenter;\r
-               \r
-               // TODO improve the fragmenter - hopefully on line breaks\r
-               if (SearchObjectType.commit == result.type) {\r
-                       fragmenter = new SimpleSpanFragmenter(scorer, 1024); \r
-               } else {\r
-                       fragmenter = new SimpleSpanFragmenter(scorer, 150);\r
-               }\r
+               Fragmenter fragmenter = new SimpleSpanFragmenter(scorer, fragmentLength); \r
 \r
                // use an artificial delimiter for the token\r
                String termTag = "<!--[";\r
@@ -1132,22 +1129,64 @@ public class LuceneExecutor implements Runnable {
                SimpleHTMLFormatter formatter = new SimpleHTMLFormatter(termTag, termTagEnd);\r
                Highlighter highlighter = new Highlighter(formatter, scorer);           \r
                highlighter.setTextFragmenter(fragmenter);\r
-               \r
+\r
                String [] fragments = highlighter.getBestFragments(analyzer, "content", content, 3);\r
                if (ArrayUtils.isEmpty(fragments)) {\r
                        if (SearchObjectType.blob  == result.type) {\r
                                return "";\r
                        }\r
-                       return "<pre class=\"text\">" + content + "</pre>";\r
+                       // clip commit message\r
+                       String fragment = content;\r
+                       if (fragment.length() > fragmentLength) {\r
+                               fragment = fragment.substring(0, fragmentLength) + "...";\r
+                       }\r
+                       return "<pre class=\"text\">" + StringUtils.escapeForHtml(fragment, true) + "</pre>";\r
                }\r
+               \r
+               int contentPos = 0;\r
                StringBuilder sb = new StringBuilder();\r
                for (int i = 0, len = fragments.length; i < len; i++) {\r
                        String fragment = fragments[i];\r
-                       \r
+                       String tag = "<pre class=\"text\">";\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
+                       String raw = fragment.replace(termTag, "").replace(termTagEnd, "");\r
+\r
+                       // determine position of the raw fragment in the content\r
+                       int pos = content.indexOf(raw, contentPos);\r
+                               \r
+                       // restore complete first line of fragment\r
+                       int c = pos;\r
+                       while (c > 0) {\r
+                               c--;\r
+                               if (content.charAt(c) == '\n') {\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if (c > 0) {\r
+                               // inject leading chunk of first fragment line\r
+                               fragment = content.substring(c + 1, pos) + fragment;\r
+                       }\r
+                               \r
+                       if (SearchObjectType.blob  == result.type) {\r
+                               // count lines as offset into the content for this fragment\r
+                               int line = StringUtils.countLines(content.substring(0, pos));\r
+                               \r
+                               // create fragment tag with line number and language\r
+                               String lang = "";\r
+                               String ext = StringUtils.getFileExtension(result.path).toLowerCase();\r
+                               if (!StringUtils.isEmpty(ext)) {\r
+                                       // maintain leading space!\r
+                                       lang = " lang-" + ext;\r
+                               }\r
+                               tag = MessageFormat.format("<pre class=\"prettyprint linenums:{0,number,0}{1}\">", line, lang);\r
+                                                               \r
+                               // update offset into content                           \r
+                               contentPos = pos + raw.length() + 1;\r
+                       }\r
                        \r
+                       sb.append(tag);\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
@@ -1157,31 +1196,7 @@ public class LuceneExecutor implements Runnable {
                        }\r
                }\r
                return sb.toString();\r
-       }\r
-       \r
-       /**\r
-        * Returns the appropriate tag for a fragment. Commit messages are visually\r
-        * differentiated from blob fragments.\r
-        * \r
-        * @param result\r
-        * @param fragment\r
-        * @param content\r
-        * @return an html tag appropriate for the fragment\r
-        */\r
-       private String getPreTag(SearchResult result, String fragment, String content) {\r
-               String pre = "<pre class=\"text\">";\r
-               if (SearchObjectType.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
        /**\r
         * Simple class to track the results of an index update. \r
index adede1fa9dcd03dbbf345132ea3804b106cc140f..d6441829544fc802b6a24a843c48e03e0f1bb341 100644 (file)
@@ -479,6 +479,12 @@ public class StringUtils {
                return "#" + rs + gs + bs;\r
        }\r
        \r
+       /**\r
+        * Strips a trailing ".git" from the value.\r
+        * \r
+        * @param value\r
+        * @return a stripped value or the original value if .git is not found\r
+        */\r
        public static String stripDotGit(String value) {\r
                if (value.toLowerCase().endsWith(".git")) {\r
                        return value.substring(0, value.length() - 4);\r
@@ -486,10 +492,30 @@ public class StringUtils {
                return value;\r
        }\r
        \r
+       /**\r
+        * Count the number of lines in a string.\r
+        * \r
+        * @param value\r
+        * @return the line count\r
+        */\r
        public static int countLines(String value) {\r
                if (isEmpty(value)) {\r
                        return 0;\r
                }\r
                return value.split("\n").length;\r
        }\r
+       \r
+       /**\r
+        * Returns the file extension of a path.\r
+        * \r
+        * @param path\r
+        * @return a blank string or a file extension\r
+        */\r
+       public static String getFileExtension(String path) {\r
+               int lastDot = path.lastIndexOf('.');\r
+               if (lastDot > -1) {\r
+                       return path.substring(lastDot + 1);\r
+               }\r
+               return "";\r
+       }\r
 }
\ No newline at end of file