Experiment: server backend that is able to produce full indices (including partially attributed Jackpot 3.0 index) and do full search including occurrence verification and possibly also apply rewrite rules
authorJan Lahoda <jlahoda@netbeans.org>
Fri, 11 Feb 2011 22:33:43 +0100
changeset 54404d4090c1fdb
parent 543 8ab0811eabd6
child 545 224ff3deee5d
Experiment: server backend that is able to produce full indices (including partially attributed Jackpot 3.0 index) and do full search including occurrence verification and possibly also apply rewrite rules
hudson/trunk
server/backend/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
server/backend/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
server/backend/build.xml
server/backend/impl/build.xml
server/backend/impl/manifest.mf
server/backend/impl/nbproject/build-impl.xml
server/backend/impl/nbproject/genfiles.properties
server/backend/impl/nbproject/project.properties
server/backend/impl/nbproject/project.xml
server/backend/impl/nbproject/suite.properties
server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/Bundle.properties
server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/CategoryStorage.java
server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/MainPage.java
server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/OptionProcessorImpl.java
server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/api/API.java
server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/api/Progress.java
server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/api/StandaloneFinder.java
server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/resources/layer.xml
server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/ui/UI.java
server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/ui/ui-apply.html
server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/ui/ui-cat.html
server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/ui/ui-search.html
server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/ui/ui-snippet.html
server/backend/nbproject/build-impl.xml
server/backend/nbproject/genfiles.properties
server/backend/nbproject/platform.properties
server/backend/nbproject/project.properties
server/backend/nbproject/project.xml
     1.1 --- a/hudson/trunk	Fri Feb 11 22:33:43 2011 +0100
     1.2 +++ b/hudson/trunk	Fri Feb 11 22:33:43 2011 +0100
     1.3 @@ -23,7 +23,7 @@
     1.4      unzip -q ../download/*$TRUNK_ID-$1.zip || exit
     1.5  }
     1.6  
     1.7 -for cluster in ide platform java harness nb apisupport extra; do
     1.8 +for cluster in ide platform java harness nb apisupport extra enterprise; do
     1.9      download_and_unpack_cluster $cluster;
    1.10  done
    1.11  
    1.12 @@ -59,3 +59,4 @@
    1.13  mkdir -p build/server
    1.14  (cp server/do-indexing server/indexer/dist; cd server/indexer/dist/; zip -r ../../../build/server/indexer.zip *)
    1.15  (cd server/web.api/dist/; zip -r ../../../build/server/web.api.zip *)
    1.16 +(cd server/backend; call_ant clean && call_ant build && call_ant test && call_ant build-zip) || exit
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/server/backend/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties	Fri Feb 11 22:33:43 2011 +0100
     2.3 @@ -0,0 +1,2 @@
     2.4 +currentVersion=Jackpot 3.0 Backend {0}
     2.5 +LBL_splash_window_title=Starting Jackpot 3.0 Backend
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/server/backend/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties	Fri Feb 11 22:33:43 2011 +0100
     3.3 @@ -0,0 +1,2 @@
     3.4 +CTL_MainWindow_Title=Jackpot 3.0 Backend {0}
     3.5 +CTL_MainWindow_Title_No_Project=Jackpot 3.0 Backend {0}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/server/backend/build.xml	Fri Feb 11 22:33:43 2011 +0100
     4.3 @@ -0,0 +1,8 @@
     4.4 +<?xml version="1.0" encoding="UTF-8"?>
     4.5 +<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
     4.6 +<!-- for some information on what you could do (e.g. targets to override). -->
     4.7 +<!-- If you delete this file and reopen the project it will be recreated. -->
     4.8 +<project name="backend" basedir=".">
     4.9 +    <description>Builds the module suite backend.</description>
    4.10 +    <import file="nbproject/build-impl.xml"/>
    4.11 +</project>
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/server/backend/impl/build.xml	Fri Feb 11 22:33:43 2011 +0100
     5.3 @@ -0,0 +1,8 @@
     5.4 +<?xml version="1.0" encoding="UTF-8"?>
     5.5 +<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
     5.6 +<!-- for some information on what you could do (e.g. targets to override). -->
     5.7 +<!-- If you delete this file and reopen the project it will be recreated. -->
     5.8 +<project name="org.netbeans.modules.jackpot30.backend.impl" default="netbeans" basedir=".">
     5.9 +    <description>Builds, tests, and runs the project org.netbeans.modules.jackpot30.backend.impl.</description>
    5.10 +    <import file="nbproject/build-impl.xml"/>
    5.11 +</project>
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/server/backend/impl/manifest.mf	Fri Feb 11 22:33:43 2011 +0100
     6.3 @@ -0,0 +1,5 @@
     6.4 +Manifest-Version: 1.0
     6.5 +OpenIDE-Module: org.netbeans.modules.jackpot30.backend.impl
     6.6 +OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/jackpot30/backend/impl/Bundle.properties
     6.7 +OpenIDE-Module-Specification-Version: 1.0
     6.8 +OpenIDE-Module-Layer: org/netbeans/modules/jackpot30/backend/impl/resources/layer.xml
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/server/backend/impl/nbproject/build-impl.xml	Fri Feb 11 22:33:43 2011 +0100
     7.3 @@ -0,0 +1,45 @@
     7.4 +<?xml version="1.0" encoding="UTF-8"?>
     7.5 +<!--
     7.6 +*** GENERATED FROM project.xml - DO NOT EDIT  ***
     7.7 +***         EDIT ../build.xml INSTEAD         ***
     7.8 +-->
     7.9 +<project name="org.netbeans.modules.jackpot30.backend.impl-impl" basedir="..">
    7.10 +    <fail message="Please build using Ant 1.7.1 or higher.">
    7.11 +        <condition>
    7.12 +            <not>
    7.13 +                <antversion atleast="1.7.1"/>
    7.14 +            </not>
    7.15 +        </condition>
    7.16 +    </fail>
    7.17 +    <property file="nbproject/private/suite-private.properties"/>
    7.18 +    <property file="nbproject/suite.properties"/>
    7.19 +    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
    7.20 +    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
    7.21 +    <property file="${suite.dir}/nbproject/platform.properties"/>
    7.22 +    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
    7.23 +        <attribute name="name"/>
    7.24 +        <attribute name="value"/>
    7.25 +        <sequential>
    7.26 +            <property name="@{name}" value="${@{value}}"/>
    7.27 +        </sequential>
    7.28 +    </macrodef>
    7.29 +    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
    7.30 +        <attribute name="property"/>
    7.31 +        <attribute name="value"/>
    7.32 +        <sequential>
    7.33 +            <property name="@{property}" value="@{value}"/>
    7.34 +        </sequential>
    7.35 +    </macrodef>
    7.36 +    <property file="${user.properties.file}"/>
    7.37 +    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
    7.38 +    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
    7.39 +    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
    7.40 +    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
    7.41 +        <condition>
    7.42 +            <not>
    7.43 +                <contains string="${cluster.path.evaluated}" substring="platform"/>
    7.44 +            </not>
    7.45 +        </condition>
    7.46 +    </fail>
    7.47 +    <import file="${harness.dir}/build.xml"/>
    7.48 +</project>
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/server/backend/impl/nbproject/genfiles.properties	Fri Feb 11 22:33:43 2011 +0100
     8.3 @@ -0,0 +1,8 @@
     8.4 +build.xml.data.CRC32=a49bef13
     8.5 +build.xml.script.CRC32=c32e03a8
     8.6 +build.xml.stylesheet.CRC32=a56c6a5b@1.44
     8.7 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
     8.8 +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
     8.9 +nbproject/build-impl.xml.data.CRC32=a49bef13
    8.10 +nbproject/build-impl.xml.script.CRC32=87e6e497
    8.11 +nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.44
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/server/backend/impl/nbproject/project.properties	Fri Feb 11 22:33:43 2011 +0100
     9.3 @@ -0,0 +1,2 @@
     9.4 +javac.source=1.6
     9.5 +javac.compilerargs=-Xlint -Xlint:-serial
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/server/backend/impl/nbproject/project.xml	Fri Feb 11 22:33:43 2011 +0100
    10.3 @@ -0,0 +1,193 @@
    10.4 +<?xml version="1.0" encoding="UTF-8"?>
    10.5 +<project xmlns="http://www.netbeans.org/ns/project/1">
    10.6 +    <type>org.netbeans.modules.apisupport.project</type>
    10.7 +    <configuration>
    10.8 +        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
    10.9 +            <code-name-base>org.netbeans.modules.jackpot30.backend.impl</code-name-base>
   10.10 +            <suite-component/>
   10.11 +            <module-dependencies>
   10.12 +                <dependency>
   10.13 +                    <code-name-base>org.netbeans.api.java.classpath</code-name-base>
   10.14 +                    <build-prerequisite/>
   10.15 +                    <compile-dependency/>
   10.16 +                    <run-dependency>
   10.17 +                        <release-version>1</release-version>
   10.18 +                        <specification-version>1.27</specification-version>
   10.19 +                    </run-dependency>
   10.20 +                </dependency>
   10.21 +                <dependency>
   10.22 +                    <code-name-base>org.netbeans.api.progress</code-name-base>
   10.23 +                    <build-prerequisite/>
   10.24 +                    <compile-dependency/>
   10.25 +                    <run-dependency>
   10.26 +                        <release-version>1</release-version>
   10.27 +                        <specification-version>1.22</specification-version>
   10.28 +                    </run-dependency>
   10.29 +                </dependency>
   10.30 +                <dependency>
   10.31 +                    <code-name-base>org.netbeans.libs.freemarker</code-name-base>
   10.32 +                    <build-prerequisite/>
   10.33 +                    <compile-dependency/>
   10.34 +                    <run-dependency>
   10.35 +                        <release-version>1</release-version>
   10.36 +                        <implementation-version/>
   10.37 +                    </run-dependency>
   10.38 +                </dependency>
   10.39 +                <dependency>
   10.40 +                    <code-name-base>org.netbeans.libs.javacapi</code-name-base>
   10.41 +                    <build-prerequisite/>
   10.42 +                    <compile-dependency/>
   10.43 +                    <run-dependency>
   10.44 +                        <specification-version>7.2.0.2</specification-version>
   10.45 +                    </run-dependency>
   10.46 +                </dependency>
   10.47 +                <dependency>
   10.48 +                    <code-name-base>org.netbeans.libs.javacimpl</code-name-base>
   10.49 +                    <build-prerequisite/>
   10.50 +                    <compile-dependency/>
   10.51 +                    <run-dependency>
   10.52 +                        <release-version>1</release-version>
   10.53 +                        <implementation-version/>
   10.54 +                    </run-dependency>
   10.55 +                </dependency>
   10.56 +                <dependency>
   10.57 +                    <code-name-base>org.netbeans.libs.lucene</code-name-base>
   10.58 +                    <build-prerequisite/>
   10.59 +                    <compile-dependency/>
   10.60 +                    <run-dependency>
   10.61 +                        <release-version>3</release-version>
   10.62 +                        <specification-version>3.0</specification-version>
   10.63 +                    </run-dependency>
   10.64 +                </dependency>
   10.65 +                <dependency>
   10.66 +                    <code-name-base>org.netbeans.modules.jackpot30.api</code-name-base>
   10.67 +                    <build-prerequisite/>
   10.68 +                    <compile-dependency/>
   10.69 +                    <run-dependency>
   10.70 +                        <implementation-version/>
   10.71 +                    </run-dependency>
   10.72 +                </dependency>
   10.73 +                <dependency>
   10.74 +                    <code-name-base>org.netbeans.modules.java.source</code-name-base>
   10.75 +                    <build-prerequisite/>
   10.76 +                    <compile-dependency/>
   10.77 +                    <run-dependency>
   10.78 +                        <specification-version>0.75.0.17.12.6</specification-version>
   10.79 +                    </run-dependency>
   10.80 +                </dependency>
   10.81 +                <dependency>
   10.82 +                    <code-name-base>org.netbeans.modules.jeriglib</code-name-base>
   10.83 +                    <build-prerequisite/>
   10.84 +                    <compile-dependency/>
   10.85 +                    <run-dependency>
   10.86 +                        <specification-version>1.16</specification-version>
   10.87 +                    </run-dependency>
   10.88 +                </dependency>
   10.89 +                <dependency>
   10.90 +                    <code-name-base>org.netbeans.modules.project.ant</code-name-base>
   10.91 +                    <build-prerequisite/>
   10.92 +                    <compile-dependency/>
   10.93 +                    <run-dependency>
   10.94 +                        <release-version>1</release-version>
   10.95 +                        <specification-version>1.39</specification-version>
   10.96 +                    </run-dependency>
   10.97 +                </dependency>
   10.98 +                <dependency>
   10.99 +                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
  10.100 +                    <build-prerequisite/>
  10.101 +                    <compile-dependency/>
  10.102 +                    <run-dependency>
  10.103 +                        <release-version>1</release-version>
  10.104 +                        <specification-version>1.34</specification-version>
  10.105 +                    </run-dependency>
  10.106 +                </dependency>
  10.107 +                <dependency>
  10.108 +                    <code-name-base>org.netbeans.modules.projectuiapi</code-name-base>
  10.109 +                    <build-prerequisite/>
  10.110 +                    <compile-dependency/>
  10.111 +                    <run-dependency>
  10.112 +                        <release-version>1</release-version>
  10.113 +                        <specification-version>1.49.0.8</specification-version>
  10.114 +                    </run-dependency>
  10.115 +                </dependency>
  10.116 +                <dependency>
  10.117 +                    <code-name-base>org.netbeans.modules.sendopts</code-name-base>
  10.118 +                    <build-prerequisite/>
  10.119 +                    <compile-dependency/>
  10.120 +                    <run-dependency>
  10.121 +                        <release-version>2</release-version>
  10.122 +                        <specification-version>2.11</specification-version>
  10.123 +                    </run-dependency>
  10.124 +                </dependency>
  10.125 +                <dependency>
  10.126 +                    <code-name-base>org.netbeans.modules.servletjspapi</code-name-base>
  10.127 +                    <build-prerequisite/>
  10.128 +                    <compile-dependency/>
  10.129 +                    <run-dependency>
  10.130 +                        <release-version>1</release-version>
  10.131 +                        <specification-version>1.10.0.25</specification-version>
  10.132 +                    </run-dependency>
  10.133 +                </dependency>
  10.134 +                <dependency>
  10.135 +                    <code-name-base>org.netbeans.modules.websvc.restlib</code-name-base>
  10.136 +                    <build-prerequisite/>
  10.137 +                    <compile-dependency/>
  10.138 +                    <run-dependency>
  10.139 +                        <release-version>0</release-version>
  10.140 +                        <specification-version>1.9</specification-version>
  10.141 +                    </run-dependency>
  10.142 +                </dependency>
  10.143 +                <dependency>
  10.144 +                    <code-name-base>org.netbeans.spi.editor.hints</code-name-base>
  10.145 +                    <build-prerequisite/>
  10.146 +                    <compile-dependency/>
  10.147 +                    <run-dependency>
  10.148 +                        <release-version>0</release-version>
  10.149 +                        <specification-version>1.16.0.7.6</specification-version>
  10.150 +                    </run-dependency>
  10.151 +                </dependency>
  10.152 +                <dependency>
  10.153 +                    <code-name-base>org.openide.filesystems</code-name-base>
  10.154 +                    <build-prerequisite/>
  10.155 +                    <compile-dependency/>
  10.156 +                    <run-dependency>
  10.157 +                        <specification-version>7.45</specification-version>
  10.158 +                    </run-dependency>
  10.159 +                </dependency>
  10.160 +                <dependency>
  10.161 +                    <code-name-base>org.openide.modules</code-name-base>
  10.162 +                    <build-prerequisite/>
  10.163 +                    <compile-dependency/>
  10.164 +                    <run-dependency>
  10.165 +                        <specification-version>7.21</specification-version>
  10.166 +                    </run-dependency>
  10.167 +                </dependency>
  10.168 +                <dependency>
  10.169 +                    <code-name-base>org.openide.text</code-name-base>
  10.170 +                    <build-prerequisite/>
  10.171 +                    <compile-dependency/>
  10.172 +                    <run-dependency>
  10.173 +                        <specification-version>6.35</specification-version>
  10.174 +                    </run-dependency>
  10.175 +                </dependency>
  10.176 +                <dependency>
  10.177 +                    <code-name-base>org.openide.util</code-name-base>
  10.178 +                    <build-prerequisite/>
  10.179 +                    <compile-dependency/>
  10.180 +                    <run-dependency>
  10.181 +                        <specification-version>8.12</specification-version>
  10.182 +                    </run-dependency>
  10.183 +                </dependency>
  10.184 +                <dependency>
  10.185 +                    <code-name-base>org.openide.util.lookup</code-name-base>
  10.186 +                    <build-prerequisite/>
  10.187 +                    <compile-dependency/>
  10.188 +                    <run-dependency>
  10.189 +                        <specification-version>8.5</specification-version>
  10.190 +                    </run-dependency>
  10.191 +                </dependency>
  10.192 +            </module-dependencies>
  10.193 +            <public-packages/>
  10.194 +        </data>
  10.195 +    </configuration>
  10.196 +</project>
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/server/backend/impl/nbproject/suite.properties	Fri Feb 11 22:33:43 2011 +0100
    11.3 @@ -0,0 +1,1 @@
    11.4 +suite.dir=${basedir}/..
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/Bundle.properties	Fri Feb 11 22:33:43 2011 +0100
    12.3 @@ -0,0 +1,1 @@
    12.4 +OpenIDE-Module-Name=Jackpot 3.0 Backend Impl
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/CategoryStorage.java	Fri Feb 11 22:33:43 2011 +0100
    13.3 @@ -0,0 +1,126 @@
    13.4 +/*
    13.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    13.6 + *
    13.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
    13.8 + *
    13.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   13.10 + * Other names may be trademarks of their respective owners.
   13.11 + *
   13.12 + * The contents of this file are subject to the terms of either the GNU
   13.13 + * General Public License Version 2 only ("GPL") or the Common
   13.14 + * Development and Distribution License("CDDL") (collectively, the
   13.15 + * "License"). You may not use this file except in compliance with the
   13.16 + * License. You can obtain a copy of the License at
   13.17 + * http://www.netbeans.org/cddl-gplv2.html
   13.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   13.19 + * specific language governing permissions and limitations under the
   13.20 + * License.  When distributing the software, include this License Header
   13.21 + * Notice in each file and include the License file at
   13.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   13.23 + * particular file as subject to the "Classpath" exception as provided
   13.24 + * by Oracle in the GPL Version 2 section of the License file that
   13.25 + * accompanied this code. If applicable, add the following below the
   13.26 + * License Header, with the fields enclosed by brackets [] replaced by
   13.27 + * your own identifying information:
   13.28 + * "Portions Copyrighted [year] [name of copyright owner]"
   13.29 + *
   13.30 + * If you wish your version of this file to be governed by only the CDDL
   13.31 + * or only the GPL Version 2, indicate your decision by adding
   13.32 + * "[Contributor] elects to include this software in this distribution
   13.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
   13.34 + * single choice of license, a recipient has the option to distribute
   13.35 + * your version of this file under either the CDDL, the GPL Version 2 or
   13.36 + * to extend the choice of license to its licensees as provided above.
   13.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
   13.38 + * Version 2 license, then the option applies only if the new code is
   13.39 + * made subject to such option by the copyright holder.
   13.40 + *
   13.41 + * Contributor(s):
   13.42 + *
   13.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
   13.44 + */
   13.45 +package org.netbeans.modules.jackpot30.backend.impl;
   13.46 +
   13.47 +import java.net.MalformedURLException;
   13.48 +import java.net.URL;
   13.49 +import java.util.HashMap;
   13.50 +import java.util.HashSet;
   13.51 +import java.util.Map;
   13.52 +import java.util.Set;
   13.53 +import java.util.prefs.BackingStoreException;
   13.54 +import java.util.prefs.Preferences;
   13.55 +import org.openide.filesystems.FileObject;
   13.56 +import org.openide.filesystems.FileStateInvalidException;
   13.57 +import org.openide.filesystems.URLMapper;
   13.58 +import org.openide.util.Exceptions;
   13.59 +import org.openide.util.NbPreferences;
   13.60 +
   13.61 +/**
   13.62 + *
   13.63 + * @author lahvac
   13.64 + */
   13.65 +public class CategoryStorage {
   13.66 +
   13.67 +    public static void setCategoryContent(String categoryId, String categoryName, Set<FileObject> content) {
   13.68 +        Preferences categoriesNode = NbPreferences.forModule(CategoryStorage.class).node("categories");
   13.69 +
   13.70 +        categoriesNode.put(categoryId + "_displayName", categoryName);
   13.71 +
   13.72 +        StringBuilder roots = new StringBuilder();
   13.73 +
   13.74 +        for (FileObject f : content) {
   13.75 +            if (roots.length() > 0) {
   13.76 +                roots.append(';');
   13.77 +            }
   13.78 +
   13.79 +            try {
   13.80 +                roots.append(f.getURL().toExternalForm());
   13.81 +            } catch (FileStateInvalidException ex) {
   13.82 +                Exceptions.printStackTrace(ex);
   13.83 +            }
   13.84 +        }
   13.85 +
   13.86 +        categoriesNode.put(categoryId + "_roots", roots.toString());
   13.87 +    }
   13.88 +
   13.89 +    public static Set<FileObject> getCategoryContent(String categoryId) {
   13.90 +        Preferences categoriesNode = NbPreferences.forModule(CategoryStorage.class).node("categories");
   13.91 +        String roots = categoriesNode.get(categoryId + "_roots", "");
   13.92 +        Set<FileObject> result = new HashSet<FileObject>();
   13.93 +
   13.94 +        for (String urlString : roots.split(";")) {
   13.95 +            if (urlString.isEmpty()) continue;
   13.96 +
   13.97 +            try {
   13.98 +                URL url = new URL(urlString);
   13.99 +                FileObject root = URLMapper.findFileObject(url);
  13.100 +
  13.101 +                if (root != null) {
  13.102 +                    result.add(root);
  13.103 +                }
  13.104 +            } catch (MalformedURLException ex) {
  13.105 +                Exceptions.printStackTrace(ex);
  13.106 +            }
  13.107 +        }
  13.108 +
  13.109 +        return result;
  13.110 +    }
  13.111 +
  13.112 +    public static Map<String, String> listCategoriesWithNames() {
  13.113 +        Map<String, String> result = new HashMap<String, String>();
  13.114 +        Preferences categoriesNode = NbPreferences.forModule(CategoryStorage.class).node("categories");
  13.115 +
  13.116 +        try {
  13.117 +            for (String key : categoriesNode.keys()) {
  13.118 +                if (key.endsWith("_displayName")) {
  13.119 +                    String id = key.substring(0, key.length() - "_displayName".length());
  13.120 +                    result.put(id, categoriesNode.get(key, id));
  13.121 +                }
  13.122 +            }
  13.123 +        } catch (BackingStoreException ex) {
  13.124 +            Exceptions.printStackTrace(ex);
  13.125 +        }
  13.126 +
  13.127 +        return result;
  13.128 +    }
  13.129 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/MainPage.java	Fri Feb 11 22:33:43 2011 +0100
    14.3 @@ -0,0 +1,59 @@
    14.4 +/*
    14.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    14.6 + *
    14.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
    14.8 + *
    14.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   14.10 + * Other names may be trademarks of their respective owners.
   14.11 + *
   14.12 + * The contents of this file are subject to the terms of either the GNU
   14.13 + * General Public License Version 2 only ("GPL") or the Common
   14.14 + * Development and Distribution License("CDDL") (collectively, the
   14.15 + * "License"). You may not use this file except in compliance with the
   14.16 + * License. You can obtain a copy of the License at
   14.17 + * http://www.netbeans.org/cddl-gplv2.html
   14.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   14.19 + * specific language governing permissions and limitations under the
   14.20 + * License.  When distributing the software, include this License Header
   14.21 + * Notice in each file and include the License file at
   14.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   14.23 + * particular file as subject to the "Classpath" exception as provided
   14.24 + * by Oracle in the GPL Version 2 section of the License file that
   14.25 + * accompanied this code. If applicable, add the following below the
   14.26 + * License Header, with the fields enclosed by brackets [] replaced by
   14.27 + * your own identifying information:
   14.28 + * "Portions Copyrighted [year] [name of copyright owner]"
   14.29 + *
   14.30 + * If you wish your version of this file to be governed by only the CDDL
   14.31 + * or only the GPL Version 2, indicate your decision by adding
   14.32 + * "[Contributor] elects to include this software in this distribution
   14.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
   14.34 + * single choice of license, a recipient has the option to distribute
   14.35 + * your version of this file under either the CDDL, the GPL Version 2 or
   14.36 + * to extend the choice of license to its licensees as provided above.
   14.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
   14.38 + * Version 2 license, then the option applies only if the new code is
   14.39 + * made subject to such option by the copyright holder.
   14.40 + *
   14.41 + * Contributor(s):
   14.42 + *
   14.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
   14.44 + */
   14.45 +
   14.46 +package org.netbeans.modules.jackpot30.backend.impl;
   14.47 +
   14.48 +import javax.ws.rs.GET;
   14.49 +import javax.ws.rs.Path;
   14.50 +
   14.51 +/**
   14.52 + *
   14.53 + * @author lahvac
   14.54 + */
   14.55 +@Path("/")
   14.56 +public class MainPage {
   14.57 +
   14.58 +    @GET
   14.59 +    public String main() {
   14.60 +        return "<html><body><ul><li><a href='index/ui/search'>Search Pattern</a></li><li><a href='index/ui/apply'>Apply Pattern</a></li></ul></body></html>";
   14.61 +    }
   14.62 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/OptionProcessorImpl.java	Fri Feb 11 22:33:43 2011 +0100
    15.3 @@ -0,0 +1,226 @@
    15.4 +/*
    15.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    15.6 + *
    15.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
    15.8 + *
    15.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   15.10 + * Other names may be trademarks of their respective owners.
   15.11 + *
   15.12 + * The contents of this file are subject to the terms of either the GNU
   15.13 + * General Public License Version 2 only ("GPL") or the Common
   15.14 + * Development and Distribution License("CDDL") (collectively, the
   15.15 + * "License"). You may not use this file except in compliance with the
   15.16 + * License. You can obtain a copy of the License at
   15.17 + * http://www.netbeans.org/cddl-gplv2.html
   15.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   15.19 + * specific language governing permissions and limitations under the
   15.20 + * License.  When distributing the software, include this License Header
   15.21 + * Notice in each file and include the License file at
   15.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   15.23 + * particular file as subject to the "Classpath" exception as provided
   15.24 + * by Oracle in the GPL Version 2 section of the License file that
   15.25 + * accompanied this code. If applicable, add the following below the
   15.26 + * License Header, with the fields enclosed by brackets [] replaced by
   15.27 + * your own identifying information:
   15.28 + * "Portions Copyrighted [year] [name of copyright owner]"
   15.29 + *
   15.30 + * If you wish your version of this file to be governed by only the CDDL
   15.31 + * or only the GPL Version 2, indicate your decision by adding
   15.32 + * "[Contributor] elects to include this software in this distribution
   15.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
   15.34 + * single choice of license, a recipient has the option to distribute
   15.35 + * your version of this file under either the CDDL, the GPL Version 2 or
   15.36 + * to extend the choice of license to its licensees as provided above.
   15.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
   15.38 + * Version 2 license, then the option applies only if the new code is
   15.39 + * made subject to such option by the copyright holder.
   15.40 + *
   15.41 + * Contributor(s):
   15.42 + *
   15.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
   15.44 + */
   15.45 +
   15.46 +package org.netbeans.modules.jackpot30.backend.impl;
   15.47 +
   15.48 +import com.sun.jersey.api.container.httpserver.HttpServerFactory;
   15.49 +import com.sun.jersey.api.core.ClassNamesResourceConfig;
   15.50 +import com.sun.net.httpserver.HttpServer;
   15.51 +import java.io.File;
   15.52 +import java.io.IOException;
   15.53 +import java.util.Arrays;
   15.54 +import java.util.HashSet;
   15.55 +import java.util.Map;
   15.56 +import java.util.Set;
   15.57 +import org.netbeans.api.java.classpath.ClassPath;
   15.58 +import org.netbeans.api.java.classpath.GlobalPathRegistry;
   15.59 +import org.netbeans.api.java.source.SourceUtils;
   15.60 +import org.netbeans.api.project.Project;
   15.61 +import org.netbeans.api.project.ProjectManager;
   15.62 +import org.netbeans.api.project.ProjectUtils;
   15.63 +import org.netbeans.api.project.SourceGroup;
   15.64 +import org.netbeans.api.sendopts.CommandException;
   15.65 +import org.netbeans.modules.jackpot30.backend.impl.api.API;
   15.66 +import org.netbeans.modules.jackpot30.backend.impl.ui.UI;
   15.67 +import org.netbeans.modules.jackpot30.impl.indexing.CustomIndexerImpl;
   15.68 +import org.netbeans.spi.java.classpath.support.ClassPathSupport;
   15.69 +import org.netbeans.spi.project.support.ant.PropertyUtils;
   15.70 +import org.netbeans.spi.sendopts.Env;
   15.71 +import org.netbeans.spi.sendopts.Option;
   15.72 +import org.netbeans.spi.sendopts.OptionProcessor;
   15.73 +import org.openide.LifecycleManager;
   15.74 +import org.openide.filesystems.FileObject;
   15.75 +import org.openide.filesystems.FileUtil;
   15.76 +import org.openide.util.Exceptions;
   15.77 +import org.openide.util.lookup.ServiceProvider;
   15.78 +
   15.79 +/**
   15.80 + *
   15.81 + * @author lahvac
   15.82 + */
   15.83 +@ServiceProvider(service=OptionProcessor.class)
   15.84 +public class OptionProcessorImpl extends OptionProcessor {
   15.85 +
   15.86 +    private final Option SHUTDOWN = Option.withoutArgument(Option.NO_SHORT_NAME, "shutdown");
   15.87 +    private final Option RESTART = Option.withoutArgument(Option.NO_SHORT_NAME, "restart"); //XXX: does not currently work
   15.88 +    private final Option START_SERVER = Option.withoutArgument(Option.NO_SHORT_NAME, "start-server");
   15.89 +    private final Option INDEX = Option.withoutArgument(Option.NO_SHORT_NAME, "index");
   15.90 +    private final Option CATEGORY_ID = Option.requiredArgument(Option.NO_SHORT_NAME, "category-id");
   15.91 +    private final Option CATEGORY_NAME = Option.requiredArgument(Option.NO_SHORT_NAME, "category-name");
   15.92 +    private final Option CATEGORY_PROJECTS = Option.additionalArguments(Option.NO_SHORT_NAME, "category-projects");
   15.93 +    private final Set<Option> OPTIONS = new HashSet<Option>(Arrays.asList(SHUTDOWN, RESTART, START_SERVER, INDEX, CATEGORY_ID, CATEGORY_NAME, CATEGORY_PROJECTS));
   15.94 +    
   15.95 +    @Override
   15.96 +    protected Set<Option> getOptions() {
   15.97 +        return OPTIONS;
   15.98 +    }
   15.99 +
  15.100 +    @Override
  15.101 +    protected void process(Env env, Map<Option, String[]> optionValues) throws CommandException {
  15.102 +        if (optionValues.containsKey(RESTART)) {
  15.103 +            LifecycleManager.getDefault().markForRestart();
  15.104 +        }
  15.105 +
  15.106 +        if (optionValues.containsKey(SHUTDOWN) || optionValues.containsKey(RESTART)) {
  15.107 +            LifecycleManager.getDefault().exit();
  15.108 +        }
  15.109 +
  15.110 +        if (optionValues.containsKey(START_SERVER)) {
  15.111 +            startServer(env);
  15.112 +        }
  15.113 +
  15.114 +        String categoryId = null;
  15.115 +        String categoryName = null;
  15.116 +
  15.117 +        if (optionValues.containsKey(CATEGORY_ID)) {
  15.118 +            categoryId = optionValues.get(CATEGORY_ID)[0];
  15.119 +        }
  15.120 +
  15.121 +        if (optionValues.containsKey(CATEGORY_NAME)) {
  15.122 +            categoryName = optionValues.get(CATEGORY_NAME)[0];
  15.123 +        }
  15.124 +
  15.125 +        if (optionValues.containsKey(CATEGORY_PROJECTS)) {
  15.126 +            if (categoryId == null) {
  15.127 +                env.getErrorStream().println("Error: no category-id specified!");
  15.128 +                return;
  15.129 +            }
  15.130 +
  15.131 +            if (categoryName == null) {
  15.132 +                env.getErrorStream().println("Warning: no category-name specified.");
  15.133 +                return;
  15.134 +            }
  15.135 +
  15.136 +            try {
  15.137 +                CategoryStorage.setCategoryContent(categoryId, categoryName, getRoots(optionValues.get(CATEGORY_PROJECTS), env));
  15.138 +            } catch (InterruptedException ex) {
  15.139 +                throw (CommandException) new CommandException(0).initCause(ex);
  15.140 +            }
  15.141 +        }
  15.142 +
  15.143 +        if (optionValues.containsKey(INDEX)) {
  15.144 +            if (categoryId == null) {
  15.145 +                env.getErrorStream().println("Error: no category-id specified!");
  15.146 +                return;
  15.147 +            }
  15.148 +            
  15.149 +            try {
  15.150 +                indexProjects(CategoryStorage.getCategoryContent(categoryId), env);
  15.151 +            } catch (InterruptedException ex) {
  15.152 +                throw (CommandException) new CommandException(0).initCause(ex);
  15.153 +            }
  15.154 +        }
  15.155 +    }
  15.156 +
  15.157 +    private Set<FileObject> getRoots(String[] projects, Env env) throws IllegalArgumentException, InterruptedException {
  15.158 +        Set<FileObject> sourceRoots = new HashSet<FileObject>(projects.length * 4 / 3 + 1);
  15.159 +
  15.160 +        for (String p : projects) {
  15.161 +            File f = PropertyUtils.resolveFile(env.getCurrentDirectory(), p);
  15.162 +            File normalized = FileUtil.normalizeFile(f);
  15.163 +            FileObject prjFO = FileUtil.toFileObject(normalized);
  15.164 +
  15.165 +            if (prjFO == null) {
  15.166 +                env.getErrorStream().println("Project location cannot be found: " + p);
  15.167 +                continue;
  15.168 +            }
  15.169 +
  15.170 +            if (!prjFO.isFolder()) {
  15.171 +                env.getErrorStream().println("Project specified as: " + p + " does not point to a directory (" + FileUtil.getFileDisplayName(prjFO));
  15.172 +                continue;
  15.173 +            }
  15.174 +
  15.175 +            try {
  15.176 +                Project prj = ProjectManager.getDefault().findProject(prjFO);
  15.177 +
  15.178 +                if (prj == null) {
  15.179 +                    env.getErrorStream().println("Project specified as: " + p + " does not resolve to a project (" + FileUtil.getFileDisplayName(prjFO));
  15.180 +                    continue;
  15.181 +                }
  15.182 +
  15.183 +                SourceGroup[] javaSG = ProjectUtils.getSources(prj).getSourceGroups("java");
  15.184 +
  15.185 +                if (javaSG.length == 0) {
  15.186 +                    env.getErrorStream().println("Project specified as: " + p + " does not define a java source groups (" + FileUtil.getFileDisplayName(prjFO));
  15.187 +                    continue;
  15.188 +                }
  15.189 +
  15.190 +                for (SourceGroup sg : javaSG) {
  15.191 +                    sourceRoots.add(sg.getRootFolder());
  15.192 +                }
  15.193 +            } catch (IOException ex) {
  15.194 +                Exceptions.printStackTrace(ex);
  15.195 +            } catch (IllegalArgumentException ex) {
  15.196 +                Exceptions.printStackTrace(ex);
  15.197 +            }
  15.198 +        }
  15.199 +
  15.200 +        return sourceRoots;
  15.201 +    }
  15.202 +
  15.203 +    private void indexProjects(Set<FileObject> sourceRoots, Env env) throws IllegalArgumentException, InterruptedException {
  15.204 +        if (sourceRoots.isEmpty()) {
  15.205 +            env.getErrorStream().println("Error: There is nothing to index!");
  15.206 +        } else {
  15.207 +            System.setProperty(CustomIndexerImpl.class.getName() + "-attributed", "true");//force partially attributed Jackpot index
  15.208 +            org.netbeans.api.project.ui.OpenProjects.getDefault().getOpenProjects();
  15.209 +            ClassPath source = ClassPathSupport.createClassPath(sourceRoots.toArray(new FileObject[0]));
  15.210 +
  15.211 +            GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[] {source});
  15.212 +            SourceUtils.waitScanFinished();
  15.213 +            GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, new ClassPath[] {source});
  15.214 +        }
  15.215 +    }
  15.216 +
  15.217 +    private void startServer(Env env) {
  15.218 +        try {
  15.219 +            HttpServer server = HttpServerFactory.create("http://localhost:9998/", new ClassNamesResourceConfig(API.class, UI.class, MainPage.class));
  15.220 +
  15.221 +            server.start();
  15.222 +        } catch (IOException ex) {
  15.223 +            Exceptions.printStackTrace(ex);
  15.224 +        } catch (IllegalArgumentException ex) {
  15.225 +            Exceptions.printStackTrace(ex);
  15.226 +        }
  15.227 +    }
  15.228 +
  15.229 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/api/API.java	Fri Feb 11 22:33:43 2011 +0100
    16.3 @@ -0,0 +1,456 @@
    16.4 +/*
    16.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    16.6 + *
    16.7 + * Copyright 2009-2010 Sun Microsystems, Inc. All rights reserved.
    16.8 + *
    16.9 + * The contents of this file are subject to the terms of either the GNU
   16.10 + * General Public License Version 2 only ("GPL") or the Common
   16.11 + * Development and Distribution License("CDDL") (collectively, the
   16.12 + * "License"). You may not use this file except in compliance with the
   16.13 + * License. You can obtain a copy of the License at
   16.14 + * http://www.netbeans.org/cddl-gplv2.html
   16.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   16.16 + * specific language governing permissions and limitations under the
   16.17 + * License.  When distributing the software, include this License Header
   16.18 + * Notice in each file and include the License file at
   16.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
   16.20 + * particular file as subject to the "Classpath" exception as provided
   16.21 + * by Sun in the GPL Version 2 section of the License file that
   16.22 + * accompanied this code. If applicable, add the following below the
   16.23 + * License Header, with the fields enclosed by brackets [] replaced by
   16.24 + * your own identifying information:
   16.25 + * "Portions Copyrighted [year] [name of copyright owner]"
   16.26 + *
   16.27 + * If you wish your version of this file to be governed by only the CDDL
   16.28 + * or only the GPL Version 2, indicate your decision by adding
   16.29 + * "[Contributor] elects to include this software in this distribution
   16.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
   16.31 + * single choice of license, a recipient has the option to distribute
   16.32 + * your version of this file under either the CDDL, the GPL Version 2 or
   16.33 + * to extend the choice of license to its licensees as provided above.
   16.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
   16.35 + * Version 2 license, then the option applies only if the new code is
   16.36 + * made subject to such option by the copyright holder.
   16.37 + *
   16.38 + * Contributor(s):
   16.39 + *
   16.40 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
   16.41 + */
   16.42 +
   16.43 +package org.netbeans.modules.jackpot30.backend.impl.api;
   16.44 +
   16.45 +import java.io.File;
   16.46 +import java.io.IOException;
   16.47 +import java.io.OutputStream;
   16.48 +import java.io.OutputStreamWriter;
   16.49 +import java.io.StringWriter;
   16.50 +import java.io.Writer;
   16.51 +import java.lang.reflect.Method;
   16.52 +import java.lang.reflect.Modifier;
   16.53 +import java.net.URL;
   16.54 +import java.util.ArrayList;
   16.55 +import java.util.Arrays;
   16.56 +import java.util.Collection;
   16.57 +import java.util.Collections;
   16.58 +import java.util.HashMap;
   16.59 +import java.util.LinkedList;
   16.60 +import java.util.List;
   16.61 +import java.util.Map;
   16.62 +import java.util.Map.Entry;
   16.63 +import java.util.Set;
   16.64 +import java.util.concurrent.atomic.AtomicBoolean;
   16.65 +import java.util.concurrent.atomic.AtomicLong;
   16.66 +import javax.tools.Diagnostic;
   16.67 +import javax.tools.JavaFileObject;
   16.68 +import javax.ws.rs.DefaultValue;
   16.69 +import javax.ws.rs.GET;
   16.70 +import javax.ws.rs.Path;
   16.71 +import javax.ws.rs.Produces;
   16.72 +import javax.ws.rs.QueryParam;
   16.73 +import javax.ws.rs.WebApplicationException;
   16.74 +import javax.ws.rs.core.StreamingOutput;
   16.75 +import org.codeviation.pojson.Pojson;
   16.76 +import org.netbeans.api.java.classpath.ClassPath;
   16.77 +import org.netbeans.api.java.source.CompilationController;
   16.78 +import org.netbeans.api.java.source.ModificationResult;
   16.79 +import org.netbeans.modules.jackpot30.backend.impl.CategoryStorage;
   16.80 +import org.netbeans.modules.jackpot30.impl.MessageImpl;
   16.81 +import org.netbeans.modules.jackpot30.impl.batch.BatchSearch;
   16.82 +import org.netbeans.modules.jackpot30.impl.batch.BatchSearch.BatchResult;
   16.83 +import org.netbeans.modules.jackpot30.impl.batch.BatchSearch.Resource;
   16.84 +import org.netbeans.modules.jackpot30.impl.batch.BatchSearch.Scope;
   16.85 +import org.netbeans.modules.jackpot30.impl.batch.BatchUtilities;
   16.86 +import org.netbeans.modules.jackpot30.impl.batch.ProgressHandleWrapper;
   16.87 +import org.netbeans.modules.jackpot30.impl.examples.Example;
   16.88 +import org.netbeans.modules.jackpot30.impl.examples.Example.Option;
   16.89 +import org.netbeans.modules.jackpot30.impl.examples.LoadExamples;
   16.90 +import org.netbeans.modules.jackpot30.impl.indexing.Cache;
   16.91 +import org.netbeans.modules.jackpot30.impl.indexing.FileBasedIndex;
   16.92 +import org.netbeans.modules.jackpot30.impl.indexing.Index;
   16.93 +import org.netbeans.modules.jackpot30.spi.HintDescription;
   16.94 +import org.netbeans.modules.jackpot30.spi.PatternConvertor;
   16.95 +import org.netbeans.spi.editor.hints.ErrorDescription;
   16.96 +import org.netbeans.spi.java.classpath.support.ClassPathSupport;
   16.97 +import org.openide.filesystems.FileObject;
   16.98 +import org.openide.filesystems.FileUtil;
   16.99 +import org.openide.util.Exceptions;
  16.100 +
  16.101 +/**
  16.102 + *
  16.103 + * @author lahvac
  16.104 + */
  16.105 +@Path("/index")
  16.106 +public class API {
  16.107 +
  16.108 +    @GET
  16.109 +    @Path("/find")
  16.110 +    @Produces("text/plain")
  16.111 +    //TODO: parameter for "verified"?
  16.112 +    public String find(@QueryParam("path") String segment, @QueryParam("pattern") String pattern, @QueryParam("asynchronous") @DefaultValue(value="false") boolean asynchronous) throws IOException {
  16.113 +        assert !asynchronous;
  16.114 +
  16.115 +        Iterable<? extends HintDescription> hints = PatternConvertor.create(pattern);
  16.116 +        Set<FileObject> srcRoots = CategoryStorage.getCategoryContent(segment);
  16.117 +        final FileObject deepestCommonParent = deepestCommonParent(srcRoots);
  16.118 +        BatchResult batchResult = BatchSearch.findOccurrences(hints, Scope.createGivenSourceRoots(true, srcRoots.toArray(new FileObject[0])));
  16.119 +        final StringBuilder result = new StringBuilder();
  16.120 +
  16.121 +        BatchSearch.getVerifiedSpans(batchResult, new ProgressHandleWrapper(1), new BatchSearch.VerifiedSpansCallBack() {
  16.122 +            @Override public void groupStarted() {}
  16.123 +            @Override public boolean spansVerified(CompilationController wc, Resource r, Collection<? extends ErrorDescription> hints) throws Exception {
  16.124 +                if (!hints.isEmpty()) {
  16.125 +                    result.append(FileUtil.getRelativePath(deepestCommonParent, r.getResolvedFile()));
  16.126 +                    result.append("\n");
  16.127 +                }
  16.128 +                System.err.println("processed file=" + r.getRelativePath());
  16.129 +                return true;
  16.130 +            }
  16.131 +            @Override public void groupFinished() {}
  16.132 +            @Override public void cannotVerifySpan(Resource r) { /*TODO: warn user?*/ }
  16.133 +        }, true, new LinkedList<MessageImpl>()); //TODO: show the messages to the user?
  16.134 +
  16.135 +        return result.toString();
  16.136 +    }
  16.137 +
  16.138 +//    @GET
  16.139 +//    @Path("/findCategorize")
  16.140 +//    @Produces("text/plain")
  16.141 +//    public String findCategorize(@QueryParam("path") final String segment, @QueryParam("pattern") final String pattern, @QueryParam("asynchronous") @DefaultValue(value="false") boolean asynchronous) throws IOException {
  16.142 +//        assert asynchronous;
  16.143 +//
  16.144 +//        long id = this.id.getAndIncrement();
  16.145 +//        final ProgressImpl progress = new ProgressImpl();
  16.146 +//
  16.147 +//        workInProgress.put(id, progress);
  16.148 +//
  16.149 +//        new Thread(new Runnable() {
  16.150 +//            public void run() {
  16.151 +//                try {
  16.152 +//                    File sourceRoot = Cache.sourceRootForKey(segment);
  16.153 +//                    Index idx = FileBasedIndex.get(sourceRoot.toURI().toURL());
  16.154 +//                    new SortedQuery().query(idx, pattern, progress);
  16.155 +//                } catch (IOException ex) {
  16.156 +//                    ex.printStackTrace();
  16.157 +//                    progress.finish();
  16.158 +//                }
  16.159 +//            }
  16.160 +//        }).start();
  16.161 +//
  16.162 +//        return Long.toString(id);
  16.163 +//    }
  16.164 +
  16.165 +    @GET
  16.166 +    @Path("/findSpans")
  16.167 +    @Produces("text/plain")
  16.168 +    public String findSpans(@QueryParam("path") String segment, @QueryParam("relativePath") String relativePath, @QueryParam("pattern") String pattern) throws IOException {
  16.169 +        Iterable<? extends HintDescription> hints = PatternConvertor.create(pattern);
  16.170 +        Set<FileObject> srcRoots = CategoryStorage.getCategoryContent(segment);
  16.171 +        FileObject deepestCommonParent = deepestCommonParent(srcRoots);
  16.172 +        BatchResult batchResult = BatchSearch.findOccurrences(hints, Scope.createGivenSourceRoots(deepestCommonParent.getFileObject(relativePath)));
  16.173 +        final StringBuilder result = new StringBuilder();
  16.174 +
  16.175 +        BatchSearch.getVerifiedSpans(batchResult, new ProgressHandleWrapper(1), new BatchSearch.VerifiedSpansCallBack() {
  16.176 +            @Override public void groupStarted() {}
  16.177 +            @Override public boolean spansVerified(CompilationController wc, Resource r, Collection<? extends ErrorDescription> hints) throws Exception {
  16.178 +                for (ErrorDescription ed : hints) {
  16.179 +                    result.append(ed.getRange().getBegin().getOffset());
  16.180 +                    result.append(":");
  16.181 +                    result.append(ed.getRange().getEnd().getOffset());
  16.182 +                    result.append(":");
  16.183 +                }
  16.184 +                return true;
  16.185 +            }
  16.186 +            @Override public void groupFinished() {}
  16.187 +            @Override public void cannotVerifySpan(Resource r) { /*TODO: warn user?*/ }
  16.188 +        }, true, new LinkedList<MessageImpl>()); //TODO: show the messages to the user?
  16.189 +
  16.190 +        if (result.length() > 0) {
  16.191 +            result.delete(result.length() - 1, result.length());
  16.192 +        }
  16.193 +        return result.toString();
  16.194 +    }
  16.195 +
  16.196 +    @GET
  16.197 +    @Path("/list")
  16.198 +    @Produces("text/plain")
  16.199 +    public String list() throws IOException {
  16.200 +        StringBuilder sb = new StringBuilder();
  16.201 +
  16.202 +        for (Entry<String, String> e : CategoryStorage.listCategoriesWithNames().entrySet()) {
  16.203 +            sb.append(e.getKey());
  16.204 +            sb.append(":");
  16.205 +            sb.append(e.getValue());
  16.206 +            sb.append("\n");
  16.207 +        }
  16.208 +
  16.209 +        return sb.toString();
  16.210 +    }
  16.211 +
  16.212 +    @GET
  16.213 +    @Path("/cat")
  16.214 +    @Produces("text/plain")
  16.215 +    public String cat(@QueryParam("path") String segment, @QueryParam("relative") String relative) throws IOException {
  16.216 +        Set<FileObject> srcRoots = CategoryStorage.getCategoryContent(segment);
  16.217 +        FileObject deepestCommonParent = deepestCommonParent(srcRoots);
  16.218 +        FileObject file = deepestCommonParent.getFileObject(relative);
  16.219 +        ClassPath cp = ClassPathSupport.createClassPath(srcRoots.toArray(new FileObject[0]));
  16.220 +        FileObject root = cp.findOwnerRoot(file);
  16.221 +        String path = cp.getResourceName(file);
  16.222 +        Index index = FileBasedIndex.get(root.getURL());
  16.223 +
  16.224 +        if (index == null) {
  16.225 +            throw new IOException("No index");
  16.226 +        }
  16.227 +
  16.228 +        CharSequence source = index.getSourceCode(path);
  16.229 +
  16.230 +        if (source == null) {
  16.231 +            throw new IOException("Source code not found");
  16.232 +        }
  16.233 +        
  16.234 +        return source.toString().replaceAll("\r\n", "\n");
  16.235 +    }
  16.236 +
  16.237 +    @GET
  16.238 +    @Path("/apply")
  16.239 +    @Produces("text/diff")
  16.240 +    //TODO: parameter for "verified"?
  16.241 +    public StreamingOutput apply(@QueryParam("path") String segment, @QueryParam("pattern") String pattern, @QueryParam("asynchronous") @DefaultValue(value="false") boolean asynchronous) throws IOException {
  16.242 +        assert !asynchronous;
  16.243 +
  16.244 +        Iterable<? extends HintDescription> hints = PatternConvertor.create(pattern);
  16.245 +        Set<FileObject> srcRoots = CategoryStorage.getCategoryContent(segment);
  16.246 +        final FileObject deepestCommonParent = deepestCommonParent(srcRoots);
  16.247 +        BatchResult batchResult = BatchSearch.findOccurrences(hints, Scope.createGivenSourceRoots(srcRoots.toArray(new FileObject[0])));
  16.248 +        final Collection<ModificationResult> modifications = BatchUtilities.applyFixes(batchResult, new ProgressHandleWrapper(1), new AtomicBoolean(), new LinkedList<MessageImpl>());
  16.249 +
  16.250 +        return new StreamingOutput() {
  16.251 +            @Override public void write(OutputStream output) throws IOException, WebApplicationException {
  16.252 +                Writer w = new OutputStreamWriter(output, "UTF-8");
  16.253 +
  16.254 +                try {
  16.255 +                    for (ModificationResult modResult : modifications) {
  16.256 +                        BatchUtilities.exportDiff(modResult, deepestCommonParent, w);
  16.257 +                    }
  16.258 +                } finally {
  16.259 +                    try {
  16.260 +                        w.close();
  16.261 +                    } catch (IOException ex) {
  16.262 +                        Exceptions.printStackTrace(ex);
  16.263 +                    }
  16.264 +                }
  16.265 +            }
  16.266 +        };
  16.267 +    }
  16.268 +
  16.269 +//    @GET
  16.270 +//    @Path("/info")
  16.271 +//    @Produces("text/plain")
  16.272 +//    public String info(@QueryParam("path") String segment) throws IOException {
  16.273 +//        URL sourceRoot = Cache.sourceRootForKey(segment).toURI().toURL();
  16.274 +//        Index index = FileBasedIndex.get(sourceRoot);
  16.275 +//
  16.276 +//        if (index == null) {
  16.277 +//            throw new IOException("No index");
  16.278 +//        }
  16.279 +//
  16.280 +//        return Pojson.save(index.getIndexInfo());
  16.281 +//    }
  16.282 +
  16.283 +    @GET
  16.284 +    @Path("/examples")
  16.285 +    @Produces("text/plain")
  16.286 +    public String examples() throws IOException {
  16.287 +        List<Map<String, String>> examples = new LinkedList<Map<String, String>>();
  16.288 +
  16.289 +        for (Example ex : LoadExamples.loadExamples()) {
  16.290 +            if (ex.getOptions().contains(Option.VERIFY) || ex.getOptions().contains(Option.FIX)) continue;
  16.291 +            Map<String, String> desc = new HashMap<String, String>();
  16.292 +
  16.293 +            desc.put("displayName", ex.getDisplayName());
  16.294 +            desc.put("pattern", ex.getCode());
  16.295 +
  16.296 +            examples.add(desc);
  16.297 +        }
  16.298 +
  16.299 +        return Pojson.save(examples);
  16.300 +    }
  16.301 +
  16.302 +    @GET
  16.303 +    @Path("/errors")
  16.304 +    @Produces("text/plain")
  16.305 +    public String errors(@QueryParam("pattern") String pattern) throws IOException {
  16.306 +        StringBuilder sb = new StringBuilder();
  16.307 +
  16.308 +        for (Diagnostic<? extends JavaFileObject> d : StandaloneFinder.parseAndReportErrors(pattern)) {
  16.309 +            sb.append(d.getMessage(null));
  16.310 +            sb.append("\n");
  16.311 +        }
  16.312 +
  16.313 +        return sb.toString();
  16.314 +    }
  16.315 +
  16.316 +    @GET
  16.317 +    @Path("/findDuplicates")
  16.318 +    @Produces("text/plain")
  16.319 +    public String findDuplicates(@QueryParam("path") String segment, @QueryParam("hashes") String hashes) throws IOException {
  16.320 +        Map<String, Map<String, Collection<? extends String>>> hash2Segment2Contains = new HashMap<String, Map<String, Collection<? extends String>>>();
  16.321 +        Collection<String> segments = new LinkedList<String>();
  16.322 +
  16.323 +        if (segment != null) segments.add(segment);
  16.324 +        else {
  16.325 +            for (String key : Cache.knownSourceRoots()) {
  16.326 +                segments.add(key);
  16.327 +            }
  16.328 +        }
  16.329 +
  16.330 +        Iterable<? extends String> hashesList = Arrays.asList(Pojson.load(String[].class, hashes));
  16.331 +
  16.332 +        for (String key : segments) {
  16.333 +            Map<String, Collection<? extends String>> found = StandaloneFinder.containsHash(Cache.sourceRootForKey(key), hashesList);
  16.334 +
  16.335 +            for (Entry<String, Collection<? extends String>> e : found.entrySet()) {
  16.336 +                Map<String, Collection<? extends String>> perRoot = hash2Segment2Contains.get(e.getKey());
  16.337 +
  16.338 +                if (perRoot == null) {
  16.339 +                    hash2Segment2Contains.put(e.getKey(), perRoot = new HashMap<String, Collection<? extends String>>());
  16.340 +                }
  16.341 +
  16.342 +                perRoot.put(key, e.getValue());
  16.343 +            }
  16.344 +        }
  16.345 +
  16.346 +        return Pojson.save(hash2Segment2Contains);
  16.347 +    }
  16.348 +
  16.349 +    @GET
  16.350 +    @Path("/checkProgress")
  16.351 +    @Produces("text/plain")
  16.352 +    public String checkProgress(@QueryParam("id") long id) throws IOException {
  16.353 +        ProgressImpl progress = workInProgress.get(id);
  16.354 +        Map<String, Object> result;
  16.355 +
  16.356 +        if (progress == null) {
  16.357 +            result = new HashMap<String, Object>();
  16.358 +            result.put("total", 0);
  16.359 +            result.put("workDone", 0);
  16.360 +            result.put("finished", true);
  16.361 +            result.put("result", Collections.<String>emptyList());
  16.362 +        } else {
  16.363 +            result = progress.progressPacket();
  16.364 +        }
  16.365 +
  16.366 +        if (result.get("finished") == Boolean.TRUE) {
  16.367 +            workInProgress.remove(id);
  16.368 +        }
  16.369 +
  16.370 +        return Pojson.save(result);
  16.371 +    }
  16.372 +
  16.373 +    @GET
  16.374 +    @Path("/cancelProgress")
  16.375 +    @Produces("text/plain")
  16.376 +    public String cancelProgress(@QueryParam("id") long id) throws IOException {
  16.377 +        ProgressImpl progress = workInProgress.get(id);
  16.378 +
  16.379 +        if (progress != null) {
  16.380 +            progress.cancel.set(true);
  16.381 +        }
  16.382 +
  16.383 +        return "done";
  16.384 +    }
  16.385 +
  16.386 +    @GET
  16.387 +    @Path("/capabilities")
  16.388 +    @Produces("text/plain")
  16.389 +    public String capabilities() throws IOException {
  16.390 +        StringBuilder sb = new StringBuilder();
  16.391 +
  16.392 +        for (Method m : API.class.getDeclaredMethods()) {
  16.393 +            if (m.isAnnotationPresent(GET.class) && (m.getModifiers() & Modifier.PUBLIC) != 0) {
  16.394 +                sb.append(m.getName());
  16.395 +                sb.append("\n");
  16.396 +            }
  16.397 +        }
  16.398 +
  16.399 +        return sb.toString();
  16.400 +    }
  16.401 +
  16.402 +    private static FileObject deepestCommonParent(Set<FileObject> roots) {
  16.403 +        FileObject result = null;
  16.404 +
  16.405 +        for (FileObject r : roots) {
  16.406 +            if (result == null) {
  16.407 +                result = r;
  16.408 +            } else {
  16.409 +                while (!FileUtil.isParentOf(result, r)) {
  16.410 +                    result = result.getParent();
  16.411 +                }
  16.412 +            }
  16.413 +        }
  16.414 +
  16.415 +        return result;
  16.416 +    }
  16.417 +
  16.418 +    private final static AtomicLong id = new AtomicLong();
  16.419 +    private final static Map<Long, ProgressImpl> workInProgress = new HashMap<Long, ProgressImpl>();//XXX: should be cleared eventually even if not read
  16.420 +
  16.421 +    private static final class ProgressImpl implements Progress {
  16.422 +        private int total = -1;
  16.423 +        private int workDone = 0;
  16.424 +        private boolean finished;
  16.425 +        private final List<String> result = new ArrayList<String>();
  16.426 +        private final AtomicBoolean cancel = new AtomicBoolean();
  16.427 +        public synchronized void setTotalWork(int total) {
  16.428 +            this.total = total;
  16.429 +        }
  16.430 +        public synchronized void progress(int totalDone) {
  16.431 +            workDone = totalDone;
  16.432 +        }
  16.433 +        public synchronized void updateProgress(int updateDone) {
  16.434 +            workDone += updateDone;
  16.435 +        }
  16.436 +        public synchronized void addResultPart(String part) {
  16.437 +            result.add(part);
  16.438 +        }
  16.439 +        public synchronized void finish() {
  16.440 +            finished = true;
  16.441 +        }
  16.442 +        public synchronized boolean isCancelled() {
  16.443 +            return cancel.get();
  16.444 +        }
  16.445 +        synchronized Map<String, Object> progressPacket() {
  16.446 +            Map<String, Object> result = new HashMap<String, Object>();
  16.447 +
  16.448 +            result.put("total", total);
  16.449 +            result.put("workDone", workDone);
  16.450 +            result.put("finished", finished);
  16.451 +            result.put("result", new ArrayList<String>(this.result));
  16.452 +
  16.453 +            this.result.clear();
  16.454 +
  16.455 +            return result;
  16.456 +        }
  16.457 +    }
  16.458 +
  16.459 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/api/Progress.java	Fri Feb 11 22:33:43 2011 +0100
    17.3 @@ -0,0 +1,60 @@
    17.4 +/*
    17.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    17.6 + *
    17.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
    17.8 + *
    17.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   17.10 + * Other names may be trademarks of their respective owners.
   17.11 + *
   17.12 + * The contents of this file are subject to the terms of either the GNU
   17.13 + * General Public License Version 2 only ("GPL") or the Common
   17.14 + * Development and Distribution License("CDDL") (collectively, the
   17.15 + * "License"). You may not use this file except in compliance with the
   17.16 + * License. You can obtain a copy of the License at
   17.17 + * http://www.netbeans.org/cddl-gplv2.html
   17.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   17.19 + * specific language governing permissions and limitations under the
   17.20 + * License.  When distributing the software, include this License Header
   17.21 + * Notice in each file and include the License file at
   17.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   17.23 + * particular file as subject to the "Classpath" exception as provided
   17.24 + * by Oracle in the GPL Version 2 section of the License file that
   17.25 + * accompanied this code. If applicable, add the following below the
   17.26 + * License Header, with the fields enclosed by brackets [] replaced by
   17.27 + * your own identifying information:
   17.28 + * "Portions Copyrighted [year] [name of copyright owner]"
   17.29 + *
   17.30 + * If you wish your version of this file to be governed by only the CDDL
   17.31 + * or only the GPL Version 2, indicate your decision by adding
   17.32 + * "[Contributor] elects to include this software in this distribution
   17.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
   17.34 + * single choice of license, a recipient has the option to distribute
   17.35 + * your version of this file under either the CDDL, the GPL Version 2 or
   17.36 + * to extend the choice of license to its licensees as provided above.
   17.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
   17.38 + * Version 2 license, then the option applies only if the new code is
   17.39 + * made subject to such option by the copyright holder.
   17.40 + *
   17.41 + * Contributor(s):
   17.42 + *
   17.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
   17.44 + */
   17.45 +
   17.46 +package org.netbeans.modules.jackpot30.backend.impl.api;
   17.47 +
   17.48 +/**
   17.49 + *
   17.50 + * @author lahvac
   17.51 + */
   17.52 +public interface Progress {
   17.53 +
   17.54 +    public void setTotalWork(int total);
   17.55 +    public void progress(int totalDone);
   17.56 +    public void updateProgress(int updateDone);
   17.57 +    public void addResultPart(String part);
   17.58 +    public void finish();
   17.59 +    
   17.60 +    public boolean isCancelled();
   17.61 +
   17.62 +
   17.63 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/api/StandaloneFinder.java	Fri Feb 11 22:33:43 2011 +0100
    18.3 @@ -0,0 +1,201 @@
    18.4 +/*
    18.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    18.6 + *
    18.7 + * Copyright 2009-2010 Sun Microsystems, Inc. All rights reserved.
    18.8 + *
    18.9 + * The contents of this file are subject to the terms of either the GNU
   18.10 + * General Public License Version 2 only ("GPL") or the Common
   18.11 + * Development and Distribution License("CDDL") (collectively, the
   18.12 + * "License"). You may not use this file except in compliance with the
   18.13 + * License. You can obtain a copy of the License at
   18.14 + * http://www.netbeans.org/cddl-gplv2.html
   18.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   18.16 + * specific language governing permissions and limitations under the
   18.17 + * License.  When distributing the software, include this License Header
   18.18 + * Notice in each file and include the License file at
   18.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
   18.20 + * particular file as subject to the "Classpath" exception as provided
   18.21 + * by Sun in the GPL Version 2 section of the License file that
   18.22 + * accompanied this code. If applicable, add the following below the
   18.23 + * License Header, with the fields enclosed by brackets [] replaced by
   18.24 + * your own identifying information:
   18.25 + * "Portions Copyrighted [year] [name of copyright owner]"
   18.26 + *
   18.27 + * If you wish your version of this file to be governed by only the CDDL
   18.28 + * or only the GPL Version 2, indicate your decision by adding
   18.29 + * "[Contributor] elects to include this software in this distribution
   18.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
   18.31 + * single choice of license, a recipient has the option to distribute
   18.32 + * your version of this file under either the CDDL, the GPL Version 2 or
   18.33 + * to extend the choice of license to its licensees as provided above.
   18.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
   18.35 + * Version 2 license, then the option applies only if the new code is
   18.36 + * made subject to such option by the copyright holder.
   18.37 + *
   18.38 + * Contributor(s):
   18.39 + *
   18.40 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
   18.41 + */
   18.42 +
   18.43 +package org.netbeans.modules.jackpot30.backend.impl.api;
   18.44 +
   18.45 +import com.sun.source.tree.CompilationUnitTree;
   18.46 +import com.sun.source.tree.Tree;
   18.47 +import com.sun.source.util.TreePath;
   18.48 +import com.sun.source.util.Trees;
   18.49 +import com.sun.tools.javac.api.JavacTaskImpl;
   18.50 +import java.io.File;
   18.51 +import java.io.IOException;
   18.52 +import java.net.URI;
   18.53 +import java.util.Arrays;
   18.54 +import java.util.BitSet;
   18.55 +import java.util.Collection;
   18.56 +import java.util.Collections;
   18.57 +import java.util.HashMap;
   18.58 +import java.util.LinkedList;
   18.59 +import java.util.Map;
   18.60 +import javax.tools.Diagnostic;
   18.61 +import javax.tools.JavaCompiler;
   18.62 +import javax.tools.JavaFileObject;
   18.63 +import javax.tools.SimpleJavaFileObject;
   18.64 +import javax.tools.ToolProvider;
   18.65 +import org.apache.lucene.document.Document;
   18.66 +import org.apache.lucene.index.IndexReader;
   18.67 +import org.apache.lucene.index.Term;
   18.68 +import org.apache.lucene.search.Collector;
   18.69 +import org.apache.lucene.search.IndexSearcher;
   18.70 +import org.apache.lucene.search.Query;
   18.71 +import org.apache.lucene.search.Searcher;
   18.72 +import org.apache.lucene.search.TermQuery;
   18.73 +import org.apache.lucene.store.FSDirectory;
   18.74 +import org.netbeans.modules.jackpot30.impl.Utilities;
   18.75 +import org.netbeans.modules.jackpot30.impl.duplicates.indexing.DuplicatesIndex;
   18.76 +import org.netbeans.modules.jackpot30.impl.indexing.AbstractLuceneIndex.BitSetCollector;
   18.77 +import org.netbeans.modules.jackpot30.impl.indexing.Cache;
   18.78 +import org.netbeans.modules.jackpot30.impl.indexing.FileBasedIndex;
   18.79 +import org.netbeans.modules.jackpot30.impl.pm.BulkSearch;
   18.80 +import org.netbeans.modules.jackpot30.impl.pm.BulkSearch.BulkPattern;
   18.81 +import org.netbeans.modules.jackpot30.spi.HintDescription;
   18.82 +import org.netbeans.modules.jackpot30.spi.HintDescription.AdditionalQueryConstraints;
   18.83 +import org.netbeans.modules.jackpot30.spi.PatternConvertor;
   18.84 +
   18.85 +/**
   18.86 + *
   18.87 + * @author lahvac
   18.88 + */
   18.89 +public class StandaloneFinder {
   18.90 +
   18.91 +    public static Collection<? extends String> findCandidates(File sourceRoot, String pattern) throws IOException {
   18.92 +        BulkPattern bulkPattern = preparePattern(pattern, null);
   18.93 +        
   18.94 +        return FileBasedIndex.get(sourceRoot.toURI().toURL()).findCandidates(bulkPattern);
   18.95 +    }
   18.96 +
   18.97 +    public static int[] findCandidateOccurrenceSpans(File sourceRoot, String relativePath, String pattern) throws IOException {
   18.98 +        BulkPattern bulkPattern = preparePattern(pattern, null);
   18.99 +        CharSequence source = FileBasedIndex.get(sourceRoot.toURI().toURL()).getSourceCode(relativePath).toString().replaceAll("\r\n", "\n");
  18.100 +        JavacTaskImpl jti = prepareJavacTaskImpl();
  18.101 +        CompilationUnitTree cut = jti.parse(new JFOImpl(source)).iterator().next();
  18.102 +        Collection<TreePath> paths = new LinkedList<TreePath>();
  18.103 +        
  18.104 +        for (Collection<TreePath> c : BulkSearch.getDefault().match(null, new TreePath(cut), bulkPattern).values()) {
  18.105 +            paths.addAll(c);
  18.106 +        }
  18.107 +
  18.108 +        Trees t = Trees.instance(jti);
  18.109 +        int[] result = new int[2 * paths.size()];
  18.110 +        int i = 0;
  18.111 +
  18.112 +        for (TreePath tp : paths) {
  18.113 +            result[i++] = (int) t.getSourcePositions().getStartPosition(cut, tp.getLeaf());
  18.114 +            result[i++] = (int) t.getSourcePositions().getEndPosition(cut, tp.getLeaf());
  18.115 +        }
  18.116 +
  18.117 +        return result;
  18.118 +    }
  18.119 +
  18.120 +    public static Collection<Diagnostic<? extends JavaFileObject>> parseAndReportErrors(String pattern) {
  18.121 +        Collection<Diagnostic<? extends JavaFileObject>> errors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
  18.122 +
  18.123 +        preparePattern(pattern, errors);
  18.124 +
  18.125 +        return errors;
  18.126 +    }
  18.127 +
  18.128 +    public static Map<String, Collection<? extends String>> containsHash(File sourceRoot, Iterable<? extends String> hashes) throws IOException {
  18.129 +        File cacheRoot = Cache.findCache(DuplicatesIndex.NAME, DuplicatesIndex.VERSION).findCacheRoot(sourceRoot.toURI().toURL());
  18.130 +        File dir = new File(cacheRoot, "fulltext");
  18.131 +
  18.132 +        if (dir.listFiles() != null && dir.listFiles().length > 0) {
  18.133 +            IndexReader reader = IndexReader.open(FSDirectory.open(dir), true);
  18.134 +            Map<String, Collection<? extends String>> result = new HashMap<String, Collection<? extends String>>();
  18.135 +
  18.136 +            for (String hash : hashes) {
  18.137 +                Collection<String> found = new LinkedList<String>();
  18.138 +                Query query = new TermQuery(new Term("generalized", hash));
  18.139 +                Searcher s = new IndexSearcher(reader);
  18.140 +                BitSet matchingDocuments = new BitSet(reader.maxDoc());
  18.141 +                Collector c = new BitSetCollector(matchingDocuments);
  18.142 +
  18.143 +                s.search(query, c);
  18.144 +
  18.145 +                for (int docNum = matchingDocuments.nextSetBit(0); docNum >= 0; docNum = matchingDocuments.nextSetBit(docNum + 1)) {
  18.146 +                    final Document doc = reader.document(docNum);
  18.147 +
  18.148 +                    found.add(doc.getField("path").stringValue());
  18.149 +                }
  18.150 +
  18.151 +                result.put(hash, found);
  18.152 +            }
  18.153 +            
  18.154 +            return result;
  18.155 +        }
  18.156 +
  18.157 +        return Collections.emptyMap();
  18.158 +    }
  18.159 +    
  18.160 +    private static BulkPattern preparePattern(String pattern, Collection<Diagnostic<? extends JavaFileObject>> errors) {
  18.161 +        return preparePattern(PatternConvertor.create(pattern), errors);
  18.162 +    }
  18.163 +
  18.164 +    //XXX: copied from BatchSearch, may be possible to merge once CompilationInfo is accessible in server mode
  18.165 +    private static BulkPattern preparePattern(final Iterable<? extends HintDescription> patterns, Collection<Diagnostic<? extends JavaFileObject>> errors) {
  18.166 +        JavacTaskImpl javac = prepareJavacTaskImpl();
  18.167 +        Collection<String> code = new LinkedList<String>();
  18.168 +        Collection<Tree> trees = new LinkedList<Tree>();
  18.169 +        Collection<AdditionalQueryConstraints> additionalConstraints = new LinkedList<AdditionalQueryConstraints>();
  18.170 +
  18.171 +        for (HintDescription pattern : patterns) {
  18.172 +            String textPattern = pattern.getTriggerPattern().getPattern();
  18.173 +
  18.174 +            code.add(textPattern);
  18.175 +            trees.add(Utilities.parseAndAttribute(javac, textPattern, errors));
  18.176 +            additionalConstraints.add(pattern.getAdditionalConstraints());
  18.177 +        }
  18.178 +
  18.179 +        return BulkSearch.getDefault().create(code, trees, additionalConstraints);
  18.180 +    }
  18.181 +
  18.182 +    private static JavacTaskImpl prepareJavacTaskImpl() {
  18.183 +        final String bootPath = System.getProperty("sun.boot.class.path"); //NOI18N
  18.184 +        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
  18.185 +
  18.186 +        assert tool != null;
  18.187 +
  18.188 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, Arrays.asList("-bootclasspath",  bootPath, "-Xjcov"), null, Collections.<JavaFileObject>emptyList());
  18.189 +        
  18.190 +        return ct;
  18.191 +    }
  18.192 +
  18.193 +    private static final class JFOImpl extends SimpleJavaFileObject {
  18.194 +        private final CharSequence code;
  18.195 +        public JFOImpl(CharSequence code) {
  18.196 +            super(URI.create(""), Kind.SOURCE);
  18.197 +            this.code = code;
  18.198 +        }
  18.199 +        @Override
  18.200 +        public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
  18.201 +            return code;
  18.202 +        }
  18.203 +    }
  18.204 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/resources/layer.xml	Fri Feb 11 22:33:43 2011 +0100
    19.3 @@ -0,0 +1,14 @@
    19.4 +<?xml version="1.0" encoding="UTF-8"?>
    19.5 +<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
    19.6 +<filesystem>
    19.7 +    <folder name="public_html">
    19.8 +        <folder name="index">
    19.9 +            <folder name="find">
   19.10 +                <attr name="net.sf.dvbcentral.http.spi.UnknownPageRequest" methodvalue="org.netbeans.modules.jackpot30.backend.impl.api.API.createFindPageRequest" />
   19.11 +            </folder>
   19.12 +            <folder name="list">
   19.13 +                <attr name="net.sf.dvbcentral.http.spi.UnknownPageRequest" methodvalue="org.netbeans.modules.jackpot30.backend.impl.api.API.createListPageRequest" />
   19.14 +            </folder>
   19.15 +        </folder>
   19.16 +    </folder>
   19.17 +</filesystem>
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/ui/UI.java	Fri Feb 11 22:33:43 2011 +0100
    20.3 @@ -0,0 +1,364 @@
    20.4 +/*
    20.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    20.6 + *
    20.7 + * Copyright 2009-2010 Sun Microsystems, Inc. All rights reserved.
    20.8 + *
    20.9 + * The contents of this file are subject to the terms of either the GNU
   20.10 + * General Public License Version 2 only ("GPL") or the Common
   20.11 + * Development and Distribution License("CDDL") (collectively, the
   20.12 + * "License"). You may not use this file except in compliance with the
   20.13 + * License. You can obtain a copy of the License at
   20.14 + * http://www.netbeans.org/cddl-gplv2.html
   20.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   20.16 + * specific language governing permissions and limitations under the
   20.17 + * License.  When distributing the software, include this License Header
   20.18 + * Notice in each file and include the License file at
   20.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
   20.20 + * particular file as subject to the "Classpath" exception as provided
   20.21 + * by Sun in the GPL Version 2 section of the License file that
   20.22 + * accompanied this code. If applicable, add the following below the
   20.23 + * License Header, with the fields enclosed by brackets [] replaced by
   20.24 + * your own identifying information:
   20.25 + * "Portions Copyrighted [year] [name of copyright owner]"
   20.26 + *
   20.27 + * If you wish your version of this file to be governed by only the CDDL
   20.28 + * or only the GPL Version 2, indicate your decision by adding
   20.29 + * "[Contributor] elects to include this software in this distribution
   20.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
   20.31 + * single choice of license, a recipient has the option to distribute
   20.32 + * your version of this file under either the CDDL, the GPL Version 2 or
   20.33 + * to extend the choice of license to its licensees as provided above.
   20.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
   20.35 + * Version 2 license, then the option applies only if the new code is
   20.36 + * made subject to such option by the copyright holder.
   20.37 + *
   20.38 + * Contributor(s):
   20.39 + *
   20.40 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
   20.41 + */
   20.42 +
   20.43 +package org.netbeans.modules.jackpot30.backend.impl.ui;
   20.44 +
   20.45 +import javax.ws.rs.core.Response;
   20.46 +import java.util.LinkedHashMap;
   20.47 +import java.util.Map.Entry;
   20.48 +import freemarker.cache.TemplateLoader;
   20.49 +import freemarker.template.Configuration;
   20.50 +import freemarker.template.Template;
   20.51 +import freemarker.template.TemplateException;
   20.52 +import java.io.IOException;
   20.53 +import java.io.InputStream;
   20.54 +import java.io.InputStreamReader;
   20.55 +import java.io.Reader;
   20.56 +import java.io.StringWriter;
   20.57 +import java.net.URI;
   20.58 +import java.net.URISyntaxException;
   20.59 +import java.util.ArrayList;
   20.60 +import java.util.Collections;
   20.61 +import java.util.HashMap;
   20.62 +import java.util.LinkedList;
   20.63 +import java.util.List;
   20.64 +import java.util.Map;
   20.65 +import javax.ws.rs.DefaultValue;
   20.66 +import javax.ws.rs.GET;
   20.67 +import javax.ws.rs.Path;
   20.68 +import javax.ws.rs.Produces;
   20.69 +import javax.ws.rs.QueryParam;
   20.70 +import org.codeviation.pojson.Pojson;
   20.71 +import org.netbeans.modules.jackpot30.impl.WebUtilities;
   20.72 +import static org.netbeans.modules.jackpot30.impl.WebUtilities.escapeForQuery;
   20.73 +
   20.74 +/**
   20.75 + *
   20.76 + * @author lahvac
   20.77 + */
   20.78 +@Path("/index/ui")
   20.79 +public class UI {
   20.80 +
   20.81 +    @GET
   20.82 +    @Path("/search")
   20.83 +    @Produces("text/html")
   20.84 +    public String search(@QueryParam("path") String path, @QueryParam("pattern") String pattern) throws URISyntaxException, IOException, TemplateException {
   20.85 +        Map<String, Object> configurationData = new HashMap<String, Object>();
   20.86 +
   20.87 +        configurationData.put("paths", list());
   20.88 +        configurationData.put("selectedPath", path);
   20.89 +        configurationData.put("pattern", pattern);
   20.90 +        configurationData.put("patternEscaped", escapeForQuery(pattern));
   20.91 +        configurationData.put("examples", loadExamples());
   20.92 +
   20.93 +        if (pattern != null && path != null) {
   20.94 +            URI u = new URI("http://localhost:9998/index/find?path=" + escapeForQuery(path) + "&pattern=" + escapeForQuery(pattern));
   20.95 +            List<Map<String, Object>> results = new LinkedList<Map<String, Object>>();
   20.96 +            long queryTime = System.currentTimeMillis();
   20.97 +            List<String> candidates = new ArrayList<String>(WebUtilities.requestStringArrayResponse(u));
   20.98 +
   20.99 +            queryTime = System.currentTimeMillis() - queryTime;
  20.100 +
  20.101 +            Collections.sort(candidates);
  20.102 +
  20.103 +            for (String c : candidates) {
  20.104 +                Map<String, Object> found = new HashMap<String, Object>(3);
  20.105 +
  20.106 +                found.put("relativePath", c);
  20.107 +
  20.108 +                results.add(found);
  20.109 +            }
  20.110 +
  20.111 +            configurationData.put("results", results);
  20.112 +
  20.113 +            Map<String, Object> statistics = new HashMap<String, Object>();
  20.114 +
  20.115 +            statistics.put("files", candidates.size());
  20.116 +            statistics.put("queryTime", queryTime);
  20.117 +
  20.118 +            configurationData.put("statistics", statistics);
  20.119 +        }
  20.120 +
  20.121 +        return processTemplate("ui-search.html", configurationData);
  20.122 +    }
  20.123 +
  20.124 +//    @GET
  20.125 +//    @Path("/searchCategorized")
  20.126 +//    @Produces("text/html")
  20.127 +//    public String searchCategorized(@QueryParam("path") String path, @QueryParam("pattern") String pattern) throws URISyntaxException, IOException, TemplateException {
  20.128 +//        Map<String, Object> configurationData = new HashMap<String, Object>();
  20.129 +//
  20.130 +//        configurationData.put("paths", list());
  20.131 +//        configurationData.put("selectedPath", path);
  20.132 +//        configurationData.put("pattern", pattern);
  20.133 +//        configurationData.put("patternEscaped", escapeForQuery(pattern));
  20.134 +//        configurationData.put("examples", loadExamples());
  20.135 +//
  20.136 +//        if (pattern != null && path != null) {
  20.137 +//            Result queryResult = new DoQuery().doQuery(path, pattern, new Cancel() {
  20.138 +//                                                           public boolean isCancelled() {
  20.139 +//                                                               return false;
  20.140 +//                                                           }
  20.141 +//                                                       });
  20.142 +//
  20.143 +//            configurationData.put("result", queryResult.result);
  20.144 +//        }
  20.145 +//
  20.146 +//        return processTemplate("ui-search-categorized.html", configurationData);
  20.147 +//    }
  20.148 +
  20.149 +    @GET
  20.150 +    @Path("/show")
  20.151 +    @Produces("text/html")
  20.152 +    public String show(@QueryParam("path") String path, @QueryParam("relative") String relativePath, @QueryParam("pattern") String pattern) throws URISyntaxException, IOException, TemplateException {
  20.153 +        Map<String, Object> configurationData = new HashMap<String, Object>();
  20.154 +        List<Map<String, String>> occurrences = new LinkedList<Map<String, String>>();
  20.155 +
  20.156 +        configurationData.put("occurrences", occurrences);
  20.157 +
  20.158 +        URI codeURL = new URI("http://localhost:9998/index/cat?path=" + escapeForQuery(path) + "&relative=" + escapeForQuery(relativePath));
  20.159 +        String code = WebUtilities.requestStringResponse(codeURL);
  20.160 +        URI spansURL = new URI("http://localhost:9998/index/findSpans?path=" + escapeForQuery(path) + "&relativePath=" + escapeForQuery(relativePath) + "&pattern=" + escapeForQuery(pattern));
  20.161 +        int currentCodePos = 0;
  20.162 +        for (int[] span : parseSpans(WebUtilities.requestStringResponse(spansURL))) { //XXX: sorted!
  20.163 +            Map<String, String> occ = new HashMap<String, String>();
  20.164 +            occ.put("prefix", WebUtilities.escapeForHTMLElement(code.substring(currentCodePos, span[0])));
  20.165 +            occ.put("occurrence", WebUtilities.escapeForHTMLElement(code.substring(span[0], span[1])));
  20.166 +            occurrences.add(occ);
  20.167 +            currentCodePos = span[1];
  20.168 +        }
  20.169 +
  20.170 +        configurationData.put("suffix", WebUtilities.escapeForHTMLElement(code.substring(currentCodePos, code.length())));
  20.171 +
  20.172 +        return processTemplate("ui-cat.html", configurationData);
  20.173 +    }
  20.174 +    
  20.175 +    @GET
  20.176 +    @Path("/snippet")
  20.177 +    @Produces("text/html")
  20.178 +    public String snippet(@QueryParam("path") String path, @QueryParam("relative") String relativePath, @QueryParam("pattern") String pattern) throws URISyntaxException, IOException, TemplateException {
  20.179 +        List<Map<String, String>> snippets = new LinkedList<Map<String, String>>();
  20.180 +
  20.181 +        URI codeURL = new URI("http://localhost:9998/index/cat?path=" + escapeForQuery(path) + "&relative=" + escapeForQuery(relativePath));
  20.182 +        String code = WebUtilities.requestStringResponse(codeURL);
  20.183 +        URI spansURL = new URI("http://localhost:9998/index/findSpans?path=" + escapeForQuery(path) + "&relativePath=" + escapeForQuery(relativePath) + "&pattern=" + escapeForQuery(pattern));
  20.184 +
  20.185 +        for (int[] span : parseSpans(WebUtilities.requestStringResponse(spansURL))) {
  20.186 +            snippets.add(prepareSnippet(code, span));
  20.187 +        }
  20.188 +
  20.189 +        return processTemplate("ui-snippet.html", Collections.<String, Object>singletonMap("snippets", snippets));
  20.190 +    }
  20.191 +
  20.192 +    @GET
  20.193 +    @Path("/apply")
  20.194 +    @Produces("text/html")
  20.195 +    public Response apply(@QueryParam("path") String path, @QueryParam("pattern") String pattern, @QueryParam("preview") @DefaultValue("") String preview, @QueryParam("download") @DefaultValue("") String download) throws URISyntaxException, IOException, TemplateException {
  20.196 +        if (!download.isEmpty()) {
  20.197 +            if (pattern != null && path != null) {
  20.198 +                URI u = new URI("http://localhost:9998/index/apply?path=" + escapeForQuery(path) + "&pattern=" + escapeForQuery(pattern));
  20.199 +
  20.200 +                return Response.temporaryRedirect(u).header("meta", "Content-Disposition: download; filename=\"patch.diff\"").build();
  20.201 +            }
  20.202 +        }
  20.203 +
  20.204 +        Map<String, Object> configurationData = new HashMap<String, Object>();
  20.205 +
  20.206 +        configurationData.put("paths", list());
  20.207 +        configurationData.put("selectedPath", path);
  20.208 +        configurationData.put("pattern", pattern);
  20.209 +        configurationData.put("patternEscaped", escapeForQuery(pattern));
  20.210 +        configurationData.put("examples", loadExamples());
  20.211 +
  20.212 +        if (pattern != null && path != null) {
  20.213 +            URI u = new URI("http://localhost:9998/index/apply?path=" + escapeForQuery(path) + "&pattern=" + escapeForQuery(pattern));
  20.214 +            long queryTime = System.currentTimeMillis();
  20.215 +            String diff = WebUtilities.requestStringResponse(u);
  20.216 +
  20.217 +            queryTime = System.currentTimeMillis() - queryTime;
  20.218 +
  20.219 +            configurationData.put("diff", diff);
  20.220 +
  20.221 +            StringBuilder sb = new StringBuilder();
  20.222 +
  20.223 +            for (String l : diff.split("\n")) {
  20.224 +                sb.append("<span");
  20.225 +
  20.226 +                for (Entry<String, String> e : prefix2SpanName.entrySet()) {
  20.227 +                    if (l.startsWith(e.getKey())) {
  20.228 +                        sb.append(" class='" + e.getValue() + "'");
  20.229 +                        break;
  20.230 +                    }
  20.231 +                }
  20.232 +
  20.233 +                sb.append(">");
  20.234 +                sb.append(l);
  20.235 +                sb.append("</span>\n");
  20.236 +            }
  20.237 +
  20.238 +            configurationData.put("result", sb.toString());
  20.239 +        }
  20.240 +
  20.241 +        return Response.ok(processTemplate("ui-apply.html", configurationData), "text/html").build();
  20.242 +    }
  20.243 +
  20.244 +    private static final Map<String, String> prefix2SpanName = new LinkedHashMap<String, String>();
  20.245 +
  20.246 +    static {
  20.247 +        prefix2SpanName.put("-", "diff-removed");
  20.248 +        prefix2SpanName.put("+", "diff-added");
  20.249 +        prefix2SpanName.put("@@", "diff-hunk");
  20.250 +        prefix2SpanName.put("Index:", "diff-index");
  20.251 +    }
  20.252 +
  20.253 +    private static List<Map<String, String>> list() throws URISyntaxException {
  20.254 +        List<Map<String, String>> result = new LinkedList<Map<String, String>>();
  20.255 +
  20.256 +        for (String enc : WebUtilities.requestStringArrayResponse(new URI("http://localhost:9998/index/list"))) {
  20.257 +            Map<String, String> rootDesc = new HashMap<String, String>();
  20.258 +            String[] col = enc.split(":", 2);
  20.259 +
  20.260 +            rootDesc.put("segment", col[0]);
  20.261 +            rootDesc.put("displayName", col[1]);
  20.262 +            result.add(rootDesc);
  20.263 +        }
  20.264 +
  20.265 +        return result;
  20.266 +    }
  20.267 +    
  20.268 +    private static Iterable<int[]> parseSpans(String from) {
  20.269 +        if (from.isEmpty()) {
  20.270 +            return Collections.emptyList();
  20.271 +        }
  20.272 +        String[] split = from.split(":");
  20.273 +        List<int[]> result = new LinkedList<int[]>();
  20.274 +
  20.275 +        for (int i = 0; i < split.length; i += 2) {
  20.276 +            result.add(new int[] {
  20.277 +                Integer.parseInt(split[i + 0].trim()),
  20.278 +                Integer.parseInt(split[i + 1].trim())
  20.279 +            });
  20.280 +        }
  20.281 +
  20.282 +        return result;
  20.283 +    }
  20.284 +
  20.285 +    private static final int DESIRED_CONTEXT = 2;
  20.286 +
  20.287 +    private static Map<String, String> prepareSnippet(String code, int[] span) {
  20.288 +        int grandStart = span[0];
  20.289 +        int firstLineStart = grandStart = lineStart(code, grandStart);
  20.290 +
  20.291 +        while (grandStart > 0 && contextLength(code.substring(grandStart, firstLineStart)) < DESIRED_CONTEXT)
  20.292 +            grandStart = lineStart(code, grandStart - 1);
  20.293 +
  20.294 +        int grandEnd = span[1];
  20.295 +        int firstLineEnd = grandEnd = lineEnd(code, grandEnd);
  20.296 +        
  20.297 +        while (grandEnd < code.length() - 1 && contextLength(code.substring(firstLineEnd, grandEnd)) < DESIRED_CONTEXT)
  20.298 +            grandEnd = lineEnd(code, grandEnd + 1);
  20.299 +
  20.300 +        Map<String, String> result = new HashMap<String, String>();
  20.301 +        
  20.302 +        result.put("prefix", WebUtilities.escapeForHTMLElement(code.substring(grandStart, span[0])));
  20.303 +        result.put("occurrence", WebUtilities.escapeForHTMLElement(code.substring(span[0], span[1])));
  20.304 +        result.put("suffix", WebUtilities.escapeForHTMLElement(code.substring(span[1], grandEnd)));
  20.305 +
  20.306 +        return result;
  20.307 +    }
  20.308 +
  20.309 +    private static int lineStart(String code, int o) {
  20.310 +        while (o > 0 && code.charAt(o) != '\n') {
  20.311 +            o--;
  20.312 +        }
  20.313 +
  20.314 +        return o;
  20.315 +    }
  20.316 +
  20.317 +    private static int lineEnd(String code, int o) {
  20.318 +        while (o < code.length() - 1 && code.charAt(o) != '\n') {
  20.319 +            o++;
  20.320 +        }
  20.321 +
  20.322 +        return o;
  20.323 +    }
  20.324 +
  20.325 +    private static int contextLength(String in) {
  20.326 +        return in.replaceAll("\n[ \t]*\n", "\n").trim().split("\n").length;
  20.327 +    }
  20.328 +
  20.329 +    @SuppressWarnings("unchecked")
  20.330 +    private List<Map<String, String>> loadExamples() throws IOException, URISyntaxException {
  20.331 +        return Pojson.load(LinkedList.class, new URI("http://localhost:9998/index/examples"));
  20.332 +    }
  20.333 +
  20.334 +    private static String processTemplate(String template, Map<String, Object> configurationData) throws TemplateException, IOException {
  20.335 +        Configuration conf = new Configuration();
  20.336 +
  20.337 +        conf.setTemplateLoader(new TemplateLoaderImpl());
  20.338 +
  20.339 +        Template templ = conf.getTemplate(template);
  20.340 +        StringWriter out = new StringWriter();
  20.341 +
  20.342 +        templ.process(configurationData, out);
  20.343 +
  20.344 +        return out.toString();
  20.345 +    }
  20.346 +
  20.347 +    private static final class TemplateLoaderImpl implements TemplateLoader {
  20.348 +
  20.349 +        public Object findTemplateSource(String name) throws IOException {
  20.350 +            return TemplateLoaderImpl.class.getResourceAsStream(name);
  20.351 +        }
  20.352 +
  20.353 +        public long getLastModified(Object templateSource) {
  20.354 +            return 0L;
  20.355 +        }
  20.356 +
  20.357 +        public Reader getReader(Object templateSource, String encoding) throws IOException {
  20.358 +            InputStream in = (InputStream) templateSource;
  20.359 +
  20.360 +            return new InputStreamReader(in);
  20.361 +        }
  20.362 +
  20.363 +        public void closeTemplateSource(Object templateSource) throws IOException {
  20.364 +        }
  20.365 +    }
  20.366 +
  20.367 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/ui/ui-apply.html	Fri Feb 11 22:33:43 2011 +0100
    21.3 @@ -0,0 +1,68 @@
    21.4 +<html>
    21.5 +<head>
    21.6 +    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
    21.7 +<#if results??>
    21.8 +    <script type="text/javascript">
    21.9 +        $(document).ready(function() {
   21.10 +            $('#list').find('dd').hide().end().find('dt').click(function() {
   21.11 +                current_dd=$(this).next();
   21.12 +                //XXX: will do the AJAX call for both show and hide!
   21.13 +                $.get("snippet?path=${selectedPath}&relative=" + current_dd.attr("id") + "&pattern=${patternEscaped}",function(data) {
   21.14 +                    current_dd.html(data).slideToggle();
   21.15 +                })
   21.16 +            });
   21.17 +        });
   21.18 +    </script>
   21.19 +</#if>
   21.20 +    <style type="text/css">
   21.21 +        .occurrence {background: #DDDD00;}
   21.22 +        .diff-removed {color: #FF0000;}
   21.23 +        .diff-added {color: #00FF00;}
   21.24 +        .diff-index {color: #0000FF;}
   21.25 +        .diff-hunk {color: #FF00FF;}
   21.26 +    </style>
   21.27 +</head>
   21.28 +<body>
   21.29 +<form method="get">
   21.30 +
   21.31 +<label for="path">Project:</label>
   21.32 +<select size="1" name="path">");
   21.33 +    <#list paths as path>
   21.34 +        <option <#if selectedPath?? && path.segment == selectedPath>selected</#if> value="${path.segment}">
   21.35 +            ${path.displayName}
   21.36 +        </option>
   21.37 +    </#list>
   21.38 +</select>
   21.39 +<br>
   21.40 +<label for="pattern">Pattern:</label><br>
   21.41 +<textarea rows="10" cols="40" name="pattern">
   21.42 +<#if pattern??>
   21.43 +${pattern}
   21.44 +</#if>
   21.45 +</textarea><br>
   21.46 +<input type="submit" name="preview" value="Show diff preview"/><input type="submit" name="download" value="Download diff"/>
   21.47 +</form>
   21.48 +
   21.49 +<div class="examples">
   21.50 +<#if examples??>
   21.51 +    Examples:
   21.52 +    <dl id="examples-list">
   21.53 +        <#list examples as example>
   21.54 +            <dt>${example.displayName}</dt>
   21.55 +            <dd><pre>${example.pattern}</pre>
   21.56 +            </dd>
   21.57 +        </#list>
   21.58 +    </dl>
   21.59 +</#if>
   21.60 +</div>
   21.61 +
   21.62 +<#if result??>
   21.63 +    Diff for rule: ${pattern}
   21.64 +<pre>${result}</pre>
   21.65 +</#if>
   21.66 +
   21.67 +<#if statistics??>
   21.68 +     Query time: ${statistics.queryTime}ms, matching files: ${statistics.files}.
   21.69 +</#if>
   21.70 +</body>
   21.71 +</html>
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/ui/ui-cat.html	Fri Feb 11 22:33:43 2011 +0100
    22.3 @@ -0,0 +1,10 @@
    22.4 +<html>
    22.5 +<head>
    22.6 +    <style type="text/css">
    22.7 +        .occurrence {BACKGROUND: #DDDD00;}
    22.8 +    </style>
    22.9 +</head>
   22.10 +<body>
   22.11 +<pre><#list occurrences as occurrence>${occurrence.prefix}<span class="occurrence">${occurrence.occurrence}</span></#list>${suffix}</pre>
   22.12 +</body>
   22.13 +</html>
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/ui/ui-search.html	Fri Feb 11 22:33:43 2011 +0100
    23.3 @@ -0,0 +1,70 @@
    23.4 +<html>
    23.5 +<head>
    23.6 +    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
    23.7 +<#if results??>
    23.8 +    <script type="text/javascript">
    23.9 +        $(document).ready(function() {
   23.10 +            $('#list').find('dd').hide().end().find('dt').click(function() {
   23.11 +                current_dd=$(this).next();
   23.12 +                //XXX: will do the AJAX call for both show and hide!
   23.13 +                $.get("snippet?path=${selectedPath}&relative=" + current_dd.attr("id") + "&pattern=${patternEscaped}",function(data) {
   23.14 +                    current_dd.html(data).slideToggle();
   23.15 +                })
   23.16 +            });
   23.17 +        });
   23.18 +    </script>
   23.19 +</#if>
   23.20 +    <style type="text/css">
   23.21 +        .occurrence {BACKGROUND: #DDDD00;}
   23.22 +    </style>
   23.23 +</head>
   23.24 +<body>
   23.25 +<form method="get">
   23.26 +
   23.27 +<label for="path">Project:</label>
   23.28 +<select size="1" name="path">");
   23.29 +    <#list paths as path>
   23.30 +        <option <#if selectedPath?? && path.segment == selectedPath>selected</#if> value="${path.segment}">
   23.31 +            ${path.displayName}
   23.32 +        </option>
   23.33 +    </#list>
   23.34 +</select>
   23.35 +<br>
   23.36 +<label for="pattern">Pattern:</label><br>
   23.37 +<textarea rows="10" cols="40" name="pattern">
   23.38 +<#if pattern??>
   23.39 +${pattern}
   23.40 +</#if>
   23.41 +</textarea><br>
   23.42 +<input type="submit" name="Find Candidates"/>
   23.43 +</form>
   23.44 +
   23.45 +<div class="examples">
   23.46 +<#if examples??>
   23.47 +    Examples:
   23.48 +    <dl id="examples-list">
   23.49 +        <#list examples as example>
   23.50 +            <dt>${example.displayName}</dt>
   23.51 +            <dd><pre>${example.pattern}</pre>
   23.52 +            </dd>
   23.53 +        </#list>
   23.54 +    </dl>
   23.55 +</#if>
   23.56 +</div>
   23.57 +
   23.58 +<#if results??>
   23.59 +    Found candidates for pattern: ${pattern}
   23.60 +    <dl id="list">
   23.61 +        <#list results as result>
   23.62 +            <dt>${result.relativePath}<a href="/index/ui/show?path=${selectedPath}&relative=${result.relativePath}&pattern=${patternEscaped}">show</a></dt>
   23.63 +            <dd id="${result.relativePath}">
   23.64 +            </dd>
   23.65 +        </#list>
   23.66 +    </dl>
   23.67 +</#if>
   23.68 +
   23.69 +<#if statistics??>
   23.70 +     Query time: ${statistics.queryTime}ms, matching files: ${statistics.files}.
   23.71 +</#if>
   23.72 +</body>
   23.73 +</html>
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/server/backend/impl/src/org/netbeans/modules/jackpot30/backend/impl/ui/ui-snippet.html	Fri Feb 11 22:33:43 2011 +0100
    24.3 @@ -0,0 +1,7 @@
    24.4 +<#if snippets??>
    24.5 +    <#list snippets as snippet>
    24.6 +        <pre>${snippet.prefix}<span class="occurrence">${snippet.occurrence}</span>${snippet.suffix}</pre><br>
    24.7 +    </#list>
    24.8 +<#else>
    24.9 +    No occurrences.
   24.10 +</#if>
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/server/backend/nbproject/build-impl.xml	Fri Feb 11 22:33:43 2011 +0100
    25.3 @@ -0,0 +1,49 @@
    25.4 +<?xml version="1.0" encoding="UTF-8"?>
    25.5 +<!--
    25.6 +*** GENERATED FROM project.xml - DO NOT EDIT  ***
    25.7 +***         EDIT ../build.xml INSTEAD         ***
    25.8 +-->
    25.9 +<project name="backend-impl" basedir=".." xmlns:sproject="http://www.netbeans.org/ns/nb-module-suite-project/1">
   25.10 +    <fail message="Please build using Ant 1.7.1 or higher.">
   25.11 +        <condition>
   25.12 +            <not>
   25.13 +                <antversion atleast="1.7.1"/>
   25.14 +            </not>
   25.15 +        </condition>
   25.16 +    </fail>
   25.17 +    <property file="nbproject/private/platform-private.properties"/>
   25.18 +    <property file="nbproject/platform.properties"/>
   25.19 +    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
   25.20 +        <attribute name="name"/>
   25.21 +        <attribute name="value"/>
   25.22 +        <sequential>
   25.23 +            <property name="@{name}" value="${@{value}}"/>
   25.24 +        </sequential>
   25.25 +    </macrodef>
   25.26 +    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
   25.27 +        <attribute name="property"/>
   25.28 +        <attribute name="value"/>
   25.29 +        <sequential>
   25.30 +            <property name="@{property}" value="@{value}"/>
   25.31 +        </sequential>
   25.32 +    </macrodef>
   25.33 +    <property file="${user.properties.file}"/>
   25.34 +    <sproject:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir"/>
   25.35 +    <sproject:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/>
   25.36 +    <sproject:evalprops property="cluster.path.evaluated" value="${cluster.path}"/>
   25.37 +    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
   25.38 +        <condition>
   25.39 +            <not>
   25.40 +                <contains string="${cluster.path.evaluated}" substring="platform"/>
   25.41 +            </not>
   25.42 +        </condition>
   25.43 +    </fail>
   25.44 +    <fail message="Cannot find NetBeans build harness. ${line.separator}Check that nbplatform.${nbplatform.active}.netbeans.dest.dir and nbplatform.${nbplatform.active}.harness.dir are defined. ${line.separator}On a developer machine these are normally defined in ${user.properties.file}=${netbeans.user}/build.properties ${line.separator}but for automated builds you should pass these properties to Ant explicitly.">
   25.45 +        <condition>
   25.46 +            <not>
   25.47 +                <available type="dir" file="${harness.dir}"/>
   25.48 +            </not>
   25.49 +        </condition>
   25.50 +    </fail>
   25.51 +    <import file="${harness.dir}/suite.xml"/>
   25.52 +</project>
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/server/backend/nbproject/genfiles.properties	Fri Feb 11 22:33:43 2011 +0100
    26.3 @@ -0,0 +1,8 @@
    26.4 +build.xml.data.CRC32=2aaf9598
    26.5 +build.xml.script.CRC32=616acaee
    26.6 +build.xml.stylesheet.CRC32=eaf9f76a@1.44
    26.7 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
    26.8 +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
    26.9 +nbproject/build-impl.xml.data.CRC32=2aaf9598
   26.10 +nbproject/build-impl.xml.script.CRC32=e8ecb000
   26.11 +nbproject/build-impl.xml.stylesheet.CRC32=183e6ef3@1.44
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/server/backend/nbproject/platform.properties	Fri Feb 11 22:33:43 2011 +0100
    27.3 @@ -0,0 +1,12 @@
    27.4 +cluster.path=\
    27.5 +    ${nbplatform.active.dir}/apisupport:\
    27.6 +    ${nbplatform.active.dir}/enterprise:\
    27.7 +    ${nbplatform.active.dir}/harness:\
    27.8 +    ${nbplatform.active.dir}/ide:\
    27.9 +    ${nbplatform.active.dir}/java:\
   27.10 +    ${nbplatform.active.dir}/platform:\
   27.11 +    ${nbplatform.active.dir}/profiler:\
   27.12 +    ${nbplatform.active.dir}/websvccommon:\
   27.13 +    ../../build/cluster
   27.14 +disabled.modules=
   27.15 +nbplatform.active=default
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/server/backend/nbproject/project.properties	Fri Feb 11 22:33:43 2011 +0100
    28.3 @@ -0,0 +1,8 @@
    28.4 +app.name=backend
    28.5 +app.title=Jackpot 3.0 Backend
    28.6 +branding.token=${app.name}
    28.7 +modules=\
    28.8 +    ${project.org.netbeans.modules.jackpot30.backend.impl}
    28.9 +project.org.netbeans.modules.jackpot30.backend.impl=impl
   28.10 +#should used -nogui, but many parts (i.e. projects) use invokeWhenUIReady which is not invoked currently when -nogui is used:
   28.11 +run.args=--nosplash --start-server -J-Xdebug -J-Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=8889
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/server/backend/nbproject/project.xml	Fri Feb 11 22:33:43 2011 +0100
    29.3 @@ -0,0 +1,9 @@
    29.4 +<?xml version="1.0" encoding="UTF-8"?>
    29.5 +<project xmlns="http://www.netbeans.org/ns/project/1">
    29.6 +    <type>org.netbeans.modules.apisupport.project.suite</type>
    29.7 +    <configuration>
    29.8 +        <data xmlns="http://www.netbeans.org/ns/nb-module-suite-project/1">
    29.9 +            <name>backend</name>
   29.10 +        </data>
   29.11 +    </configuration>
   29.12 +</project>