Adding web UI for find subclasses and find overriders.
1.1 --- a/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/UI.java Thu Jul 05 23:44:17 2012 +0200
1.2 +++ b/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/UI.java Fri Jul 06 23:11:32 2012 +0200
1.3 @@ -214,7 +214,87 @@
1.4 @GET
1.5 @Path("/usages")
1.6 @Produces("text/html")
1.7 - public String usages(@QueryParam("path") String segment, @QueryParam("signatures") String signatures) throws URISyntaxException, IOException, TemplateException {
1.8 + public String usages(@QueryParam("path") String segment, @QueryParam("signatures") final String signatures) throws URISyntaxException, IOException, TemplateException {
1.9 + Map<String, Object> configurationData = usagesSubclassesImpl(segment, signatures, "files", new ComputeSegmentData() {
1.10 + @Override public Object compute(String currentSegment) throws URISyntaxException, TemplateException, IOException {
1.11 + URI u = new URI(URL_BASE + "/usages/search?path=" + escapeForQuery(currentSegment) + "&signatures=" + escapeForQuery(simplify(signatures)));
1.12 + List<String> files = new ArrayList<String>(WebUtilities.requestStringArrayResponse(u));
1.13 + Collections.sort(files);
1.14 + return files;
1.15 + }
1.16 + });
1.17 +
1.18 + return FreemarkerUtilities.processTemplate("org/netbeans/modules/jackpot30/backend/ui/usages.html", configurationData);
1.19 + }
1.20 +
1.21 + @GET
1.22 + @Path("/implements")
1.23 + @Produces("text/html")
1.24 + public String impl(@QueryParam("path") String segment, @QueryParam("type") String typeSignature, @QueryParam("method") final String methodSignature) throws URISyntaxException, IOException, TemplateException {
1.25 + Map<String, Object> configurationData;
1.26 +
1.27 + if (typeSignature != null) {
1.28 + final String type = strip(typeSignature, "CLASS:", "INTERFACE:", "ENUM:", "ANNOTATION_TYPE:");
1.29 + configurationData = usagesSubclassesImpl(segment, typeSignature, "implementors", new ComputeSegmentData() {
1.30 + @Override
1.31 + public Object compute(String currentSegment) throws URISyntaxException, TemplateException, IOException {
1.32 + URI u = new URI(URL_BASE + "/implements/search?path=" + escapeForQuery(currentSegment) + "&type=" + escapeForQuery(type));
1.33 + Map<String, List<Map<String, String>>> data = Pojson.load(HashMap.class, u);
1.34 + List<Map<String, String>> implementors = new ArrayList<Map<String, String>>();
1.35 + for (Entry<String, List<Map<String, String>>> relpath2ImplementorsE : data.entrySet()) {
1.36 + for (Map<String, String> implementorData : relpath2ImplementorsE.getValue()) {
1.37 + Map<String, String> implementor = new HashMap<String, String>();
1.38 +
1.39 + implementor.put("file", implementorData.get("file"));
1.40 + implementor.put("class", implementorData.get("class"));
1.41 + implementors.add(implementor);
1.42 + }
1.43 + }
1.44 + Collections.sort(implementors, new Comparator<Map<String, String>>() {
1.45 + @Override
1.46 + public int compare(Map<String, String> o1, Map<String, String> o2) {
1.47 + return o1.get("class").compareTo(o2.get("class"));
1.48 + }
1.49 + });
1.50 + return implementors;
1.51 + }
1.52 + });
1.53 +
1.54 + configurationData.put("isSubtypes", true);
1.55 + } else {
1.56 + final String method = methodSignature.substring(0, methodSignature.length() - 1);
1.57 + configurationData = usagesSubclassesImpl(segment, methodSignature, "implementors", new ComputeSegmentData() {
1.58 + @Override
1.59 + public Object compute(String currentSegment) throws URISyntaxException, TemplateException, IOException {
1.60 + URI u = new URI(URL_BASE + "/implements/search?path=" + escapeForQuery(currentSegment) + "&method=" + escapeForQuery(method));
1.61 + Map<String, List<Map<String, String>>> data = Pojson.load(HashMap.class, u);
1.62 + List<Map<String, String>> implementors = new ArrayList<Map<String, String>>();
1.63 + for (Entry<String, List<Map<String, String>>> relpath2ImplementorsE : data.entrySet()) {
1.64 + for (Map<String, String> implementorData : relpath2ImplementorsE.getValue()) {
1.65 + Map<String, String> implementor = new HashMap<String, String>();
1.66 +
1.67 + implementor.put("file", implementorData.get("file"));
1.68 + implementor.put("class", implementorData.get("enclosingFQN"));
1.69 + implementors.add(implementor);
1.70 + }
1.71 + }
1.72 + Collections.sort(implementors, new Comparator<Map<String, String>>() {
1.73 + @Override
1.74 + public int compare(Map<String, String> o1, Map<String, String> o2) {
1.75 + return o1.get("class").compareTo(o2.get("class"));
1.76 + }
1.77 + });
1.78 + return implementors;
1.79 + }
1.80 + });
1.81 +
1.82 + configurationData.put("isSubtypes", false);
1.83 + }
1.84 +
1.85 + return FreemarkerUtilities.processTemplate("org/netbeans/modules/jackpot30/backend/ui/implementors.html", configurationData);
1.86 + }
1.87 +
1.88 + private Map<String, Object> usagesSubclassesImpl(String segment, String elementSignature, String dataKey, ComputeSegmentData computeSegmentData) throws URISyntaxException, TemplateException, IOException {
1.89 List<Map<String, String>> segments2Process = new ArrayList<Map<String, String>>();
1.90
1.91 for (Map<String, String> m : list()) {
1.92 @@ -229,7 +309,7 @@
1.93
1.94 Map<String, Object> configurationData = new HashMap<String, Object>();
1.95
1.96 - configurationData.put("elementDisplayName", elementDisplayName(signatures)); //TODO
1.97 + configurationData.put("elementDisplayName", elementDisplayName(elementSignature)); //TODO
1.98
1.99 List<Map<String, Object>> results = new ArrayList<Map<String, Object>>(segments2Process.size());
1.100
1.101 @@ -239,17 +319,18 @@
1.102
1.103 rootResults.put("rootDisplayName", m.get("displayName"));
1.104 rootResults.put("rootPath", currentSegment);
1.105 - URI u = new URI(URL_BASE + "/usages/search?path=" + escapeForQuery(currentSegment) + "&signatures=" + escapeForQuery(simplify(signatures)));
1.106 - List<String> files = new ArrayList<String>(WebUtilities.requestStringArrayResponse(u));
1.107 - Collections.sort(files);
1.108 - rootResults.put("files", files);
1.109 + rootResults.put(dataKey, computeSegmentData.compute(currentSegment));
1.110
1.111 results.add(rootResults);
1.112 }
1.113
1.114 configurationData.put("results", results);
1.115
1.116 - return FreemarkerUtilities.processTemplate("org/netbeans/modules/jackpot30/backend/ui/usages.html", configurationData);
1.117 + return configurationData;
1.118 + }
1.119 +
1.120 + private interface ComputeSegmentData {
1.121 + public Object compute(String segment) throws URISyntaxException, TemplateException, IOException;
1.122 }
1.123
1.124 private static String elementDisplayName(String signatures) {
1.125 @@ -471,4 +552,14 @@
1.126
1.127 return target.delete(target.length() - 1, target.length()).toString();
1.128 }
1.129 +
1.130 + static String strip(String originalSignature, String... prefixesToStrip) {
1.131 + for (String strip : prefixesToStrip) {
1.132 + if (originalSignature.startsWith(strip)) {
1.133 + return originalSignature.substring(strip.length());
1.134 + }
1.135 + }
1.136 +
1.137 + return originalSignature;
1.138 + }
1.139 }
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/implementors.html Fri Jul 06 23:11:32 2012 +0200
2.3 @@ -0,0 +1,24 @@
2.4 +<html>
2.5 +<head>
2.6 + <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
2.7 + <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
2.8 + <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/base/jquery-ui.css" rel="stylesheet" type="text/css">
2.9 +</head>
2.10 +<body>
2.11 + <#if isSubtypes>
2.12 + Subtypes of ${elementDisplayName?replace("&", "&")?replace("<", "<")}:<br>
2.13 + <#else>
2.14 + Overriders of ${elementDisplayName?replace("&", "&")?replace("<", "<")} found in the following classes:<br>
2.15 + </#if>
2.16 + <ul>
2.17 + <#list results as rootResults>
2.18 + <li>${rootResults.rootDisplayName?replace("&", "&")?replace("<", "<")}<br>
2.19 + <#list rootResults.implementors as implementor>
2.20 + <img src="/index/icons/class.png" alt="Java Class"/>
2.21 + <a href='/index/ui/show?path=${rootResults.rootPath}&relative=${implementor.file}'>${implementor.class}</a><br>
2.22 + </#list>
2.23 + </li>
2.24 + </#list>
2.25 + </ul>
2.26 +</body>
2.27 +</html>
3.1 --- a/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/ui-findType.html Thu Jul 05 23:44:17 2012 +0200
3.2 +++ b/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/ui-findType.html Fri Jul 06 23:11:32 2012 +0200
3.3 @@ -7,17 +7,23 @@
3.4 function methodPopup(relativePath, resultFile, signature) {
3.5 $('#popup').html('<a href="/index/ui/show?path=' + relativePath + '&relative=' + resultFile + '">Source Code</a><br>' +
3.6 '<a href="/index/ui/usages?path=' + relativePath + '&signatures=' + signature + '">Usages in the current project</a><br>' +
3.7 - '<a href="/index/ui/usages?signatures=' + signature + '">Usages in all known projects</a><br>')
3.8 + '<a href="/index/ui/usages?signatures=' + signature + '">Usages in all known projects</a><br>' +
3.9 + '<a href="/index/ui/implements?path=' + relativePath + '&method=' + signature + '">Overriders in the current project</a><br>' +
3.10 + '<a href="/index/ui/implements?method=' + signature + '">Overriders in all known projects</a><br>')
3.11 .dialog({
3.12 - title: 'Show'
3.13 + title: 'Show',
3.14 + width: 460 //XXX: hardcoded size
3.15 });
3.16 }
3.17 function classPopup(relativePath, resultFile, signature) {
3.18 $('#popup').html('<a href="/index/ui/show?path=' + relativePath + '&relative=' + resultFile + '">Source Code</a><br>' +
3.19 '<a href="/index/ui/usages?path=' + relativePath + '&signatures=' + signature + '">Usages in the current project</a><br>' +
3.20 - '<a href="/index/ui/usages?signatures=' + signature + '">Usages in all known projects</a><br>')
3.21 + '<a href="/index/ui/usages?signatures=' + signature + '">Usages in all known projects</a><br>' +
3.22 + '<a href="/index/ui/implements?path=' + relativePath + '&type=' + signature + '">Subtypes in the current project</a><br>' +
3.23 + '<a href="/index/ui/implements?type=' + signature + '">Subtypes in all known projects</a><br>')
3.24 .dialog({
3.25 - title: 'Show'
3.26 + title: 'Show',
3.27 + width: 400 //XXX: hardcoded size
3.28 });
3.29 }
3.30 function otherPopup(relativePath, resultFile, signature) {