package org.netbeans.gradle.project.query; import java.io.File; import java.net.URL; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.netbeans.api.java.queries.SourceForBinaryQuery; import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation2; import org.openide.filesystems.FileUtil; public abstract class AbstractSourceForBinaryQuery implements SourceForBinaryQueryImplementation2 { // This cache cannot shrink because SourceForBinaryQueryImplementation // requires that we return the exact same object when the same URL is // querried. This is a very limiting constraint but I don't want to risk to // violate the constraint. private final ConcurrentMap<File, Result> cache; public AbstractSourceForBinaryQuery() { this.cache = new ConcurrentHashMap<>(); } // TODO: Instead of protected methods, they should be provided as an argument. protected File normalizeBinaryPath(File binaryRoot) { return binaryRoot; } protected abstract Result tryFindSourceRoot(File binaryRoot); @Override public final Result findSourceRoots2(URL binaryRoot) { File binaryRootFile = FileUtil.archiveOrDirForURL(binaryRoot); if (binaryRootFile == null) { return null; } File normBinaryRoot = normalizeBinaryPath(binaryRootFile); if (normBinaryRoot == null) { return null; } Result result = cache.get(normBinaryRoot); if (result != null) { return result; } result = tryFindSourceRoot(normBinaryRoot); if (result == null) { return null; } Result oldResult = cache.putIfAbsent(normBinaryRoot, result); return oldResult != null ? oldResult : result; } @Override public final SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) { return findSourceRoots2(binaryRoot); } }