JavaParameters migrated to new api (IDEA-55925 fixed), special order processing for maven implemented

This commit is contained in:
nik
2010-06-29 12:02:40 +04:00
parent 6352d39e36
commit 11d962a5a3
10 changed files with 228 additions and 123 deletions
@@ -18,13 +18,11 @@ package com.intellij.execution.configurations;
import com.intellij.execution.CantRunException;
import com.intellij.execution.ExecutionBundle;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ProjectClasspathTraversing;
import com.intellij.openapi.roots.ProjectRootsTraversing;
import com.intellij.openapi.roots.OrderEnumerator;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
@@ -66,7 +64,7 @@ public class JavaParameters extends SimpleJavaParameters {
}
setDefaultCharset(module.getProject());
ProjectRootsTraversing.collectRoots(module, getPolicy(null, module, classPathType), getClassPath());
configureEnumerator(OrderEnumerator.orderEntries(module).runtimeOnly().recursively(), classPathType).collectPaths(getClassPath());
}
public void setDefaultCharset(final Project project) {
@@ -104,22 +102,16 @@ public class JavaParameters extends SimpleJavaParameters {
return;
}
ProjectRootsTraversing.collectRoots(project, getPolicy(project, null, classPathType), getClassPath());
configureEnumerator(OrderEnumerator.orderEntries(project).runtimeOnly(), classPathType).collectPaths(getClassPath());
}
private ProjectRootsTraversing.RootTraversePolicy getPolicy(Project project, Module module, int classPathType) {
ProjectRootsTraversing.RootTraversePolicy result = (classPathType & TESTS_ONLY) != 0
? (classPathType & JDK_ONLY) != 0 ? ProjectClasspathTraversing.FULL_CLASSPATH_RECURSIVE : ProjectClasspathTraversing.FULL_CLASS_RECURSIVE_WO_JDK
: (classPathType & JDK_ONLY) != 0 ? ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_TESTS : ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_JDK_AND_TESTS;
for (JavaClasspathPolicyExtender each : Extensions.getExtensions(JavaClasspathPolicyExtender.EP_NAME)) {
if (project == null) {
result = each.extend(module, result);
}
else {
result = each.extend(project, result);
}
private static OrderEnumerator configureEnumerator(OrderEnumerator enumerator, int classPathType) {
if ((classPathType & JDK_ONLY) == 0) {
enumerator = enumerator.withoutSdk();
}
return result;
if ((classPathType & TESTS_ONLY) == 0) {
enumerator = enumerator.productionOnly();
}
return enumerator;
}
}
@@ -0,0 +1,43 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.roots;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author nik
*/
public abstract class OrderEnumerationHandler {
public static final ExtensionPointName<OrderEnumerationHandler> EP_NAME = ExtensionPointName.create("com.intellij.orderEnumerationHandler");
public abstract boolean isApplicable(@NotNull Project project);
public abstract boolean isApplicable(@NotNull Module module);
public boolean shouldProcessRecursively(@NotNull ModuleOrderEntry dependency) {
return true;
}
public boolean addCustomOutput(@NotNull ModuleOrderEntry orderEntry, boolean productionOnly, @NotNull List<VirtualFile> result) {
return false;
}
}
@@ -27,6 +27,7 @@ public class ModuleOrderEnumerator extends OrderEnumeratorBase {
private final RootModelImpl myRootModel;
public ModuleOrderEnumerator(RootModelImpl rootModel) {
super(rootModel.getModule(), rootModel.getProject());
myRootModel = rootModel;
}
@@ -16,12 +16,16 @@
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.PathsList;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -40,6 +44,18 @@ public abstract class OrderEnumeratorBase extends OrderEnumerator {
private boolean myRecursivelyExportedOnly;
private boolean myExportedOnly;
private Condition<OrderEntry> myCondition;
private List<OrderEnumerationHandler> myCustomHandlers;
public OrderEnumeratorBase(@Nullable Module module, @NotNull Project project) {
for (OrderEnumerationHandler handler : OrderEnumerationHandler.EP_NAME.getExtensions()) {
if (handler.isApplicable(project) && (module == null || handler.isApplicable(module))) {
if (myCustomHandlers == null) {
myCustomHandlers = new SmartList<OrderEnumerationHandler>();
}
myCustomHandlers.add(handler);
}
}
}
@Override
public OrderEnumerator productionOnly() {
@@ -148,12 +164,21 @@ public abstract class OrderEnumeratorBase extends OrderEnumerator {
forEach(new Processor<OrderEntry>() {
@Override
public boolean process(OrderEntry orderEntry) {
final Module ownerModule = orderEntry.getOwnerModule();
if (orderEntry instanceof ModuleSourceOrderEntry) {
collectModulePaths(((ModuleSourceOrderEntry)orderEntry).getRootModel(), list, collectSources);
}
else if (orderEntry instanceof ModuleOrderEntry) {
final Module module = ((ModuleOrderEntry)orderEntry).getModule();
ModuleOrderEntry moduleOrderEntry = (ModuleOrderEntry)orderEntry;
final Module module = moduleOrderEntry.getModule();
if (module != null) {
if (myCustomHandlers != null) {
for (OrderEnumerationHandler handler : myCustomHandlers) {
if (handler.addCustomOutput(moduleOrderEntry, myProductionOnly, list)) {
return true;
}
}
}
collectModulePaths(ModuleRootManager.getInstance(module), list, collectSources);
}
}
@@ -179,9 +204,13 @@ public abstract class OrderEnumeratorBase extends OrderEnumerator {
if (entry instanceof ExportableOrderEntry) {
ExportableOrderEntry exportableEntry = (ExportableOrderEntry)entry;
final DependencyScope scope = exportableEntry.getScope();
if (myProductionOnly && !scope.isForProductionCompile() && !scope.isForProductionRuntime()) continue;
if (myCompileOnly && !scope.isForProductionCompile() && !scope.isForTestCompile()) continue;
if (myRuntimeOnly && !scope.isForProductionRuntime() && !scope.isForTestRuntime()) continue;
if (myProductionOnly) {
if (!scope.isForProductionCompile() && !scope.isForProductionRuntime()
|| myCompileOnly && !scope.isForProductionCompile()
|| myRuntimeOnly && !scope.isForProductionRuntime()) continue;
}
if (!exportableEntry.isExported()) {
if (myExportedOnly) continue;
if (myRecursivelyExportedOnly && !firstLevel) continue;
@@ -191,10 +220,23 @@ public abstract class OrderEnumeratorBase extends OrderEnumerator {
if (myCondition != null && !myCondition.value(entry)) continue;
if (myRecursively && entry instanceof ModuleOrderEntry) {
final Module module = ((ModuleOrderEntry)entry).getModule();
ModuleOrderEntry moduleOrderEntry = (ModuleOrderEntry)entry;
final Module module = moduleOrderEntry.getModule();
if (module != null) {
processEntries(ModuleRootManager.getInstance(module), processor, processed, false);
continue;
boolean processRecursively = true;
if (myCustomHandlers != null) {
for (OrderEnumerationHandler handler : myCustomHandlers) {
if (!handler.shouldProcessRecursively(moduleOrderEntry)) {
processRecursively = false;
break;
}
}
}
if (processRecursively) {
processEntries(ModuleRootManager.getInstance(module), processor, processed, false);
continue;
}
}
}
@@ -30,6 +30,7 @@ public class ProjectOrderEnumerator extends OrderEnumeratorBase {
private Project myProject;
public ProjectOrderEnumerator(Project project) {
super(null, project);
myProject = project;
}
@@ -142,6 +142,7 @@
<extensionPoint name="roots.watchedRootsProvider" interface="com.intellij.openapi.roots.WatchedRootsProvider" area="IDEA_PROJECT"/>
<extensionPoint name="moduleExtension" interface="com.intellij.openapi.roots.ModuleExtension" area="IDEA_MODULE"/>
<extensionPoint name="orderRootType" interface="com.intellij.openapi.roots.OrderRootType"/>
<extensionPoint name="orderEnumerationHandler" interface="com.intellij.openapi.roots.OrderEnumerationHandler"/>
<extensionPoint name="directoryIndexExcludePolicy" interface="com.intellij.openapi.roots.impl.DirectoryIndexExcludePolicy"
area="IDEA_PROJECT"/>
@@ -1,98 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.maven.execution;
import com.intellij.execution.configurations.JavaClasspathPolicyExtender;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.model.MavenArtifact;
import org.jetbrains.idea.maven.model.MavenConstants;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import java.util.Collections;
public class MavenJavaClasspathPolicyExtender implements JavaClasspathPolicyExtender {
@NotNull
public ProjectRootsTraversing.RootTraversePolicy extend(Project project, @NotNull ProjectRootsTraversing.RootTraversePolicy policy) {
return policy;
}
@NotNull
public ProjectRootsTraversing.RootTraversePolicy extend(final Module module, @NotNull ProjectRootsTraversing.RootTraversePolicy policy) {
Project project = module.getProject();
final MavenProjectsManager manager = MavenProjectsManager.getInstance(project);
if (!manager.isMavenizedProject() || !manager.isMavenizedModule(module)) return policy;
return new ProjectRootsTraversing.RootTraversePolicy(extend(module, manager, policy.getVisitSource(), false),
policy.getVisitJdk(),
extend(module, manager, policy.getVisitLibrary(), true),
extend(module, manager, policy.getVisitModule(), true));
}
private <T extends OrderEntry> ProjectRootsTraversing.RootTraversePolicy.Visit<T> extend(
final Module originalModule,
final MavenProjectsManager manager,
final ProjectRootsTraversing.RootTraversePolicy.Visit<T> original,
final boolean skipDependencyModules) {
return new ProjectRootsTraversing.RootTraversePolicy.Visit<T>() {
public void visit(T entry, ProjectRootsTraversing.TraverseState state, RootPolicy<ProjectRootsTraversing.TraverseState> policy) {
Module ownerModule = entry.getOwnerModule();
if (skipDependencyModules && originalModule != ownerModule) return;
if (originalModule != ownerModule && entry instanceof ModuleSourceOrderEntry) {
MavenProject project = manager.findProject(originalModule);
MavenProject depProject = manager.findProject(ownerModule);
if (project == null || depProject == null) {
original.visit(entry, state, policy);
return;
}
for (MavenArtifact each : project.findDependencies(depProject)) {
boolean isTestClasspath = original == ProjectClasspathTraversing.ALL_OUTPUTS;
if (!isTestClasspath && MavenConstants.SCOPE_PROVIDEED.equals(each.getScope())) continue;
if (isTestClasspath || !MavenConstants.SCOPE_TEST.equals(each.getScope())) {
boolean isTestJar = MavenConstants.TYPE_TEST_JAR.equals(each.getType()) || "tests".equals(each.getClassifier());
addOutput(ownerModule, isTestJar, state);
}
}
}
else {
// should be in some generic place
if (entry instanceof ExportableOrderEntry) {
boolean isTestClasspath = original == ProjectRootsTraversing.RootTraversePolicy.ADD_CLASSES
|| original == ProjectRootsTraversing.RootTraversePolicy.RECURSIVE;
if (!isTestClasspath && ((ExportableOrderEntry)entry).getScope() == DependencyScope.PROVIDED) return;
}
original.visit(entry, state, policy);
}
}
};
}
public void addOutput(Module module, boolean tests, ProjectRootsTraversing.TraverseState state) {
CompilerModuleExtension ex = CompilerModuleExtension.getInstance(module);
if (ex == null) return;
String output = tests ? ex.getCompilerOutputUrlForTests() : ex.getCompilerOutputUrl();
if (output != null) state.addAllUrls(Collections.singletonList(output));
}
}
@@ -0,0 +1,87 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.maven.execution;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.roots.ModuleOrderEntry;
import com.intellij.openapi.roots.OrderEnumerationHandler;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.model.MavenArtifact;
import org.jetbrains.idea.maven.model.MavenConstants;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import java.util.List;
/**
* @author nik
*/
public class MavenOrderEnumeratorHandler extends OrderEnumerationHandler {
@Override
public boolean isApplicable(@NotNull Project project) {
return MavenProjectsManager.getInstance(project).isMavenizedProject();
}
@Override
public boolean isApplicable(@NotNull Module module) {
final MavenProjectsManager manager = MavenProjectsManager.getInstance(module.getProject());
return manager.isMavenizedModule(module);
}
@Override
public boolean shouldProcessRecursively(@NotNull ModuleOrderEntry dependency) {
return false;
}
@Override
public boolean addCustomOutput(@NotNull ModuleOrderEntry orderEntry,
boolean productionOnly,
@NotNull List<VirtualFile> result) {
final Module ownerModule = orderEntry.getOwnerModule();
final Module depModule = orderEntry.getModule();
if (depModule == null) return false;
final MavenProjectsManager manager = MavenProjectsManager.getInstance(ownerModule.getProject());
MavenProject project = manager.findProject(ownerModule);
MavenProject depProject = manager.findProject(depModule);
if (project == null || depProject == null) {
return false;
}
for (MavenArtifact each : project.findDependencies(depProject)) {
if (productionOnly && MavenConstants.SCOPE_PROVIDEED.equals(each.getScope())) continue;
if (productionOnly && MavenConstants.SCOPE_TEST.equals(each.getScope())) continue;
boolean isTestJar = MavenConstants.TYPE_TEST_JAR.equals(each.getType()) || "tests".equals(each.getClassifier());
addOutput(depModule, isTestJar, result);
}
return true;
}
private static void addOutput(Module module, boolean tests, List<VirtualFile> result) {
CompilerModuleExtension ex = CompilerModuleExtension.getInstance(module);
if (ex == null) return;
VirtualFile output = tests ? ex.getCompilerOutputPathForTests() : ex.getCompilerOutputPath();
if (output != null) {
result.add(output);
}
}
}
@@ -30,7 +30,7 @@
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
<configurationType implementation="org.jetbrains.idea.maven.execution.MavenRunConfigurationType"/>
<configurationProducer implementation="org.jetbrains.idea.maven.execution.MavenConfigurationProducer"/>
<javaClasspathPolicyExtender implementation="org.jetbrains.idea.maven.execution.MavenJavaClasspathPolicyExtender"/>
<orderEnumerationHandler implementation="org.jetbrains.idea.maven.execution.MavenOrderEnumeratorHandler"/>
<compiler implementation="org.jetbrains.idea.maven.compiler.MavenResourceCompiler" order="last"/>
@@ -18,17 +18,22 @@ package org.jetbrains.idea.maven.execution;
import com.intellij.execution.CantRunException;
import com.intellij.execution.configurations.JavaParameters;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.MavenImportingTestCase;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -304,6 +309,7 @@ public class JavaClasspathConfigurationTest extends MavenImportingTestCase {
}
public void testOptionalLibraryDependencies() throws Exception {
createRepositoryFile("jmock/jmock/1.0/jmock-1.0.jar");
VirtualFile m1 = createModulePom("m1", "<groupId>test</groupId>" +
"<artifactId>m1</artifactId>" +
"<version>1</version>" +
@@ -419,6 +425,7 @@ public class JavaClasspathConfigurationTest extends MavenImportingTestCase {
}
public void testDoNotIncludeProvidedAndTestDependenciesInProductionClasspath() throws Exception {
createRepositoryFile("jmock/jmock/4.0/jmock-4.0.jar");
VirtualFile m1 = createModulePom("m1", "<groupId>test</groupId>" +
"<artifactId>m1</artifactId>" +
"<version>1</version>" +
@@ -479,6 +486,7 @@ public class JavaClasspathConfigurationTest extends MavenImportingTestCase {
}
public void testDoNotIncludeProvidedAndTestTransitiveDependencies() throws Exception {
createRepositoryFile("jmock/jmock/1.0/jmock-1.0.jar");
VirtualFile m1 = createModulePom("m1", "<groupId>test</groupId>" +
"<artifactId>m1</artifactId>" +
"<version>1</version>" +
@@ -604,6 +612,7 @@ public class JavaClasspathConfigurationTest extends MavenImportingTestCase {
}
private void assertModuleClasspath(String moduleName, int classpathType, String... paths) throws CantRunException {
createOutputDirectories();
JavaParameters params = new JavaParameters();
params.configureByModule(getModule(moduleName), classpathType);
List<String> systemPaths = new ArrayList<String>();
@@ -612,4 +621,31 @@ public class JavaClasspathConfigurationTest extends MavenImportingTestCase {
}
assertOrderedElementsAreEqual(params.getClassPath().getPathList(), systemPaths);
}
private void createRepositoryFile(String filePath) throws IOException {
createProjectSubFile("repo/" + filePath);
setRepositoryPath(createProjectSubDir("repo").getPath());
}
private void createOutputDirectories() {
for (Module module : ModuleManager.getInstance(myProject).getModules()) {
final CompilerModuleExtension extension = CompilerModuleExtension.getInstance(module);
if (extension != null) {
createDirectoryIfDoesntExist(extension.getCompilerOutputUrl());
createDirectoryIfDoesntExist(extension.getCompilerOutputUrlForTests());
}
}
}
private static void createDirectoryIfDoesntExist(@Nullable String url) {
if (StringUtil.isEmpty(url)) return;
File file = new File(FileUtil.toSystemDependentName(VfsUtil.urlToPath(url)));
if (file.exists()) return;
if (!file.mkdirs()) {
fail("Cannot create directory " + file);
}
VirtualFileManager.getInstance().refreshAndFindFileByUrl(url);
}
}