Ability to search more than one project through web UI.
authorJan Lahoda <jlahoda@netbeans.org>
Wed, 15 Aug 2012 20:06:51 +0200
changeset 8471abf467d6406
parent 844 033c4fe9cdc7
child 848 659636ea24a7
child 849 41166974cf74
Ability to search more than one project through web UI.
remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/UI.java
remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/ui-findType.html
     1.1 --- a/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/UI.java	Fri Aug 10 22:46:58 2012 +0200
     1.2 +++ b/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/UI.java	Wed Aug 15 20:06:51 2012 +0200
     1.3 @@ -82,81 +82,91 @@
     1.4      @GET
     1.5      @Path("/search")
     1.6      @Produces("text/html")
     1.7 -    public String searchType(@QueryParam("path") String path, @QueryParam("prefix") String prefix) throws URISyntaxException, IOException, TemplateException {
     1.8 +    public String searchType(@QueryParam("path") List<String> paths, @QueryParam("prefix") String prefix) throws URISyntaxException, IOException, TemplateException {
     1.9          Map<String, Object> configurationData = new HashMap<String, Object>();
    1.10 +        Map<String,Map<String, String>> pathsList = list();
    1.11  
    1.12 -        configurationData.put("paths", list());
    1.13 -        configurationData.put("selectedPath", path);
    1.14 +        configurationData.put("paths", pathsList.values());
    1.15 +        configurationData.put("selectedPath", paths);
    1.16          configurationData.put("prefix", prefix);
    1.17  
    1.18 -        if (prefix != null && path != null) {
    1.19 -            URI u = new URI(URL_BASE + "/symbol/search?path=" + escapeForQuery(path) + "&prefix=" + escapeForQuery(prefix));
    1.20 -            @SuppressWarnings("unchecked") //XXX: should not trust something got from the network!
    1.21 -            Map<String, List<Map<String, Object>>> symbols = Pojson.load(LinkedHashMap.class, u);
    1.22 +        if (prefix != null && paths != null) {
    1.23              List<Map<String, Object>> results = new LinkedList<Map<String, Object>>();
    1.24  
    1.25 -            for (Entry<String, List<Map<String, Object>>> e : symbols.entrySet()) {
    1.26 -                for (Map<String, Object> found : e.getValue()) {
    1.27 -                    found.put("icon", getElementIcon((String) found.get("kind"), (Collection<String>) found.get("modifiers")));
    1.28 -                    if ("METHOD".equals(found.get("kind")) || "CONSTRUCTOR".equals(found.get("kind"))) {
    1.29 -                        found.put("displayName", found.get("simpleName") + decodeMethodSignature((String) found.get("signature")));
    1.30 -                    } else {
    1.31 -                        found.put("displayName", found.get("simpleName"));
    1.32 +            for (String path : paths) {
    1.33 +                URI u = new URI(URL_BASE + "/symbol/search?path=" + escapeForQuery(path) + "&prefix=" + escapeForQuery(prefix));
    1.34 +                @SuppressWarnings("unchecked") //XXX: should not trust something got from the network!
    1.35 +                Map<String, List<Map<String, Object>>> symbols = Pojson.load(LinkedHashMap.class, u);
    1.36 +                Map<String, ?> segmentDescription = pathsList.get(path);
    1.37 +
    1.38 +                for (Entry<String, List<Map<String, Object>>> e : symbols.entrySet()) {
    1.39 +                    for (Map<String, Object> found : e.getValue()) {
    1.40 +                        found.put("icon", getElementIcon((String) found.get("kind"), (Collection<String>) found.get("modifiers")));
    1.41 +                        if ("METHOD".equals(found.get("kind")) || "CONSTRUCTOR".equals(found.get("kind"))) {
    1.42 +                            found.put("displayName", found.get("simpleName") + decodeMethodSignature((String) found.get("signature")));
    1.43 +                        } else {
    1.44 +                            found.put("displayName", found.get("simpleName"));
    1.45 +                        }
    1.46 +
    1.47 +                        found.put("segment", segmentDescription);
    1.48 +
    1.49 +                        results.add(found);
    1.50                      }
    1.51 +                }
    1.52  
    1.53 -                    results.add(found);
    1.54 +                URI typeSearch = new URI(URL_BASE + "/type/search?path=" + escapeForQuery(path) + "&prefix=" + escapeForQuery(prefix));
    1.55 +                @SuppressWarnings("unchecked") //XXX: should not trust something got from the network!
    1.56 +                Map<String, List<String>> types = Pojson.load(LinkedHashMap.class, typeSearch);
    1.57 +
    1.58 +                for (Entry<String, List<String>> e : types.entrySet()) {
    1.59 +                    for (String fqn : e.getValue()) {
    1.60 +                        Map<String, Object> result = new HashMap<String, Object>();
    1.61 +
    1.62 +                        result.put("icon", getElementIcon("CLASS", Collections.<String>emptyList()));
    1.63 +                        result.put("kind", "CLASS");
    1.64 +                        result.put("fqn", fqn);
    1.65 +
    1.66 +                        String displayName = fqn;
    1.67 +                        String enclosingFQN = "";
    1.68 +
    1.69 +                        if (displayName.lastIndexOf('.') > 0) {
    1.70 +                            displayName = displayName.substring(displayName.lastIndexOf('.') + 1);
    1.71 +                            enclosingFQN = fqn.substring(0, fqn.lastIndexOf('.'));
    1.72 +                        }
    1.73 +
    1.74 +                        if (displayName.lastIndexOf('$') > 0) {
    1.75 +                            displayName = displayName.substring(displayName.lastIndexOf('$') + 1);
    1.76 +                            enclosingFQN = fqn.substring(0, fqn.lastIndexOf('$'));
    1.77 +                        }
    1.78 +
    1.79 +                        result.put("displayName", displayName);
    1.80 +                        result.put("enclosingFQN", enclosingFQN);
    1.81 +
    1.82 +                        if (fqn.contains("$")) {
    1.83 +                            fqn = fqn.substring(0, fqn.indexOf("$"));
    1.84 +                        }
    1.85 +
    1.86 +                        result.put("file", e.getKey() + fqn.replace('.', '/') + ".java");
    1.87 +
    1.88 +                        result.put("segment", segmentDescription);
    1.89 +
    1.90 +                        results.add(result);
    1.91 +                    }
    1.92                  }
    1.93 +
    1.94 +                Collections.sort(results, new Comparator<Map<String, Object>>() {
    1.95 +                    @Override public int compare(Map<String, Object> o1, Map<String, Object> o2) {
    1.96 +                        int r = ((String) o1.get("displayName")).compareTo((String) o2.get("displayName"));
    1.97 +
    1.98 +                        if (r == 0) {
    1.99 +                            r = ((String) o1.get("enclosingFQN")).compareTo((String) o2.get("enclosingFQN"));
   1.100 +                        }
   1.101 +                        return r;
   1.102 +                    }
   1.103 +                });
   1.104 +
   1.105              }
   1.106  
   1.107 -            URI typeSearch = new URI(URL_BASE + "/type/search?path=" + escapeForQuery(path) + "&prefix=" + escapeForQuery(prefix));
   1.108 -            @SuppressWarnings("unchecked") //XXX: should not trust something got from the network!
   1.109 -            Map<String, List<String>> types = Pojson.load(LinkedHashMap.class, typeSearch);
   1.110 -
   1.111 -            for (Entry<String, List<String>> e : types.entrySet()) {
   1.112 -                for (String fqn : e.getValue()) {
   1.113 -                    Map<String, Object> result = new HashMap<String, Object>();
   1.114 -
   1.115 -                    result.put("icon", getElementIcon("CLASS", Collections.<String>emptyList()));
   1.116 -                    result.put("kind", "CLASS");
   1.117 -                    result.put("fqn", fqn);
   1.118 -
   1.119 -                    String displayName = fqn;
   1.120 -                    String enclosingFQN = "";
   1.121 -
   1.122 -                    if (displayName.lastIndexOf('.') > 0) {
   1.123 -                        displayName = displayName.substring(displayName.lastIndexOf('.') + 1);
   1.124 -                        enclosingFQN = fqn.substring(0, fqn.lastIndexOf('.'));
   1.125 -                    }
   1.126 -
   1.127 -                    if (displayName.lastIndexOf('$') > 0) {
   1.128 -                        displayName = displayName.substring(displayName.lastIndexOf('$') + 1);
   1.129 -                        enclosingFQN = fqn.substring(0, fqn.lastIndexOf('$'));
   1.130 -                    }
   1.131 -
   1.132 -                    result.put("displayName", displayName);
   1.133 -                    result.put("enclosingFQN", enclosingFQN);
   1.134 -
   1.135 -                    if (fqn.contains("$")) {
   1.136 -                        fqn = fqn.substring(0, fqn.indexOf("$"));
   1.137 -                    }
   1.138 -
   1.139 -                    result.put("file", e.getKey() + fqn.replace('.', '/') + ".java");
   1.140 -
   1.141 -                    results.add(result);
   1.142 -                }
   1.143 -            }
   1.144 -
   1.145 -            Collections.sort(results, new Comparator<Map<String, Object>>() {
   1.146 -                @Override public int compare(Map<String, Object> o1, Map<String, Object> o2) {
   1.147 -                    int r = ((String) o1.get("displayName")).compareTo((String) o2.get("displayName"));
   1.148 -
   1.149 -                    if (r == 0) {
   1.150 -                        r = ((String) o1.get("enclosingFQN")).compareTo((String) o2.get("enclosingFQN"));
   1.151 -                    }
   1.152 -                    return r;
   1.153 -                }
   1.154 -            });
   1.155 -
   1.156              configurationData.put("results", results);
   1.157          }
   1.158  
     2.1 --- a/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/ui-findType.html	Fri Aug 10 22:46:58 2012 +0200
     2.2 +++ b/remoting/server/web/web.ui/src/org/netbeans/modules/jackpot30/backend/ui/ui-findType.html	Wed Aug 15 20:06:51 2012 +0200
     2.3 @@ -6,9 +6,9 @@
     2.4      <script type="text/javascript">
     2.5          function methodPopup(relativePath, resultFile, signature) {
     2.6              $('#popup').html('<a href="/index/ui/show?path=' + relativePath + '&relative=' + resultFile + '">Source Code</a><br>' +
     2.7 -                             '<a href="/index/ui/usages?path=' + relativePath + '&signatures=' + signature + '">Usages in the current project</a><br>' +
     2.8 +                             '<a href="/index/ui/usages?path=' + relativePath + '&signatures=' + signature + '">Usages in the defining project</a><br>' +
     2.9                               '<a href="/index/ui/usages?signatures=' + signature + '">Usages in all known projects</a><br>' +
    2.10 -                             '<a href="/index/ui/implements?path=' + relativePath + '&method=' + signature + '">Overriders in the current project</a><br>' +
    2.11 +                             '<a href="/index/ui/implements?path=' + relativePath + '&method=' + signature + '">Overriders in the defining project</a><br>' +
    2.12                               '<a href="/index/ui/implements?method=' + signature + '">Overriders in all known projects</a><br>')
    2.13                              .dialog({
    2.14                                  title: 'Show',
    2.15 @@ -17,9 +17,9 @@
    2.16          }
    2.17          function classPopup(relativePath, resultFile, signature) {
    2.18              $('#popup').html('<a href="/index/ui/show?path=' + relativePath + '&relative=' + resultFile + '">Source Code</a><br>' +
    2.19 -                             '<a href="/index/ui/usages?path=' + relativePath + '&signatures=' + signature + '">Usages in the current project</a><br>' +
    2.20 +                             '<a href="/index/ui/usages?path=' + relativePath + '&signatures=' + signature + '">Usages in the defining project</a><br>' +
    2.21                               '<a href="/index/ui/usages?signatures=' + signature + '">Usages in all known projects</a><br>' +
    2.22 -                             '<a href="/index/ui/implements?path=' + relativePath + '&type=' + signature + '">Subtypes in the current project</a><br>' +
    2.23 +                             '<a href="/index/ui/implements?path=' + relativePath + '&type=' + signature + '">Subtypes in the defining project</a><br>' +
    2.24                               '<a href="/index/ui/implements?type=' + signature + '">Subtypes in all known projects</a><br>')
    2.25                              .dialog({
    2.26                                  title: 'Show',
    2.27 @@ -28,7 +28,7 @@
    2.28          }
    2.29          function otherPopup(relativePath, resultFile, signature) {
    2.30              $('#popup').html('<a href="/index/ui/show?path=' + relativePath + '&relative=' + resultFile + '">Source Code</a><br>' +
    2.31 -                             '<a href="/index/ui/usages?path=' + relativePath + '&signatures=' + signature + '">Usages in the current project</a><br>' +
    2.32 +                             '<a href="/index/ui/usages?path=' + relativePath + '&signatures=' + signature + '">Usages in the defining project</a><br>' +
    2.33                               '<a href="/index/ui/usages?signatures=' + signature + '">Usages in all known projects</a><br>')
    2.34                              .dialog({
    2.35                                  title: 'Show'
    2.36 @@ -38,14 +38,10 @@
    2.37  </head>
    2.38  <body>
    2.39  <form method="get">
    2.40 -<label for="path">Project:</label>
    2.41 -<select size="1" name="path">");
    2.42 -    <#list paths as path>
    2.43 -        <option <#if selectedPath?? && path.segment == selectedPath>selected</#if> value="${path.segment}">
    2.44 -            ${path.displayName}
    2.45 -        </option>
    2.46 -    </#list>
    2.47 -</select>
    2.48 +<label>Projects:</label>
    2.49 +<#list paths as path>
    2.50 +    <input type="checkbox" name="path" value="${path.segment}" <#if selectedPath?seq_contains(path.segment)> checked="yes"</#if>>${path.displayName}</input>
    2.51 +</#list>
    2.52  <br>
    2.53  <label for="prefix">Symbol Prefix:</label><input type="text" name="prefix"<#if prefix??>value="${prefix}"</#if>/><br>
    2.54  <input type="submit" name="Find Candidates"/>
    2.55 @@ -53,17 +49,24 @@
    2.56  
    2.57  <#if results??>
    2.58      Found symbols:<br>
    2.59 +    <table>
    2.60          <#list results as result>
    2.61 +        <tr>
    2.62 +            <td>
    2.63 +                <nobr>
    2.64                  <img src="/index/icons/${result.icon}" alt="${result.kind}"/>
    2.65                  <#if result.kind == "METHOD">
    2.66 -                    <a href="javascript: methodPopup('${selectedPath}', '${result.file}', '${result.kind}:${result.enclosingFQN}:${result.simpleName}:${result.signature}')">
    2.67 +                    <a href="javascript: methodPopup('${result.segment.segment}', '${result.file}', '${result.kind}:${result.enclosingFQN}:${result.simpleName}:${result.signature}')">
    2.68                  <#elseif result.kind == "CLASS" || result.kind == "INTERFACE" || result.kind == "ENUM" || result.kind == "ANNOTATION_TYPE">
    2.69 -                    <a href="javascript: classPopup('${selectedPath}', '${result.file}', '${result.kind}:${result.fqn}')">
    2.70 +                    <a href="javascript: classPopup('${result.segment.segment}', '${result.file}', '${result.kind}:${result.fqn}')">
    2.71                  <#else>
    2.72 -                    <a href="javascript: otherPopup('${selectedPath}', '${result.file}', '${result.kind}:${result.enclosingFQN}:${result.simpleName}')">
    2.73 +                    <a href="javascript: otherPopup('${result.segment.segment}', '${result.file}', '${result.kind}:${result.enclosingFQN}:${result.simpleName}')">
    2.74                  </#if>
    2.75                  ${result.displayName?replace("&", "&amp;")?replace("<", "&lt;")}</a> in ${result.enclosingFQN?replace("&", "&amp;")?replace("<", "&lt;")}
    2.76 -                <br>
    2.77 +                </nobr>
    2.78 +            </td>
    2.79 +            <td width="100%" align="right">${result.segment.displayName?replace("&", "&amp;")?replace("<", "&lt;")}</td>
    2.80 +        </tr>
    2.81          </#list>
    2.82  </#if>
    2.83