Skip to content

Commit eef29f7

Browse files
Lubos Koscotrondn
Lubos Kosco
authored andcommitted
Add annotation with revision description
(thanks to Emilio Monti - [email protected] for idea and original code - http://www.emilmont.net/doku.php?id=java:opengrok ) license stuff fixes only show line # button when showing a file
1 parent 2b02435 commit eef29f7

13 files changed

+235
-24
lines changed

LICENSE.txt

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ Unless otherwise noted, all files in this distribution are released
22
under the Common Development and Distribution License (CDDL),
33
Version 1.0 only. Exceptions are noted within the associated
44
source files.
5+
Where we have dual MIT and GPL license we choosen MIT license.
6+
File NOTICE.txt contains all notices from apache licensed software we distribute.
57

68
--------------------------------------------------------------------
79

NOTICE.txt

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
List of notices from Apache licensed software OpenGrok uses:
2+
3+
Apache Lucene
4+
Copyright 2006 The Apache Software Foundation
5+
6+
This product includes software developed by
7+
The Apache Software Foundation (http://www.apache.org/).
8+
9+
The snowball stemmers in
10+
contrib/snowball/src/java/net/sf/snowball
11+
were developed by Martin Porter and Richard Boulton.
12+
The full snowball package is available from
13+
http://snowball.tartarus.org/
14+
15+
The Arabic stemmer (contrib/analyzers) comes with a default
16+
stopword list that is BSD-licensed created by Jacques Savoy. The file resides in
17+
contrib/analyzers/common/src/resources/org/apache/lucene/analysis/ar/stopwords.txt.
18+
See http://members.unine.ch/jacques.savoy/clef/index.html.
19+
20+
The Persian analyzer (contrib/analyzers) comes with a default
21+
stopword list that is BSD-licensed created by Jacques Savoy. The file resides in
22+
contrib/analyzers/common/src/resources/org/apache/lucene/analysis/fa/stopwords.txt.
23+
See http://members.unine.ch/jacques.savoy/clef/index.html.
24+
25+
Includes lib/servlet-api-2.4.jar from Apache Tomcat
26+
27+
The SmartChineseAnalyzer source code (under contrib/analyzers) was
28+
provided by Xiaoping Gao and copyright 2009 by www.imdict.net.
29+
30+
ICU4J, (under contrib/collation) is licensed under an MIT styles license
31+
(contrib/collation/lib/ICU-LICENSE.txt) and Copyright (c) 1995-2008
32+
International Business Machines Corporation and others

conf/default/jquery.tooltip.css

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#tooltip {
2+
position: absolute;
3+
z-index: 3000;
4+
border: 1px solid #111;
5+
background-color: #eee;
6+
padding: 5px;
7+
opacity: 0.90;
8+
}
9+
#tooltip h3, #tooltip div { margin: 0; font-size: small; }

conf/offwhite/jquery.tooltip.css

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#tooltip {
2+
position: absolute;
3+
z-index: 3000;
4+
border: 1px solid #111;
5+
background-color: #eee;
6+
padding: 5px;
7+
opacity: 0.90;
8+
}
9+
#tooltip h3, #tooltip div { margin: 0; font-size: small; }

conf/polished/jquery.tooltip.css

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#tooltip {
2+
position: absolute;
3+
z-index: 3000;
4+
border: 1px solid #111;
5+
background-color: #eee;
6+
padding: 5px;
7+
opacity: 0.90;
8+
}
9+
#tooltip h3, #tooltip div { margin: 0; font-size: small; }

src/org/opensolaris/opengrok/history/Annotation.java

+62
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,26 @@
2424

2525
package org.opensolaris.opengrok.history;
2626

27+
import java.io.IOException;
28+
import java.io.StringWriter;
29+
import java.io.Writer;
2730
import java.util.ArrayList;
31+
import java.util.HashMap;
32+
import java.util.Iterator;
2833
import java.util.List;
2934

35+
import java.util.Map.Entry;
36+
import java.util.HashSet;
37+
import org.opensolaris.opengrok.web.Util;
38+
3039
/**
3140
* Class representing file annotation, i.e., revision and author for the last
3241
* modification of each line in the file.
3342
*/
3443
public class Annotation {
3544

3645
private final List<Line> lines = new ArrayList<Line>();
46+
private final HashMap<String, String> desc = new HashMap<String, String>();
3747
private int widestRevision;
3848
private int widestAuthor;
3949
private final String filename;
@@ -57,6 +67,20 @@ public String getRevision(int line) {
5767
}
5868
}
5969

