http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/EnhancedScopes.java ---------------------------------------------------------------------- diff --git a/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/EnhancedScopes.java b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/EnhancedScopes.java new file mode 100644 index 0000000..075aea9 --- /dev/null +++ b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/EnhancedScopes.java @@ -0,0 +1,500 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009-2011 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2009-2011 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.jackpot30.indexing.batch; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.codeviation.pojson.Pojson; +import org.netbeans.api.java.classpath.ClassPath; +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.Task; +import org.netbeans.modules.jackpot30.indexing.index.IndexQuery; +import org.netbeans.modules.jackpot30.indexing.index.Indexer; +import org.netbeans.modules.jackpot30.remoting.api.RemoteIndex; +import org.netbeans.modules.jackpot30.remoting.api.WebUtilities; +import static org.netbeans.modules.jackpot30.remoting.api.WebUtilities.escapeForQuery; +import org.netbeans.modules.java.hints.providers.spi.HintDescription; +import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription; +import org.netbeans.modules.java.hints.spiimpl.MessageImpl; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Folder; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.IndexEnquirer; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.LocalIndexEnquirer; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.MapIndices; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Resource; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Scope; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.VerifiedSpansCallBack; +import org.netbeans.modules.java.hints.spiimpl.batch.ProgressHandleWrapper; +import org.netbeans.modules.java.hints.spiimpl.batch.Scopes; +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings; +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern; +import org.netbeans.modules.java.preprocessorbridge.spi.JavaIndexerPlugin; +import org.netbeans.modules.parsing.impl.indexing.FileObjectIndexable; +import org.netbeans.modules.parsing.impl.indexing.IndexableImpl; +import org.netbeans.modules.parsing.impl.indexing.SPIAccessor; +import org.netbeans.spi.editor.hints.ErrorDescription; +import org.netbeans.spi.editor.hints.ErrorDescriptionFactory; +import org.netbeans.spi.editor.hints.Severity; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.filesystems.URLMapper; +import org.openide.util.Exceptions; + +/** + * + * @author lahvac + */ +public class EnhancedScopes { + + private static final Logger LOG = Logger.getLogger(EnhancedScopes.class.getName()); + + public static Scope allRemote() { + return new RemoteIndexScope(); + } + + public static final class GivenFolderScope extends Scope { + + public final String folder; + public final String indexURL; + public final String subIndex; + public final boolean update; + + public GivenFolderScope(String folder, String indexURL, String subIndex, boolean update) { + this.folder = folder; + this.indexURL = indexURL; + this.subIndex = subIndex; + this.update = update; + } + + @Override + public String getDisplayName() { + return folder; + } + + @Override + public Collection<? extends Folder> getTodo() { + return Collections.singletonList(new Folder(FileUtil.toFileObject(new File(folder)))); + } + + @Override + public MapIndices getIndexMapper(Iterable<? extends HintDescription> patterns) { + MapIndices mapper; + + if (indexURL != null) { + if (subIndex == null) { + mapper = new MapIndices() { + public IndexEnquirer findIndex(FileObject root, ProgressHandleWrapper progress, boolean recursive) { + try { + return new SimpleIndexIndexEnquirer(root, createOrUpdateIndex(root, new File(indexURL), update, progress, recursive)); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + return null; + } + } + }; + } else { + mapper = new MapIndices() { + public IndexEnquirer findIndex(FileObject root, ProgressHandleWrapper progress, boolean recursive) { + progress.startNextPart(1); + try { + return new SimpleIndexIndexEnquirer(root, IndexQuery.remote(RemoteIndex.create(root.toURL(), new URL(indexURL), subIndex))); + } catch (MalformedURLException ex) { + Exceptions.printStackTrace(ex); + return null; + } + } + }; + } + } else { + mapper = Scopes.getDefaultIndicesMapper(); + } + + return mapper; + } + + } + + private static final class RemoteIndexScope extends Scope { + @Override + public String getDisplayName() { + return "All Remote Indices"; + } + + @Override + public Collection<? extends Folder> getTodo() { + Collection<Folder> todo = new HashSet<Folder>(); + + for (RemoteIndex remoteIndex : RemoteIndex.loadIndices()) { + FileObject localFolder = URLMapper.findFileObject(remoteIndex.getLocalFolder()); + + if (localFolder == null) continue; + todo.add(new Folder(localFolder)); + } + + return todo; + } + + @Override + public MapIndices getIndexMapper(final Iterable<? extends HintDescription> patterns) { + return new MapIndices() { + public IndexEnquirer findIndex(FileObject root, ProgressHandleWrapper progress, boolean recursive) { + for (RemoteIndex remoteIndex : RemoteIndex.loadIndices()) { + FileObject localFolder = URLMapper.findFileObject(remoteIndex.getLocalFolder()); + + if (localFolder == null) continue; + if (localFolder == root) { + return enquirerForRemoteIndex(root, remoteIndex, patterns); + } + } + throw new IllegalStateException(); + } + }; + } + } + + private static IndexQuery createOrUpdateIndex(final FileObject src, File indexRoot, boolean update, ProgressHandleWrapper progress, boolean recursive) throws IOException { + final JavaIndexerPlugin index = new Indexer.FactoryImpl().create(src.toURL(), FileUtil.toFileObject(indexRoot)); + + File timeStampsFile = new File(indexRoot, "timestamps.properties"); + Properties timeStamps = new Properties(); + + if (timeStampsFile.exists()) { + if (!update) { + progress.startNextPart(1); + return IndexQuery.open(src.toURL()); + } + + InputStream in = null; + + try { + in = new BufferedInputStream(new FileInputStream(timeStampsFile)); + timeStamps.load(in); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } finally { + try { + if (in != null) + in.close(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + } + + Collection<FileObject> collected = new LinkedList<FileObject>(); + Set<String> removed = new HashSet<String>(timeStamps.stringPropertyNames()); + + org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities.recursive(src, src, collected, progress, 0, timeStamps, removed, recursive); + + for (String r : removed) { + index.delete(SPIAccessor.getInstance().create(new FakeIndexableImpl(r))); + } + + JavaSource js = JavaSource.create(ClasspathInfo.create(ClassPath.EMPTY, ClassPath.EMPTY, ClassPath.EMPTY), collected); + + js.runUserActionTask(new Task<CompilationController>() { + @Override public void run(CompilationController parameter) throws Exception { + if (parameter.toPhase(JavaSource.Phase.PARSED).compareTo(JavaSource.Phase.PARSED) < 0) return; + + index.process(parameter.getCompilationUnit(), SPIAccessor.getInstance().create(new FileObjectIndexable(src, parameter.getFileObject())), null); + } + }, true); + + OutputStream out = null; + + try { + out = new BufferedOutputStream(new FileOutputStream(timeStampsFile)); + timeStamps.store(out, null); + } finally { + try { + if (out != null) { + out.close(); + } + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + + return IndexQuery.open(src.toURL()); + } + + private static final class FakeIndexableImpl implements IndexableImpl { + + private final String path; + + public FakeIndexableImpl(String path) { + this.path = path; + } + + @Override public String getRelativePath() { + return path; + } + + @Override public URL getURL() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override public String getMimeType() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override public boolean isTypeOf(String mimeType) { + throw new UnsupportedOperationException("Not supported yet."); + } + + } + + private static boolean isAttributedIndexWithSpans(RemoteIndex remoteIndex) { + try { + URI capabilitiesURI = new URI(remoteIndex.remote.toExternalForm() + "/capabilities"); + String capabilitiesString = WebUtilities.requestStringResponse(capabilitiesURI); + + if (capabilitiesURI == null) return false; + + @SuppressWarnings("unchecked") + Map<String, Object> capabilities = Pojson.load(HashMap.class, capabilitiesString); + + return capabilities.get("attributed") == Boolean.TRUE; //TODO: should also check "methods contains findWithSpans" + } catch (URISyntaxException ex) { + LOG.log(Level.FINE, null, ex); + return false; + } + } + + private static IndexEnquirer enquirerForRemoteIndex(FileObject src, RemoteIndex remoteIndex, Iterable<? extends HintDescription> hints) { + if (hints == null) return null; + + boolean fullySupported = isAttributedIndexWithSpans(remoteIndex); + StringBuilder textualRepresentation = new StringBuilder(); + + for (HintDescription hd : hints) { + if (!(hd.getTrigger() instanceof PatternDescription)) { + fullySupported = false; + break; + } + + if (((PatternDescription) hd.getTrigger()).getImports().iterator().hasNext()) { + fullySupported = false; + } + + if (!fullySupported) break; + + String hintText = hd.getHintText(); + + if (hintText != null) { + textualRepresentation.append(hintText); + } else { + textualRepresentation.append(defaultHintText(hd)); + fullySupported = false; + } + + textualRepresentation.append("\n"); + } + + if (fullySupported) { + return new RemoteFullyAttributedIndexEnquirer(src, remoteIndex, textualRepresentation.toString()); + } else { + return new SimpleIndexIndexEnquirer(src, IndexQuery.remote(remoteIndex)); + } + } + + private static final class SimpleIndexIndexEnquirer extends LocalIndexEnquirer { + private final IndexQuery idx; + public SimpleIndexIndexEnquirer(FileObject src, IndexQuery idx) { + super(src); + this.idx = idx; + } + public Collection<? extends Resource> findResources(final Iterable<? extends HintDescription> hints, ProgressHandleWrapper progress, final Callable<BulkPattern> bulkPattern, final Collection<? super MessageImpl> problems, HintsSettings settingsProvider) { + final Collection<Resource> result = new ArrayList<Resource>(); + + progress.startNextPart(1); + + try { + BulkPattern bp = bulkPattern.call(); + + for (String candidate : idx.findCandidates(bp)) { + result.add(new Resource(this, candidate, hints, bp, settingsProvider)); + } + } catch (Exception ex) { + Exceptions.printStackTrace(ex); + } + + return result; + } + + } + + private static final class RemoteFullyAttributedIndexEnquirer extends IndexEnquirer { + private final RemoteIndex remoteIndex; + private final String textualHintRepresentation; + public RemoteFullyAttributedIndexEnquirer(FileObject src, RemoteIndex remoteIndex, String textualHintRepresentation) { + super(src); + assert isAttributedIndexWithSpans(remoteIndex); + this.remoteIndex = remoteIndex; + this.textualHintRepresentation = textualHintRepresentation; + } + public Collection<? extends Resource> findResources(final Iterable<? extends HintDescription> hints, ProgressHandleWrapper progress, final Callable<BulkPattern> bulkPattern, final Collection<? super MessageImpl> problems, HintsSettings settingsProvider) { + final Collection<Resource> result = new ArrayList<Resource>(); + + progress.startNextPart(1); + + try { + URI u = new URI(remoteIndex.remote.toExternalForm() + "/find?path=" + escapeForQuery(remoteIndex.remoteSegment) + "&pattern=" + escapeForQuery(textualHintRepresentation)); + + for (String occurrence : new ArrayList<String>(WebUtilities.requestStringArrayResponse(u))) { + try { + BulkPattern bp = bulkPattern.call(); + result.add(new Resource(this, occurrence, hints, bp, settingsProvider)); + } catch (Exception ex) { + //from bulkPattern.call()? should not happen. + Exceptions.printStackTrace(ex); + } + } + + } catch (URISyntaxException ex) { + Exceptions.printStackTrace(ex); + } + + return result; + } + + @Override + public void validateResource(Collection<? extends Resource> resources, ProgressHandleWrapper progress, VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, Collection<? super MessageImpl> problems, AtomicBoolean cancel) { + for (Resource r : resources) { + try { + URI spanURI = new URI(remoteIndex.remote.toExternalForm() + "/findSpans?path=" + escapeForQuery(remoteIndex.remoteSegment) + "&relativePath=" + escapeForQuery(r.getRelativePath()) + "&pattern=" + escapeForQuery(textualHintRepresentation)); + FileObject fo = r.getResolvedFile(); + + if (fo == null) { + callback.cannotVerifySpan(r); + } else { + List<ErrorDescription> result = new ArrayList<ErrorDescription>(); + + for (int[] span : parseSpans(WebUtilities.requestStringResponse(spanURI))) { + result.add(ErrorDescriptionFactory.createErrorDescription(Severity.WARNING, "Occurrence", fo, span[0], span[1])); + } + + callback.spansVerified(null, r, result); + } + } catch (Exception ex) { + Exceptions.printStackTrace(ex); + } + } + } + + } + + private static Iterable<int[]> parseSpans(String from) { + if (from.isEmpty()) { + return Collections.emptyList(); + } + String[] split = from.split(":"); + List<int[]> result = new LinkedList<int[]>(); + + for (int i = 0; i < split.length; i += 2) { + result.add(new int[] { + Integer.parseInt(split[i + 0].trim()), + Integer.parseInt(split[i + 1].trim()) + }); + } + + return result; + } + + private static String defaultHintText(HintDescription hd) { + StringBuilder result = new StringBuilder(); + + PatternDescription pd = (PatternDescription) hd.getTrigger(); + + if (pd == null) return null; + + if (pd.getImports().iterator().hasNext()) { + //cannot currently handle patterns with imports: + return null; + } + + result.append(pd.getPattern()); + + if (!pd.getConstraints().isEmpty()) { + result.append(" :: "); + + for (Iterator<Entry<String, String>> it = pd.getConstraints().entrySet().iterator(); it.hasNext(); ) { + Entry<String, String> e = it.next(); + + result.append(e.getKey()).append(" instanceof ").append(e.getValue()); + + if (it.hasNext()) { + result.append(" && "); + } + } + } + + result.append(";;\n"); + + return result.toString(); + } +}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/OptionProcessorImpl.java ---------------------------------------------------------------------- diff --git a/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/OptionProcessorImpl.java b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/OptionProcessorImpl.java new file mode 100644 index 0000000..bb51cf5 --- /dev/null +++ b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/OptionProcessorImpl.java @@ -0,0 +1,276 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2008-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 2008-2010 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.jackpot30.indexing.batch; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.logging.Logger; +import org.netbeans.api.java.classpath.ClassPath; +import org.netbeans.api.java.source.ModificationResult; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.api.project.ProjectUtils; +import org.netbeans.api.project.SourceGroup; +import org.netbeans.api.project.ui.OpenProjects; +import org.netbeans.api.sendopts.CommandException; +import org.netbeans.modules.java.hints.providers.spi.HintDescription; +import org.netbeans.modules.java.hints.spiimpl.MessageImpl; +import org.netbeans.modules.java.hints.spiimpl.Utilities; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.BatchResult; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Folder; +import org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities; +import org.netbeans.modules.java.hints.spiimpl.batch.ProgressHandleWrapper; +import org.netbeans.modules.java.hints.spiimpl.batch.Scopes; +import org.netbeans.spi.java.classpath.support.ClassPathSupport; +import org.netbeans.spi.java.hints.HintContext.MessageKind; +import org.netbeans.spi.sendopts.Env; +import org.netbeans.spi.sendopts.Option; +import org.netbeans.spi.sendopts.OptionProcessor; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author Jan Lahoda + */ +@ServiceProvider(service=OptionProcessor.class) +public class OptionProcessorImpl extends OptionProcessor { + + private static final Logger LOG = Logger.getLogger(OptionProcessorImpl.class.getName()); + + private static final String APPLY_TRANSFORMATIONS_PROJECT_OPTION = "apply-transformations-project"; + + private static final Option LIST = Option.withoutArgument(Option.NO_SHORT_NAME, "list-hints-transformation"); + private static final Option APPLY_TRANSFORMATIONS = Option.shortDescription( + Option.requiredArgument(Option.NO_SHORT_NAME, "apply-transformations"), + "org.netbeans.modules.jackpot30.impl.batch.Bundle", + "SD_ApplyTransformations"); + private static final Option APPLY_TRANSFORMATIONS_PROJECT = Option.shortDescription( + Option.additionalArguments(Option.NO_SHORT_NAME, APPLY_TRANSFORMATIONS_PROJECT_OPTION), + "org.netbeans.modules.jackpot30.impl.batch.Bundle", + "SD_ApplyTransformationsProject"); + + private static final Set<Option> OPTIONS = new HashSet<Option>(Arrays.asList(LIST, APPLY_TRANSFORMATIONS, APPLY_TRANSFORMATIONS_PROJECT)); + + @Override + protected Set<Option> getOptions() { + return OPTIONS; + } + + @Override + protected void process(Env env, Map<Option, String[]> optionValues) throws CommandException { + List<Project> projects = new LinkedList<Project>(); + Map<String, List<ClassPath>> classPaths = new HashMap<String, List<ClassPath>>(); + + if (optionValues.containsKey(APPLY_TRANSFORMATIONS_PROJECT)) { + String[] projectNames = optionValues.get(APPLY_TRANSFORMATIONS_PROJECT); + + if (projectNames.length == 0) { + env.getErrorStream().println("At least one parameter needed for " + APPLY_TRANSFORMATIONS_PROJECT_OPTION); + throw new CommandException(1); + } + + FileObject currentDirectory = FileUtil.toFileObject(env.getCurrentDirectory()); + + OUTER: for (String p : projectNames) { + FileObject projectFile = currentDirectory.getFileObject(p); + + if (projectFile == null) { + projectFile = FileUtil.toFileObject(new File(p)); + } + + if (projectFile == null) { + env.getErrorStream().println("Ignoring file " + p + " - cannot be found."); + continue; + } + + if (!projectFile.isFolder()) { + env.getErrorStream().println("Ignoring file " + p + " - not a folder."); + continue; + } + + Project project = null; + String error = null; + + try { + project = ProjectManager.getDefault().findProject(projectFile); + } catch (IOException ex) { + error = ex.getLocalizedMessage(); + } catch (IllegalArgumentException ex) { + error = ex.getLocalizedMessage(); + } + + if (project == null) { + if (error == null) { + env.getErrorStream().println("Ignoring file " + p + " - not a project."); + } else { + env.getErrorStream().println("Ignoring file " + p + " - not a project (" + error + ")."); + } + + continue; + } + + for (SourceGroup sg : ProjectUtils.getSources(project).getSourceGroups("java")) { + FileObject root = sg.getRootFolder(); + + for (String type : Arrays.asList(ClassPath.BOOT, ClassPath.COMPILE, ClassPath.SOURCE)) { + if (!handleClassPath(root, type, env, p, classPaths)) { + continue OUTER; + } + } + } + + projects.add(project); + } + } else { + projects.addAll(Arrays.asList(OpenProjects.getDefault().getOpenProjects())); + } + + if (optionValues.containsKey(LIST)) { + env.getOutputStream().println("Supported Hints:"); + + Set<ClassPath> cps = new HashSet<ClassPath>(); + + for (List<ClassPath> c : classPaths.values()) { + cps.addAll(c); + } + + Set<String> displayNames = Utilities.sortOutHints(Utilities.listAllHints(cps), new TreeMap<String, Collection<HintDescription>>()).keySet(); + + for (String displayName : displayNames) { + env.getOutputStream().println(displayName); + } + } + + if (optionValues.containsKey(APPLY_TRANSFORMATIONS)) { + String hintsArg = optionValues.get(APPLY_TRANSFORMATIONS)[0]; + List<HintDescription> hintDescriptions = new LinkedList<HintDescription>(); + Set<ClassPath> cps = new HashSet<ClassPath>(); + + for (List<ClassPath> c : classPaths.values()) { + cps.addAll(c); + } + + Map<String, Collection<HintDescription>> sorted = Utilities.sortOutHints(Utilities.listAllHints(cps), new TreeMap<String, Collection<HintDescription>>()); + + for (String hint : hintsArg.split(":")) { + Collection<HintDescription> descs = sorted.get(hint); + + if (descs == null) { + env.getErrorStream().println("Unknown hint: " + hint); + continue; + } + + hintDescriptions.addAll(descs); + } + + Collection<Folder> roots = new ArrayList<Folder>(); + + for (FileObject f : BatchUtilities.getSourceGroups(projects)) { + roots.add(new Folder(f)); + } + + BatchResult candidates = BatchSearch.findOccurrences(hintDescriptions, Scopes.specifiedFoldersScope(roots.toArray(new Folder[0]))); + List<MessageImpl> problems = new LinkedList<MessageImpl>(candidates.problems); + Collection<? extends ModificationResult> res = BatchUtilities.applyFixes(candidates, new ProgressHandleWrapper(100), null, problems); + Set<FileObject> modified = new HashSet<FileObject>(); + + for (ModificationResult mr : res) { + try { + mr.commit(); + } catch (IOException ex) { + ex.printStackTrace(env.getErrorStream()); + problems.add(new MessageImpl(MessageKind.ERROR, "Cannot apply changes: " + ex.getLocalizedMessage())); + } + modified.addAll(mr.getModifiedFileObjects()); + } + + try { + org.netbeans.modules.jackpot30.indexing.batch.BatchUtilities.removeUnusedImports(modified); + } catch (IOException ex) { + ex.printStackTrace(env.getErrorStream()); + problems.add(new MessageImpl(MessageKind.ERROR, "Cannot remove unused imports: " + ex.getLocalizedMessage())); + } + + if (!problems.isEmpty()) { + env.getErrorStream().println("Problem encountered while applying the transformations:"); + + for (MessageImpl problem : problems) { + env.getErrorStream().println(problem.text); + } + } + } + + } + + private boolean handleClassPath(FileObject root, String type, Env env, String p, Map<String, List<ClassPath>> classPaths) { + ClassPath cp = ClassPath.getClassPath(root, type); + + if (cp == null) { + env.getErrorStream().println("Ignoring file " + p + " - no " + type + " classpath for source group: " + FileUtil.getFileDisplayName(root)); + return false; + } + + List<ClassPath> cps = classPaths.get(type); + + if (cps == null) { + classPaths.put(type, cps = new LinkedList<ClassPath>()); + } + + cp = ClassPathSupport.createProxyClassPath(cp); + + cps.add(cp); + + return true; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/IndexQuery.java ---------------------------------------------------------------------- diff --git a/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/IndexQuery.java b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/IndexQuery.java new file mode 100644 index 0000000..ba48594 --- /dev/null +++ b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/IndexQuery.java @@ -0,0 +1,255 @@ +/* + * 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.indexing.index; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.zip.DataFormatException; +import org.apache.lucene.analysis.KeywordAnalyzer; +import org.apache.lucene.document.CompressionTools; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.FieldSelector; +import org.apache.lucene.document.FieldSelectorResult; +import org.apache.lucene.index.Term; +import org.apache.lucene.queryParser.ParseException; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.PhraseQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TermQuery; +import org.netbeans.api.annotations.common.NullAllowed; +import org.netbeans.modules.jackpot30.remoting.api.RemoteIndex; +import org.netbeans.modules.jackpot30.remoting.api.WebUtilities; +import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints; +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch; +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern; +import org.netbeans.modules.parsing.lucene.support.Convertor; +import org.netbeans.modules.parsing.lucene.support.Index; +import org.netbeans.modules.parsing.lucene.support.Index.Status; +import org.netbeans.modules.parsing.lucene.support.IndexManager; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.Exceptions; + +/** + * + * @author lahvac + */ +public abstract class IndexQuery { + + public abstract Collection<? extends String> findCandidates(BulkPattern pattern) throws IOException; + + public abstract Map<String, Map<String, Integer>> findCandidatesWithFrequencies(BulkPattern pattern) throws IOException; + + public static Map<String, Map<String, Integer>> performLocalQuery(Index index, final BulkPattern pattern, final boolean withFrequencies) throws IOException, InterruptedException, ParseException { + final Map<String, Map<String, Integer>> result = new HashMap<String, Map<String, Integer>>(); + + index.query(new ArrayList<Object>(), new Convertor<Document, Object>() { + @Override public Object convert(Document doc) { + try { + ByteArrayInputStream in = new ByteArrayInputStream(CompressionTools.decompress(doc.getField("languageEncoded").getBinaryValue())); + + try { + Map<String, Integer> freqs; + boolean matches; + + if (withFrequencies) { + freqs = BulkSearch.getDefault().matchesWithFrequencies(in, pattern, new AtomicBoolean()); + matches = !freqs.isEmpty(); + } else { + freqs = null; + matches = BulkSearch.getDefault().matches(in, new AtomicBoolean(), pattern); + } + + if (matches) { + result.put(doc.getField("languagePath").stringValue(), freqs); + } + } finally { + in.close(); + } + } catch (DataFormatException ex) { + throw new IllegalStateException(ex); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + + return null; + } + }, new FieldSelector() { + public FieldSelectorResult accept(String string) { + return "languageEncoded".equals(string) || "languagePath".equals(string) ? FieldSelectorResult.LOAD : FieldSelectorResult.NO_LOAD; + } + }, null, query(pattern)); + + return result; + } + + private static Query query(BulkPattern pattern) throws ParseException { + BooleanQuery result = new BooleanQuery(); + + for (int cntr = 0; cntr < pattern.getIdentifiers().size(); cntr++) { + assert !pattern.getRequiredContent().get(cntr).isEmpty(); + + BooleanQuery emb = new BooleanQuery(); + + for (List<String> c : pattern.getRequiredContent().get(cntr)) { + if (c.isEmpty()) continue; + + PhraseQuery pq = new PhraseQuery(); + + for (String s : c) { + pq.add(new Term("languageContent", s)); + } + + emb.add(pq, BooleanClause.Occur.MUST); + } + + AdditionalQueryConstraints additionalConstraints = pattern.getAdditionalConstraints().get(cntr); + + if (additionalConstraints != null && !additionalConstraints.requiredErasedTypes.isEmpty()) { + BooleanQuery constraintsQuery = new BooleanQuery(); + + constraintsQuery.add(new TermQuery(new Term("languageAttributed", "false")), BooleanClause.Occur.SHOULD); + + BooleanQuery constr = new BooleanQuery(); + + for (String tc : additionalConstraints.requiredErasedTypes) { + constr.add(new TermQuery(new Term("languageErasedTypes", tc)), BooleanClause.Occur.MUST); + } + + constraintsQuery.add(constr, BooleanClause.Occur.SHOULD); + emb.add(constraintsQuery, BooleanClause.Occur.MUST); + } + + result.add(emb, BooleanClause.Occur.SHOULD); + } + + return result; + } + + private static final class LocalIndexQuery extends IndexQuery { + private final @NullAllowed File cacheDir; + + public LocalIndexQuery(@NullAllowed File cacheDir) { + this.cacheDir = cacheDir; + } + + public Collection<? extends String> findCandidates(BulkPattern pattern) throws IOException { + return findCandidates(pattern, false).keySet(); + } + + public Map<String, Map<String, Integer>> findCandidatesWithFrequencies(BulkPattern pattern) throws IOException { + return findCandidates(pattern, true); + } + + private Map<String, Map<String, Integer>> findCandidates(BulkPattern pattern, boolean withFrequencies) throws IOException { + Index index = IndexManager.createIndex(cacheDir, new KeywordAnalyzer()); + + if (index.getStatus(true) != Status.VALID) { + return Collections.emptyMap(); + } + + try { + return performLocalQuery(index, pattern, withFrequencies); + } catch (InterruptedException ex) { + throw new IOException(ex); + } catch (ParseException ex) { + throw new IOException(ex); + } finally { + index.close(); + } + } + + } + + private static final class RemoteIndexQuery extends IndexQuery { + private final RemoteIndex idx; + + public RemoteIndexQuery(RemoteIndex idx) { + this.idx = idx; + } + + @Override + public Collection<? extends String> findCandidates(BulkPattern pattern) throws IOException { + try { + StringBuilder patterns = new StringBuilder(); + + for (String p : pattern.getPatterns()) { + patterns.append(p); + patterns.append(";;"); + } + + URI u = new URI(idx.remote.toExternalForm() + "?path=" + WebUtilities.escapeForQuery(idx.remoteSegment) + "&pattern=" + WebUtilities.escapeForQuery(patterns.toString())); + + return new ArrayList<String>(WebUtilities.requestStringArrayResponse(u)); + } catch (URISyntaxException ex) { + //XXX: better handling? + Exceptions.printStackTrace(ex); + return Collections.emptyList(); + } + } + @Override + public Map<String, Map<String, Integer>> findCandidatesWithFrequencies(BulkPattern pattern) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + } + + public static IndexQuery open(URL sourceRoot) throws IOException { + FileObject cacheFO = Indexer.resolveCacheFolder(sourceRoot).getFileObject(Indexer.INDEX_NAME); + File cache = cacheFO != null ? FileUtil.toFile(cacheFO) : null; + + return new LocalIndexQuery(cache); + } + + public static IndexQuery remote(RemoteIndex idx) { + return new RemoteIndexQuery(idx); + } +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/Indexer.java ---------------------------------------------------------------------- diff --git a/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/Indexer.java b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/Indexer.java new file mode 100644 index 0000000..962015f --- /dev/null +++ b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/Indexer.java @@ -0,0 +1,241 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009-2012 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-2012 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.jackpot30.indexing.index; + +import org.netbeans.modules.jackpot30.common.api.IndexAccess; +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.Tree; +import com.sun.source.util.TreePath; +import com.sun.source.util.TreePathScanner; +import com.sun.source.util.Trees; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.lang.model.type.ArrayType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Types; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.tokenattributes.TermAttribute; +import org.apache.lucene.document.CompressionTools; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.index.CorruptIndexException; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.Term; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.editor.mimelookup.MimeRegistration; +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch; +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.EncodingContext; +import org.netbeans.modules.java.preprocessorbridge.spi.JavaIndexerPlugin; +import org.netbeans.modules.java.source.indexing.JavaIndex; +import org.netbeans.modules.parsing.impl.indexing.CacheFolder; +import org.netbeans.modules.parsing.spi.indexing.Indexable; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; + +/** + * + * @author lahvac + */ +public final class Indexer implements JavaIndexerPlugin { + + public static final String INDEX_NAME = "jackpot30"; + private final @NonNull URL root; + private final @NonNull FileObject cacheRoot; + private final @NonNull IndexAccess access; + + private Indexer(URL root, FileObject cacheRoot) { + this.root = root; + this.cacheRoot = cacheRoot; + this.access = Lookup.getDefault().lookup(IndexAccess.class); + } + + @Override + public void process (@NonNull CompilationUnitTree toProcess, @NonNull Indexable indexable, @NonNull Lookup services) { + IndexWriter luceneWriter = access.getIndexWriter(root, cacheRoot, INDEX_NAME); + String relative = access.getRelativePath(indexable); + ByteArrayOutputStream out = null; + EncodingContext ec; + + try { + out = new ByteArrayOutputStream(); + + ec = new EncodingContext(out, false); + + BulkSearch.getDefault().encode(toProcess, ec, new AtomicBoolean()); + + luceneWriter.deleteDocuments(new Term("languagePath", relative)); + + Document doc = new Document(); + + doc.add(new Field("languageContent", new TokenStreamImpl(ec.getContent()))); + out.close(); + doc.add(new Field("languageEncoded", CompressionTools.compress(out.toByteArray()), Field.Store.YES)); + doc.add(new Field("languagePath", relative, Field.Store.YES, Field.Index.NOT_ANALYZED)); + + if (services != null) { + final Set<String> erased = new HashSet<String>(); + final Trees trees = services.lookup(Trees.class); + final Types types = services.lookup(Types.class); + + new TreePathScanner<Void, Void>() { + @Override + public Void scan(Tree tree, Void p) { + if (tree != null) { + TreePath tp = new TreePath(getCurrentPath(), tree); + TypeMirror type = trees.getTypeMirror(tp); + + if (type != null) { + if (type.getKind() == TypeKind.ARRAY) { + erased.add(types.erasure(type).toString()); + type = ((ArrayType) type).getComponentType(); + } + + if (type.getKind().isPrimitive() || type.getKind() == TypeKind.DECLARED) { + addErasedTypeAndSuperTypes(types, erased, type); + } + } + + //bounds for type variables!!! + } + return super.scan(tree, p); + } + }.scan(toProcess, null); + + doc.add(new Field("languageErasedTypes", new TokenStreamImpl(erased))); + } + + luceneWriter.addDocument(doc); + } catch (ThreadDeath td) { + throw td; + } catch (Throwable t) { + Logger.getLogger(Indexer.class.getName()).log(Level.WARNING, null, t); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + } + } + + + @Override + public void delete (@NonNull Indexable indexable) { + IndexWriter luceneWriter = access.getIndexWriter(root, cacheRoot, INDEX_NAME); + String relative = access.getRelativePath(indexable); + + try { + luceneWriter.deleteDocuments(new Term("languagePath", relative)); + } catch (CorruptIndexException ex) { + Logger.getLogger(Indexer.class.getName()).log(Level.WARNING, null, ex); + } catch (IOException ex) { + Logger.getLogger(Indexer.class.getName()).log(Level.WARNING, null, ex); + } + } + + @Override + public void finish () { + access.finish(); + } + + private static void addErasedTypeAndSuperTypes(Types javacTypes, Set<String> types, TypeMirror type) { + if (type.getKind() == TypeKind.DECLARED) { + if (types.add(javacTypes.erasure(type).toString())) { + for (TypeMirror sup : javacTypes.directSupertypes(type)) { + addErasedTypeAndSuperTypes(javacTypes, types, sup); + } + } + } else if (type.getKind().isPrimitive()) { + types.add(type.toString()); + } + } + + public static final class TokenStreamImpl extends TokenStream { + + private final Iterator<? extends String> tokens; + private final TermAttribute termAtt; + + public TokenStreamImpl(Iterable<? extends String> tokens) { + this.tokens = tokens != null ? tokens.iterator() : /*???*/Collections.<String>emptyList().iterator(); + this.termAtt = addAttribute(TermAttribute.class); + } + + @Override + public boolean incrementToken() throws IOException { + if (!tokens.hasNext()) + return false; + + String t = tokens.next(); + + termAtt.setTermBuffer(t); + + return true; + } + } + + public static @NonNull FileObject resolveCacheFolder(@NonNull URL sourceRoot) throws IOException { + FileObject dataFolder = CacheFolder.getDataFolder(sourceRoot); + + return FileUtil.createFolder(dataFolder, JavaIndex.NAME + "/" + JavaIndex.VERSION); + } + + @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 Indexer(root, cacheFolder); + } + + } +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/indexing/test/unit/src/org/netbeans/modules/jackpot30/indexing/index/IndexerTest.java ---------------------------------------------------------------------- diff --git a/language/ide/indexing/test/unit/src/org/netbeans/modules/jackpot30/indexing/index/IndexerTest.java b/language/ide/indexing/test/unit/src/org/netbeans/modules/jackpot30/indexing/index/IndexerTest.java new file mode 100644 index 0000000..be974d1 --- /dev/null +++ b/language/ide/indexing/test/unit/src/org/netbeans/modules/jackpot30/indexing/index/IndexerTest.java @@ -0,0 +1,304 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2009 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.jackpot30.indexing.index; + +import java.net.URL; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import org.netbeans.api.editor.mimelookup.MimePath; +import org.netbeans.api.java.classpath.ClassPath; +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.SourceUtilsTestUtil; +import org.netbeans.api.java.source.Task; +import org.netbeans.api.java.source.TestUtilities; +import org.netbeans.modules.jackpot30.common.test.IndexTestBase; +import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints; +import org.netbeans.modules.java.hints.spiimpl.Utilities; +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch; +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern; +import org.netbeans.modules.parsing.api.indexing.IndexingManager; +import org.netbeans.spi.editor.mimelookup.MimeDataProvider; +import org.netbeans.spi.java.classpath.support.ClassPathSupport; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.Lookup; +import org.openide.util.lookup.Lookups; +import org.openide.util.lookup.ServiceProvider; + + +/** + * + * @author lahvac + */ +public class IndexerTest extends IndexTestBase { + + public IndexerTest(String name) { + super(name); + } + + public void testMultiplePatternsIndexing() 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 void test() { new javax.swing.ImageIcon(null); } }")); + + String[] patterns = new String[] { + "$1.isDirectory()", + "new ImageIcon($1)" + }; + + verifyIndex(patterns, "test/Test1.java", "test/Test2.java"); + } + + public void testLambdaPattern() throws Exception { + writeFilesAndWaitForScan(src, + new File("test/Test1.java", "package test; public class Test1 { private void test() { Runnable r = new Runnable() { public void run() { System.err.println(); } } } }")); + + String[] patterns = new String[] { + "new $type() {\n $mods$ $resultType $methodName($args$) {\n $statements$;\n }\n }\n", + }; + + verifyIndex(patterns, "test/Test1.java"); + } + + public void testUpdates() throws Exception { + String[] patterns = new String[] { + "$1.isDirectory()", + "new ImageIcon($1)" + }; + + 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 void test() { new javax.swing.ImageIcon(null); } }")); + + verifyIndex(patterns, "test/Test1.java", "test/Test2.java"); +// assertEquals(2, FileBasedIndex.get(src.getURL()).getIndexInfo().totalFiles); + + src.getFileObject("test/Test1.java").delete(); + + assertNull(src.getFileObject("test/Test1.java")); + + IndexingManager.getDefault().refreshIndexAndWait(src.toURL(), null, true); + + verifyIndex(patterns, "test/Test2.java"); +// assertEquals(1, FileBasedIndex.get(src.getURL()).getIndexInfo().totalFiles); + + FileObject test3 = FileUtil.createData(src, "test/Test3.java"); + TestUtilities.copyStringToFile(test3, "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"); + + IndexingManager.getDefault().refreshIndexAndWait(src.toURL(), null, true); + + verifyIndex(patterns, "test/Test2.java", "test/Test3.java"); +// assertEquals(2, FileBasedIndex.get(src.getURL()).getIndexInfo().totalFiles); + } + + public void testPartiallyAttributed1() 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 void isDirectory() { this.isDirectory(); } }"), + new File("test/Test3.java", "package test; public class Test3 { private void isDirectory() { this.isDirectory(); } }")); + + verifyIndex("$1.isDirectory()", new AdditionalQueryConstraints(Collections.singleton("java.io.File")), "test/Test1.java"); + } + + public void testPartiallyAttributed2() throws Exception { + writeFilesAndWaitForScan(src, + new File("test/Test1.java", "package test; public class Test1 { private void test() { String str = null; int l = str.length(); } }")); + + verifyIndex("$1.length()", new AdditionalQueryConstraints(Collections.singleton("java.lang.CharSequence")), "test/Test1.java"); + } + + public void testFrequencies() throws Exception { + writeFilesAndWaitForScan(src, + new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); f.isDirectory(); } }"), + new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); java.io.File f = null; f.isDirectory(); } }"), + new File("test/Test3.java", "package test; public class Test3 { private void test() { new javax.swing.ImageIcon(null); new javax.swing.ImageIcon(null); } }") + ); + + String[] patterns = new String[] { + "$1.isDirectory()", + "new ImageIcon($1)" + }; + + Map<String, Map<String, Integer>> golden = new HashMap<String, Map<String, Integer>>(); + + golden.put("test/Test3.java", Collections.singletonMap("new ImageIcon($1)", 2)); + golden.put("test/Test1.java", Collections.singletonMap("$1.isDirectory()", 2)); + + Map<String, Integer> freqsTest2 = new HashMap<String, Integer>(); + + freqsTest2.put("$1.isDirectory()", 1); + freqsTest2.put("new ImageIcon($1)", 1); + + golden.put("test/Test2.java", freqsTest2); + + verifyIndexWithFrequencies(patterns, golden); + } + + public void testInnerClass() throws Exception { + writeFilesAndWaitForScan(src, + new File("test/Test1.java", "package test; public class Test1 { private static final class O implements Iterable<String> { private String next; private String computeNext() { return null; } public String hasNext() { next = computeNext(); return next != null; } } }")); + + verifyIndex("$this.computeNext()", new AdditionalQueryConstraints(Collections.singleton("test.Test1.O")), "test/Test1.java"); + } + + public void testIndexing() 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 void test() { new javax.swing.ImageIcon(null); } }")); + + verifyIndex("$1.isDirectory()", "test/Test1.java"); + verifyIndex("new ImageIcon($1)", "test/Test2.java"); + + writeFilesAndWaitForScan(src, + new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); new javax.swing.ImageIcon(null); } }"), + new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }")); + + verifyIndex("$1.isDirectory()", "test/Test1.java"); + verifyIndex("new ImageIcon($1)", "test/Test1.java", "test/Test2.java"); + + writeFilesAndWaitForScan(src, + new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); new javax.swing.ImageIcon(null); } }"), + new File("test/Test2.java", "package test; public class Test2 { }")); + + verifyIndex("$1.isDirectory()", "test/Test1.java"); + verifyIndex("new ImageIcon($1)", "test/Test1.java"); + } + + private void verifyIndex(final String[] patterns, String... containedIn) throws Exception { + ClassPath EMPTY = ClassPathSupport.createClassPath(new FileObject[0]); + ClasspathInfo cpInfo = ClasspathInfo.create(ClassPathSupport.createClassPath(SourceUtilsTestUtil.getBootClassPath().toArray(new URL[0])), + EMPTY, + EMPTY); + + final Set<String> real = new HashSet<String>(); + + JavaSource.create(cpInfo).runUserActionTask(new Task<CompilationController>() { + public void run(CompilationController parameter) throws Exception { + real.addAll(IndexQuery.open(src.toURL()).findCandidates(BulkSearch.getDefault().create(parameter, new AtomicBoolean(), patterns))); + } + }, true); + + Set<String> golden = new HashSet<String>(Arrays.asList(containedIn)); + + assertEquals(golden, real); + } + + private void verifyIndex(final String pattern, final AdditionalQueryConstraints additionalConstraints, String... containedIn) throws Exception { + ClassPath EMPTY = ClassPathSupport.createClassPath(new FileObject[0]); + ClasspathInfo cpInfo = ClasspathInfo.create(ClassPathSupport.createClassPath(SourceUtilsTestUtil.getBootClassPath().toArray(new URL[0])), + EMPTY, + EMPTY); + + final Set<String> real = new HashSet<String>(); + + JavaSource.create(cpInfo).runUserActionTask(new Task<CompilationController>() { + public void run(CompilationController parameter) throws Exception { + BulkPattern bulkPattern = BulkSearch.getDefault().create(Collections.singletonList(pattern), + Collections.singletonList(Utilities.parseAndAttribute(parameter, pattern, null)), + Collections.singletonList(additionalConstraints), + new AtomicBoolean()); + + real.addAll(IndexQuery.open(src.toURL()).findCandidates(bulkPattern)); + } + }, true); + + Set<String> golden = new HashSet<String>(Arrays.asList(containedIn)); + + assertEquals(golden, real); + } + + private void verifyIndexWithFrequencies(final String[] patterns, Map<String, Map<String, Integer>> golden) throws Exception { + ClassPath EMPTY = ClassPathSupport.createClassPath(new FileObject[0]); + ClasspathInfo cpInfo = ClasspathInfo.create(ClassPathSupport.createClassPath(SourceUtilsTestUtil.getBootClassPath().toArray(new URL[0])), + EMPTY, + EMPTY); + + final Map<String, Map<String, Integer>> real = new HashMap<String, Map<String, Integer>>(); + + JavaSource.create(cpInfo).runUserActionTask(new Task<CompilationController>() { + public void run(CompilationController parameter) throws Exception { + real.putAll(IndexQuery.open(src.toURL()).findCandidatesWithFrequencies(BulkSearch.getDefault().create(parameter, new AtomicBoolean(), patterns))); + } + }, true); + + assertEquals(golden, real); + } + + private void verifyIndex(final String pattern, String... containedIn) throws Exception { + ClassPath EMPTY = ClassPathSupport.createClassPath(new FileObject[0]); + ClasspathInfo cpInfo = ClasspathInfo.create(ClassPathSupport.createClassPath(SourceUtilsTestUtil.getBootClassPath().toArray(new URL[0])), + EMPTY, + EMPTY); + + final Set<String> real = new HashSet<String>(); + + JavaSource.create(cpInfo).runUserActionTask(new Task<CompilationController>() { + public void run(CompilationController parameter) throws Exception { + real.addAll(IndexQuery.open(src.toURL()).findCandidates(BulkSearch.getDefault().create(parameter, new AtomicBoolean(), pattern))); + } + }, true); + + Set<String> golden = new HashSet<String>(Arrays.asList(containedIn)); + + assertEquals(golden, real); + } + + @ServiceProvider(service=MimeDataProvider.class) + public static final class MimeDataProviderImpl implements MimeDataProvider { + + private static final Lookup L = Lookups.fixed(new Indexer.FactoryImpl()); + + @Override + public Lookup getLookup(MimePath mp) { + if ("text/x-java".equals(mp.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/language/ide/nbproject/build-impl.xml ---------------------------------------------------------------------- diff --git a/language/ide/nbproject/build-impl.xml b/language/ide/nbproject/build-impl.xml new file mode 100644 index 0000000..e667e4e --- /dev/null +++ b/language/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="language-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/language/ide/nbproject/genfiles.properties ---------------------------------------------------------------------- diff --git a/language/ide/nbproject/genfiles.properties b/language/ide/nbproject/genfiles.properties new file mode 100644 index 0000000..4d0ed1d --- /dev/null +++ b/language/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=d27fe1de +build.xml.script.CRC32=466d9285 [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=c11ee7c3 +nbproject/build-impl.xml.script.CRC32=74ef45bc +nbproject/[email protected] +nbproject/platform.xml.data.CRC32=c11ee7c3 +nbproject/platform.xml.script.CRC32=6dcbd131 +nbproject/[email protected] http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/nbproject/platform.properties ---------------------------------------------------------------------- diff --git a/language/ide/nbproject/platform.properties b/language/ide/nbproject/platform.properties new file mode 100644 index 0000000..8cef692 --- /dev/null +++ b/language/ide/nbproject/platform.properties @@ -0,0 +1,58 @@ +# 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}/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/ide/build/cluster.javadoc= +extcluster.../../remoting/ide/build/cluster.sources=../../remoting/ide +extcluster.../remoting/common/build/cluster.javadoc= +extcluster.../remoting/common/build/cluster.sources=../../remoting/common +nbplatform.active=default http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/nbproject/platform.xml ---------------------------------------------------------------------- diff --git a/language/ide/nbproject/platform.xml b/language/ide/nbproject/platform.xml new file mode 100644 index 0000000..1917e28 --- /dev/null +++ b/language/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>
