You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by po...@apache.org on 2017/09/03 17:33:03 UTC

[10/51] [partial] incubator-netbeans-jackpot30 git commit: INFRA-15006 Import for http://bits.netbeans.org/download/apache-donation

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/web/base.web.api/nbproject/project.properties
----------------------------------------------------------------------
diff --git a/remoting/server/web/base.web.api/nbproject/project.properties b/remoting/server/web/base.web.api/nbproject/project.properties
new file mode 100644
index 0000000..9f5553f
--- /dev/null
+++ b/remoting/server/web/base.web.api/nbproject/project.properties
@@ -0,0 +1,127 @@
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2009-2017 Oracle and/or its affiliates. All rights reserved.
+#
+# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+# Other names may be trademarks of their respective owners.
+#
+# The contents of this file are subject to the terms of either the GNU
+# General Public License Version 2 only ("GPL") or the Common
+# Development and Distribution License("CDDL") (collectively, the
+# "License"). You may not use this file except in compliance with the
+# License. You can obtain a copy of the License at
+# http://www.netbeans.org/cddl-gplv2.html
+# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+# specific language governing permissions and limitations under the
+# License.  When distributing the software, include this License Header
+# Notice in each file and include the License file at
+# nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the GPL Version 2 section of the License file that
+# accompanied this code. If applicable, add the following below the
+# License Header, with the fields enclosed by brackets [] replaced by
+# your own identifying information:
+# "Portions Copyrighted [year] [name of copyright owner]"
+#
+# Contributor(s):
+#
+# The Original Software is NetBeans. The Initial Developer of the Original
+# Software is Sun Microsystems, Inc. Portions Copyright 2009-2010 Sun
+# Microsystems, Inc. All Rights Reserved.
+#
+# If you wish your version of this file to be governed by only the CDDL
+# or only the GPL Version 2, indicate your decision by adding
+# "[Contributor] elects to include this software in this distribution
+# under the [CDDL or GPL Version 2] license." If you do not indicate a
+# single choice of license, a recipient has the option to distribute
+# your version of this file under either the CDDL, the GPL Version 2 or
+# to extend the choice of license to its licensees as provided above.
+# However, if you add GPL Version 2 code and therefore, elected the GPL
+# Version 2 license, then the option applies only if the new code is
+# made subject to such option by the copyright holder.
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=false
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+application.title=base.web.api
+application.vendor=lahvac
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+# Uncomment to specify the preferred debugger connection transport:
+#debug.transport=dt_socket
+debug.classpath=\
+    ${run.classpath}
+debug.test.classpath=\
+    ${run.test.classpath}
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/base.web.api.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
+excludes=
+file.reference.org-netbeans-modules-parsing-lucene.jar=../../../../lib/org-netbeans-modules-parsing-lucene.jar
+file.reference.org-openide-filesystems.jar=../../../../lib/org-openide-filesystems.jar
+file.reference.org-openide-util-lookup.jar=../../../../lib/org-openide-util-lookup.jar
+file.reference.util-commons.jar=../../../ide/api/external/util-commons.jar
+file.reference.util-pojson.jar=../../../ide/api/external/util-pojson.jar
+includes=**
+jar.compress=false
+javac.classpath=\
+    ${libs.freemarker.classpath}:\
+    ${libs.jersey.classpath}:\
+    ${file.reference.org-openide-filesystems.jar}:\
+    ${file.reference.org-openide-util-lookup.jar}:\
+    ${file.reference.util-commons.jar}:\
+    ${file.reference.util-pojson.jar}:\
+    ${libs.lucene.classpath}:\
+    ${file.reference.org-netbeans-modules-parsing-lucene.jar}
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.deprecation=false
+javac.processorpath=\
+    ${javac.classpath}
+javac.source=1.6
+javac.target=1.6
+javac.test.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+javac.test.processorpath=\
+    ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+main.class=org.netbeans.modules.jackpot30.backend.base.BaseWebApi
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+mkdist.disabled=false
+platform.active=default_platform
+run.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
+# or test-sys-prop.name=value to set system properties for unit tests):
+run.jvmargs=
+run.test.classpath=\
+    ${javac.test.classpath}:\
+    ${build.test.classes.dir}
+source.encoding=UTF-8
+src.dir=src
+test.src.dir=test

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/web/base.web.api/nbproject/project.xml
----------------------------------------------------------------------
diff --git a/remoting/server/web/base.web.api/nbproject/project.xml b/remoting/server/web/base.web.api/nbproject/project.xml
new file mode 100644
index 0000000..225e48a
--- /dev/null
+++ b/remoting/server/web/base.web.api/nbproject/project.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+Copyright 2009-2017 Oracle and/or its affiliates. All rights reserved.
+
+Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+Other names may be trademarks of their respective owners.
+
+The contents of this file are subject to the terms of either the GNU
+General Public License Version 2 only ("GPL") or the Common
+Development and Distribution License("CDDL") (collectively, the
+"License"). You may not use this file except in compliance with the
+License. You can obtain a copy of the License at
+http://www.netbeans.org/cddl-gplv2.html
+or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+specific language governing permissions and limitations under the
+License.  When distributing the software, include this License Header
+Notice in each file and include the License file at
+nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the GPL Version 2 section of the License file that
+accompanied this code. If applicable, add the following below the
+License Header, with the fields enclosed by brackets [] replaced by
+your own identifying information:
+"Portions Copyrighted [year] [name of copyright owner]"
+
+Contributor(s):
+
+The Original Software is NetBeans. The Initial Developer of the Original
+Software is Sun Microsystems, Inc. Portions Copyright 2009-2010 Sun
+Microsystems, Inc. All Rights Reserved.
+
+If you wish your version of this file to be governed by only the CDDL
+or only the GPL Version 2, indicate your decision by adding
+"[Contributor] elects to include this software in this distribution
+under the [CDDL or GPL Version 2] license." If you do not indicate a
+single choice of license, a recipient has the option to distribute
+your version of this file under either the CDDL, the GPL Version 2 or
+to extend the choice of license to its licensees as provided above.
+However, if you add GPL Version 2 code and therefore, elected the GPL
+Version 2 license, then the option applies only if the new code is
+made subject to such option by the copyright holder.
+-->
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.java.j2seproject</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
+            <name>base.web.api</name>
+            <source-roots>
+                <root id="src.dir"/>
+            </source-roots>
+            <test-roots>
+                <root id="test.src.dir"/>
+            </test-roots>
+        </data>
+        <libraries xmlns="http://www.netbeans.org/ns/ant-project-libraries/1">
+            <definitions>../../../../lib/nblibraries.properties</definitions>
+        </libraries>
+    </configuration>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/AccessStatistics.java
----------------------------------------------------------------------
diff --git a/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/AccessStatistics.java b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/AccessStatistics.java
new file mode 100644
index 0000000..dc36f5c
--- /dev/null
+++ b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/AccessStatistics.java
@@ -0,0 +1,187 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2012 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.jackpot30.backend.base;
+
+import com.sun.jersey.spi.container.ContainerRequest;
+import com.sun.jersey.spi.container.ContainerRequestFilter;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author lahvac
+ */
+public class AccessStatistics implements ContainerRequestFilter {
+
+    private static Map<String, Long> statistics = null;
+    private static long lastModifyStamp = 0;
+    private static long lastSaveStamp = -1;
+    private static ScheduledExecutorService store = Executors.newSingleThreadScheduledExecutor();
+
+    private static synchronized void incrementUsage(String key) {
+        if (statistics == null) {
+            statistics = new HashMap<String, Long>();
+
+            File accessStatistics = CategoryStorage.getAccessStatisticsFile();
+
+            if (accessStatistics.canRead()) {
+                InputStream in = null;
+
+                try {
+                    in = new BufferedInputStream(new FileInputStream(accessStatistics));
+                    Properties p = new Properties();
+
+                    p.load(in);
+
+                    for (String propertyKey : p.stringPropertyNames()) {
+                        try {
+                            long count = Long.parseLong(p.getProperty(propertyKey));
+
+                            statistics.put(propertyKey, count);
+                        } catch (NumberFormatException ex) {
+                            //ignore...
+                            Logger.getLogger(AccessStatistics.class.getName()).log(Level.SEVERE, null, ex);
+                        }
+                    }
+                } catch (IOException ex) {
+                    Logger.getLogger(AccessStatistics.class.getName()).log(Level.SEVERE, null, ex);
+                } finally {
+                    if (in != null) {
+                        try {
+                            in.close();
+                        } catch (IOException ex) {
+                            Logger.getLogger(AccessStatistics.class.getName()).log(Level.SEVERE, null, ex);
+                        }
+                    }
+                }
+            }
+        }
+
+        Long l = statistics.get(key);
+
+        if (l == null) l = 0L;
+
+        statistics.put(key, l + 1);
+
+        lastModifyStamp++;
+
+        store.schedule(new Runnable() {
+            @Override public void run() {
+                storeStatistics();
+            }
+        }, 1, TimeUnit.SECONDS);
+    }
+
+    private static void storeStatistics() {
+        Properties p = new Properties();
+
+        synchronized (AccessStatistics.class) {
+            if (lastSaveStamp == lastModifyStamp) return;
+            lastSaveStamp = lastModifyStamp;
+            for (Entry<String, Long> e : statistics.entrySet()) {
+                p.setProperty(e.getKey(), Long.toString(e.getValue()));
+            }
+        }
+
+        File accessStatistics = CategoryStorage.getAccessStatisticsFile();
+        File tempFile = new File(accessStatistics.getParentFile(), accessStatistics.getName() + ".new");
+        OutputStream out = null;
+
+        try {
+            out = new BufferedOutputStream(new FileOutputStream(tempFile));
+
+            p.store(out, "");
+        } catch (IOException ex) {
+            Logger.getLogger(AccessStatistics.class.getName()).log(Level.SEVERE, null, ex);
+        } finally {
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException ex) {
+                    Logger.getLogger(AccessStatistics.class.getName()).log(Level.SEVERE, null, ex);
+                }
+
+                tempFile.renameTo(accessStatistics);
+            }
+        }
+    }
+
+    public static synchronized Map<String, Long> getStatistics() {
+        return Collections.unmodifiableMap(new HashMap<String, Long>(statistics));
+    }
+
+    @Override
+    public ContainerRequest filter(ContainerRequest request) {
+        StringBuilder statisticsKey = new StringBuilder();
+        List<String> paths = request.getQueryParameters().get("path");
+
+        statisticsKey.append(request.getPath());
+
+        if (paths != null) {
+            for (String path : paths) {
+                statisticsKey.append(":").append(path);
+            }
+        }
+
+        incrementUsage(statisticsKey.toString());
+        
+        return request;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/CategoryStorage.java
----------------------------------------------------------------------
diff --git a/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/CategoryStorage.java b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/CategoryStorage.java
new file mode 100644
index 0000000..e98a93e
--- /dev/null
+++ b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/CategoryStorage.java
@@ -0,0 +1,315 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.jackpot30.backend.base;
+
+import com.sun.jersey.api.NotFoundException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.apache.lucene.analysis.KeywordAnalyzer;
+import org.codeviation.pojson.Pojson;
+import org.netbeans.modules.parsing.lucene.support.Index;
+import org.netbeans.modules.parsing.lucene.support.IndexManager;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileSystem;
+import org.openide.filesystems.FileUtil;
+import org.openide.filesystems.JarFileSystem;
+
+/**
+ *
+ * @author lahvac
+ */
+public class CategoryStorage {
+
+    public static synchronized void setCacheRoot(File cacheRoot) {
+        CategoryStorage.cacheRoot = cacheRoot;
+        categoryCache = null;
+    }
+
+    public static synchronized File getAccessStatisticsFile() {
+        return new File(cacheRoot, "accessStatistics");
+    }
+
+    public static void internalReset() {
+        setCacheRoot(cacheRoot);
+    }
+
+    private static File cacheRoot;
+    private static Reference<Iterable<? extends CategoryStorage>> categoryCache;
+
+    public static synchronized Iterable<? extends CategoryStorage> listCategories() {
+        Iterable<? extends CategoryStorage> cached = categoryCache != null ? categoryCache.get() : null;
+
+        if (cached != null) return cached;
+
+        List<CategoryStorage> result = new ArrayList<CategoryStorage>();
+
+        for (File cat : cacheRoot.listFiles()) {
+            if (!cat.isDirectory()) continue;
+            File info = new File(cat, "info");
+            String displayName = cat.getName();
+            if (info.canRead()) {
+                try {
+                    @SuppressWarnings("unchecked")
+                    Map<String, Object> data = Pojson.load(HashMap.class, info);
+                    if (data.containsKey("displayName")) {
+                        displayName = (String) data.get("displayName"); //XXX: should check type!
+                    }
+                } catch (FileNotFoundException ex) {
+                    Logger.getLogger(CategoryStorage.class.getName()).log(Level.SEVERE, null, ex);
+                } catch (IOException ex) {
+                    Logger.getLogger(CategoryStorage.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+            result.add(new CategoryStorage(cat.getName(), displayName));
+        }
+
+        categoryCache = new SoftReference<Iterable<? extends CategoryStorage>>(result);
+        
+        return result;
+    }
+
+    public static CategoryStorage forId(String id) {
+        for (CategoryStorage s : listCategories()) {
+            if (s.id.equals(id)) return s;
+        }
+
+        throw new NotFoundException("No category with id: " + id);
+    }
+    
+    private final String id;
+    private final String displayName;
+
+    private CategoryStorage(String id, String displayName) {
+        this.id = id;
+        this.displayName = displayName;
+    }
+
+    private Iterable<? extends SourceRoot> sourceRoots;
+
+    public synchronized Iterable<? extends SourceRoot> getSourceRoots() {
+        if (sourceRoots != null) return sourceRoots;
+
+        List<SourceRoot> result = new ArrayList<SourceRoot>();
+
+        try {
+            Map<String, String> invertedSegments = getInvertedSegments();
+
+            for (Entry<String, String> e : invertedSegments.entrySet()) {
+                if (!e.getKey().startsWith("rel:")) continue;
+                result.add(new SourceRoot(this, new URL(e.getKey()).getPath().substring(1), e.getValue()));
+            }
+        } catch (IllegalArgumentException ex) {
+            Logger.getLogger(CategoryStorage.class.getName()).log(Level.SEVERE, null, ex);
+        } catch (SecurityException ex) {
+            Logger.getLogger(CategoryStorage.class.getName()).log(Level.SEVERE, null, ex);
+        } catch (IOException ex) {
+            Logger.getLogger(CategoryStorage.class.getName()).log(Level.SEVERE, null, ex);
+        }
+
+        return sourceRoots = result;
+    }
+
+    private final Map<String, Reference<FileSystem>> embeddedJar2FileSystem = new HashMap<String, Reference<FileSystem>>();
+
+    public synchronized FileObject getEmbeddedJarRoot(String jarName) throws IOException {
+        Reference<FileSystem> fsRef = embeddedJar2FileSystem.get(jarName);
+        FileSystem fs = fsRef != null ? fsRef.get() : null;
+
+        if (fs == null) {
+            File f = new File(FileUtil.toFile(getCacheRoot()), jarName);
+
+            if (!f.canRead()) {
+                return null;//XXX: should not happen, but does?
+//                throw new IllegalStateException(jarName);
+            }
+
+            embeddedJar2FileSystem.put(jarName, new SoftReference<FileSystem>(fs = new JarFileSystem(f)));
+        }
+
+        return fs.getRoot();
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public FileObject getCacheRoot() {
+        return FileUtil.toFileObject(FileUtil.normalizeFile(new File(cacheRoot, id)));
+    }
+
+    private File getIndexFile() {
+        return new File(new File(cacheRoot, id), "index");
+    }
+
+    private Reference<Index> cachedIndex;
+
+    public synchronized Index getIndex() {
+        Index cached = cachedIndex != null ? cachedIndex.get() : null;
+
+        if (cached != null) return cached;
+
+        try {
+            Index index = IndexManager.createIndex(getIndexFile(), new KeywordAnalyzer());
+
+            index.getStatus(true);
+
+            cachedIndex = new SoftReference<Index>(index);
+
+            return index;
+        } catch (IOException ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    private Map<String, String> getInvertedSegments() throws IOException {
+        FileObject root = getCacheRoot();
+        FileObject segments = root.getFileObject("segments");
+
+        if (segments == null) return null;
+
+        Properties segmentsMap = loadProperties(segments);
+        Map<String, String> invertedSegments = new HashMap<String, String>();
+
+        for (Entry<Object, Object> e : segmentsMap.entrySet()) {
+            invertedSegments.put((String) e.getValue(), (String) e.getKey());
+        }
+
+        return invertedSegments;
+    }
+
+    public File getSegment(String relPath) {
+        try {
+            Map<String, String> invertedSegments = getInvertedSegments();
+            String segment = invertedSegments.get(relPath);
+
+            if (segment == null) {
+                segment = invertedSegments.get("rel:/" + relPath);
+            }
+
+            if (segment == null) {
+                segment = invertedSegments.get("rel:/" + relPath + "/");
+            }
+            
+            if (segment != null) {
+                return new File(new File(cacheRoot, id), segment);
+            } else {
+                return null;
+            }
+        } catch (IOException ex) {
+            Logger.getLogger(CategoryStorage.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        return null;
+    }
+
+    private static Properties loadProperties(FileObject properties) throws IOException {
+        Properties inProps = new Properties();
+        InputStream inPropsIS = properties.getInputStream();
+        try {
+            inProps.load(inPropsIS);
+        } finally {
+            inPropsIS.close();
+        }
+        return inProps;
+    }
+
+    private long getSize() {
+        long result = 0;
+
+        for (Enumeration<? extends FileObject> en = getCacheRoot().getChildren(true); en.hasMoreElements(); ) {
+            FileObject f = en.nextElement();
+
+            if (f.isData()) {
+                result += f.getSize();
+            }
+        }
+
+        return result;
+    }
+
+    private AtomicReference<String> info = new AtomicReference<String>();
+
+    public String getInfo() {
+        String result = info.get();
+
+        if (result != null) return result;
+
+        FileObject infoFile = getCacheRoot().getFileObject("info");
+        String content;
+        try {
+            content = infoFile != null ? infoFile.asText("UTF-8") : "{}";
+        } catch (IOException ex) {
+            Logger.getLogger(CategoryStorage.class.getName()).log(Level.SEVERE, null, ex);
+            content = "{}";
+        }
+        Map<String, Object> infoData = Pojson.load(HashMap.class, content);
+
+        if (!infoData.containsKey("indexSize")) {
+            infoData.put("indexSize", getSize());
+        }
+
+        info.set(result = Pojson.save(infoData));
+
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/FreemarkerUtilities.java
----------------------------------------------------------------------
diff --git a/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/FreemarkerUtilities.java b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/FreemarkerUtilities.java
new file mode 100644
index 0000000..49d6475
--- /dev/null
+++ b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/FreemarkerUtilities.java
@@ -0,0 +1,94 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.jackpot30.backend.base;
+
+import freemarker.cache.TemplateLoader;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.util.Map;
+
+/**
+ *
+ * @author lahvac
+ */
+public class FreemarkerUtilities {
+
+    public static String processTemplate(String template, Map<String, Object> configurationData) throws TemplateException, IOException {
+        Configuration conf = new Configuration();
+
+        conf.setTemplateLoader(new TemplateLoaderImpl());
+
+        Template templ = conf.getTemplate(template);
+        StringWriter out = new StringWriter();
+
+        templ.process(configurationData, out);
+
+        return out.toString();
+    }
+
+    private static final class TemplateLoaderImpl implements TemplateLoader {
+
+        public Object findTemplateSource(String name) throws IOException {
+            return TemplateLoaderImpl.class.getResourceAsStream("/" + name);
+        }
+
+        public long getLastModified(Object templateSource) {
+            return 0L;
+        }
+
+        public Reader getReader(Object templateSource, String encoding) throws IOException {
+            InputStream in = (InputStream) templateSource;
+
+            return new InputStreamReader(in);
+        }
+
+        public void closeTemplateSource(Object templateSource) throws IOException {
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/RelStreamHandlerFactory.java
----------------------------------------------------------------------
diff --git a/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/RelStreamHandlerFactory.java b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/RelStreamHandlerFactory.java
new file mode 100644
index 0000000..3813992
--- /dev/null
+++ b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/RelStreamHandlerFactory.java
@@ -0,0 +1,72 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.jackpot30.backend.base;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+import org.openide.util.lookup.ServiceProvider;
+
+/**
+ *
+ * @author lahvac
+ */
+@ServiceProvider(service=URLStreamHandlerFactory.class)
+public class RelStreamHandlerFactory implements URLStreamHandlerFactory {
+
+    @Override
+    public URLStreamHandler createURLStreamHandler(String protocol) {
+        if ("rel".equals(protocol)) return new RelStreamHandler();
+        return null;
+    }
+
+    private static final class RelStreamHandler extends URLStreamHandler {
+
+        @Override protected URLConnection openConnection(URL u) throws IOException {
+            throw new IOException("Cannot open");
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/SourceRoot.java
----------------------------------------------------------------------
diff --git a/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/SourceRoot.java b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/SourceRoot.java
new file mode 100644
index 0000000..026c707
--- /dev/null
+++ b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/SourceRoot.java
@@ -0,0 +1,154 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2012 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.jackpot30.backend.base;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.JarFileSystem;
+
+/**
+ *
+ * @author lahvac
+ */
+public class SourceRoot {
+    
+    private static final Logger LOG = Logger.getLogger(SourceRoot.class.getName());
+    private final CategoryStorage category;
+    private final String relativePath;
+    private final String code;
+
+    SourceRoot(CategoryStorage category, String relativePath, String code) {
+        this.category = category;
+        this.relativePath = relativePath;
+        this.code = code;
+    }
+
+    public CategoryStorage getCategory() {
+        return category;
+    }
+
+    public String getRelativePath() {
+        return relativePath;
+    }
+
+    private Reference<Collection<FileObject>> classPath;
+
+    public synchronized Collection<FileObject> getClassPath() {
+        Collection<FileObject> cp = classPath != null ? classPath.get() : null;
+        if (cp == null) {
+            classPath = new SoftReference<Collection<FileObject>>(cp = computeClassPath());
+        }
+
+        return cp;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getClassPathString() {
+        try {
+            InputStream in = category.getCacheRoot().getFileObject("classpath").getInputStream();
+            Properties props = new Properties();
+
+            try {
+                props.load(in);
+            } finally {
+                in.close();
+            }
+
+            return props.getProperty(code);
+        } catch (IOException ex) {
+            Logger.getLogger(SourceRoot.class.getName()).log(Level.SEVERE, null, ex);
+            return null;
+        }
+    }
+    
+    private Collection<FileObject> computeClassPath() {
+        Collection<FileObject> result = new ArrayList<FileObject>();
+
+        try {
+            final String bootPath = System.getProperty("sun.boot.class.path");
+
+            for (String bp : bootPath.split(":")) {
+                File f = new File(bp);
+
+                if (!f.canRead()) continue;
+
+                FileObject root = new JarFileSystem(f).getRoot();
+
+                result.add(root);
+            }
+
+            String classpath = getClassPathString();
+
+            if (classpath != null) {
+                for (String entry : classpath.split(":")) {
+                    FileObject root = category.getEmbeddedJarRoot(entry);
+
+                    if (!entry.endsWith(".jar")) {
+                        root = root.getFileObject("java/15/classes");
+                    }
+
+                    if (root != null) {
+                        result.add(root);
+                    } else {
+                        LOG.log(Level.FINE, "Cannot find {0}", entry);
+                    }
+                }
+            }
+        } catch (IOException ex) {
+            ex.printStackTrace();//XXX
+        }
+
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/Utilities.java
----------------------------------------------------------------------
diff --git a/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/Utilities.java b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/Utilities.java
new file mode 100644
index 0000000..df40d15
--- /dev/null
+++ b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/Utilities.java
@@ -0,0 +1,76 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.jackpot30.backend.base;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ *
+ * @author lahvac
+ */
+public class Utilities {
+
+    public static <T> Map<String, List<T>> sortBySourceRoot(List<Entry<String, T>> found, CategoryStorage category) {
+        Map<String, List<T>> result = new LinkedHashMap<String, List<T>>();
+
+        for (Entry<String, T> e : found) {
+            for (SourceRoot sourceRoot : category.getSourceRoots()) {
+                if (e.getKey().startsWith(sourceRoot.getRelativePath())) {
+                    List<T> current = result.get(sourceRoot.getRelativePath());
+
+                    if (current == null) {
+                        result.put(sourceRoot.getRelativePath(), current = new ArrayList<T>());
+                    }
+
+                    current.add(e.getValue());
+                }
+            }
+        }
+
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/WebUtilities.java
----------------------------------------------------------------------
diff --git a/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/WebUtilities.java b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/WebUtilities.java
new file mode 100644
index 0000000..c7c6c0a
--- /dev/null
+++ b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/WebUtilities.java
@@ -0,0 +1,137 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2009 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.jackpot30.backend.base;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ *
+ */
+public class WebUtilities {
+
+    private WebUtilities() {
+    }
+
+    public static String requestStringResponse (URI uri) {
+        final StringBuffer sb = new StringBuffer ();
+        final URL url;
+        try {
+            url = uri.toURL();
+            final URLConnection urlConnection = url.openConnection ();
+            urlConnection.connect ();
+            final Object content = urlConnection.getContent ();
+//            System.out.println (content);
+//            System.out.println (content.getClass ());
+            final InputStream inputStream = (InputStream) content;
+            final BufferedReader reader = new BufferedReader (new InputStreamReader (inputStream, "ASCII"));
+            try {
+                for (;;) {
+                    String line = reader.readLine ();
+                    if (line == null)
+                        break;
+                    sb.append (line).append ('\n');
+                }
+            } finally {
+                reader.close ();
+            }
+        } catch (IOException e) {
+            e.printStackTrace ();  // TODO
+            return null;
+        }
+        return sb.toString ();
+    }
+    
+    public static Collection<? extends String> requestStringArrayResponse (URI uri) {
+        final List<String> result = new LinkedList<String> ();
+        final URL url;
+        try {
+            url = uri.toURL();
+            final URLConnection urlConnection = url.openConnection ();
+            urlConnection.connect ();
+            final Object content = urlConnection.getContent ();
+//            System.out.println (content);
+//            System.out.println (content.getClass ());
+            final InputStream inputStream = (InputStream) content;
+            final BufferedReader reader = new BufferedReader (new InputStreamReader (inputStream, "ASCII"));
+            try {
+                for (;;) {
+                    String line = reader.readLine ();
+                    if (line == null)
+                        break;
+                    result.add (line);
+                }
+            } finally {
+                reader.close ();
+            }
+        } catch (IOException e) {
+            e.printStackTrace ();  // TODO
+        }
+        return result;
+    }
+
+    private static String[] c = new String[] {"&", "<", ">", "\n", "\""}; // NOI18N
+    private static String[] tags = new String[] {"&amp;", "&lt;", "&gt;", "<br>", "&quot;"}; // NOI18N
+
+    public static String escapeForHTMLElement(String input) {
+        for (int cntr = 0; cntr < c.length; cntr++) {
+            input = input.replaceAll(c[cntr], tags[cntr]);
+        }
+
+        return input;
+    }
+
+    public static String escapeForQuery(String pattern) throws URISyntaxException {
+        if (pattern == null) return null;
+        return new URI(null, null, null, -1, null, pattern, null).getRawQuery().replaceAll(Pattern.quote("&"), Matcher.quoteReplacement("%26"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/api/API.java
----------------------------------------------------------------------
diff --git a/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/api/API.java b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/api/API.java
new file mode 100644
index 0000000..a16e096
--- /dev/null
+++ b/remoting/server/web/base.web.api/src/org/netbeans/modules/jackpot30/backend/base/api/API.java
@@ -0,0 +1,101 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009-2011 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.jackpot30.backend.base.api;
+
+import java.io.IOException;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.codeviation.pojson.Pojson;
+import org.netbeans.modules.jackpot30.backend.base.AccessStatistics;
+import org.netbeans.modules.jackpot30.backend.base.CategoryStorage;
+
+/**
+ *
+ * @author lahvac
+ */
+@Path("/index")
+public class API {
+
+    @GET
+    @Path("/list")
+    @Produces("text/plain")
+    public String list() throws IOException {
+        StringBuilder sb = new StringBuilder();
+
+        for (CategoryStorage c : CategoryStorage.listCategories()) {
+            sb.append(c.getId());
+            sb.append(":");
+            sb.append(c.getDisplayName());
+            sb.append("\n");
+        }
+
+        return sb.toString();
+    }
+
+    @GET
+    @Path("/internal/indexUpdated")
+    @Produces("text/plain")
+    public String indexUpdated() throws IOException {
+        //XXX: should allow individual providers to do their own cleanup:
+        
+        CategoryStorage.internalReset();
+        
+        return "Done";
+    }
+
+    @GET
+    @Path("/info")
+    @Produces("text/plain")
+    public String info(@QueryParam("path") String segment) throws IOException {
+        CategoryStorage cat = CategoryStorage.forId(segment);
+
+        return cat.getInfo();
+    }
+
+    @GET
+    @Path("/accessStatistics")
+    @Produces("text/plain")
+    public String accessStatistics() throws IOException {
+        return Pojson.save(AccessStatistics.getStatistics());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/web/nbindex.web.api/build.xml
----------------------------------------------------------------------
diff --git a/remoting/server/web/nbindex.web.api/build.xml b/remoting/server/web/nbindex.web.api/build.xml
new file mode 100644
index 0000000..5ed7175
--- /dev/null
+++ b/remoting/server/web/nbindex.web.api/build.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+Copyright 2009-2017 Oracle and/or its affiliates. All rights reserved.
+
+Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+Other names may be trademarks of their respective owners.
+
+The contents of this file are subject to the terms of either the GNU
+General Public License Version 2 only ("GPL") or the Common
+Development and Distribution License("CDDL") (collectively, the
+"License"). You may not use this file except in compliance with the
+License. You can obtain a copy of the License at
+http://www.netbeans.org/cddl-gplv2.html
+or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+specific language governing permissions and limitations under the
+License.  When distributing the software, include this License Header
+Notice in each file and include the License file at
+nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the GPL Version 2 section of the License file that
+accompanied this code. If applicable, add the following below the
+License Header, with the fields enclosed by brackets [] replaced by
+your own identifying information:
+"Portions Copyrighted [year] [name of copyright owner]"
+
+Contributor(s):
+
+The Original Software is NetBeans. The Initial Developer of the Original
+Software is Sun Microsystems, Inc. Portions Copyright 2009-2010 Sun
+Microsystems, Inc. All Rights Reserved.
+
+If you wish your version of this file to be governed by only the CDDL
+or only the GPL Version 2, indicate your decision by adding
+"[Contributor] elects to include this software in this distribution
+under the [CDDL or GPL Version 2] license." If you do not indicate a
+single choice of license, a recipient has the option to distribute
+your version of this file under either the CDDL, the GPL Version 2 or
+to extend the choice of license to its licensees as provided above.
+However, if you add GPL Version 2 code and therefore, elected the GPL
+Version 2 license, then the option applies only if the new code is
+made subject to such option by the copyright holder.
+-->
+<!-- You may freely edit this file. See commented blocks below for -->
+<!-- some examples of how to customize the build. -->
+<!-- (If you delete it and reopen the project it will be recreated.) -->
+<!-- By default, only the Clean and Build commands use this build script. -->
+<!-- Commands such as Run, Debug, and Test only use this build script if -->
+<!-- the Compile on Save feature is turned off for the project. -->
+<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
+<!-- in the project's Project Properties dialog box.-->
+<project name="nbindex.web.api" default="default" basedir=".">
+    <description>Builds, tests, and runs the project nbindex.web.api.</description>
+    <import file="nbproject/build-impl.xml"/>
+    <!--
+
+    There exist several targets which are by default empty and which can be 
+    used for execution of your tasks. These targets are usually executed 
+    before and after some main targets. They are: 
+
+      -pre-init:                 called before initialization of project properties
+      -post-init:                called after initialization of project properties
+      -pre-compile:              called before javac compilation
+      -post-compile:             called after javac compilation
+      -pre-compile-single:       called before javac compilation of single file
+      -post-compile-single:      called after javac compilation of single file
+      -pre-compile-test:         called before javac compilation of JUnit tests
+      -post-compile-test:        called after javac compilation of JUnit tests
+      -pre-compile-test-single:  called before javac compilation of single JUnit test
+      -post-compile-test-single: called after javac compilation of single JUunit test
+      -pre-jar:                  called before JAR building
+      -post-jar:                 called after JAR building
+      -post-clean:               called after cleaning build products
+
+    (Targets beginning with '-' are not intended to be called on their own.)
+
+    Example of inserting an obfuscator after compilation could look like this:
+
+        <target name="-post-compile">
+            <obfuscate>
+                <fileset dir="${build.classes.dir}"/>
+            </obfuscate>
+        </target>
+
+    For list of available properties check the imported 
+    nbproject/build-impl.xml file. 
+
+
+    Another way to customize the build is by overriding existing main targets.
+    The targets of interest are: 
+
+      -init-macrodef-javac:     defines macro for javac compilation
+      -init-macrodef-junit:     defines macro for junit execution
+      -init-macrodef-debug:     defines macro for class debugging
+      -init-macrodef-java:      defines macro for class execution
+      -do-jar:                  JAR building
+      run:                      execution of project 
+      -javadoc-build:           Javadoc generation
+      test-report:              JUnit report generation
+
+    An example of overriding the target for project execution could look like this:
+
+        <target name="run" depends="nbindex.web.api-impl.jar">
+            <exec dir="bin" executable="launcher.exe">
+                <arg file="${dist.jar}"/>
+            </exec>
+        </target>
+
+    Notice that the overridden target depends on the jar target and not only on 
+    the compile target as the regular run target does. Again, for a list of available 
+    properties which you can use, check the target you are overriding in the
+    nbproject/build-impl.xml file. 
+
+    -->
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/web/nbindex.web.api/manifest.mf
----------------------------------------------------------------------
diff --git a/remoting/server/web/nbindex.web.api/manifest.mf b/remoting/server/web/nbindex.web.api/manifest.mf
new file mode 100644
index 0000000..328e8e5
--- /dev/null
+++ b/remoting/server/web/nbindex.web.api/manifest.mf
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+X-COMMENT: Main-Class will be added automatically by build
+