http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/DeferredCustomIndexer.java ---------------------------------------------------------------------- diff --git a/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/DeferredCustomIndexer.java b/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/DeferredCustomIndexer.java new file mode 100644 index 0000000..40945e6 --- /dev/null +++ b/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/DeferredCustomIndexer.java @@ -0,0 +1,500 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009-2010 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-2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.jackpot30.impl.duplicates.indexing; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.net.URL; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JButton; +import javax.swing.SwingUtilities; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.java.classpath.ClassPath; +import org.netbeans.api.java.source.CancellableTask; +import org.netbeans.api.java.source.ClasspathInfo; +import org.netbeans.api.java.source.CompilationController; +import org.netbeans.api.java.source.CompilationInfo; +import org.netbeans.api.java.source.JavaSource; +import org.netbeans.api.java.source.JavaSource.Phase; +import org.netbeans.api.java.source.JavaSource.Priority; +import org.netbeans.api.java.source.JavaSourceTaskFactory; +import org.netbeans.api.java.source.Task; +import org.netbeans.api.progress.ProgressHandle; +import org.netbeans.api.progress.ProgressHandleFactory; +import org.netbeans.modules.parsing.impl.indexing.CacheFolder; +import org.netbeans.modules.parsing.impl.indexing.SPIAccessor; +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.DialogDescriptor; +import org.openide.DialogDisplayer; +import org.openide.filesystems.FileAlreadyLockedException; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.filesystems.URLMapper; +import org.openide.util.Cancellable; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author lahvac + */ +public abstract class DeferredCustomIndexer extends CustomIndexer { + + private static final Logger LOG = Logger.getLogger(DeferredCustomIndexer.class.getName()); + + private final DeferredCustomIndexerFactory factory; + + protected DeferredCustomIndexer(DeferredCustomIndexerFactory factory) { + this.factory = factory; + } + + protected abstract void doIndex(DeferredContext ctx, Collection<? extends FileObject> modifiedAndAdded, Collection<? extends String> removed) throws IOException; + + @Override + protected final void index(Iterable<? extends Indexable> files, Context context) { + update(factory, context.getRootURI(), files, Collections.<Indexable>emptyList()); + } + + private static void dump(File where, Iterable<? extends String> lines) { + Writer out = null; + + try { + out = new BufferedWriter(new OutputStreamWriter(FileUtil.createData(where).getOutputStream(), "UTF-8")); + + for (String line : lines) { + out.write(line); + out.write("\n"); + } + } catch (FileAlreadyLockedException ex) { + Exceptions.printStackTrace(ex); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + } + } + + private static Set<String> gatherRelativePaths(Iterable<? extends Indexable> it) { + Set<String> result = new HashSet<String>(); + + for (Indexable i : it) { + result.add(i.getRelativePath()); + } + + return result; + } + + private static void update(DeferredCustomIndexerFactory factory, URL root, Iterable<? extends Indexable> modified, Iterable<? extends Indexable> deleted) { + try { + Set<String> mod = gatherRelativePaths(modified); + Set<String> del = gatherRelativePaths(deleted); + + File cacheRoot = cacheRoot(root, factory); + + File modifiedFile = new File(cacheRoot, "modified"); + FileObject modifiedFileFO = FileUtil.toFileObject(modifiedFile); + Set<String> modifiedFiles = modifiedFileFO != null ? new HashSet<String>(modifiedFileFO.asLines("UTF-8")) : new HashSet<String>(); + boolean modifiedFilesChanged = modifiedFiles.removeAll(del); + + modifiedFilesChanged |= modifiedFiles.addAll(mod); + + if (modifiedFilesChanged) { + dump(modifiedFile, modifiedFiles); + } + + File deletedFile = new File(cacheRoot, "deleted"); + FileObject deletedFileFO = FileUtil.toFileObject(deletedFile); + Set<String> deletedFiles = deletedFileFO != null ? new HashSet<String>(deletedFileFO.asLines("UTF-8")) : new HashSet<String>(); + + boolean deletedFilesChanged = deletedFiles.removeAll(mod); + + deletedFilesChanged |= deletedFiles.addAll(del); + + if (deletedFilesChanged) { + dump(deletedFile, deletedFiles); + } + + if (!modifiedFiles.isEmpty() || !deletedFiles.isEmpty()) { + add2TODO(root, factory); + } + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + + public static abstract class DeferredCustomIndexerFactory extends CustomIndexerFactory { + + public abstract DeferredCustomIndexer createIndexer(); + + @Override + public final void filesDeleted(Iterable<? extends Indexable> deleted, Context context) { + update(this, context.getRootURI(), Collections.<Indexable>emptyList(), deleted); + } + + @Override + public final void filesDirty(Iterable<? extends Indexable> dirty, Context context) {} + + @Override + public final boolean supportsEmbeddedIndexers() { + return false; + } + + @Override + public final void rootsRemoved(Iterable<? extends URL> removedRoots) { + super.rootsRemoved(removedRoots); + } + + @Override + public final void scanFinished(Context context) { + super.scanFinished(context); + } + + @Override + public final boolean scanStarted(Context context) { + return super.scanStarted(context); + } + + public void updateIndex(final URL root, final AtomicBoolean cancel) throws IOException { + final FileObject rootFO = URLMapper.findFileObject(root); + final ClasspathInfo cpInfo = ClasspathInfo.create(ClassPath.EMPTY, ClassPath.EMPTY, ClassPath.EMPTY); + + JavaSource.create(cpInfo).runUserActionTask(new Task<CompilationController>() { + public void run(CompilationController parameter) throws Exception { + if (cancel.get()) return ; + updateRoot(DeferredCustomIndexerFactory.this, root, rootFO, cancel); + } + }, true); + } + + } + + public static final class DeferredContext { + private final @NonNull URL root; + private final @NonNull FileObject rootFileObject; + private final @NonNull FileObject cacheRoot; + private final @NonNull Set<? extends FileObject> modifiedAndAdded; + private final @NonNull Set<? extends String> removed; + private final @NonNull AtomicBoolean cancel; + + public DeferredContext(URL root, FileObject rootFileObject, FileObject cacheRoot, Set<? extends FileObject> modifiedAndAdded, Set<? extends String> removed, AtomicBoolean cancel) { + this.root = root; + this.rootFileObject = rootFileObject; + this.cacheRoot = cacheRoot; + this.modifiedAndAdded = modifiedAndAdded; + this.removed = removed; + this.cancel = cancel; + } + + public @NonNull URL getRoot() { + return root; + } + + public @NonNull FileObject getRootFileObject() { + return rootFileObject; + } + + public FileObject getCacheRoot() { + return cacheRoot; + } + + public boolean isCancelled() { + return cancel.get(); + } + + public void handledModifiedFile(FileObject file) { + modifiedAndAdded.remove(file); + } + + public void handledRemovedFile(String relative) { + removed.remove(relative); + } + } + + /*return: true == done*/ + private static boolean updateRoot(DeferredCustomIndexerFactory factory, URL root, FileObject rootFO, AtomicBoolean cancel) throws IOException { + LOG.log(Level.FINE, "updating: {0}, for indexer: {1}", new Object[] {root.toExternalForm(), factory.getIndexerName()}); + File cacheRoot = cacheRoot(root, factory); + FileObject deletedFile = FileUtil.toFileObject(new File(cacheRoot, "deleted")); + Set<String> deletedFiles = deletedFile != null ? new HashSet<String>(deletedFile.asLines("UTF-8")) : Collections.<String>emptySet(); + + FileObject modifiedFile = FileUtil.toFileObject(new File(cacheRoot, "modified")); + Set<String> modifiedFiles = modifiedFile != null ? new HashSet<String>(modifiedFile.asLines("UTF-8")) : Collections.<String>emptySet(); + + Set<FileObject> toIndex = new HashSet<FileObject>(); + + for (String r : modifiedFiles) { + FileObject f = rootFO.getFileObject(r); + + if (f != null) { + toIndex.add(f); + } + } + + if (!toIndex.isEmpty() || !modifiedFiles.isEmpty()) { + factory.createIndexer().doIndex(new DeferredContext(root, rootFO, FileUtil.toFileObject(cacheRoot), toIndex, deletedFiles, cancel), new HashSet<FileObject>(toIndex), new HashSet<String>(deletedFiles)); + } + + boolean done = true; + + if (deletedFile != null) { + if (deletedFiles.isEmpty()) { + deletedFile.delete(); + } else { + dump(new File(cacheRoot, "deleted"), deletedFiles); + done = false; + } + } + if (modifiedFile != null) { + if (toIndex.isEmpty()) { + modifiedFile.delete(); + } else { + modifiedFiles.clear(); + + for (FileObject f : toIndex) { + modifiedFiles.add(FileUtil.getRelativePath(rootFO, f)); + } + + dump(new File(cacheRoot, "modified"), modifiedFiles); + done = false; + } + } + + return done; + } + + private static final Map<String, TODO> todo = new HashMap<String, TODO>(); //XXX: synchronization!!! + + private static void add2TODO(URL root, DeferredCustomIndexerFactory factory) { + if (DISABLED_INDEXERS.contains(factory.getIndexerName())) return; + + boolean wasEmpty = todo.isEmpty(); + TODO roots = todo.get(factory.getIndexerName()); + + if (roots == null) { + todo.put(factory.getIndexerName(), roots = new TODO(factory)); + } + + roots.roots.add(root); + + LOG.log(Level.FINE, "add2TODO, root: {0}, for factory: {1}, wasEmpty: {2}, todo: {3}", new Object[] {root.toExternalForm(), factory.getIndexerName(), wasEmpty, todo.toString()}); + + if (wasEmpty) RunAsNeededFactory.fileChanged(); + else RunAsNeededFactory.refresh(); + } + + private static File cacheRoot(URL root, CustomIndexerFactory factory) throws IOException { + FileObject indexBaseFolder = CacheFolder.getDataFolder(root); + String path = SPIAccessor.getInstance().getIndexerPath(factory.getIndexerName(), factory.getIndexVersion()); + FileObject indexFolder = FileUtil.createFolder(indexBaseFolder, path); + return FileUtil.toFile(indexFolder); + } + + private static final Set<String> DISABLED_INDEXERS = Collections.synchronizedSet(new HashSet<String>()); + + private static class UpdateWorker implements CancellableTask<CompilationInfo> { + + private static ProgressHandle progressForCurrentFactory; + private static DeferredCustomIndexerFactory currentFactory; + + private final AtomicBoolean cancel = new AtomicBoolean(); + + public void run(CompilationInfo parameter) throws Exception { + cancel.set(false); + + for (Iterator<Entry<String, TODO>> it = todo.entrySet().iterator(); it.hasNext();) { + if (cancel.get()) return; + + final Entry<String, TODO> e = it.next(); + + if (DISABLED_INDEXERS.contains(e.getKey())) { + it.remove(); + continue; + } + + if (currentFactory != e.getValue().factory) { + if (progressForCurrentFactory != null) { + progressForCurrentFactory.finish(); + } + + currentFactory = e.getValue().factory; + progressForCurrentFactory = ProgressHandleFactory.createSystemHandle("Background indexing for: " + currentFactory.getIndexerName(), new Cancellable() { + public boolean cancel() { + assert SwingUtilities.isEventDispatchThread(); + + JButton disableInThisSession = new JButton("Disable in This Session"); + JButton disablePermanently = new JButton("Disable Permanently"); + + disablePermanently.setEnabled(false); + + Object[] buttons = new Object[]{disableInThisSession, disablePermanently, DialogDescriptor.CANCEL_OPTION}; + DialogDescriptor dd = new DialogDescriptor("Disable background indexing for: " + e.getValue().factory.getIndexerName(), "Disable Background Indexing", true, buttons, disableInThisSession, DialogDescriptor.DEFAULT_ALIGN, null, null); + + dd.setClosingOptions(buttons); + + Object result = DialogDisplayer.getDefault().notify(dd); + + if (result == disableInThisSession) { + DISABLED_INDEXERS.add(e.getKey()); + return true; + } else if (result == disablePermanently) { + throw new UnsupportedOperationException(); + } else { + return false; + } + } + }); + + progressForCurrentFactory.start(); + } + + for (Iterator<URL> factIt = e.getValue().roots.iterator(); factIt.hasNext();) { + if (cancel.get()) return; + + URL root = factIt.next(); + FileObject rootFO = URLMapper.findFileObject(root); + + if (rootFO == null) { + //already deleted + it.remove(); + continue; + } + + if (updateRoot(e.getValue().factory, root, rootFO, cancel)) { + factIt.remove(); + } else { + if (!cancel.get()) { + LOG.log(Level.WARNING, "indexer: {0} did not update all files even if the process was not cancelled", currentFactory.getIndexerName()); + } + } + } + + if (e.getValue().roots.isEmpty()) + it.remove(); + + progressForCurrentFactory.finish(); + progressForCurrentFactory = null; + currentFactory = null; + } + + if (todo.isEmpty()) RunAsNeededFactory.fileChanged(); + } + + public void cancel() { + cancel.set(true); + } + } + + private static final class TODO { + final DeferredCustomIndexerFactory factory; + final Collection<URL> roots = new HashSet<URL>(); + TODO(DeferredCustomIndexerFactory factory) { + this.factory = factory; + } + } + + private static final boolean DEFERRED_INDEXER_ENABLED = Boolean.getBoolean(DeferredCustomIndexerFactory.class.getName() + ".enable"); + + private static final FileObject EMPTY_FILE; + + static { + try { + EMPTY_FILE = FileUtil.createMemoryFileSystem().getRoot().createData("empty.java"); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + + @ServiceProvider(service=JavaSourceTaskFactory.class) + public static final class RunAsNeededFactory extends JavaSourceTaskFactory { + + public RunAsNeededFactory() { + super(Phase.PARSED, Priority.MIN); + } + + @Override + protected CancellableTask<CompilationInfo> createTask(FileObject file) { + return new UpdateWorker(); + } + + @Override + protected Collection<FileObject> getFileObjects() { + return DEFERRED_INDEXER_ENABLED && !todo.isEmpty() ? Collections.singletonList(EMPTY_FILE) : Collections.<FileObject>emptyList(); + } + + public static void fileChanged() { + for (JavaSourceTaskFactory f : Lookup.getDefault().lookupAll(JavaSourceTaskFactory.class)) { + if (f instanceof RunAsNeededFactory) { + ((RunAsNeededFactory) f).fileObjectsChanged(); + } + } + } + + public static void refresh() { + for (JavaSourceTaskFactory f : Lookup.getDefault().lookupAll(JavaSourceTaskFactory.class)) { + if (f instanceof RunAsNeededFactory) { + ((RunAsNeededFactory) f).reschedule(EMPTY_FILE); + } + } + } + } +}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/DuplicatesCustomIndexerImpl.java ---------------------------------------------------------------------- diff --git a/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/DuplicatesCustomIndexerImpl.java b/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/DuplicatesCustomIndexerImpl.java new file mode 100644 index 0000000..434ea46 --- /dev/null +++ b/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/DuplicatesCustomIndexerImpl.java @@ -0,0 +1,131 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009-2010 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-2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.jackpot30.impl.duplicates.indexing; + +import java.io.IOException; +import java.net.URL; +import java.util.Collection; +import org.netbeans.api.java.source.ClasspathInfo; +import org.netbeans.api.java.source.CompilationController; +import org.netbeans.api.java.source.JavaSource; +import org.netbeans.api.java.source.JavaSource.Phase; +import org.netbeans.api.java.source.Task; +import org.netbeans.modules.parsing.impl.indexing.IndexableImpl; +import org.netbeans.modules.parsing.impl.indexing.SPIAccessor; +import org.openide.filesystems.FileObject; +import org.openide.util.Exceptions; + +/** + * + * @author lahvac + */ +public class DuplicatesCustomIndexerImpl extends DeferredCustomIndexer { + + public DuplicatesCustomIndexerImpl(DeferredCustomIndexerFactory factory) { + super(factory); + } + + protected void doIndex(final DeferredContext ctx, Collection<? extends FileObject> modifiedAndAdded, Collection<? extends String> removed) throws IOException { + final DuplicatesIndex[] w = new DuplicatesIndex[1]; + + try { + w[0] = new DuplicatesIndex(ctx.getRoot(), ctx.getCacheRoot()); + + for (String r : removed) { + w[0].remove(r); + ctx.handledRemovedFile(r); + } + + final ClasspathInfo cpInfo = ClasspathInfo.create(ctx.getRootFileObject()); + + JavaSource.create(cpInfo, modifiedAndAdded).runUserActionTask(new Task<CompilationController>() { + public void run(final CompilationController cc) throws Exception { + if (cc.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0) + return ; + + w[0].record(cc, SPIAccessor.getInstance().create(new IndexableImpl() { + @Override public String getRelativePath() { + throw new UnsupportedOperationException("Not supported yet."); + } + @Override public URL getURL() { + return cc.getFileObject().toURL(); + } + @Override public String getMimeType() { + throw new UnsupportedOperationException("Not supported yet."); + } + @Override public boolean isTypeOf(String mimeType) { + throw new UnsupportedOperationException("Not supported yet."); + } + }), cc.getCompilationUnit()); + + ctx.handledModifiedFile(cc.getFileObject()); + } + }, true); + } finally { + if (w[0] != null) { + try { + w[0].close(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + } + } + + public static final class FactoryImpl extends DeferredCustomIndexerFactory { + + @Override + public DeferredCustomIndexer createIndexer() { + return new DuplicatesCustomIndexerImpl(this); + } + + @Override + public String getIndexerName() { + return DuplicatesIndex.NAME; + } + + @Override + public int getIndexVersion() { + return DuplicatesIndex.VERSION; + } + + } + +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/DuplicatesIndex.java ---------------------------------------------------------------------- diff --git a/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/DuplicatesIndex.java b/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/DuplicatesIndex.java new file mode 100644 index 0000000..7d94830 --- /dev/null +++ b/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/DuplicatesIndex.java @@ -0,0 +1,119 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009-2010 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-2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.jackpot30.impl.duplicates.indexing; + +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.util.Trees; +import java.io.IOException; +import java.net.URL; +import java.util.Map; +import java.util.Map.Entry; +import java.util.logging.Level; +import java.util.logging.Logger; +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.netbeans.api.java.source.CompilationInfo; +import org.netbeans.modules.jackpot30.common.api.IndexAccess; +import org.netbeans.modules.jackpot30.impl.duplicates.ComputeDuplicates; +import org.netbeans.modules.parsing.spi.indexing.Indexable; +import org.openide.filesystems.FileObject; +import org.openide.util.Lookup; + +/** + * + * @author lahvac + */ +public class DuplicatesIndex { + + private final org.apache.lucene.index.IndexWriter luceneWriter; + + public DuplicatesIndex(URL sourceRoot, FileObject cacheRoot) throws IOException { + luceneWriter = Lookup.getDefault().lookup(IndexAccess.class).getIndexWriter(sourceRoot, cacheRoot, NAME); + } + + public void record(final CompilationInfo info, Indexable idx, final CompilationUnitTree cut) throws IOException { + record(info.getTrees(), idx, cut); + } + + public void record(final Trees trees, Indexable idx, final CompilationUnitTree cut) throws IOException { + String relative = Lookup.getDefault().lookup(IndexAccess.class).getRelativePath(idx); + + try { + final Document doc = new Document(); + + doc.add(new Field("duplicatesPath", relative, Field.Store.YES, Field.Index.NOT_ANALYZED)); + + final Map<String, long[]> positions = ComputeDuplicates.encodeGeneralized(trees, cut); + + for (Entry<String, long[]> e : positions.entrySet()) { + doc.add(new Field("duplicatesGeneralized", e.getKey(), Store.YES, Index.NOT_ANALYZED)); + + StringBuilder positionsSpec = new StringBuilder(); + + for (int i = 0; i < e.getValue().length; i += 2) { + if (positionsSpec.length() > 0) positionsSpec.append(';'); + positionsSpec.append(e.getValue()[i]).append(':').append(e.getValue()[i + 1] - e.getValue()[i]); + } + + doc.add(new Field("duplicatesPositions", positionsSpec.toString(), Store.YES, Index.NO)); + } + + luceneWriter.addDocument(doc); + } catch (ThreadDeath td) { + throw td; + } catch (Throwable t) { + Logger.getLogger(DuplicatesIndex.class.getName()).log(Level.WARNING, null, t); + } + } + + public void remove(String relativePath) throws IOException { + luceneWriter.deleteDocuments(new Term("duplicatesPath", relativePath)); + } + + public void close() throws IOException { + Lookup.getDefault().lookup(IndexAccess.class).finish(); + } + + public static final String NAME = "duplicates"; //NOI18N + public static final int VERSION = 1; //NOI18N +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndex.java ---------------------------------------------------------------------- diff --git a/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndex.java b/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndex.java new file mode 100644 index 0000000..197154e --- /dev/null +++ b/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndex.java @@ -0,0 +1,360 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 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 2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.jackpot30.impl.duplicates.indexing; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import java.util.logging.Logger; +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.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.Collector; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Searcher; +import org.apache.lucene.search.TermQuery; +import org.codeviation.pojson.Pojson; +import org.netbeans.modules.jackpot30.common.api.LuceneHelpers.BitSetCollector; +import org.netbeans.modules.jackpot30.impl.duplicates.ComputeDuplicates.DuplicateDescription; +import org.netbeans.modules.jackpot30.impl.duplicates.ComputeDuplicates.Span; +import org.netbeans.modules.jackpot30.remoting.api.LocalCache; +import org.netbeans.modules.jackpot30.remoting.api.LocalCache.Task; +import org.netbeans.modules.jackpot30.remoting.api.RemoteIndex; +import org.netbeans.modules.jackpot30.remoting.api.WebUtilities; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.URLMapper; +import org.openide.util.Exceptions; + +/** + * + * @author lahvac + */ +@SuppressWarnings("ClassWithMultipleLoggers") +public class RemoteDuplicatesIndex { + + private static final Logger TIMER = Logger.getLogger("TIMER"); + + public static List<DuplicateDescription> findDuplicates(Map<String, long[]> hashes, FileObject currentFile, AtomicBoolean cancel) throws IOException, URISyntaxException { + return translate(hashes, findHashOccurrences(hashes.keySet(), currentFile, cancel), currentFile); + } + + private static Map<String, Map<RemoteIndex, Collection<String>>> findHashOccurrences(Collection<? extends String> hashes, FileObject currentFile, AtomicBoolean cancel) throws IOException, URISyntaxException { + Map<URI, Collection<RemoteIndex>> indices = new LinkedHashMap<URI, Collection<RemoteIndex>>(); + + for (RemoteIndex ri : RemoteIndex.loadIndices()) { + try { + URI uri = ri.remote.toURI(); + Collection<RemoteIndex> list = indices.get(uri); + + if (list == null) { + indices.put(uri, list = new ArrayList<RemoteIndex>()); + } + + list.add(ri); + } catch (URISyntaxException ex) { + Exceptions.printStackTrace(ex); + } + } + + Map<String, Map<RemoteIndex, Collection<String>>> result = new LinkedHashMap<String, Map<RemoteIndex, Collection<String>>>(); + long localTime = 0; + long remoteTime = 0; + + for (RemoteIndex ri : RemoteIndex.loadIndices()) { + if (cancel.get()) return Collections.emptyMap(); + + Set<String> toProcess = new LinkedHashSet<String>(hashes); + Map<String, Map<String, Collection<? extends String>>> indexResult = new LinkedHashMap<String, Map<String, Collection<? extends String>>>(); + + long locS = System.currentTimeMillis(); + indexResult.putAll(findHashOccurrencesInLocalCache(ri, toProcess, cancel)); + localTime += System.currentTimeMillis() - locS; + + toProcess.removeAll(indexResult.keySet()); + + if (!toProcess.isEmpty()) { + long remS = System.currentTimeMillis(); + Map<String, Map<String, Collection<? extends String>>> remoteResults = findHashOccurrencesRemote(ri.remote.toURI(), toProcess, cancel); + remoteTime += System.currentTimeMillis() - remS; + + Map<String, Map<String, Collection<? extends String>>> toSave = new LinkedHashMap<String, Map<String, Collection<? extends String>>>(remoteResults); + + for (String hash : toProcess) { + if (!toSave.containsKey(hash)) { + toSave.put(hash, Collections.<String, Collection<? extends String>>emptyMap()); + } + } + + if (cancel.get()) return Collections.emptyMap(); + + saveToLocalCache(ri, toSave); + + indexResult.putAll(remoteResults); + } + + for (Entry<String, Map<String, Collection<? extends String>>> e : indexResult.entrySet()) { + Map<RemoteIndex, Collection<String>> hashResult = result.get(e.getKey()); + + if (hashResult == null) { + result.put(e.getKey(), hashResult = new LinkedHashMap<RemoteIndex, Collection<String>>()); + } + + for (Entry<String, Collection<? extends String>> insideHash : e.getValue().entrySet()) { + if (cancel.get()) return Collections.emptyMap(); + + Collection<String> dupes = hashResult.get(ri); + + if (dupes == null) { + hashResult.put(ri, dupes = new LinkedHashSet<String>()); + } + + dupes.addAll(insideHash.getValue()); + } + } + } + + TIMER.log(Level.FINE, "local hash duplicates", new Object[] {currentFile, localTime}); + TIMER.log(Level.FINE, "remote hash duplicates", new Object[] {currentFile, remoteTime}); + return result; + } + + private static Map<String, Map<String, Collection<? extends String>>> findHashOccurrencesRemote(URI remoteIndex, Iterable<? extends String> hashes, AtomicBoolean cancel) { + try { + String indexURL = remoteIndex.toASCIIString(); + URI u = new URI(indexURL + "/duplicates/findDuplicates?hashes=" + WebUtilities.escapeForQuery(Pojson.save(hashes))); + String hashesMap = WebUtilities.requestStringResponse(u, cancel); + + if (hashesMap == null || cancel.get()) { + //some kind of error while getting the duplicates (cannot access remote server)? + //ignore: + return Collections.emptyMap(); + } + return Pojson.load(LinkedHashMap.class, hashesMap); + } catch (URISyntaxException ex) { + //XXX: better handling? + Exceptions.printStackTrace(ex); + return Collections.emptyMap(); + } + } + + private static Map<String, Map<String, Collection<? extends String>>> findHashOccurrencesInLocalCache(RemoteIndex ri, final Iterable<? extends String> hashes, AtomicBoolean cancel) throws IOException, URISyntaxException { + return LocalCache.runOverLocalCache(ri, new Task<IndexReader, Map<String, Map<String, Collection<? extends String>>>>() { + @Override public Map<String, Map<String, Collection<? extends String>>> run(IndexReader reader, AtomicBoolean cancel) throws IOException { + Map<String, Map<String, Collection<String>>> result = new LinkedHashMap<String, Map<String, Collection<String>>>(); + + for (Entry<String, Collection<? extends String>> e : containsHash(reader, hashes, cancel).entrySet()) { + if (cancel.get()) return Collections.emptyMap(); + + Map<String, Collection<String>> forHash = result.get(e.getKey()); + + if (forHash == null) { + result.put(e.getKey(), forHash = new LinkedHashMap<String, Collection<String>>()); + } + + for (String path : e.getValue()) { + String segment = path.substring(0, path.indexOf('/')); + + path = path.substring(path.indexOf('/') + 1); + + Collection<String> list = forHash.get(segment); + + if (list == null) { + forHash.put(segment, list = new LinkedList<String>()); + } + + list.add(path); + } + } + + return (Map)result; //XXX + } + }, Collections.<String, Map<String, Collection<? extends String>>>emptyMap(), cancel); + } + + private static synchronized void saveToLocalCache(RemoteIndex ri, final Map<String, Map<String, Collection<? extends String>>> what) throws IOException, URISyntaxException { + LocalCache.saveToLocalCache(ri, new Task<IndexWriter, Void>() { + @Override public Void run(IndexWriter w, AtomicBoolean cancel) throws IOException { + for (Entry<String, Map<String, Collection<? extends String>>> e : what.entrySet()) { + Document doc = new Document(); + + doc.add(new Field("hash", e.getKey(), Store.YES, Index.NOT_ANALYZED)); + + for (Entry<String, Collection<? extends String>> pe : e.getValue().entrySet()) { + for (String path : pe.getValue()) { + doc.add(new Field("path", pe.getKey() + "/" + path, Store.YES, Index.NO)); + } + } + + w.addDocument(doc); + } + + return null; + } + }); + } + + private static List<DuplicateDescription> translate(Map<String, long[]> hashes, Map<String, Map<RemoteIndex, Collection<String>>> occ, FileObject currentFile) { + Map<String, Map<RemoteIndex, Collection<String>>> sorted = hashMap(); + Map<long[], DuplicateDescription> result = new LinkedHashMap<long[], DuplicateDescription>(); + List<long[]> seen = new LinkedList<long[]>(); + + sorted.putAll(occ); + + OUTER: for (Entry<String, Map<RemoteIndex, Collection<String>>> e : occ.entrySet()) { + long[] currentSpan = hashes.get(e.getKey()); + + for (Iterator<Entry<long[], DuplicateDescription>> it = result.entrySet().iterator(); it.hasNext();) { + Entry<long[], DuplicateDescription> span = it.next(); + + if (span.getKey()[0] <= currentSpan[0] && span.getKey()[1] >= currentSpan[1]) { + continue OUTER; + } + + if (currentSpan[0] <= span.getKey()[0] && currentSpan[1] >= span.getKey()[1]) { + it.remove(); + } + } + + if (currentSpan[0] == (-1) || currentSpan[1] == (-1)) continue; + + seen.add(currentSpan); + + String longest = e.getKey(); + List<Span> foundDuplicates = new LinkedList<Span>(); + + for (Entry<RemoteIndex, Collection<String>> root2Occurrences : e.getValue().entrySet()) { + FileObject localRoot = URLMapper.findFileObject(root2Occurrences.getKey().getLocalFolder()); + + for (String cand : root2Occurrences.getValue()) { + FileObject o = localRoot.getFileObject(cand); + + if (o == null) continue; //XXX log! + if (areEquivalent(currentFile, o)) continue; + + foundDuplicates.add(new Span(o, -1, -1)); + } + } + + if (foundDuplicates.isEmpty()) continue; + + DuplicateDescription current = DuplicateDescription.of(foundDuplicates, getValue(longest), longest); + + result.put(currentSpan, current); + } + + return new LinkedList<DuplicateDescription>(result.values()); + } + + private static boolean areEquivalent(FileObject f1, FileObject f2) { + return f1.equals(f2); + } + + private static long getValue(String encoded) { + return Long.parseLong(encoded.substring(encoded.lastIndexOf(":") + 1)); + } + + private static <T> TreeMap<String, T> hashMap() { + return new TreeMap<String, T>(new Comparator<String>() { + public int compare(String arg0, String arg1) { + return (int) Math.signum(getValue(arg1) - getValue(arg0)); + } + }); + } + + private static Map<String, Collection<? extends String>> containsHash(IndexReader reader, Iterable<? extends String> hashes, AtomicBoolean cancel) throws IOException { + Map<String, Collection<? extends String>> result = new LinkedHashMap<String, Collection<? extends String>>(); + + for (String hash : hashes) { + if (cancel.get()) return Collections.emptyMap(); + + Collection<String> found = new LinkedList<String>(); + Query query = new TermQuery(new Term("hash", hash)); + Searcher s = new IndexSearcher(reader); + BitSet matchingDocuments = new BitSet(reader.maxDoc()); + Collector c = new BitSetCollector(matchingDocuments); + + s.search(query, c); + + boolean wasFound = false; + + for (int docNum = matchingDocuments.nextSetBit(0); docNum >= 0; docNum = matchingDocuments.nextSetBit(docNum + 1)) { + if (cancel.get()) return Collections.emptyMap(); + + final Document doc = reader.document(docNum); + + found.addAll(Arrays.asList(doc.getValues("path"))); + wasFound = true; + } + + if (wasFound) { + result.put(hash, found); + } + } + + return result; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/duplicates/ide/impl/test/unit/src/org/netbeans/modules/jackpot30/impl/duplicates/ComputeDuplicatesTest.java ---------------------------------------------------------------------- diff --git a/duplicates/ide/impl/test/unit/src/org/netbeans/modules/jackpot30/impl/duplicates/ComputeDuplicatesTest.java b/duplicates/ide/impl/test/unit/src/org/netbeans/modules/jackpot30/impl/duplicates/ComputeDuplicatesTest.java new file mode 100644 index 0000000..1ae259b --- /dev/null +++ b/duplicates/ide/impl/test/unit/src/org/netbeans/modules/jackpot30/impl/duplicates/ComputeDuplicatesTest.java @@ -0,0 +1,134 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009-2010 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-2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.jackpot30.impl.duplicates; + +import org.netbeans.api.progress.ProgressHandle; +import org.openide.filesystems.FileObject; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import org.netbeans.api.java.source.TestUtilities; +import org.netbeans.api.progress.ProgressHandleFactory; +import org.netbeans.modules.jackpot30.impl.duplicates.ComputeDuplicates.DuplicateDescription; +import org.netbeans.modules.jackpot30.impl.duplicates.ComputeDuplicates.Span; +import org.netbeans.modules.jackpot30.common.test.IndexTestBase; +import org.openide.filesystems.FileUtil; +import org.openide.util.NbCollections; +import static org.junit.Assert.*; +import org.netbeans.api.editor.mimelookup.MimePath; +import org.netbeans.modules.jackpot30.impl.duplicates.indexing.DuplicatesCustomIndexerImpl; +import org.netbeans.spi.editor.mimelookup.MimeDataProvider; +import org.openide.util.Lookup; +import org.openide.util.lookup.Lookups; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author lahvac + */ +public class ComputeDuplicatesTest extends IndexTestBase { + + public ComputeDuplicatesTest(String name) { + super(name); + } + + public void testDuplicateDuplicates() throws Exception { + writeFilesAndWaitForScan(src, + new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"), + new File("test/Test2.java", "package test; public class Test2 { private int a; private void test() { java.io.File f = null; f.isDirectory(); } }"), + new File("test/Test3.java", "package test; public class Test3 { private void test() { for (int i = 0; i < 10; i++) { System.err.println(3 * i); System.err.println(4 * i); } }")); + + verifyDuplicates("test/Test1.java", + "private void test() { java.io.File f = null; f.isDirectory(); }", + "test/Test2.java", + "private void test() { java.io.File f = null; f.isDirectory(); }"); + } + + public void testCrossIndex() throws Exception { + writeFilesAndWaitForScan(src, + new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }")); + + writeFilesAndWaitForScan(src2, + new File("test/Test2.java", "package test; public class Test2 { private int a; private void test() { java.io.File f = null; f.isDirectory(); } }")); + + verifyDuplicates("test/Test1.java", + "private void test() { java.io.File f = null; f.isDirectory(); }", + "test/Test2.java", + "private void test() { java.io.File f = null; f.isDirectory(); }"); + } + + private void verifyDuplicates(String... fileAndDuplicateCode) throws Exception { + Map<String, String> duplicatesGolden = new HashMap<String, String>(); + + for (int cntr = 0; cntr < fileAndDuplicateCode.length; cntr += 2) { + duplicatesGolden.put(fileAndDuplicateCode[cntr], fileAndDuplicateCode[cntr + 1]); + } + + Map<String, String> duplicatesReal = new HashMap<String, String>(); + ProgressHandle handle = ProgressHandleFactory.createHandle("test"); + + handle.start(); + + for (DuplicateDescription dd : NbCollections.iterable(new ComputeDuplicates().computeDuplicatesForAllOpenedProjects(handle, new AtomicBoolean()))) { + for (Span s : dd.dupes) { + duplicatesReal.put(relativePath(s.file), TestUtilities.copyFileToString(FileUtil.toFile(s.file)).substring(s.startOff, s.endOff)); + } + } + + assertEquals(duplicatesGolden, duplicatesReal); + } + + private String relativePath(FileObject file) { + return FileUtil.isParentOf(src, file) ? FileUtil.getRelativePath(src, file) : FileUtil.getRelativePath(src2, file); + } + + @ServiceProvider(service=MimeDataProvider.class) + public static final class MimeDataProviderImpl implements MimeDataProvider { + + private final Lookup L = Lookups.fixed(new DuplicatesCustomIndexerImpl.FactoryImpl()); + + @Override + public Lookup getLookup(MimePath mimePath) { + if ("text/x-java".equals(mimePath.getPath())) return L; + return Lookup.EMPTY; + } + + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/duplicates/ide/impl/test/unit/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndexTest.java ---------------------------------------------------------------------- diff --git a/duplicates/ide/impl/test/unit/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndexTest.java b/duplicates/ide/impl/test/unit/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndexTest.java new file mode 100644 index 0000000..f51503a --- /dev/null +++ b/duplicates/ide/impl/test/unit/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndexTest.java @@ -0,0 +1,136 @@ +/* + * 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.impl.duplicates.indexing; + +import java.io.File; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import org.netbeans.api.java.source.TestUtilities; +import static org.junit.Assert.*; +import org.netbeans.api.java.source.SourceUtilsTestUtil; +import org.netbeans.core.startup.Main; +import org.netbeans.junit.NbTestCase; +import org.netbeans.modules.jackpot30.impl.TestUtils; +import org.netbeans.modules.jackpot30.impl.duplicates.ComputeDuplicates.DuplicateDescription; +import org.netbeans.modules.jackpot30.impl.duplicates.ComputeDuplicates.Span; +import org.netbeans.modules.jackpot30.remoting.api.RemoteIndex; +import org.netbeans.modules.parsing.impl.indexing.CacheFolder; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; + +/** + * + * @author lahvac + */ +public class RemoteDuplicatesIndexTest extends NbTestCase { + + public RemoteDuplicatesIndexTest(String name) { + super(name); + } + + public void setUp() throws Exception { + SourceUtilsTestUtil.prepareTest(new String[0], new Object[0]); + Main.initializeURLFactory(); + TestUtils.clearRemoteContent(); + super.setUp(); + } + + public void testFindHashOccurrences() throws Exception { + clearWorkDir(); + File cacheDir = new File(getWorkDir(), "cache"); + File dataDir = new File(getWorkDir(), "data"); + + CacheFolder.setCacheFolder(FileUtil.createFolder(cacheDir)); + + FileObject data1 = FileUtil.createFolder(new File(dataDir, "data1")); + FileObject data2 = FileUtil.createFolder(new File(dataDir, "data2")); + FileObject source = FileUtil.createData(new File(dataDir, "src/Test.java")); + + TestUtilities.copyStringToFile(data1.createData("T1.java"), "0123456789"); + TestUtilities.copyStringToFile(data1.createData("T2.java"), "0123456789"); + TestUtilities.copyStringToFile(data2.createData("T3.java"), "0123456789"); + TestUtilities.copyStringToFile(data2.createData("T4.java"), "0123456789"); + + TestUtils.addRemoteContent(new URL("test://test/index/duplicates/findDuplicates?hashes=[%0A%20%20%20%20%2200%22,%0A%20%20%20%20%2201%22,%0A%20%20%20%20%2202%22%0A]"), "{ \"00\": { \"foo1\": [ \"T1.java\", \"T2.java\" ], \"foo2\": [ \"T3.java\", \"T4.java\" ] } }"); + TestUtils.addRemoteContent(new URL("test://test/index/info?path=foo1"), "{ }"); + TestUtils.addRemoteContent(new URL("test://test/index/info?path=foo2"), "{ }"); + RemoteIndex.saveIndices(Arrays.asList(RemoteIndex.create(FileUtil.toFile(data1).toURI().toURL(), new URL("test://test/index"), "foo1"), + RemoteIndex.create(FileUtil.toFile(data2).toURI().toURL(), new URL("test://test/index"), "foo2"))); + + TestUtilities.copyStringToFile(source, "01234567890123456789"); + + Map<String, long[]> hashes = new HashMap<String, long[]>(); + + hashes.put("00", new long[] {1, 2, 5, 6}); + hashes.put("01", new long[] {8, 9}); + hashes.put("02", new long[] {3, 4}); + + List<DuplicateDescription> duplicates = RemoteDuplicatesIndex.findDuplicates(hashes, source, new AtomicBoolean()); + List<String> duplicatesReal = new ArrayList<String>(); + + for (DuplicateDescription dd : duplicates) { + for (Span s : dd.dupes) { + duplicatesReal.add(s.file.getName()); + } + } + + assertEquals(Arrays.asList("T1", "T2", "T3", "T4"), duplicatesReal); + + //check local cache: + duplicates = RemoteDuplicatesIndex.findDuplicates(hashes, source, new AtomicBoolean()); + duplicatesReal = new ArrayList<String>(); + + for (DuplicateDescription dd : duplicates) { + for (Span s : dd.dupes) { + duplicatesReal.add(s.file.getName()); + } + } + + assertEquals(Arrays.asList("T1", "T2", "T3", "T4"), duplicatesReal); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/duplicates/ide/nbproject/build-impl.xml ---------------------------------------------------------------------- diff --git a/duplicates/ide/nbproject/build-impl.xml b/duplicates/ide/nbproject/build-impl.xml new file mode 100644 index 0000000..822d89e --- /dev/null +++ b/duplicates/ide/nbproject/build-impl.xml @@ -0,0 +1,93 @@ +<?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. +--> +<!-- +*** GENERATED FROM project.xml - DO NOT EDIT *** +*** EDIT ../build.xml INSTEAD *** +--> +<project name="duplicates-ide-impl" basedir=".." xmlns:sproject="http://www.netbeans.org/ns/nb-module-suite-project/1"> + <fail message="Please build using Ant 1.7.1 or higher."> + <condition> + <not> + <antversion atleast="1.7.1"/> + </not> + </condition> + </fail> + <property file="nbproject/private/platform-private.properties"/> + <property file="nbproject/platform.properties"/> + <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-suite-project/1"> + <attribute name="name"/> + <attribute name="value"/> + <sequential> + <property name="@{name}" value="${@{value}}"/> + </sequential> + </macrodef> + <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-suite-project/1"> + <attribute name="property"/> + <attribute name="value"/> + <sequential> + <property name="@{property}" value="@{value}"/> + </sequential> + </macrodef> + <property file="${user.properties.file}"/> + <sproject:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir"/> + <sproject:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/> + <sproject:evalprops property="cluster.path.evaluated" value="${cluster.path}"/> + <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness)."> + <condition> + <not> + <contains string="${cluster.path.evaluated}" substring="platform"/> + </not> + </condition> + </fail> + <ant antfile="nbproject/platform.xml"/> + <fail message="Cannot find NetBeans build harness. ${line.separator}Check that nbplatform.${nbplatform.active}.netbeans.dest.dir and nbplatform.${nbplatform.active}.harness.dir are defined. ${line.separator}On a developer machine these are normally defined in ${user.properties.file}=${netbeans.user}/build.properties ${line.separator}but for automated builds you should pass these properties to Ant explicitly. ${line.separator}You may instead download the harness and platform: -Dbootstrap.url=.../tasks.jar -Dautoupdate.catalog.url=.../updates.xml"> + <condition> + <not> + <available file="${harness.dir}/suite.xml"/> + </not> + </condition> + </fail> + <import file="${harness.dir}/suite.xml"/> +</project> http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/duplicates/ide/nbproject/genfiles.properties ---------------------------------------------------------------------- diff --git a/duplicates/ide/nbproject/genfiles.properties b/duplicates/ide/nbproject/genfiles.properties new file mode 100644 index 0000000..5207440 --- /dev/null +++ b/duplicates/ide/nbproject/genfiles.properties @@ -0,0 +1,52 @@ +# 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. +build.xml.data.CRC32=891734f5 +build.xml.script.CRC32=82b74f72 [email protected] +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=44b3f6ba +nbproject/build-impl.xml.script.CRC32=d800a24f +nbproject/[email protected] +nbproject/platform.xml.data.CRC32=44b3f6ba +nbproject/platform.xml.script.CRC32=6dcbd131 +nbproject/[email protected] http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/duplicates/ide/nbproject/platform.properties ---------------------------------------------------------------------- diff --git a/duplicates/ide/nbproject/platform.properties b/duplicates/ide/nbproject/platform.properties new file mode 100644 index 0000000..f8d652e --- /dev/null +++ b/duplicates/ide/nbproject/platform.properties @@ -0,0 +1,61 @@ +# 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. +cluster.path=\ + ${nbplatform.active.dir}/apisupport:\ + ${nbplatform.active.dir}/cnd:\ + ${nbplatform.active.dir}/dlight:\ + ${nbplatform.active.dir}/enterprise:\ + ${nbplatform.active.dir}/harness:\ + ${nbplatform.active.dir}/ide:\ + ${nbplatform.active.dir}/extide:\ + ${nbplatform.active.dir}/java:\ + ${nbplatform.active.dir}/nb:\ + ${nbplatform.active.dir}/platform:\ + ${nbplatform.active.dir}/profiler:\ + ${nbplatform.active.dir}/websvccommon:\ + ../../remoting/common/build/cluster:\ + ../../remoting/ide/build/cluster +extcluster.../../remoting/common/build/cluster.javadoc= +extcluster.../../remoting/common/build/cluster.sources=../../remoting/common +extcluster.../../remoting/ide/build/cluster.javadoc= +extcluster.../../remoting/ide/build/cluster.sources=../../remoting/ide +nbplatform.active=default http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/duplicates/ide/nbproject/platform.xml ---------------------------------------------------------------------- diff --git a/duplicates/ide/nbproject/platform.xml b/duplicates/ide/nbproject/platform.xml new file mode 100644 index 0000000..1917e28 --- /dev/null +++ b/duplicates/ide/nbproject/platform.xml @@ -0,0 +1,77 @@ +<?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 name="platform" default="download" basedir=".."> + <condition property="download.required"> + <and> + <not> + <available file="${harness.dir}/suite.xml"/> + </not> + <isset property="bootstrap.url"/> + <isset property="autoupdate.catalog.url"/> + </and> + </condition> + <target name="download" if="download.required"> + <mkdir dir="${harness.dir}"/> + <pathconvert pathsep="|" property="download.clusters"> + <mapper type="flatten"/> + <path path="${cluster.path}"/> + </pathconvert> + <property name="disabled.modules" value=""/> + <pathconvert property="module.includes" pathsep=""> + <mapper type="glob" from="${basedir}${file.separator}*" to="(?!^\Q*\E$)"/> + <path> + <filelist files="${disabled.modules}" dir="."/> + </path> + </pathconvert> + <echo message="Downloading clusters ${download.clusters}"/> + <property name="tasks.jar" location="${java.io.tmpdir}/tasks.jar"/> + <get src="${bootstrap.url}" dest="${tasks.jar}" usetimestamp="true" verbose="true"/> + <taskdef name="autoupdate" classname="org.netbeans.nbbuild.AutoUpdate" classpath="${tasks.jar}"/> + <autoupdate installdir="${nbplatform.active.dir}" updatecenter="${autoupdate.catalog.url}"> + <modules includes="${module.includes}.*" clusters="${download.clusters}"/> + <modules includes="org[.]netbeans[.]modules[.]apisupport[.]harness" clusters="harness"/> + </autoupdate> + </target> +</project> http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/duplicates/ide/nbproject/project.properties ---------------------------------------------------------------------- diff --git a/duplicates/ide/nbproject/project.properties b/duplicates/ide/nbproject/project.properties new file mode 100644 index 0000000..8877ce6 --- /dev/null +++ b/duplicates/ide/nbproject/project.properties @@ -0,0 +1,44 @@ +# 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. +modules=\ + ${project.org.netbeans.modules.jackpot30.duplicates.impl} +project.org.netbeans.modules.jackpot30.duplicates.impl=impl http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/duplicates/ide/nbproject/project.xml ---------------------------------------------------------------------- diff --git a/duplicates/ide/nbproject/project.xml b/duplicates/ide/nbproject/project.xml new file mode 100644 index 0000000..9052409 --- /dev/null +++ b/duplicates/ide/nbproject/project.xml @@ -0,0 +1,52 @@ +<?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.apisupport.project.suite</type> + <configuration> + <data xmlns="http://www.netbeans.org/ns/nb-module-suite-project/1"> + <name>duplicates-ide</name> + </data> + </configuration> +</project> http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/duplicates/server/indexer/build.xml ---------------------------------------------------------------------- diff --git a/duplicates/server/indexer/build.xml b/duplicates/server/indexer/build.xml new file mode 100644 index 0000000..bb9edf2 --- /dev/null +++ b/duplicates/server/indexer/build.xml @@ -0,0 +1,51 @@ +<?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 harness/README in the NetBeans platform --> +<!-- for some information on what you could do (e.g. targets to override). --> +<!-- If you delete this file and reopen the project it will be recreated. --> +<project name="duplicates-indexer" basedir="."> + <description>Builds the module suite indexer.</description> + <import file="nbproject/build-impl.xml"/> +</project>
