diff --git a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/RuleEntryParams.java b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/RuleEntryParams.java index beb9829..0e01e76 100644 --- a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/RuleEntryParams.java +++ b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/RuleEntryParams.java @@ -2,25 +2,29 @@ import static java.lang.String.format; +import java.util.ArrayList; import java.util.List; import java.util.Map; public class RuleEntryParams { - + private final String projectName; private final String query; private final int location; private final String analysisMode; + private final ArrayList includedPaths; public RuleEntryParams(final String commandId, final List arguments) { @SuppressWarnings("unchecked") Map obj = (Map) arguments.stream().findFirst() - .orElseThrow(() -> new UnsupportedOperationException(format("Command '%s' must be called with one rule entry argument!", commandId))); + .orElseThrow(() -> new UnsupportedOperationException( + format("Command '%s' must be called with one rule entry argument!", commandId))); this.projectName = (String) obj.get("project"); this.query = (String) obj.get("query"); this.location = Integer.parseInt((String) obj.get("location")); this.analysisMode = (String) obj.get("analysisMode"); + this.includedPaths = (ArrayList) obj.get("includedPaths"); } public String getProjectName() { @@ -39,4 +43,7 @@ public String getAnalysisMode() { return analysisMode; } + public ArrayList getIncludedPaths() { + return includedPaths; + } } diff --git a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/SampleDelegateCommandHandler.java b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/SampleDelegateCommandHandler.java index 7d2d96e..9a7a055 100644 --- a/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/SampleDelegateCommandHandler.java +++ b/java-analyzer-bundle.core/src/main/java/io/konveyor/tackle/core/internal/SampleDelegateCommandHandler.java @@ -4,10 +4,19 @@ import static org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin.logInfo; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.io.File; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.core.search.SearchEngine; @@ -37,7 +46,7 @@ public Object executeCommand(String commandId, List arguments, IProgress case RULE_ENTRY_COMMAND_ID: logInfo("Here we get the arguments for rule entry: "+arguments); RuleEntryParams params = new RuleEntryParams(commandId, arguments); - return search(params.getProjectName(), params.getQuery(), params.getLocation(), params.getAnalysisMode(), progress); + return search(params.getProjectName(), params.getIncludedPaths(), params.getQuery(), params.getLocation(), params.getAnalysisMode(), progress); default: throw new UnsupportedOperationException(format("Unsupported command '%s'!", commandId)); } @@ -137,9 +146,7 @@ private static SearchPattern getPatternSingleQuery(int location, String query) t throw new Exception("unable to create search pattern"); } - private static List search(String projectName, String query, int location, String analsysisMode, IProgressMonitor monitor) throws Exception { - //IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); - + private static List search(String projectName, ArrayList includedPaths, String query, int location, String analsysisMode, IProgressMonitor monitor) throws Exception { IJavaProject[] targetProjects; IJavaProject project = ProjectUtils.getJavaProject(projectName); if (project != null) { @@ -167,7 +174,43 @@ private static List search(String projectName, String query, logInfo("for project: " + iJavaProject + " found errors: " + errors + " warnings: " + warnings); } - IJavaSearchScope scope = SearchEngine.createJavaSearchScope(targetProjects, s); + IJavaSearchScope scope; + if (includedPaths != null && includedPaths.size() > 0) { + ArrayList includedFragments = new ArrayList(); + for (IJavaProject proj : targetProjects) { + for (IPackageFragment fragment : proj.getPackageFragments()) { + IPath fragmentPath = fragment.getPath(); + // if there's no file extension, it's a path to java package from source + // else it is a path pointing to jar, ear, etc. we ignore deps for now + if (fragmentPath.getFileExtension() == null) { + // fragment paths are not actual filesystem paths + // they are of form //src/main/java + // we can only compare the relative path + fragmentPath = fragmentPath.removeFirstSegments(1); + for (String includedPath : includedPaths) { + IPath includedIPath = Path.fromOSString(includedPath); + // when there are more than one sub-projects, the paths are of form + // /src/main/java/ + if (includedPath.startsWith(proj.getElementName())) { + includedIPath = includedIPath.removeFirstSegments(1); + } + // instead of comparing path strings, comparing segments is better for 2 reasons: + // - we don't have to worry about redundant . / etc in input + // - matching sub-trees is easier with segments than strings + if (includedIPath.segmentCount() <= fragmentPath.segmentCount() && + includedIPath.matchingFirstSegments(fragmentPath) == includedIPath.segmentCount()) { + includedFragments.add(fragment); + } + } + } + } + } + IJavaElement[] includedElements = new IJavaElement[includedFragments.size()]; + includedElements = includedFragments.toArray(includedElements); + scope = SearchEngine.createJavaSearchScope(true, includedElements, s); + } else { + scope = SearchEngine.createJavaSearchScope(true, targetProjects, s); + } logInfo("scope: " + scope);