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:09 UTC

[16/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/indexer/usages/src/org/netbeans/modules/jackpot30/indexer/usages/IndexerImpl.java
----------------------------------------------------------------------
diff --git a/remoting/server/indexer/usages/src/org/netbeans/modules/jackpot30/indexer/usages/IndexerImpl.java b/remoting/server/indexer/usages/src/org/netbeans/modules/jackpot30/indexer/usages/IndexerImpl.java
new file mode 100644
index 0000000..d475e82
--- /dev/null
+++ b/remoting/server/indexer/usages/src/org/netbeans/modules/jackpot30/indexer/usages/IndexerImpl.java
@@ -0,0 +1,525 @@
+/*
+ * 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.indexer.usages;
+
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.IdentifierTree;
+import com.sun.source.tree.MemberSelectTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.NewClassTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.util.Trees;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ErrorType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import org.apache.lucene.document.CompressionTools;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.Field.Index;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.index.CorruptIndexException;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanClause.Occur;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.TermQuery;
+import org.netbeans.api.editor.mimelookup.MimeRegistration;
+import org.netbeans.api.java.source.ElementHandle;
+import org.netbeans.modules.jackpot30.backend.impl.spi.IndexAccessor;
+import org.netbeans.modules.java.preprocessorbridge.spi.JavaIndexerPlugin;
+import org.netbeans.modules.java.source.usages.ClassFileUtil;
+import org.netbeans.modules.parsing.spi.indexing.Indexable;
+import org.openide.filesystems.FileObject;
+import org.openide.util.Exceptions;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author lahvac
+ */
+public class IndexerImpl implements JavaIndexerPlugin {
+
+    private static final boolean NAVIGABLE = Boolean.getBoolean("jackpot.navigable.index");
+            static final String KEY_SIGNATURES = "signatures";
+            static final String KEY_MARKER = "usagesIndexMarker";
+
+    private final URL root;
+
+    public IndexerImpl(URL root) {
+        this.root = root;
+    }
+
+    static long treePosition(Trees trees, TreePath tree) {
+        switch (tree.getLeaf().getKind()) {
+            case MEMBER_SELECT:
+                return trees.getSourcePositions().getEndPosition(tree.getCompilationUnit(), tree.getLeaf()) - ((MemberSelectTree) tree.getLeaf()).getIdentifier().length();
+        }
+
+        return trees.getSourcePositions().getStartPosition(tree.getCompilationUnit(), tree.getLeaf());
+    }
+
+    @Override
+    public void process(CompilationUnitTree toProcess, Indexable indexable, Lookup services) {
+        if (!IndexAccessor.getCurrent().isAcceptable(indexable.getURL())) return;
+        try {
+            doDelete(indexable);
+            
+            final String file = IndexAccessor.getCurrent().getPath(indexable.getURL());
+            final Trees trees = services.lookup(Trees.class);
+            final Elements elements = services.lookup(Elements.class);
+            final Types types = services.lookup(Types.class);
+            final Document usages = new Document();
+
+            usages.add(new Field("file", file, Store.YES, Index.NOT_ANALYZED));
+            usages.add(new Field(KEY_MARKER, "true", Store.NO, Index.NOT_ANALYZED));
+
+            final StringBuilder attributedSignatures = new StringBuilder();
+            final StringBuilder attributedSubSignatures = new StringBuilder();
+
+            new TreePathScanner<Void, Void>() {
+                private final Set<String> SEEN_SIGNATURES = new HashSet<String>();
+                @Override public Void visitIdentifier(IdentifierTree node, Void p) {
+                    handleNode();
+                    return super.visitIdentifier(node, p);
+                }
+                @Override public Void visitMemberSelect(MemberSelectTree node, Void p) {
+                    handleNode();
+                    return super.visitMemberSelect(node, p);
+                }
+                @Override public Void visitNewClass(NewClassTree node, Void p) {
+                    handleNode();
+                    return super.visitNewClass(node, p);
+                }
+                private void handleNode() {
+                    Element el = trees.getElement(getCurrentPath());
+
+                    if (el != null && Common.SUPPORTED_KINDS.contains(el.getKind())) {
+                        String serialized = Common.serialize(ElementHandle.create(el));
+
+                        if (SEEN_SIGNATURES.add(serialized)) {
+                            usages.add(new Field(KEY_SIGNATURES, serialized, Store.YES, Index.NOT_ANALYZED));
+                        }
+
+                        long pos = treePosition(trees, getCurrentPath());
+
+                        if (NAVIGABLE) {
+                            attributedSignatures.append(Long.toString(pos));
+                            attributedSignatures.append(":");
+                            attributedSignatures.append(serialized);
+                            attributedSignatures.append(",");
+                            attributedSubSignatures.append(Long.toString(pos));
+                            attributedSubSignatures.append(":");
+                            attributedSubSignatures.append(serialized);
+                            attributedSubSignatures.append(",");
+                        }
+
+                        if (el.getKind() == ElementKind.METHOD) {
+                            for (ExecutableElement e : overrides(types, elements, (ExecutableElement) el)) {
+                                serialized = Common.serialize(ElementHandle.create(e));
+
+                                if (SEEN_SIGNATURES.add(serialized)) {
+                                    usages.add(new Field(KEY_SIGNATURES, serialized, Store.YES, Index.NOT_ANALYZED));
+                                }
+
+                                if (NAVIGABLE) {
+                                    attributedSubSignatures.append(Long.toString(pos));
+                                    attributedSubSignatures.append(":");
+                                    attributedSubSignatures.append(serialized);
+                                    attributedSubSignatures.append(",");
+                                }
+                            }
+                        }
+                    }
+                }
+
+                private String currentClassFQN;
+                @Override public Void visitClass(ClassTree node, Void p) {
+                    String oldClassFQN = currentClassFQN;
+                    boolean oldInMethod = inMethod;
+
+                    try {
+                        Element el = trees.getElement(getCurrentPath());
+
+                        if (el != null) {
+                            try {
+                                TypeElement tel = (TypeElement) el;
+                                currentClassFQN = elements.getBinaryName(tel).toString();
+                                Document currentClassDocument = new Document();
+
+                                currentClassDocument.add(new Field("classFQN", currentClassFQN, Store.YES, Index.NO));
+                                currentClassDocument.add(new Field("classSimpleName", node.getSimpleName().toString(), Store.YES, Index.NOT_ANALYZED));
+                                currentClassDocument.add(new Field("classSimpleNameLower", node.getSimpleName().toString().toLowerCase(), Store.YES, Index.NOT_ANALYZED));
+                                currentClassDocument.add(new Field("classKind", el.getKind().name(), Store.YES, Index.NO));
+                                for (Modifier m : el.getModifiers()) {
+                                    currentClassDocument.add(new Field("classModifiers", m.name(), Store.YES, Index.NO));
+                                }
+
+                                recordSuperTypes(currentClassDocument, tel, new HashSet<String>(Arrays.asList(tel.getQualifiedName().toString())));
+
+                                currentClassDocument.add(new Field("file", file, Store.YES, Index.NOT_ANALYZED));
+                                currentClassDocument.add(new Field(KEY_MARKER, "true", Store.NO, Index.NOT_ANALYZED));
+
+                                if (NAVIGABLE) {
+                                    currentClassDocument.add(new Field("declarationSignature", Common.serialize(ElementHandle.create(el)), Store.YES, Index.NOT_ANALYZED));
+                                    currentClassDocument.add(new Field("declarationPosition", Long.toString(trees.getSourcePositions().getStartPosition(getCurrentPath().getCompilationUnit(), node)), Store.YES, Index.NO));
+                                }
+
+                                IndexAccessor.getCurrent().getIndexWriter().addDocument(currentClassDocument);
+                            } catch (CorruptIndexException ex) {
+                                Exceptions.printStackTrace(ex);
+                            } catch (IOException ex) {
+                                Exceptions.printStackTrace(ex);
+                            }
+                        }
+
+                        inMethod = false;
+
+                        return super.visitClass(node, p);
+                    } finally {
+                        currentClassFQN = oldClassFQN;
+                        inMethod = oldInMethod;
+                    }
+                }
+
+                private boolean inMethod;
+                @Override public Void visitMethod(MethodTree node, Void p) {
+                    boolean oldInMethod = inMethod;
+
+                    try {
+                        handleFeature();
+                        inMethod = true;
+                        return super.visitMethod(node, p);
+                    } finally {
+                        inMethod = oldInMethod;
+                    }
+                }
+
+                @Override public Void visitVariable(VariableTree node, Void p) {
+                    if (!inMethod)
+                        handleFeature();
+                    return super.visitVariable(node, p);
+                }
+
+                public void handleFeature() {
+                    Element el = trees.getElement(getCurrentPath());
+
+                    if (el != null) {
+                        try {
+                            Document currentFeatureDocument = new Document();
+
+                            currentFeatureDocument.add(new Field("featureClassFQN", currentClassFQN, Store.YES, Index.NO));
+                            currentFeatureDocument.add(new Field("featureSimpleName", el.getSimpleName().toString(), Store.YES, Index.NOT_ANALYZED));
+                            currentFeatureDocument.add(new Field("featureSimpleNameLower", el.getSimpleName().toString().toLowerCase(), Store.YES, Index.NOT_ANALYZED));
+                            currentFeatureDocument.add(new Field("featureKind", el.getKind().name(), Store.YES, Index.NO));
+                            for (Modifier m : el.getModifiers()) {
+                                currentFeatureDocument.add(new Field("featureModifiers", m.name(), Store.YES, Index.NO));
+                            }
+                            currentFeatureDocument.add(new Field("file", file, Store.YES, Index.NOT_ANALYZED));
+                            currentFeatureDocument.add(new Field(KEY_MARKER, "true", Store.NO, Index.NOT_ANALYZED));
+
+                            if (el.getKind() == ElementKind.METHOD || el.getKind() == ElementKind.CONSTRUCTOR) {
+                                String featureSignature = methodTypeSignature(elements, (ExecutableElement) el);
+
+                                currentFeatureDocument.add(new Field("featureSignature", featureSignature, Store.YES, Index.NO));
+                                currentFeatureDocument.add(new Field("featureVMSignature", ClassFileUtil.createExecutableDescriptor((ExecutableElement) el)[2], Store.YES, Index.NO));
+
+                                for (ExecutableElement e : overrides(types, elements, (ExecutableElement) el)) {
+                                    currentFeatureDocument.add(new Field("featureOverrides", Common.serialize(ElementHandle.create(e)), Store.YES, Index.NOT_ANALYZED));
+                                }
+                            }
+
+                            if (NAVIGABLE) {
+                                currentFeatureDocument.add(new Field("declarationSignature", Common.serialize(ElementHandle.create(el)), Store.YES, Index.NOT_ANALYZED));
+                                currentFeatureDocument.add(new Field("declarationPosition", Long.toString(trees.getSourcePositions().getStartPosition(getCurrentPath().getCompilationUnit(), getCurrentPath().getLeaf())), Store.YES, Index.NO));
+                            }
+
+                            IndexAccessor.getCurrent().getIndexWriter().addDocument(currentFeatureDocument);
+                        } catch (CorruptIndexException ex) {
+                            Exceptions.printStackTrace(ex);
+                        } catch (IOException ex) {
+                            Exceptions.printStackTrace(ex);
+                        }
+                    }
+                }
+            }.scan(toProcess, null);
+
+            if (NAVIGABLE) {
+                usages.add(new Field("attributedSignatures", CompressionTools.compressString(attributedSignatures.toString())));
+                usages.add(new Field("attributedSubSignatures", CompressionTools.compressString(attributedSubSignatures.toString())));
+            }
+            
+            IndexAccessor.getCurrent().getIndexWriter().addDocument(usages);
+        } catch (IOException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+    }
+
+    static Collection<? extends ExecutableElement> overrides(Types types, Elements elements, ExecutableElement method) {
+        TypeElement enclosing = (TypeElement) method.getEnclosingElement();
+        List<TypeMirror> todo = new LinkedList<TypeMirror>(types.directSupertypes(enclosing.asType()));
+        List<TypeMirror> seen = new ArrayList<TypeMirror>();
+        List<ExecutableElement> result = new LinkedList<ExecutableElement>();
+
+        OUTER: while (!todo.isEmpty()) {
+            TypeMirror type = todo.remove(0);
+
+            if (type.getKind() != TypeKind.DECLARED) continue;
+
+            for (TypeMirror s : seen) {
+                if (types.isSameType(s, type)) continue OUTER;
+            }
+
+            TypeElement te = (TypeElement) ((DeclaredType) type).asElement();
+
+            for (ExecutableElement m : ElementFilter.methodsIn(te.getEnclosedElements())) {
+                if (elements.overrides(method, m, enclosing))
+                    result.add(m);
+            }
+
+        }
+
+        return result;
+    }
+    
+    private static void recordSuperTypes(Document target, TypeElement tel, Set<String> alreadySeen) {
+        String fqn = tel.getQualifiedName().toString();
+
+        if (alreadySeen.add(fqn)) {
+            target.add(new Field("classSupertypes", fqn, Store.YES, Index.NOT_ANALYZED));
+        }
+
+        if (tel.getSuperclass().getKind() == TypeKind.DECLARED) {
+            recordSuperTypes(target, (TypeElement) ((DeclaredType) tel.getSuperclass()).asElement(), alreadySeen);
+        }
+
+        for (TypeMirror i : tel.getInterfaces()) {
+            if (i.getKind() == TypeKind.DECLARED) {
+                recordSuperTypes(target, (TypeElement) ((DeclaredType) i).asElement(), alreadySeen);
+            }
+        }
+    }
+
+    private static void encodeTypeParameters(Elements elements, Collection<? extends TypeParameterElement> params, StringBuilder result) {
+        if (params.isEmpty()) return;
+        result.append("<");
+        for (TypeParameterElement tpe : params) {
+            result.append(tpe.getSimpleName());
+            boolean wasClass = false;
+            
+            for (TypeMirror tm : tpe.getBounds()) {
+                if (tm.getKind() == TypeKind.DECLARED && !((DeclaredType) tm).asElement().getKind().isClass() && !wasClass) {
+                    result.append(":Ljava/lang/Object;");
+                }
+                
+                wasClass = true;
+                result.append(':');
+                encodeType(elements, tm, result);
+            }
+        }
+        result.append(">");
+    }
+    
+    static String methodTypeSignature(Elements elements, ExecutableElement ee) {
+        StringBuilder sb = new StringBuilder ();
+        encodeTypeParameters(elements, ee.getTypeParameters(), sb);
+        sb.append('(');             // NOI18N
+        for (VariableElement pd : ee.getParameters()) {
+            encodeType(elements, pd.asType(),sb);
+        }
+        sb.append(')');             // NOI18N
+        encodeType(elements, ee.getReturnType(), sb);
+        for (TypeMirror tm : ee.getThrownTypes()) {
+            sb.append('^');
+            encodeType(elements, tm, sb);
+        }
+        sb.append(';'); //TODO: unsure about this, but classfile signatures seem to have it
+        return sb.toString();
+    }
+
+    private static void encodeType(Elements elements, final TypeMirror type, final StringBuilder sb) {
+	switch (type.getKind()) {
+	    case VOID:
+		sb.append('V');	    // NOI18N
+		break;
+	    case BOOLEAN:
+		sb.append('Z');	    // NOI18N
+		break;
+	    case BYTE:
+		sb.append('B');	    // NOI18N
+		break;
+	    case SHORT:
+		sb.append('S');	    // NOI18N
+		break;
+	    case INT:
+		sb.append('I');	    // NOI18N
+		break;
+	    case LONG:
+		sb.append('J');	    // NOI18N
+		break;
+	    case CHAR:
+		sb.append('C');	    // NOI18N
+		break;
+	    case FLOAT:
+		sb.append('F');	    // NOI18N
+		break;
+	    case DOUBLE:
+		sb.append('D');	    // NOI18N
+		break;
+	    case ARRAY:
+		sb.append('[');	    // NOI18N
+		assert type instanceof ArrayType;
+		encodeType(elements, ((ArrayType)type).getComponentType(),sb);
+		break;
+	    case DECLARED:
+            {
+		sb.append('L');	    // NOI18N
+                DeclaredType dt = (DeclaredType) type;
+		TypeElement te = (TypeElement) dt.asElement();
+                sb.append(elements.getBinaryName(te).toString().replace('.', '/'));
+                if (!dt.getTypeArguments().isEmpty()) {
+                    sb.append('<');
+                    for (TypeMirror tm : dt.getTypeArguments()) {
+                        encodeType(elements, tm, sb);
+                    }
+                    sb.append('>');
+                }
+		sb.append(';');	    // NOI18N
+		break;
+            }
+	    case TYPEVAR:
+            {
+		assert type instanceof TypeVariable;
+		TypeVariable tr = (TypeVariable) type;
+                sb.append('T');
+                sb.append(tr.asElement().getSimpleName());
+                sb.append(';');
+		break;
+            }
+            case WILDCARD: {
+                WildcardType wt = (WildcardType) type;
+
+                if (wt.getExtendsBound() != null) {
+                    sb.append('+');
+                    encodeType(elements, wt.getExtendsBound(), sb);
+                } else if (wt.getSuperBound() != null) {
+                    sb.append('-');
+                    encodeType(elements, wt.getSuperBound(), sb);
+                } else {
+                    sb.append('*');
+                }
+                break;
+            }
+            case ERROR:
+            {
+                TypeElement te = (TypeElement) ((ErrorType)type).asElement();
+                if (te != null) {
+                    sb.append('L');
+                    sb.append(elements.getBinaryName(te).toString().replace('.', '/'));
+                    sb.append(';');	    // NOI18N
+                    break;
+                }
+            }
+	    default:
+		throw new IllegalArgumentException (type.getKind().name());
+	}
+    }
+
+
+    @Override
+    public void delete(Indexable indexable) {
+        try {
+            doDelete(indexable);
+        } catch (IOException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+    }
+
+    @Override
+    public void finish() {}
+
+    private void doDelete(Indexable indexable) throws IOException {
+        BooleanQuery q = new BooleanQuery();
+
+        q.add(new BooleanClause(new TermQuery(new Term("file", IndexAccessor.getCurrent().getPath(indexable.getURL()))), Occur.MUST));
+        q.add(new BooleanClause(new TermQuery(new Term(KEY_MARKER, "true")), Occur.MUST));
+
+        IndexAccessor.getCurrent().getIndexWriter().deleteDocuments(q);
+    }
+
+    @MimeRegistration(mimeType="text/x-java", service=Factory.class)
+    public static final class FactoryImpl implements Factory {
+
+        @Override
+        public JavaIndexerPlugin create(URL root, FileObject cacheFolder) {
+            return new IndexerImpl(root);
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/indexer/usages/src/org/netbeans/modules/jackpot30/indexer/usages/ResourceIndexerImpl.java
----------------------------------------------------------------------
diff --git a/remoting/server/indexer/usages/src/org/netbeans/modules/jackpot30/indexer/usages/ResourceIndexerImpl.java b/remoting/server/indexer/usages/src/org/netbeans/modules/jackpot30/indexer/usages/ResourceIndexerImpl.java
new file mode 100644
index 0000000..a212c4a
--- /dev/null
+++ b/remoting/server/indexer/usages/src/org/netbeans/modules/jackpot30/indexer/usages/ResourceIndexerImpl.java
@@ -0,0 +1,176 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 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 2013 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.jackpot30.indexer.usages;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.Field.Index;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanClause.Occur;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.TermQuery;
+import org.netbeans.api.editor.mimelookup.MimeRegistration;
+import org.netbeans.modules.jackpot30.backend.impl.spi.IndexAccessor;
+import org.netbeans.modules.jackpot30.backend.impl.spi.Utilities;
+import org.netbeans.modules.parsing.spi.indexing.Context;
+import org.netbeans.modules.parsing.spi.indexing.CustomIndexer;
+import org.netbeans.modules.parsing.spi.indexing.CustomIndexerFactory;
+import org.netbeans.modules.parsing.spi.indexing.Indexable;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.URLMapper;
+import org.openide.util.Exceptions;
+
+/**
+ *
+ * @author lahvac
+ */
+public class ResourceIndexerImpl extends CustomIndexer {
+
+    @Override
+    protected void index(Iterable<? extends Indexable> files, Context context) {
+        for (Indexable indexable : files) {
+            doIndexFile(indexable);
+        }
+    }
+
+    private static final Pattern INTERESTING_PATTERN = Pattern.compile("\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*([.-]\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)+");
+
+    private void doIndexFile(Indexable indexable) {
+        if (!IndexAccessor.getCurrent().isAcceptable(indexable.getURL()) || "text/x-java".equals(indexable.getMimeType())) return;
+        try {
+            doDelete(indexable);
+
+            FileObject file = URLMapper.findFileObject(indexable.getURL());
+
+            if (file == null) return ;
+
+            final String relative = IndexAccessor.getCurrent().getPath(indexable.getURL());
+            final Document usages = new Document();
+
+            usages.add(new Field("file", relative, Store.YES, Index.NOT_ANALYZED));
+            usages.add(new Field(IndexerImpl.KEY_MARKER, "true", Store.NO, Index.NOT_ANALYZED));
+
+            //sources indexer does the same, we should really look into files only once!
+            String content = Utilities.readFully(file);
+            Matcher matcher = INTERESTING_PATTERN.matcher(content);
+            Set<String> SEEN_SIGNATURES = new HashSet<String>();
+
+            while (matcher.find()) {
+                String reference = matcher.group();
+                String[] elements = reference.split("[.-]");
+                StringBuilder currentElement = new StringBuilder();
+
+                currentElement.append(elements[0]);
+
+                for (int i = 1; i < elements.length; i++) {
+                    currentElement.append(".");
+                    currentElement.append(elements[i]);
+                    String serialized = "OTHER:" + currentElement.toString();
+
+                    if (SEEN_SIGNATURES.add(serialized)) {
+                        usages.add(new Field(IndexerImpl.KEY_SIGNATURES, serialized, Store.YES, Index.NOT_ANALYZED));
+                    }
+                }
+            }
+
+            IndexAccessor.getCurrent().getIndexWriter().addDocument(usages);
+        } catch (IOException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+    }
+
+    private static void doDelete(Indexable indexable) throws IOException {
+        BooleanQuery q = new BooleanQuery();
+
+        q.add(new BooleanClause(new TermQuery(new Term("file", IndexAccessor.getCurrent().getPath(indexable.getURL()))), Occur.MUST));
+        q.add(new BooleanClause(new TermQuery(new Term(IndexerImpl.KEY_MARKER, "true")), Occur.MUST));
+
+        IndexAccessor.getCurrent().getIndexWriter().deleteDocuments(q);
+    }
+
+    @MimeRegistration(mimeType="", service=CustomIndexerFactory.class)
+    public static final class FactoryImpl extends CustomIndexerFactory {
+
+        @Override
+        public CustomIndexer createIndexer() {
+            return new ResourceIndexerImpl();
+        }
+
+        @Override
+        public boolean supportsEmbeddedIndexers() {
+            return true;
+        }
+
+        @Override
+        public void filesDeleted(Iterable<? extends Indexable> deleted, Context context) {
+            for (Indexable indexable : deleted) {
+                try {
+                    doDelete(indexable);
+                } catch (IOException ex) {
+                    Exceptions.printStackTrace(ex);
+                }
+            }
+        }
+
+        @Override
+        public void filesDirty(Iterable<? extends Indexable> dirty, Context context) { }
+
+        @Override
+        public String getIndexerName() {
+            return "resource-usages-indexer";
+        }
+
+        @Override
+        public int getIndexVersion() {
+            return 1;
+        }
+        
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/indexer/usages/src/org/netbeans/modules/jackpot30/indexer/usages/UsagesStatisticsGenerator.java
----------------------------------------------------------------------
diff --git a/remoting/server/indexer/usages/src/org/netbeans/modules/jackpot30/indexer/usages/UsagesStatisticsGenerator.java b/remoting/server/indexer/usages/src/org/netbeans/modules/jackpot30/indexer/usages/UsagesStatisticsGenerator.java
new file mode 100644
index 0000000..7e5e39f
--- /dev/null
+++ b/remoting/server/indexer/usages/src/org/netbeans/modules/jackpot30/indexer/usages/UsagesStatisticsGenerator.java
@@ -0,0 +1,72 @@
+/*
+ * 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.indexer.usages;
+
+import java.io.IOException;
+import javax.lang.model.element.ElementKind;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.IndexReader;
+import org.netbeans.modules.jackpot30.backend.impl.spi.StatisticsGenerator;
+import org.openide.util.lookup.ServiceProvider;
+
+/**
+ *
+ * @author lahvac
+ */
+@ServiceProvider(service=StatisticsGenerator.class)
+public class UsagesStatisticsGenerator extends StatisticsGenerator {
+
+    @Override
+    protected void amendStatistics(IndexReader r, Document doc) throws IOException {
+        if (doc.getFieldable("classFQN") != null) increment("java-classes");
+        else if (doc.getFieldable("featureClassFQN") != null) {
+            ElementKind kind = ElementKind.valueOf(doc.getFieldable("featureKind").stringValue());
+
+            if (kind.isField()) {
+                increment("java-fields");
+            } else {
+                increment("java-methods");
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/indexer/usages/test/unit/src/org/netbeans/modules/jackpot30/indexer/usages/IndexerImplTest.java
----------------------------------------------------------------------
diff --git a/remoting/server/indexer/usages/test/unit/src/org/netbeans/modules/jackpot30/indexer/usages/IndexerImplTest.java b/remoting/server/indexer/usages/test/unit/src/org/netbeans/modules/jackpot30/indexer/usages/IndexerImplTest.java
new file mode 100644
index 0000000..aabf7f6
--- /dev/null
+++ b/remoting/server/indexer/usages/test/unit/src/org/netbeans/modules/jackpot30/indexer/usages/IndexerImplTest.java
@@ -0,0 +1,357 @@
+/*
+ * 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.indexer.usages;
+
+import com.sun.source.util.TreePath;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.util.ElementFilter;
+import org.apache.lucene.analysis.KeywordAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.Field.Index;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.document.Fieldable;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.api.java.source.CompilationController;
+import org.netbeans.api.java.source.ElementHandle;
+import org.netbeans.api.java.source.JavaSource;
+import org.netbeans.api.java.source.Task;
+import org.netbeans.junit.NbTestCase;
+import org.netbeans.modules.jackpot30.backend.impl.spi.IndexAccessor;
+import org.netbeans.modules.java.source.indexing.JavaCustomIndexer;
+import org.netbeans.modules.java.source.parsing.JavacParser;
+import org.netbeans.modules.java.source.parsing.JavacParserFactory;
+import org.netbeans.modules.parsing.impl.indexing.CacheFolder;
+import org.netbeans.modules.parsing.impl.indexing.FileObjectIndexable;
+import org.netbeans.modules.parsing.impl.indexing.MimeTypes;
+import org.netbeans.modules.parsing.impl.indexing.SPIAccessor;
+import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.filesystems.MIMEResolver;
+import org.openide.util.Lookup;
+import org.openide.util.lookup.Lookups;
+import org.openide.util.lookup.ServiceProvider;
+
+/**
+ *
+ * @author lahvac
+ */
+public class IndexerImplTest extends NbTestCase {
+
+    public IndexerImplTest(String testName) {
+        super(testName);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        Set<String> mimeTypes = MimeTypes.getAllMimeTypes();
+        if (mimeTypes == null) {
+            mimeTypes = new HashSet<String>();
+        } else {
+            mimeTypes = new HashSet<String>(mimeTypes);
+        }
+
+        mimeTypes.add("text/x-java");
+        MimeTypes.setAllMimeTypes(mimeTypes);
+        
+        org.netbeans.api.project.ui.OpenProjects.getDefault().getOpenProjects();
+        clearWorkDir();
+        CacheFolder.setCacheFolder(FileUtil.toFileObject(getWorkDir()));
+        super.setUp();
+    }
+
+    public void testMethodSignatures() throws IOException {
+        doMethodSignatureTest("package test; public class Test { public void test() {} }", "()V;");
+        doMethodSignatureTest("package test; public class Test { public <T extends String> void test(java.util.Map<java.util.List<String>, T> m, boolean p) {} }", "<T:Ljava/lang/String;>(Ljava/util/Map<Ljava/util/List<Ljava/lang/String;>;TT;>;Z)V;");
+        doMethodSignatureTest("package test; public class Test <T extends String> { public void test(java.util.Map<java.util.List<String>, T> m, boolean p) {} }", "(Ljava/util/Map<Ljava/util/List<Ljava/lang/String;>;TT;>;Z)V;");
+        doMethodSignatureTest("package test; public class Test { public void test() throws java.io.IOException {} }", "()V^Ljava/io/IOException;;");
+        doMethodSignatureTest("package test; public class Test { public void test(java.util.List<? extends String> l) {} }", "(Ljava/util/List<+Ljava/lang/String;>;)V;");
+        doMethodSignatureTest("package test; public class Test <T extends String> { public <P extends T> void test(P p) {} }", "<P:TT;>(TP;)V;");
+    }
+    
+    protected void doMethodSignatureTest(String code, final String signature) throws IOException {
+        FileObject testFile = FileUtil.createData(new File(getWorkDir(), "Test.java"));
+
+        copyToFile(testFile, code);
+
+        final boolean[] invoked = new boolean[1];
+
+        JavaSource.forFileObject(testFile).runUserActionTask(new Task<CompilationController>() {
+            @Override public void run(CompilationController parameter) throws Exception {
+                parameter.toPhase(JavaSource.Phase.RESOLVED);
+
+                ExecutableElement method = ElementFilter.methodsIn(parameter.getTopLevelElements().get(0).getEnclosedElements()).iterator().next();
+
+                assertEquals(signature, IndexerImpl.methodTypeSignature(parameter.getElements(), method));
+                invoked[0] = true;
+            }
+        }, true);
+
+        assertTrue(invoked[0]);
+    }
+
+    public void testOverriddenMethods() throws IOException {
+        doOverriddenMethodsTest("package test; public class Test { public String toStr|ing() { return null; } }",
+                                "METHOD:java.lang.Object:toString:()Ljava/lang/String;");
+        doOverriddenMethodsTest("package test; public class Test extends A implements B { public void t|t() { } } class A implements B { public void tt() {} } interface B { public void tt(); }",
+                                "METHOD:test.A:tt:()V",
+                                "METHOD:test.B:tt:()V");
+    }
+
+    protected void doOverriddenMethodsTest(String code, final String... signature) throws IOException {
+        final int pos = code.indexOf('|');
+
+        code = code.replace("|", "");
+        FileObject testFile = FileUtil.createData(new File(getWorkDir(), "Test.java"));
+        
+        copyToFile(testFile, code);
+
+        final boolean[] invoked = new boolean[1];
+
+        JavaSource.forFileObject(testFile).runUserActionTask(new Task<CompilationController>() {
+            @Override public void run(CompilationController parameter) throws Exception {
+                parameter.toPhase(JavaSource.Phase.RESOLVED);
+
+                TreePath selected = parameter.getTreeUtilities().pathFor(pos);
+                ExecutableElement method = (ExecutableElement) parameter.getTrees().getElement(selected);
+                List<String> result = new ArrayList<String>();
+
+                for (ExecutableElement ee : IndexerImpl.overrides(parameter.getTypes(), parameter.getElements(), method)) {
+                    result.add(Common.serialize(ElementHandle.create(ee)));
+                }
+
+                assertEquals(Arrays.asList(signature), result);
+                invoked[0] = true;
+            }
+        }, true);
+
+        assertTrue(invoked[0]);
+    }
+
+    public void testRepeatedIndexing() throws IOException {
+        final FileObject root = FileUtil.toFileObject(getWorkDir());
+        FileObject testFile = FileUtil.createData(root, "Test.java");
+        copyToFile(testFile, "public class Test {}");
+
+        Directory store = new RAMDirectory();
+        IndexWriter iw = new IndexWriter(store, new KeywordAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
+        IndexAccessor.current = new IndexAccessor(iw, root);
+
+        iw.addDocument(fakeDocument(testFile));
+
+        doIndex(root, testFile);
+        
+        iw.close();
+        IndexReader ir = IndexReader.open(store);
+
+        int expectedDocumentsCount = ir.numDocs();
+
+        assertEquals(3 + 1, expectedDocumentsCount);
+
+        store = new RAMDirectory();
+        iw = new IndexWriter(store, new KeywordAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
+        IndexAccessor.current = new IndexAccessor(iw, root);
+
+        iw.addDocument(fakeDocument(testFile));
+
+        doIndex(root, testFile);
+        doIndex(root, testFile);
+
+        iw.close();
+        ir = IndexReader.open(store);
+
+        assertEquals(expectedDocumentsCount, ir.numDocs());
+    }
+
+    public void testSubdirIndexing() throws IOException {
+        final FileObject root = FileUtil.toFileObject(getWorkDir());
+        FileObject aFile = FileUtil.createData(root, "a/A.java");
+        copyToFile(aFile, "public class A {}");
+        FileObject bFile = FileUtil.createData(root, "b/B.java");
+        copyToFile(bFile, "public class B {}");
+
+        Directory store = new RAMDirectory();
+        IndexWriter iw = new IndexWriter(store, new KeywordAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
+        IndexAccessor.current = new IndexAccessor(iw, root.getFileObject("a"));
+
+        doIndex(root, aFile, bFile);
+
+        iw.close();
+
+        IndexReader ir = IndexReader.open(store);
+        int maxDocs = ir.maxDoc();
+        boolean foundA = false;
+        
+        for (int i = 0; i < maxDocs; i++) {
+            Fieldable f = ir.document(i).getFieldable("file");
+            
+            if (f != null) {
+                assertFalse(f.stringValue(), f.stringValue().contains("B"));
+                if (f.stringValue().contains("A.java")) {
+                    foundA = true;
+                }
+            }
+        }
+
+        assertTrue(foundA);
+    }
+
+    public void testTreePositions() throws IOException {
+        doPositionTests("package test; public class Test { private Test() { ^Sy|stem.err.println(1); } }");
+        doPositionTests("package test; public class Test { private Test() { System.^e|rr.println(1); } }");
+        doPositionTests("package test; public class Test { private Test() { System.err.^p|rintln(1); } }");
+    }
+
+    private void doPositionTests(String code) throws IOException {
+        final int caret = code.replace("^", "").indexOf('|');
+
+        assertTrue("" + caret, caret != (-1));
+
+        code = code.replace("|", "");
+
+        final int expected = code.indexOf('^');
+
+        assertTrue("" + expected, expected != (-1));
+
+        FileObject testFile = FileUtil.createData(new File(getWorkDir(), "Test.java"));
+
+        copyToFile(testFile, code.replace("^", ""));
+
+        final boolean[] invoked = new boolean[1];
+
+        JavaSource.forFileObject(testFile).runUserActionTask(new Task<CompilationController>() {
+            @Override public void run(CompilationController parameter) throws Exception {
+                parameter.toPhase(JavaSource.Phase.RESOLVED);
+
+                TreePath tp = parameter.getTreeUtilities().pathFor(caret);
+
+                assertEquals(expected, IndexerImpl.treePosition(parameter.getTrees(), tp));
+
+                invoked[0] = true;
+            }
+        }, true);
+
+        assertTrue(invoked[0]);
+    }
+
+    private void copyToFile(FileObject testFile, String code) throws IOException {
+        OutputStream out = testFile.getOutputStream();
+        
+        try {
+            out.write(code.getBytes());
+        } finally {
+            out.close();
+        }
+    }
+
+    private Document fakeDocument(FileObject testFile) {
+        //to test that unrelated document are not deleted:
+        Document doc = new Document();
+
+        doc.add(new Field("file", IndexAccessor.getCurrent().getPath(testFile.toURL()), Store.YES, Index.NOT_ANALYZED));
+
+        return doc;
+    }
+
+    private void doIndex(final FileObject root, FileObject... testFiles) throws IOException, IllegalArgumentException {
+        final boolean[] invoked = new boolean[1];
+
+        for (FileObject testFile : testFiles) {
+            JavaSource.forFileObject(testFile).runUserActionTask(new Task<CompilationController>() {
+                @Override public void run(CompilationController parameter) throws Exception {
+                    parameter.toPhase(JavaSource.Phase.RESOLVED);
+
+                    new IndexerImpl(root.toURL()).process(parameter.getCompilationUnit(), SPIAccessor.getInstance().create(new FileObjectIndexable(root, parameter.getFileObject())), Lookups.fixed(parameter.getTrees(), parameter.getElements(), parameter.getTypes()));
+                    invoked[0] = true;
+                }
+            }, true);
+        }
+
+        assertTrue(invoked[0]);
+    }
+
+    @ServiceProvider(service=MimeDataProvider.class)
+    public static final class JavacParserProvider implements MimeDataProvider {
+
+        private Lookup javaLookup = Lookups.fixed(new JavacParserFactory(), new JavaCustomIndexer.Factory());
+
+        public Lookup getLookup(MimePath mimePath) {
+            if (mimePath.getPath().endsWith(JavacParser.MIME_TYPE)) {
+                return javaLookup;
+            }
+
+            return Lookup.EMPTY;
+        }
+
+    }
+
+    @ServiceProvider(service=MIMEResolver.class)
+    public static final class JavaMimeResolver extends MIMEResolver {
+
+        public JavaMimeResolver() {
+            super(JavacParser.MIME_TYPE);
+        }
+
+        @Override
+        public String findMIMEType(FileObject fo) {
+            if ("java".equals(fo.getExt())) {
+                return JavacParser.MIME_TYPE;
+            }
+
+            return null;
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/indexer/usages/test/unit/src/org/netbeans/modules/parsing/impl/indexing/MimeTypes.java
----------------------------------------------------------------------
diff --git a/remoting/server/indexer/usages/test/unit/src/org/netbeans/modules/parsing/impl/indexing/MimeTypes.java b/remoting/server/indexer/usages/test/unit/src/org/netbeans/modules/parsing/impl/indexing/MimeTypes.java
new file mode 100644
index 0000000..ce7bd86
--- /dev/null
+++ b/remoting/server/indexer/usages/test/unit/src/org/netbeans/modules/parsing/impl/indexing/MimeTypes.java
@@ -0,0 +1,66 @@
+/*
+ * 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.parsing.impl.indexing;
+
+import java.util.Set;
+import org.netbeans.api.annotations.common.CheckForNull;
+import org.netbeans.api.annotations.common.NonNull;
+import org.openide.util.Parameters;
+
+/**
+ *
+ * @author Tomas Zezula
+ */
+public class MimeTypes {
+
+    private MimeTypes() {}
+
+    public static void setAllMimeTypes(@NonNull final Set<String> allMimeTypes) {
+        Parameters.notNull("allMimeTypes", allMimeTypes);   //NOI18N
+        Util.allMimeTypes = allMimeTypes;
+    }
+
+    @CheckForNull
+    public static Set<String> getAllMimeTypes() {
+        return Util.allMimeTypes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/scripts/index.sh
----------------------------------------------------------------------
diff --git a/remoting/server/scripts/index.sh b/remoting/server/scripts/index.sh
new file mode 100755
index 0000000..bd032fe
--- /dev/null
+++ b/remoting/server/scripts/index.sh
@@ -0,0 +1,54 @@
+# 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.
+
+DIR=`dirname $0`
+USERDIR=`mktemp -d`;
+trap "rm -rf -- '$USERDIR'" EXIT
+
+ID="$1"; shift
+NAME="$1"; shift
+TARGET="$1"; shift
+ROOT_DIR="$1"; shift
+
+$DIR/indexer/bin/indexer -J-Djava.awt.headless=true --userdir $USERDIR --nosplash --nogui -J-Xmx2048m -J-Dnetbeans.indexing.recursiveListeners=false --info "$JPT30_INFO" --category-id "$ID" --category-name "$NAME" --cache-target "$TARGET" --category-root-dir "$ROOT_DIR" --category-projects "$@"
+
+exit

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/scripts/web.sh
----------------------------------------------------------------------
diff --git a/remoting/server/scripts/web.sh b/remoting/server/scripts/web.sh
new file mode 100755
index 0000000..eca2138
--- /dev/null
+++ b/remoting/server/scripts/web.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+# 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.
+
+#XXX: unix only
+DIR=$(readlink -m `dirname $0`)
+classpath="$DIR/web/web.main.jar"
+for jar in $DIR/web/lib/*.jar; do
+    classpath="$classpath:$jar"
+done
+exec java $JACKPOT_WEB_OPTS -Djava.index.useMemCache=false -Xbootclasspath/p:$DIR/web/lib/nb-javac-api.jar:$DIR/web/lib/nb-javac-impl.jar -classpath "$classpath" org.netbeans.modules.jackpot30.backend.main.WebMain "$@" "$DIR/web/public_html"

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/remoting/server/tests/data/group1/prj1/build.xml
----------------------------------------------------------------------
diff --git a/remoting/server/tests/data/group1/prj1/build.xml b/remoting/server/tests/data/group1/prj1/build.xml
new file mode 100644
index 0000000..7433c98
--- /dev/null
+++ b/remoting/server/tests/data/group1/prj1/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="prj1" default="default" basedir=".">
+    <description>Builds, tests, and runs the project prj1.</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="prj1-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/tests/data/group1/prj1/manifest.mf
----------------------------------------------------------------------
diff --git a/remoting/server/tests/data/group1/prj1/manifest.mf b/remoting/server/tests/data/group1/prj1/manifest.mf
new file mode 100644
index 0000000..328e8e5
--- /dev/null
+++ b/remoting/server/tests/data/group1/prj1/manifest.mf
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+X-COMMENT: Main-Class will be added automatically by build
+