sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchSearch.java
1.1 --- a/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchSearch.java Mon Dec 19 11:37:36 2016 +0100
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,714 +0,0 @@
1.4 -/*
1.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
1.6 - *
1.7 - * Copyright 2009-2011 Oracle and/or its affiliates. All rights reserved.
1.8 - *
1.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
1.10 - * Other names may be trademarks of their respective owners.
1.11 - *
1.12 - * The contents of this file are subject to the terms of either the GNU
1.13 - * General Public License Version 2 only ("GPL") or the Common
1.14 - * Development and Distribution License("CDDL") (collectively, the
1.15 - * "License"). You may not use this file except in compliance with the
1.16 - * License. You can obtain a copy of the License at
1.17 - * http://www.netbeans.org/cddl-gplv2.html
1.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
1.19 - * specific language governing permissions and limitations under the
1.20 - * License. When distributing the software, include this License Header
1.21 - * Notice in each file and include the License file at
1.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
1.23 - * particular file as subject to the "Classpath" exception as provided
1.24 - * by Oracle in the GPL Version 2 section of the License file that
1.25 - * accompanied this code. If applicable, add the following below the
1.26 - * License Header, with the fields enclosed by brackets [] replaced by
1.27 - * your own identifying information:
1.28 - * "Portions Copyrighted [year] [name of copyright owner]"
1.29 - *
1.30 - * If you wish your version of this file to be governed by only the CDDL
1.31 - * or only the GPL Version 2, indicate your decision by adding
1.32 - * "[Contributor] elects to include this software in this distribution
1.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
1.34 - * single choice of license, a recipient has the option to distribute
1.35 - * your version of this file under either the CDDL, the GPL Version 2 or
1.36 - * to extend the choice of license to its licensees as provided above.
1.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
1.38 - * Version 2 license, then the option applies only if the new code is
1.39 - * made subject to such option by the copyright holder.
1.40 - *
1.41 - * Contributor(s):
1.42 - *
1.43 - * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
1.44 - */
1.45 -package org.netbeans.modules.java.hints.spiimpl.batch;
1.46 -
1.47 -import org.netbeans.spi.java.hints.HintContext.MessageKind;
1.48 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
1.49 -import com.sun.source.tree.Tree;
1.50 -import com.sun.source.util.TreePath;
1.51 -import java.io.IOException;
1.52 -import java.io.OutputStreamWriter;
1.53 -import java.io.Writer;
1.54 -import java.nio.ByteBuffer;
1.55 -import java.util.ArrayList;
1.56 -import java.util.Collection;
1.57 -import java.util.Collections;
1.58 -import java.util.HashMap;
1.59 -import java.util.HashSet;
1.60 -import java.util.LinkedList;
1.61 -import java.util.List;
1.62 -import java.util.Map;
1.63 -import java.util.Map.Entry;
1.64 -import java.util.Set;
1.65 -import java.util.concurrent.Callable;
1.66 -import java.util.concurrent.atomic.AtomicBoolean;
1.67 -import java.util.concurrent.atomic.AtomicInteger;
1.68 -import java.util.concurrent.atomic.AtomicReference;
1.69 -import java.util.logging.Level;
1.70 -import java.util.logging.Logger;
1.71 -import org.netbeans.api.annotations.common.NonNull;
1.72 -import org.netbeans.api.annotations.common.NullAllowed;
1.73 -import org.netbeans.api.fileinfo.NonRecursiveFolder;
1.74 -import org.netbeans.api.java.classpath.ClassPath;
1.75 -import org.netbeans.api.java.classpath.GlobalPathRegistry;
1.76 -import org.netbeans.api.java.source.ClasspathInfo;
1.77 -import org.netbeans.api.java.source.ClasspathInfo.PathKind;
1.78 -import org.netbeans.api.java.source.CompilationController;
1.79 -import org.netbeans.api.java.source.CompilationInfo;
1.80 -import org.netbeans.api.java.source.JavaSource;
1.81 -import org.netbeans.api.java.source.JavaSource.Phase;
1.82 -import org.netbeans.api.java.source.Task;
1.83 -import org.netbeans.api.queries.FileEncodingQuery;
1.84 -import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
1.85 -import org.netbeans.modules.java.hints.spiimpl.Utilities;
1.86 -import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker;
1.87 -import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch;
1.88 -import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern;
1.89 -import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints;
1.90 -import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
1.91 -import org.netbeans.spi.editor.hints.ErrorDescription;
1.92 -import org.netbeans.api.java.source.matching.Matcher;
1.93 -import org.netbeans.api.java.source.matching.Pattern;
1.94 -import org.netbeans.modules.java.hints.providers.spi.Trigger.DecisionTrigger;
1.95 -import org.netbeans.modules.java.hints.spiimpl.SPIAccessor;
1.96 -import org.netbeans.modules.java.hints.spiimpl.hints.GlobalProcessingContext;
1.97 -import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
1.98 -import org.netbeans.spi.java.hints.Decision;
1.99 -import org.netbeans.spi.java.hints.HintContext;
1.100 -import org.openide.filesystems.FileObject;
1.101 -import org.openide.filesystems.FileUtil;
1.102 -import org.openide.util.Exceptions;
1.103 -
1.104 -/**
1.105 - *
1.106 - * @author lahvac
1.107 - */
1.108 -public class BatchSearch {
1.109 -
1.110 - private static final Logger LOG = Logger.getLogger(BatchSearch.class.getName());
1.111 -
1.112 - public static BatchResult findOccurrences(Iterable<? extends HintDescription> patterns, Scope scope) {
1.113 - return findOccurrences(patterns, scope, new ProgressHandleWrapper(null), HintsSettings.getGlobalSettings());
1.114 - }
1.115 -
1.116 - public static BatchResult findOccurrences(final Iterable<? extends HintDescription> patterns, final Scope scope, final ProgressHandleWrapper progress, @NullAllowed HintsSettings settingsProvider) {
1.117 - return findOccurrencesLocal(patterns, scope.getIndexMapper(patterns), scope.getTodo(), progress, settingsProvider);
1.118 - }
1.119 -
1.120 - private static BatchResult findOccurrencesLocal(final Iterable<? extends HintDescription> patterns, final MapIndices indexMapper, final Collection<? extends Folder> todo, final ProgressHandleWrapper progress, final @NullAllowed HintsSettings settingsProvider) {
1.121 - final BatchResult[] result = new BatchResult[1];
1.122 -
1.123 - try {
1.124 - JavaSource.create(Utilities.createUniversalCPInfo()).runUserActionTask(new Task<CompilationController>() {
1.125 - public void run(CompilationController parameter) throws Exception {
1.126 - result[0] = findOccurrencesLocalImpl(parameter, patterns, indexMapper, todo, progress, settingsProvider);
1.127 - }
1.128 - }, true);
1.129 - } catch (IOException ex) {
1.130 - throw new IllegalStateException(ex);
1.131 - }
1.132 -
1.133 - return result[0];
1.134 - }
1.135 -
1.136 - private static BatchResult findOccurrencesLocalImpl(final CompilationInfo info, final Iterable<? extends HintDescription> patterns, MapIndices indexMapper, Collection<? extends Folder> todo, ProgressHandleWrapper progress, HintsSettings settingsProvider) {
1.137 - boolean hasKindPatterns = false;
1.138 -
1.139 - for (HintDescription pattern : patterns) {
1.140 - if (!(pattern.getTrigger() instanceof PatternDescription)) {
1.141 - hasKindPatterns = true;
1.142 - break;
1.143 - }
1.144 - }
1.145 -
1.146 - final Callable<BulkPattern> bulkPattern = hasKindPatterns ? null : new Callable<BulkPattern>() {
1.147 - private final AtomicReference<BulkPattern> pattern = new AtomicReference<BulkPattern>();
1.148 - public BulkPattern call() {
1.149 - if (pattern.get() == null) {
1.150 - pattern.set(preparePattern(patterns, info));
1.151 - }
1.152 -
1.153 - return pattern.get();
1.154 - }
1.155 - };
1.156 - final Map<IndexEnquirer, Collection<? extends Resource>> result = new HashMap<IndexEnquirer, Collection<? extends Resource>>();
1.157 - final Collection<MessageImpl> problems = new LinkedList<MessageImpl>();
1.158 - ProgressHandleWrapper innerForAll = progress.startNextPartWithEmbedding(ProgressHandleWrapper.prepareParts(2 * todo.size()));
1.159 -
1.160 - for (final Folder src : todo) {
1.161 - LOG.log(Level.FINE, "Processing: {0}", FileUtil.getFileDisplayName(src.getFileObject()));
1.162 -
1.163 - IndexEnquirer indexEnquirer;// = indexMapper.findIndex(src.getFileObject(), innerForAll, src.isRecursive());
1.164 -
1.165 -// if (indexEnquirer == null) {
1.166 - indexEnquirer = new FileSystemBasedIndexEnquirer(src.getFileObject(), src.isRecursive());
1.167 -// }
1.168 -
1.169 - Collection<? extends Resource> occurrences = indexEnquirer.findResources(patterns, innerForAll, bulkPattern, problems, settingsProvider);
1.170 -
1.171 - if (!occurrences.isEmpty()) {
1.172 - result.put(indexEnquirer, occurrences);
1.173 - }
1.174 -
1.175 - innerForAll.tick();
1.176 - }
1.177 -
1.178 - return new BatchResult(result, patterns, problems);
1.179 - }
1.180 -
1.181 - private static BulkPattern preparePattern(final Iterable<? extends HintDescription> patterns, CompilationInfo info) {
1.182 - Collection<String> code = new LinkedList<String>();
1.183 - Collection<Tree> trees = new LinkedList<Tree>();
1.184 - Collection<AdditionalQueryConstraints> additionalConstraints = new LinkedList<AdditionalQueryConstraints>();
1.185 -
1.186 - for (HintDescription pattern : patterns) {
1.187 - String textPattern = ((PatternDescription) pattern.getTrigger()).getPattern();
1.188 -
1.189 - code.add(textPattern);
1.190 - trees.add(Utilities.parseAndAttribute(info, textPattern, null));
1.191 - additionalConstraints.add(pattern.getAdditionalConstraints());
1.192 - }
1.193 -
1.194 - return BulkSearch.getDefault().create(code, trees, additionalConstraints, new AtomicBoolean());
1.195 - }
1.196 -
1.197 - public static void getVerifiedSpans(BatchResult candidates, @NonNull ProgressHandleWrapper progress, final VerifiedSpansCallBack callback, final Collection<? super MessageImpl> problems, AtomicBoolean cancel) {
1.198 - getVerifiedSpans(candidates, progress, callback, false, problems, cancel);
1.199 - }
1.200 -
1.201 - public static void getVerifiedSpans(BatchResult candidates, @NonNull ProgressHandleWrapper progress, final VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, final Collection<? super MessageImpl> problems, AtomicBoolean cancel) {
1.202 - int[] parts = new int[candidates.projectId2Resources.size()];
1.203 - int index = 0;
1.204 -
1.205 - for (Entry<? extends IndexEnquirer, ? extends Collection<? extends Resource>> e : candidates.projectId2Resources.entrySet()) {
1.206 - parts[index++] = e.getValue().size();
1.207 - }
1.208 -
1.209 - ProgressHandleWrapper inner = progress.startNextPartWithEmbedding(parts);
1.210 -
1.211 - for (Entry<? extends IndexEnquirer, ? extends Collection<? extends Resource>> e : candidates.projectId2Resources.entrySet()) {
1.212 - if (cancel.get())
1.213 - return;
1.214 - inner.startNextPart(e.getValue().size());
1.215 -
1.216 - e.getKey().validateResource(e.getValue(), inner, callback, doNotRegisterClassPath, problems, cancel);
1.217 - }
1.218 - }
1.219 -
1.220 - private static void getLocalVerifiedSpans(Collection<? extends Resource> resources, @NonNull final ProgressHandleWrapper progress, final VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, final Collection<? super MessageImpl> problems, final AtomicBoolean cancel) {
1.221 - Collection<FileObject> files = new LinkedList<FileObject>();
1.222 - final Map<FileObject, Resource> file2Resource = new HashMap<FileObject, Resource>();
1.223 -
1.224 - for (Resource r : resources) {
1.225 - FileObject file = r.getResolvedFile();
1.226 -
1.227 - if (file != null) {
1.228 - files.add(file);
1.229 - file2Resource.put(file, r);
1.230 - } else {
1.231 - callback.cannotVerifySpan(r);
1.232 - progress.tick();
1.233 - }
1.234 - }
1.235 -
1.236 - Map<ClasspathInfo, Collection<FileObject>> cp2Files = BatchUtilities.sortFiles(files);
1.237 - ClassPath[] toRegister = null;
1.238 -
1.239 - if (!doNotRegisterClassPath) {
1.240 - Set<ClassPath> toRegisterSet = new HashSet<ClassPath>();
1.241 -
1.242 - for (ClasspathInfo cpInfo : cp2Files.keySet()) {
1.243 - toRegisterSet.add(cpInfo.getClassPath(PathKind.SOURCE));
1.244 - }
1.245 -
1.246 - toRegister = !toRegisterSet.isEmpty() ? toRegisterSet.toArray(new ClassPath[0]) : null;
1.247 -
1.248 - if (toRegister != null) {
1.249 - GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, toRegister);
1.250 - try {
1.251 - Utilities.waitScanFinished();
1.252 - } catch (InterruptedException ex) {
1.253 - Exceptions.printStackTrace(ex);
1.254 - }
1.255 - }
1.256 - }
1.257 -
1.258 - callback.groupStarted();
1.259 -
1.260 - try {
1.261 - final GlobalProcessingContext gpc = new GlobalProcessingContext();
1.262 - for (Entry<ClasspathInfo, Collection<FileObject>> e : cp2Files.entrySet()) {
1.263 - try {
1.264 - List<FileObject> toProcess = new ArrayList<FileObject>(e.getValue());
1.265 - final AtomicInteger currentPointer = new AtomicInteger();
1.266 -
1.267 -// for (FileObject f : toProcess) {
1.268 - while (currentPointer.get() < toProcess.size()) {
1.269 - if (cancel.get())
1.270 - return;
1.271 - final AtomicBoolean stop = new AtomicBoolean();
1.272 -// JavaSource js = JavaSource.create(e.getKey(), f);
1.273 - JavaSource js = JavaSource.create(e.getKey(), toProcess.subList(currentPointer.get(), toProcess.size()));
1.274 -
1.275 - js.runUserActionTask(new Task<CompilationController>() {
1.276 - public void run(CompilationController parameter) throws Exception {
1.277 - if (stop.get()) return;
1.278 - if (cancel.get()) return;
1.279 -
1.280 - boolean cont = true;
1.281 -
1.282 - try {
1.283 - if (parameter.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0)
1.284 - return ;
1.285 -
1.286 - progress.setMessage("processing: " + FileUtil.getFileDisplayName(parameter.getFileObject()));
1.287 - Resource r = file2Resource.get(parameter.getFileObject());
1.288 -
1.289 - HintsSettings settings = r.settings;
1.290 - Iterable<? extends HintDescription> enabledHints;
1.291 -
1.292 - if (settings == null) {
1.293 - settings = HintsSettings.getSettingsFor(parameter.getFileObject());
1.294 - List<HintDescription> hintsCopy = new ArrayList<>();
1.295 - for (HintDescription hd : r.hints) {
1.296 - if (settings.isEnabled(hd.getMetadata())) {
1.297 - hintsCopy.add(hd);
1.298 - }
1.299 - }
1.300 - enabledHints = hintsCopy;
1.301 - } else {
1.302 - enabledHints = r.hints;
1.303 - }
1.304 -
1.305 - List<ErrorDescription> hints = new HintsInvoker(settings, gpc, new AtomicBoolean()).computeHints(parameter, r.hints, problems);
1.306 -
1.307 - assert hints != null;
1.308 -
1.309 - cont = callback.spansVerified(parameter, r, hints);
1.310 - } catch (ThreadDeath td) {
1.311 - throw td;
1.312 - } catch (Throwable t) {
1.313 - LOG.log(Level.INFO, "Exception while performing batch processing in " + FileUtil.getFileDisplayName(parameter.getFileObject()), t);
1.314 - problems.add(new MessageImpl(MessageKind.WARNING, "An exception occurred while processing file: " + FileUtil.getFileDisplayName(parameter.getFileObject()) + " (" + t.getLocalizedMessage() + ")."));
1.315 - }
1.316 -
1.317 - if (cont) {
1.318 - progress.tick();
1.319 - currentPointer.incrementAndGet();
1.320 - } else {
1.321 - stop.set(true);
1.322 - }
1.323 - }
1.324 - }, true);
1.325 - }
1.326 - } catch (IOException ex) {
1.327 - Exceptions.printStackTrace(ex);
1.328 - }
1.329 - }
1.330 -
1.331 - final Map<FileObject, List<Decision>> file2Decision = new HashMap<FileObject, List<Decision>>();
1.332 - for (List<Decision<?, ?>> decisions : gpc.decisions.values()) {
1.333 - for (Decision<?, ?> d : decisions) {
1.334 - if (d.makeDecision()) {
1.335 - List<Decision> fileDecisions = file2Decision.get(d.root.getFileObject());
1.336 -
1.337 - if (fileDecisions == null) {
1.338 - file2Decision.put(d.root.getFileObject(), fileDecisions = new ArrayList<Decision>());
1.339 - }
1.340 -
1.341 - fileDecisions.add(d);
1.342 - }
1.343 - }
1.344 - }
1.345 -
1.346 - Map<ClasspathInfo, Collection<FileObject>> cp2FilesAfterDecision = BatchUtilities.sortFiles(file2Decision.keySet());
1.347 -
1.348 - for (Entry<ClasspathInfo, Collection<FileObject>> e : cp2FilesAfterDecision.entrySet()) {
1.349 - JavaSource js = JavaSource.create(e.getKey(), e.getValue());
1.350 -
1.351 - try {
1.352 - js.runUserActionTask(new Task<CompilationController>() {
1.353 - @Override public void run(CompilationController parameter) throws Exception {
1.354 - if (parameter.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0)
1.355 - return ;
1.356 -
1.357 - Resource r = file2Resource.get(parameter.getFileObject());
1.358 -
1.359 - HintsSettings settings = r.settings;
1.360 -
1.361 - if (settings == null) {
1.362 - settings = HintsSettings.getSettingsFor(parameter.getFileObject());
1.363 - }
1.364 -
1.365 - for (Decision<?, ?> d : file2Decision.get(parameter.getFileObject())) {
1.366 - for (HintDescription hd : r.hints) {
1.367 - if (!(hd.getTrigger() instanceof DecisionTrigger)) continue;
1.368 - if (r.settings == null && !settings.isEnabled(hd.getMetadata())) continue;
1.369 - DecisionTrigger dt = (DecisionTrigger) hd.getTrigger();
1.370 - if (dt.getDecisionClass() != d.getClass()) continue;
1.371 - TreePath tp = d.root.resolve(parameter);
1.372 - HintContext ctx = SPIAccessor.getINSTANCE().createHintContext(parameter, settings, hd.getMetadata(), new GlobalProcessingContext(), tp, Collections.<String, TreePath>emptyMap(), Collections.<String, Collection<? extends TreePath>>emptyMap(), Collections.<String, String>emptyMap());
1.373 - ctx.decision = d;
1.374 - Collection<? extends ErrorDescription> errors = hd.getWorker().createErrors(ctx);
1.375 -
1.376 - if (errors != null) {
1.377 - callback.spansVerified(parameter, file2Resource.get(parameter.getFileObject()), errors);
1.378 - }
1.379 - }
1.380 - }
1.381 - }
1.382 - }, true);
1.383 - } catch (IOException ex) {
1.384 - Exceptions.printStackTrace(ex);
1.385 - }
1.386 - }
1.387 - } finally {
1.388 - callback.groupFinished();
1.389 -
1.390 - if (toRegister != null) {
1.391 - GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, toRegister);
1.392 - }
1.393 - progress.finish();
1.394 - }
1.395 - }
1.396 -
1.397 - public interface VerifiedSpansCallBack {
1.398 - public void groupStarted();
1.399 - public boolean spansVerified(CompilationController wc, Resource r, Collection<? extends ErrorDescription> hints) throws Exception;
1.400 - public void groupFinished();
1.401 - public void cannotVerifySpan(Resource r);
1.402 - }
1.403 -
1.404 -
1.405 - public static class Folder {
1.406 -
1.407 - private FileObject file;
1.408 - private NonRecursiveFolder folder;
1.409 -
1.410 - public Folder(FileObject file) {
1.411 - this.file = file;
1.412 - }
1.413 -
1.414 - public Folder(NonRecursiveFolder folder) {
1.415 - this.folder = folder;
1.416 - }
1.417 -
1.418 - public FileObject getFileObject() {
1.419 - if (file!=null) {
1.420 - return file;
1.421 - }
1.422 - return folder.getFolder();
1.423 -
1.424 - }
1.425 -
1.426 - private boolean isRecursive() {
1.427 - if (file!=null) {
1.428 - return file.isFolder();
1.429 - }
1.430 - return false;
1.431 - }
1.432 -
1.433 - public static Folder[] convert(FileObject... files) {
1.434 - Folder[] result = new Folder[files.length];
1.435 - for (int i=0;i<files.length;i++) {
1.436 - result[i] = new Folder(files[i]);
1.437 - }
1.438 - return result;
1.439 - }
1.440 -
1.441 - public static Folder[] convert(Collection list) {
1.442 - Folder[] result = new Folder[list.size()];
1.443 - int i=0;
1.444 - for (Object item:list) {
1.445 - if (item instanceof FileObject)
1.446 - result[i] = new Folder((FileObject) item);
1.447 - else
1.448 - result[i] = new Folder((NonRecursiveFolder) item);
1.449 - i++;
1.450 - }
1.451 - return result;
1.452 - }
1.453 -
1.454 - @Override
1.455 - public String toString() {
1.456 - return !isRecursive()?"Non":"" + "Recursive file " + getFileObject().getPath();
1.457 - }
1.458 -
1.459 -
1.460 - }
1.461 -
1.462 - public abstract static class Scope {
1.463 -
1.464 - public abstract String getDisplayName();
1.465 - public abstract Collection<? extends Folder> getTodo();
1.466 - public abstract MapIndices getIndexMapper(Iterable<? extends HintDescription> hints);
1.467 -
1.468 - }
1.469 -
1.470 - public static final class BatchResult {
1.471 -
1.472 - private final Map<? extends IndexEnquirer, ? extends Collection<? extends Resource>> projectId2Resources;
1.473 - private final Iterable<? extends HintDescription> patterns;
1.474 - public final Collection<? extends MessageImpl> problems;
1.475 -
1.476 - public BatchResult(Map<? extends IndexEnquirer, ? extends Collection<? extends Resource>> projectId2Resources, Iterable<? extends HintDescription> patterns, Collection<? extends MessageImpl> problems) {
1.477 - this.projectId2Resources = projectId2Resources;
1.478 - this.patterns = patterns;
1.479 - this.problems = problems;
1.480 - }
1.481 -
1.482 - public Collection<? extends Collection<? extends Resource>> getResources() {
1.483 - return projectId2Resources.values();
1.484 - }
1.485 -
1.486 - public Map<FileObject, Collection<? extends Resource>> getResourcesWithRoots() {
1.487 - Map<FileObject, Collection<? extends Resource>> result = new HashMap<FileObject, Collection<? extends Resource>>();
1.488 -
1.489 - for (Entry<? extends IndexEnquirer, ? extends Collection<? extends Resource>> e : projectId2Resources.entrySet()) {
1.490 - result.put(e.getKey().src, e.getValue());
1.491 - }
1.492 -
1.493 - return result;
1.494 - }
1.495 -
1.496 - public Iterable<? extends HintDescription> getPatterns() {
1.497 - return patterns;
1.498 - }
1.499 - }
1.500 -
1.501 - public static final class Resource {
1.502 - private final IndexEnquirer indexEnquirer;
1.503 - private final String relativePath;
1.504 - final Iterable<? extends HintDescription> hints;
1.505 - private final BulkPattern pattern;
1.506 - final HintsSettings settings;
1.507 -
1.508 - public Resource(IndexEnquirer indexEnquirer, String relativePath, Iterable<? extends HintDescription> hints, BulkPattern pattern, HintsSettings settings) {
1.509 - this.indexEnquirer = indexEnquirer;
1.510 - this.relativePath = relativePath;
1.511 - this.hints = hints;
1.512 - this.pattern = pattern;
1.513 - this.settings = settings;
1.514 - }
1.515 -
1.516 - public String getRelativePath() {
1.517 - return relativePath;
1.518 - }
1.519 -
1.520 - public Iterable<int[]> getCandidateSpans() {
1.521 - FileObject file = getResolvedFile();
1.522 - JavaSource js;
1.523 -
1.524 - if (file != null) {
1.525 - js = JavaSource.forFileObject(file);
1.526 - } else {
1.527 - CharSequence text = getSourceCode();
1.528 -
1.529 - if (text == null) {
1.530 - return null;
1.531 - }
1.532 -
1.533 - Writer out = null;
1.534 -
1.535 - try {
1.536 - file = FileUtil.createData(FileUtil.createMemoryFileSystem().getRoot(), relativePath);
1.537 - out = new OutputStreamWriter(file.getOutputStream());
1.538 -
1.539 - out.write(text.toString());
1.540 - } catch (IOException ex) {
1.541 - Exceptions.printStackTrace(ex);
1.542 - return null;
1.543 - } finally {
1.544 - if (out != null) {
1.545 - try {
1.546 - out.close();
1.547 - } catch (IOException ex) {
1.548 - Exceptions.printStackTrace(ex);
1.549 - }
1.550 - }
1.551 - }
1.552 -
1.553 - js = JavaSource.create(Utilities.createUniversalCPInfo(), file);
1.554 - }
1.555 -
1.556 - final List<int[]> span = new LinkedList<int[]>();
1.557 -
1.558 - try {
1.559 - js.runUserActionTask(new Task<CompilationController>() {
1.560 - public void run(CompilationController cc) throws Exception {
1.561 - cc.toPhase(Phase.PARSED);
1.562 -
1.563 - span.addAll(doComputeSpans(cc));
1.564 - }
1.565 - }, true);
1.566 - } catch (IOException ex) {
1.567 - Exceptions.printStackTrace(ex);
1.568 - }
1.569 -
1.570 - return span;
1.571 - }
1.572 -
1.573 - private Collection<int[]> doComputeSpans(CompilationInfo ci) {
1.574 - Collection<int[]> result = new LinkedList<int[]>();
1.575 - Map<String, Collection<TreePath>> found = BulkSearch.getDefault().match(ci, new AtomicBoolean(), new TreePath(ci.getCompilationUnit()), pattern);
1.576 -
1.577 - for (Entry<String, Collection<TreePath>> e : found.entrySet()) {
1.578 - Tree treePattern = Utilities.parseAndAttribute(ci, e.getKey(), null);
1.579 -
1.580 - for (TreePath tp : e.getValue()) {
1.581 - //XXX: this pass will not be performed on the web!!!
1.582 - if ( BulkSearch.getDefault().requiresLightweightVerification()
1.583 - && !Matcher.create(ci).setCancel(new AtomicBoolean()).setSearchRoot(tp).setTreeTopSearch().setUntypedMatching().match(Pattern.createSimplePattern(new TreePath(new TreePath(ci.getCompilationUnit()), treePattern))).iterator().hasNext()) {
1.584 - continue;
1.585 - }
1.586 - int[] span = new int[] {
1.587 - (int) ci.getTrees().getSourcePositions().getStartPosition(ci.getCompilationUnit(), tp.getLeaf()),
1.588 - (int) ci.getTrees().getSourcePositions().getEndPosition(ci.getCompilationUnit(), tp.getLeaf())
1.589 - };
1.590 -
1.591 - result.add(span);
1.592 - }
1.593 - }
1.594 -
1.595 - return result;
1.596 - }
1.597 -
1.598 - public FileObject getResolvedFile() {
1.599 - return indexEnquirer.src.getFileObject(relativePath);
1.600 - }
1.601 -
1.602 - public String getDisplayName() {
1.603 - FileObject file = getResolvedFile();
1.604 -
1.605 - if (file != null) {
1.606 - return FileUtil.getFileDisplayName(file);
1.607 - } else {
1.608 - return relativePath; //TODO:+container
1.609 - }
1.610 - }
1.611 -
1.612 - public CharSequence getSourceCode() {
1.613 - try {
1.614 - FileObject file = getResolvedFile();
1.615 - ByteBuffer bb = ByteBuffer.wrap(file.asBytes());
1.616 -
1.617 - return FileEncodingQuery.getEncoding(file).decode(bb);
1.618 - } catch (IOException ex) {
1.619 - Exceptions.printStackTrace(ex);
1.620 - return null;
1.621 - }
1.622 - }
1.623 -
1.624 - public FileObject getRoot() {
1.625 - return indexEnquirer.src;
1.626 - }
1.627 - }
1.628 -
1.629 - public static interface MapIndices {
1.630 - public IndexEnquirer findIndex(FileObject root, ProgressHandleWrapper progress, boolean recursive);
1.631 - }
1.632 -
1.633 - public static abstract class IndexEnquirer {
1.634 - final FileObject src;
1.635 - public IndexEnquirer(FileObject src) {
1.636 - this.src = src;
1.637 - }
1.638 - public abstract Collection<? extends Resource> findResources(Iterable<? extends HintDescription> hints, ProgressHandleWrapper progress, @NullAllowed Callable<BulkPattern> bulkPattern, Collection<? super MessageImpl> problems, HintsSettings settingsProvider);
1.639 - public abstract void validateResource(Collection<? extends Resource> resources, ProgressHandleWrapper progress, VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, Collection<? super MessageImpl> problems, AtomicBoolean cancel);
1.640 -// public int[] getEstimatedSpan(Resource r);
1.641 - }
1.642 -
1.643 - public static abstract class LocalIndexEnquirer extends IndexEnquirer {
1.644 - public LocalIndexEnquirer(FileObject src) {
1.645 - super(src);
1.646 - }
1.647 - public void validateResource(Collection<? extends Resource> resources, ProgressHandleWrapper progress, VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, Collection<? super MessageImpl> problems, AtomicBoolean cancel) {
1.648 - getLocalVerifiedSpans(resources, progress, callback, doNotRegisterClassPath, problems, cancel);
1.649 - }
1.650 - }
1.651 -
1.652 - public static final class FileSystemBasedIndexEnquirer extends LocalIndexEnquirer {
1.653 - private boolean recursive;
1.654 - public FileSystemBasedIndexEnquirer(FileObject src, boolean recursive) {
1.655 - super(src);
1.656 - this.recursive = recursive;
1.657 - }
1.658 - public Collection<? extends Resource> findResources(final Iterable<? extends HintDescription> hints, ProgressHandleWrapper progress, final @NullAllowed Callable<BulkPattern> bulkPattern, final Collection<? super MessageImpl> problems, final HintsSettings settingsProvider) {
1.659 - Collection<FileObject> files = new LinkedList<FileObject>();
1.660 -
1.661 - final ProgressHandleWrapper innerProgress = progress.startNextPartWithEmbedding(30, 70);
1.662 -
1.663 - BatchUtilities.recursive(src, src, files, innerProgress, 0, null, null, recursive);
1.664 -
1.665 - LOG.log(Level.FINE, "files: {0}", files);
1.666 -
1.667 - innerProgress.startNextPart(files.size());
1.668 -
1.669 - final Collection<Resource> result = new ArrayList<Resource>();
1.670 -
1.671 - if (!files.isEmpty()) {
1.672 - try {
1.673 - if (bulkPattern != null) {
1.674 - long start = System.currentTimeMillis();
1.675 -
1.676 - JavaSource.create(Utilities.createUniversalCPInfo(), files).runUserActionTask(new Task<CompilationController>() {
1.677 - public void run(CompilationController cc) throws Exception {
1.678 - if (cc.toPhase(Phase.PARSED).compareTo(Phase.PARSED) <0) {
1.679 - return ;
1.680 - }
1.681 -
1.682 - try {
1.683 - boolean matches = BulkSearch.getDefault().matches(cc, new AtomicBoolean(), new TreePath(cc.getCompilationUnit()), bulkPattern.call());
1.684 -
1.685 - if (matches) {
1.686 - result.add(new Resource(FileSystemBasedIndexEnquirer.this, FileUtil.getRelativePath(src, cc.getFileObject()), hints, bulkPattern.call(), settingsProvider));
1.687 - }
1.688 - } catch (ThreadDeath td) {
1.689 - throw td;
1.690 - } catch (Throwable t) {
1.691 - LOG.log(Level.INFO, "Exception while performing batch search in " + FileUtil.getFileDisplayName(cc.getFileObject()), t);
1.692 - problems.add(new MessageImpl(MessageKind.WARNING, "An exception occurred while testing file: " + FileUtil.getFileDisplayName(cc.getFileObject()) + " (" + t.getLocalizedMessage() + ")."));
1.693 - }
1.694 -
1.695 - innerProgress.tick();
1.696 - }
1.697 - }, true);
1.698 -
1.699 - long end = System.currentTimeMillis();
1.700 -
1.701 - LOG.log(Level.FINE, "took: {0}, per file: {1}", new Object[]{end - start, (end - start) / files.size()});
1.702 - } else {
1.703 - for (FileObject file : files) {
1.704 - result.add(new Resource(this, FileUtil.getRelativePath(src, file), hints, null, settingsProvider));
1.705 - }
1.706 - }
1.707 - } catch (IOException ex) {
1.708 - Exceptions.printStackTrace(ex);
1.709 - }
1.710 - }
1.711 -
1.712 - return result;
1.713 - }
1.714 -
1.715 - }
1.716 -
1.717 -}