70+
/**
71+
* Gets all revisions that are in use, first is the lowest one (sorted using natural order)
72+
*
73+
* @return list of all revisions the file has
74+
*/
75+
public HashSet<String> getRevisions() {
76+
HashSet<String> ret=new HashSet<String>();
77+
for (Iterator<Line> it = this.lines.iterator(); it.hasNext();) {
78+
Line ln = it.next();
79+
ret.add(ln.revision);
80+
}
81+
return ret;
82+
}
83+
6084
/**
6185
* Gets the author who last modified the specified line.
6286
*
@@ -127,6 +151,14 @@ void addLine(String revision, String author, boolean enabled) {
127151
widestAuthor = Math.max(widestAuthor, line.author.length());
128152
}
129153

154+
void addDesc(String revision, String description) {
155+
desc.put(revision, Util.encode(description));
156+
}
157+
158+
public String getDesc(String revision) {
159+
return desc.get(revision);
160+
}
161+
130162
/** Class representing one line in the file. */
131163
private static class Line {
132164
final String revision;
@@ -142,4 +174,34 @@ private static class Line {
142174
public String getFilename() {
143175
return filename;
144176
}
177+
178+
//TODO below might be useless, need to test with more SCMs and different commit messages
179+
// to see if it will not be usefull, if title attribute of <a> loses it's breath
180+
public void writeTooltipMap(Writer out) throws IOException {
181+
StringBuffer map = new StringBuffer();
182+
map.append("<script type=\"text/javascript\">\n");
183+
map.append(" var desc = new Object();\n");
184+
for (Entry<String, String> entry : desc.entrySet()) {
185+
map.append("desc['"+entry.getKey()+"'] = \""+entry.getValue()+"\";\n");
186+
}
187+
map.append("</script>\n");
188+
out.write(map.toString());
189+
}
190+
191+
@Override
192+
public String toString() {
193+
StringBuffer sb = new StringBuffer();
194+
for (Line line : lines) {
195+
sb.append(line.revision+"|"+line.author+": "+"\n");
196+
}
197+
StringWriter sw = new StringWriter();
198+
try {
199+
writeTooltipMap(sw);
200+
} catch (IOException e) {
201+
e.printStackTrace();
202+
}
203+
sb.append(sw.toString());
204+
205+
return sb.toString();
206+
}
145207
}

src/org/opensolaris/opengrok/history/HistoryGuru.java

+26
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import java.util.HashMap;
3131
import java.util.List;
3232
import java.util.Map;
33+
import java.util.HashSet;
34+
import java.util.Iterator;
3335
import java.util.concurrent.ExecutorService;
3436
import java.util.concurrent.Executors;
3537
import java.util.concurrent.TimeUnit;
@@ -122,6 +124,30 @@ public Annotation annotate(File file, String rev) throws IOException {
122124
Repository repos = getRepository(file);
123125
if (repos != null) {
124126
ret = repos.annotate(file, rev);
127+
History hist = null;
128+
boolean h=true;
129+
try {
130+
hist = repos.getHistory(file);
131+
} catch (HistoryException ex) {
132+
Logger.getLogger(HistoryGuru.class.getName()).log(Level.FINEST, "Cannot get messages for tooltip: ", ex);
133+
h=false;
134+
}
135+
if (h) {
136+
HashSet<String> revs=ret.getRevisions();
137+
List<HistoryEntry> hent = hist.getHistoryEntries();
138+
//if (hent.indexOf(rev)>0) {
139+
// hent = hent.subList(hent.indexOf(rev), hent.size()); // !!! cannot do this because of not matching rev ids (keys)
140+
//first is the most recent one, so we need the position of "rev" until the end of the list
141+
//}
142+
for (Iterator it = hent.iterator(); it.hasNext();) {
143+
HistoryEntry he = (HistoryEntry) it.next();
144+
String cmr=he.getRevision();
145+
String[] brev=cmr.split(":"); //TODO this is only for mercurial, for other SCMs it might also be a problem, we need to revise how we shorten the rev # for annotate
146+
if (revs.contains(brev[0])) {
147+
ret.addDesc(brev[0], "changeset: "+he.getRevision()+"\nsummary: "+he.getMessage()+"\nuser: "+he.getAuthor()+"\ndate: "+he.getDate());
148+
}
149+
}
150+
}
125151
}
126152

127153
return ret;

src/org/opensolaris/opengrok/history/MercurialRepository.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,13 @@ public Annotation annotate(File file, String revision) throws IOException {
209209
Matcher matcher = ANNOTATION_PATTERN.matcher(line);
210210
if (matcher.find()) {
211211
String author = matcher.group(1);
212-
String rev = matcher.group(2);
213-
ret.addLine(rev, author, true);
212+
String rev = matcher.group(2);
213+
ret.addLine(rev, author, true);
214214
} else {
215215
OpenGrokLogger.getLogger().log(Level.SEVERE, "Error: did not find annotation in line " +
216216
lineno + ": [" + line + "]");
217217
}
218-
}
218+
}
219219
} finally {
220220
if (in != null) {
221221
try {

src/org/opensolaris/opengrok/web/Util.java

+31
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,33 @@ public static String redableSize(long num) {
285285
}
286286
}
287287

288+
/**
289+
* Converts different html special characters into their encodings used in html
290+
* currently used only for tooltips of annotation revision number view
291+
* @param s input text
292+
* @return encoded text for use in <a title=""> tag
293+
*/
294+
public static String encode(String s) {
295+
StringBuffer sb = new StringBuffer();
296+
for (int i = 0; i < s.length(); i++) {
297+
char c = s.charAt(i);
298+
299+
switch (c) {
300+
case '"': sb.append("'"); break; // \\\"
301+
case '&': sb.append("&amp;"); break;
302+
case '>': sb.append("&gt;"); break;
303+
case '<': sb.append("&lt;"); break;
304+
case ' ': sb.append("&nbsp;"); break;
305+
case '\t': sb.append("&nbsp;&nbsp;&nbsp;&nbsp;"); break;
306+
case '\n': sb.append("<br/>"); break;
307+
case '\r': break;
308+
default: sb.append(c); break;
309+
}
310+
}
311+
312+
return sb.toString();
313+
}
314+
288315
public static void readableLine(int num, Writer out, Annotation annotation)
289316
throws IOException {
290317
String snum = String.valueOf(num);
@@ -316,6 +343,10 @@ public static void readableLine(int num, Writer out, Annotation annotation)
316343
out.write(URIEncode(annotation.getFilename()));
317344
out.write("?a=true&amp;r=");
318345
out.write(URIEncode(r));
346+
String msg=annotation.getDesc(r);
347+
if (msg!=null) {
348+
out.write("\" id=\"r\" title=\""+msg+"\"");
349+
}
319350
out.write(closeQuotedTag);
320351
}
321352

web/httpheader.jspf

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ String httpHeaderContext = request.getContextPath();
3636
<link rel="stylesheet" type="text/css" href="<%=httpHeaderContext%>/<%=laf%>/style.css"/>
3737
<link rel="stylesheet" type="text/css" href="<%=httpHeaderContext%>/<%=laf%>/print.css" media="print" />
3838
<link rel="stylesheet" type="text/css" href="<%=httpHeaderContext%>/<%=laf%>/jquery.autocomplete.css" />
39+
<link rel="stylesheet" type="text/css" href="<%=httpHeaderContext%>/<%=laf%>/jquery.tooltip.css" />
3940
<link rel="alternate stylesheet" type="text/css" media="all" title="Paper White" href="<%=httpHeaderContext%>/<%=laf%>/print.css"/>
4041
<link rel="search" href="<%=httpHeaderContext%>/opensearch" type="application/opensearchdescription+xml" title="OpenGrok Search for current project(s)" />
4142
<title><%=pageTitle%></title>

web/jquery.tooltip-1.3.pack.js

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/list.jsp

+6-18
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ information: Portions Copyright [yyyy] [name of copyright owner]
1616
1717
CDDL HEADER END
1818
19-
Copyright 2005 Sun Microsystems, Inc. All rights reserved.
19+
Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2020
Use is subject to license terms.
2121
--%><%@ page import = "javax.servlet.*,
2222
java.lang.*,
@@ -34,22 +34,10 @@ org.opensolaris.opengrok.web.*,
3434
org.opensolaris.opengrok.history.*
3535
"
3636
%><%@include file="mast.jsp"%><script type="text/javascript">/* <![CDATA[ */
37-
function toggle_annotations() {
38-
var spans = document.getElementsByTagName("span");
39-
40-
for (var i = 0; i < spans.length; i++) {
41-
var span = spans[i];
42-
if (span.className == 'blame') {
43-
span.className = 'blame-hidden';
44-
} else if (span.className == 'blame-hidden') {
45-
span.className = 'blame';
46-
}
47-
}
48-
}
4937
function lntoggle() {
50-
var a = document.getElementsByTagName("a");
38+
var a = document.getElementsByTagName("a");
5139
for (var i = 0; i < a.length; i++) {
52-
var el = a[i]; //fix all line #
40+
var el = a[i];
5341
if (el.className == 'l' || el.className == 'hl') {
5442
el.className=el.className+'-hide';
5543
el.setAttribute("tmp", el.innerHTML);
@@ -61,8 +49,7 @@ function lntoggle() {
6149
}
6250
}
6351
}
64-
/* ]]> */
65-
</script><%
52+
/* ]]> */</script><%
6653
String rev = null;
6754
if(!isDir && ef != null) {
6855
try {
@@ -201,6 +188,7 @@ if (valid) {
201188
%><div id="src"><span class="pagetitle"><%=basename%> revision <%=rev%> </span><pre><%
202189
if (g == Genre.PLAIN) {
203190
Annotation annotation = annotate ? HistoryGuru.getInstance().annotate(resourceFile, rev) : null;
191+
//annotation.writeTooltipMap(out); //not needed yet
204192
AnalyzerGuru.writeXref(a, in, out, annotation, Project.getProject(resourceFile));
205193
} else if (g == Genre.IMAGE) {
206194
%><img src="<%=context%>/raw<%=path%>?r=<%=rev%>"/><%
@@ -275,7 +263,7 @@ if (valid) {
275263
}
276264
} else if(g == Genre.PLAIN) {
277265
%><div id="src"><pre><%
278-
Annotation annotation = annotate ? HistoryGuru.getInstance().annotate(resourceFile, rev) : null;
266+
Annotation annotation = annotate ? HistoryGuru.getInstance().annotate(resourceFile, rev) : null;
279267
AnalyzerGuru.writeXref(a, bin, out, annotation, Project.getProject(resourceFile));
280268
%></pre></div><%
281269
} else {

0 commit comments

Comments
 (0)