When showing a source code, allow to highlight some spans.
1.1 --- a/remoting/server/web/web.ui/nbproject/project.properties Fri Jul 13 11:06:24 2012 +0200
1.2 +++ b/remoting/server/web/web.ui/nbproject/project.properties Mon Jul 16 16:16:38 2012 +0200
1.3 @@ -1,5 +1,6 @@
1.4 annotation.processing.enabled=true
1.5 annotation.processing.enabled.in.editor=false
1.6 +annotation.processing.processors.list=
1.7 annotation.processing.run.all.processors=true
1.8 annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
1.9 application.title=web.ui
1.10 @@ -33,10 +34,13 @@
1.11 file.reference.org-netbeans-modules-lexer.jar=../../../../lib/org-netbeans-modules-lexer.jar
1.12 file.reference.org-netbeans-modules-parsing-lucene.jar=../../../../lib/org-netbeans-modules-parsing-lucene.jar
1.13 file.reference.org-openide-filesystems.jar=../../../../lib/org-openide-filesystems.jar
1.14 +file.reference.org-openide-util.jar=../../../../lib/org-openide-util.jar
1.15 file.reference.util-commons.jar-1=../../../ide/api/external/util-commons.jar
1.16 file.reference.util-pojson.jar-1=../../../ide/api/external/util-pojson.jar
1.17 includes=**
1.18 +jar.archive.disabled=${jnlp.enabled}
1.19 jar.compress=false
1.20 +jar.index=${jnlp.enabled}
1.21 javac.classpath=\
1.22 ${libs.lucene.classpath}:\
1.23 ${libs.jersey.classpath}:\
1.24 @@ -50,7 +54,8 @@
1.25 ${file.reference.util-commons.jar-1}:\
1.26 ${file.reference.util-pojson.jar-1}:\
1.27 ${file.reference.org-netbeans-modules-java-lexer.jar}:\
1.28 - ${file.reference.org-netbeans-modules-lexer.jar}
1.29 + ${file.reference.org-netbeans-modules-lexer.jar}:\
1.30 + ${file.reference.org-openide-util.jar}
1.31 # Space-separated list of extra javac options
1.32 javac.compilerargs=
1.33 javac.deprecation=false
1.34 @@ -75,6 +80,15 @@
1.35 javadoc.use=true
1.36 javadoc.version=false
1.37 javadoc.windowtitle=
1.38 +jnlp.codebase.type=no.codebase
1.39 +jnlp.descriptor=application
1.40 +jnlp.enabled=false
1.41 +jnlp.mixed.code=default
1.42 +jnlp.offline-allowed=false
1.43 +jnlp.signed=false
1.44 +jnlp.signing=
1.45 +jnlp.signing.alias=
1.46 +jnlp.signing.keystore=
1.47 main.class=type.web.api.TypeWebApi
1.48 manifest.file=manifest.mf
1.49 meta.inf.dir=${src.dir}/META-INF
2.1 --- a/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/UI.java Fri Jul 13 11:06:24 2012 +0200
2.2 +++ b/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/UI.java Mon Jul 16 16:16:38 2012 +0200
2.3 @@ -56,6 +56,7 @@
2.4 import java.util.List;
2.5 import java.util.Map;
2.6 import java.util.Map.Entry;
2.7 +import javax.ws.rs.DefaultValue;
2.8 import javax.ws.rs.GET;
2.9 import javax.ws.rs.Path;
2.10 import javax.ws.rs.Produces;
2.11 @@ -165,49 +166,95 @@
2.12 @GET
2.13 @Path("/show")
2.14 @Produces("text/html")
2.15 - public String show(@QueryParam("path") String segment, @QueryParam("relative") String relative) throws URISyntaxException, IOException, TemplateException {
2.16 + public String show(@QueryParam("path") String segment, @QueryParam("relative") String relative, @QueryParam("highlight") @DefaultValue("[]") String highlightSpec) throws URISyntaxException, IOException, TemplateException {
2.17 URI u = new URI(URL_BASE + "/source/cat?path=" + escapeForQuery(segment) + "&relative=" + escapeForQuery(relative));
2.18 String content = WebUtilities.requestStringResponse(u);
2.19 + List<Long> highlightSpans = Pojson.load(ArrayList.class, highlightSpec);
2.20 + Map<String, Object> configurationData = new HashMap<String, Object>();
2.21 + String[] highlights = colorTokens(content, highlightSpans);
2.22 +
2.23 + configurationData.put("spans", highlights[0]);
2.24 + configurationData.put("categories", highlights[1]);
2.25 + configurationData.put("code", translate(content));
2.26 +
2.27 + return FreemarkerUtilities.processTemplate("org/netbeans/modules/jackpot30/backend/ui/showCode.html", configurationData);
2.28 + }
2.29 +
2.30 + static String[] colorTokens(String content, List<Long> highlight) {
2.31 TokenSequence<?> ts = TokenHierarchy.create(content, JavaTokenId.language()).tokenSequence();
2.32 StringBuilder spans = new StringBuilder();
2.33 StringBuilder cats = new StringBuilder();
2.34 - int currentOffset = 0;
2.35 + long currentOffset = 0;
2.36 + boolean cont = false;
2.37
2.38 - while (ts.moveNext()) {
2.39 + while (cont || ts.moveNext()) {
2.40 if (spans.length() > 0) spans.append(", ");
2.41 - int endOffset = ts.offset() + ts.token().length();
2.42 +
2.43 + long endOffset = ts.offset() + ts.token().length();
2.44 + boolean foundHighlight = false;
2.45 +
2.46 + cont = false;
2.47 +
2.48 + for (int i = 0; i < highlight.size(); i += 2) {
2.49 + if ( currentOffset <= highlight.get(i)
2.50 + && endOffset >= highlight.get(i)) {
2.51 + if (currentOffset < highlight.get(i)) {
2.52 + endOffset = highlight.get(i);
2.53 + cont = true;
2.54 + } else if ((highlight.get(i + 1) + 1) < endOffset) {
2.55 + endOffset = highlight.get(i + 1) + 1;
2.56 + cont = true;
2.57 + foundHighlight = true;
2.58 + } else {
2.59 + foundHighlight = true;
2.60 + }
2.61 + } else if ( highlight.get(i) <= currentOffset
2.62 + && (highlight.get(i + 1) + 1) > endOffset) {
2.63 + foundHighlight = true;
2.64 + } else if ( currentOffset < (highlight.get(i + 1) + 1)
2.65 + && (highlight.get(i + 1) + 1) < endOffset) {
2.66 + endOffset = highlight.get(i + 1) + 1;
2.67 + cont = true;
2.68 + foundHighlight = true;
2.69 + }
2.70 + }
2.71 +
2.72 spans.append(endOffset - currentOffset);
2.73 - currentOffset = endOffset;
2.74 String category = ts.token().id().primaryCategory();
2.75
2.76 + char cat;
2.77 +
2.78 if ("keyword".equals(category)) {
2.79 - cats.append("K");
2.80 + cat = 'K';
2.81 } else if ("keyword-directive".equals(category)) {
2.82 - cats.append("K");
2.83 + cat = 'K';
2.84 } else if ("literal".equals(category)) {
2.85 - cats.append("K");
2.86 + cat = 'K';
2.87 } else if ("whitespace".equals(category)) {
2.88 - cats.append("W");
2.89 + cat = 'W';
2.90 } else if ("comment".equals(category)) {
2.91 - cats.append("C");
2.92 + cat = 'C';
2.93 } else if ("character".equals(category)) {
2.94 - cats.append("H");
2.95 + cat = 'H';
2.96 } else if ("number".equals(category)) {
2.97 - cats.append("N");
2.98 + cat = 'N';
2.99 } else if ("string".equals(category)) {
2.100 - cats.append("S");
2.101 + cat = 'S';
2.102 } else {
2.103 - cats.append("E");
2.104 + cat = 'E';
2.105 }
2.106 +
2.107 + if (foundHighlight) cat++;
2.108 +
2.109 + cats.append(cat);
2.110 +
2.111 + currentOffset = endOffset;
2.112 }
2.113
2.114 - Map<String, Object> configurationData = new HashMap<String, Object>();
2.115 -
2.116 - configurationData.put("spans", spans.toString());
2.117 - configurationData.put("categories", cats.toString());
2.118 - configurationData.put("code", translate(content));
2.119 -
2.120 - return FreemarkerUtilities.processTemplate("org/netbeans/modules/jackpot30/backend/ui/showCode.html", configurationData);
2.121 + return new String[] {
2.122 + spans.toString(),
2.123 + cats.toString()
2.124 + };
2.125 }
2.126
2.127 //XXX: usages on fields do not work because the field signature in the index contain also the field type
3.1 --- a/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/showCode.html Fri Jul 13 11:06:24 2012 +0200
3.2 +++ b/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/showCode.html Mon Jul 16 16:16:38 2012 +0200
3.3 @@ -25,6 +25,15 @@
3.4 .H {color: #006F00;}
3.5 .N {color: #780000;}
3.6 .S {color: #99009D;}
3.7 + .E {}
3.8 + .W {}
3.9 + .L {color: #0000FF; font-weight: bold;background-color:#DDDD00;}
3.10 + .D {color: #737373;background-color:#DDDD00;}
3.11 + .I {color: #006F00;background-color:#DDDD00;}
3.12 + .O {color: #780000;background-color:#DDDD00;}
3.13 + .T {color: #99009D;background-color:#DDDD00;}
3.14 + .F {background-color:#DDDD00;}
3.15 + .X {background-color:#DDDD00;}
3.16 </style>
3.17 </head>
3.18 <body>
4.1 --- a/remoting/server/web/web.ui/test/org/netbeans/modules/jackpot30/backend/ui/UITest.java Fri Jul 13 11:06:24 2012 +0200
4.2 +++ b/remoting/server/web/web.ui/test/org/netbeans/modules/jackpot30/backend/ui/UITest.java Mon Jul 16 16:16:38 2012 +0200
4.3 @@ -42,6 +42,8 @@
4.4
4.5 package org.netbeans.modules.jackpot30.backend.ui;
4.6
4.7 +import java.util.ArrayList;
4.8 +import java.util.Arrays;
4.9 import junit.framework.TestCase;
4.10
4.11 /**
4.12 @@ -71,4 +73,22 @@
4.13 assertEquals("METHOD:org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities:fixDependencies:(Lorg/openide/filesystems/FileObject;Ljava/util/List;Ljava/util/Map;)Z",
4.14 UI.simplify("METHOD:org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities:fixDependencies:(Lorg/openide/filesystems/FileObject;Ljava/util/List<Lorg/netbeans/spi/java/hints/JavaFix;>;Ljava/util/Map<Lorg/netbeans/api/project/Project;Ljava/util/Set<Ljava/lang/String;>;>;)Z;"));
4.15 }
4.16 +
4.17 + public void testSpansColoring() {
4.18 + String[] coloring = UI.colorTokens("package test; public class Test { }", new ArrayList<Long>());
4.19 + assertEquals("7, 1, 4, 1, 1, 6, 1, 5, 1, 4, 1, 1, 1, 1", coloring[0]);
4.20 + assertEquals("KWEEWKWKWEWEWE", coloring[1]);
4.21 + coloring = UI.colorTokens("package test; public class Test { }", Arrays.asList(0L, 6L));
4.22 + assertEquals("7, 1, 4, 1, 1, 6, 1, 5, 1, 4, 1, 1, 1, 1", coloring[0]);
4.23 + assertEquals("LWEEWKWKWEWEWE", coloring[1]);
4.24 + coloring = UI.colorTokens("package test; public class Test { }", Arrays.asList(1L, 3L));
4.25 + assertEquals("1, 3, 3, 1, 4, 1, 1, 6, 1, 5, 1, 4, 1, 1, 1, 1", coloring[0]);
4.26 + assertEquals("KLKWEEWKWKWEWEWE", coloring[1]);
4.27 + coloring = UI.colorTokens("package test; public class Test { }", Arrays.asList(16L, 17L));
4.28 + assertEquals("7, 1, 4, 1, 1, 2, 2, 2, 1, 5, 1, 4, 1, 1, 1, 1", coloring[0]);
4.29 + assertEquals("KWEEWKLKWKWEWEWE", coloring[1]);
4.30 + coloring = UI.colorTokens("package test; public class Test { }", Arrays.asList(3L, 17L));
4.31 + assertEquals("3, 4, 1, 4, 1, 1, 4, 2, 1, 5, 1, 4, 1, 1, 1, 1", coloring[0]);
4.32 + assertEquals("KLXFFXLKWKWEWEWE", coloring[1]);
4.33 + }
4.34 }