mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-53476 Gradle integration (Maven's level - dependencies, modules, repositories)
1. IJ modules are properly configured on importing from gradle now; 2. Module path received from the gradle api are checked now to be compatible with the content root; 3. 'Project icon' is displayed during importing project from gradle; 4. Improved error notification;
This commit is contained in:
@@ -4,11 +4,9 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.util.containers.ConcurrentFactoryMap;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.lang.reflect.*;
|
||||
import java.rmi.Remote;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -137,4 +135,24 @@ public class RemoteUtil {
|
||||
thread.setContextClassLoader(prev);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* There is a possible case that remotely called code throws exception during processing. That exception is wrapped at different
|
||||
* levels then - {@link InvocationTargetException}, {@link UndeclaredThrowableException} etc.
|
||||
* <p/>
|
||||
* This method tries to extract the 'real exception' from the given potentially wrapped one.
|
||||
*
|
||||
* @param e exception to process
|
||||
* @return extracted 'real exception' if any; given exception otherwise
|
||||
*/
|
||||
@NotNull
|
||||
public static Throwable unwrap(@NotNull Throwable e) {
|
||||
for (Throwable candidate = e; candidate != null; candidate = candidate.getCause()) {
|
||||
Class<? extends Throwable> clazz = candidate.getClass();
|
||||
if (clazz != InvocationTargetException.class && clazz != UndeclaredThrowableException.class) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,14 @@ gradle.import.structure.settings.label.name=Name:
|
||||
gradle.import.structure.settings.label.language.level=Language level:
|
||||
|
||||
gradle.import.title.error.resolve.generic=Resolve error
|
||||
gradle.import.text.error.resolve.generic=Can't resolve target gradle project at '{0}'
|
||||
gradle.import.text.error.resolve.generic.without.reason=Can''t resolve target gradle project at ''{0}''
|
||||
gradle.import.text.error.resolve.generic.with.reason=Can''t resolve target gradle project at ''{0}''.\nReason: {1}
|
||||
gradle.import.text.error.project.undefined=No project file is defined
|
||||
gradle.import.text.error.directory.instead.file=Given path points to directory instead of gradle build file
|
||||
gradle.import.text.error.invalid.path=Can't resolve gradle project. Reason: given path ({0}) doesn't point to a file
|
||||
gradle.import.text.error.cannot.parse.project=Can not parse gradle project
|
||||
gradle.import.text.error.undefined.name=Name is undefined
|
||||
|
||||
gradle.library.resolve.progress.text=Resolving gradle libraries
|
||||
|
||||
gradle.generic.text.error.sdk.undefined=Gradle installation is unknown
|
||||
+203
-13
@@ -1,12 +1,20 @@
|
||||
package org.jetbrains.plugins.gradle.importing;
|
||||
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.module.ModifiableModuleModel;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.module.StdModuleTypes;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.containers.hash.HashMap;
|
||||
@@ -14,6 +22,9 @@ import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.gradle.importing.model.*;
|
||||
import org.jetbrains.plugins.gradle.remote.GradleApiFacadeManager;
|
||||
import org.jetbrains.plugins.gradle.remote.GradleProjectResolver;
|
||||
import org.jetbrains.plugins.gradle.util.GradleBundle;
|
||||
import org.jetbrains.plugins.gradle.util.GradleLog;
|
||||
|
||||
import java.io.File;
|
||||
@@ -42,27 +53,28 @@ public class GradleModulesImporter {
|
||||
/**
|
||||
* Entry point for the whole 'import modules' procedure.
|
||||
*
|
||||
* @param modules module info containers received from the gradle api
|
||||
* @param project project that should host the modules
|
||||
* @param model modules model
|
||||
* @return mappings between the given gradle modules and newly created intellij modules
|
||||
* @param modules module info containers received from the gradle api
|
||||
* @param project project that should host the modules
|
||||
* @param model modules model
|
||||
* @param gradleProjectPath file system path to the gradle project file being imported
|
||||
* @return mappings between the given gradle modules and newly created intellij modules
|
||||
*/
|
||||
@NotNull
|
||||
public Map<GradleModule, Module> importModules(@NotNull final Iterable<GradleModule> modules, @Nullable final Project project,
|
||||
@Nullable final ModifiableModuleModel model)
|
||||
@Nullable final ModifiableModuleModel model, @NotNull String gradleProjectPath)
|
||||
{
|
||||
if (project == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
removeExistingModulesSettings(modules);
|
||||
if (!project.isInitialized()) {
|
||||
myAlarm.addRequest(new ImportModulesTask(project, modules), PROJECT_INITIALISATION_DELAY_MS);
|
||||
myAlarm.addRequest(new ImportModulesTask(project, modules, gradleProjectPath), PROJECT_INITIALISATION_DELAY_MS);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
if (model == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return importModules(modules, model);
|
||||
return importModules(modules, model, project, gradleProjectPath);
|
||||
}
|
||||
|
||||
private static void removeExistingModulesSettings(@NotNull Iterable<GradleModule> modules) {
|
||||
@@ -80,7 +92,9 @@ public class GradleModulesImporter {
|
||||
}
|
||||
|
||||
public Map<GradleModule, Module> importModules(@NotNull final Iterable<GradleModule> modules,
|
||||
@NotNull final ModifiableModuleModel model)
|
||||
@NotNull final ModifiableModuleModel model,
|
||||
@NotNull final Project intellijProject,
|
||||
@NotNull final String gradleProjectPath)
|
||||
{
|
||||
final Map<GradleModule, Module> result = new HashMap<GradleModule, Module>();
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@@ -90,7 +104,13 @@ public class GradleModulesImporter {
|
||||
AccessToken writeLock = application.acquireWriteActionLock(getClass());
|
||||
try {
|
||||
try {
|
||||
result.putAll(doImportModules(modules, model));
|
||||
Map<GradleModule, Module> moduleMappings = doImportModules(modules, model);
|
||||
result.putAll(moduleMappings);
|
||||
myAlarm.cancelAllRequests();
|
||||
myAlarm.addRequest(
|
||||
new SetupExternalLibrariesTask(moduleMappings, gradleProjectPath, intellijProject),
|
||||
PROJECT_INITIALISATION_DELAY_MS
|
||||
);
|
||||
}
|
||||
finally {
|
||||
model.commit();
|
||||
@@ -105,7 +125,7 @@ public class GradleModulesImporter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Actual implementation of {@link #importModules(Iterable, Project, ModifiableModuleModel)}. Insists on all arguments to
|
||||
* Actual implementation of {@link #importModules(Iterable, Project, ModifiableModuleModel, String)}. Insists on all arguments to
|
||||
* be ready to use.
|
||||
*
|
||||
* @param modules modules to import
|
||||
@@ -216,6 +236,156 @@ public class GradleModulesImporter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves (downloads if necessary) external libraries necessary for the gradle project located at the given path and configures
|
||||
* them for the corresponding intellij project.
|
||||
* <p/>
|
||||
* <b>Note:</b> is assumed to be executed under write action.
|
||||
*
|
||||
* @param moduleMappings gradle-intellij module mappings
|
||||
* @param intellijProject intellij project for the target gradle project
|
||||
* @param gradleProjectPath file system path to the target gradle project
|
||||
*/
|
||||
private static void setupLibraries(@NotNull final Map<GradleModule, Module> moduleMappings,
|
||||
@NotNull final Project intellijProject,
|
||||
@NotNull final String gradleProjectPath)
|
||||
{
|
||||
final GradleApiFacadeManager manager = ServiceManager.getService(GradleApiFacadeManager.class);
|
||||
|
||||
Runnable edtAction = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Ref<GradleProject> gradleProjectRef = new Ref<GradleProject>();
|
||||
//ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
|
||||
ProgressManager.getInstance().run(
|
||||
new Task.Backgroundable(intellijProject, GradleBundle.message("gradle.library.resolve.progress.text"), false) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
indicator.setIndeterminate(true);
|
||||
try {
|
||||
GradleProjectResolver resolver = manager.getFacade().getResolver();
|
||||
gradleProjectRef.set(resolver.resolveProjectInfo(gradleProjectPath, true));
|
||||
}
|
||||
catch (Exception e) {
|
||||
GradleLog.LOG.warn("Can't resolve external dependencies of the target gradle project (" + gradleProjectPath + ")", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final GradleProject gradleProject = gradleProjectRef.get();
|
||||
if (gradleProject == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Application application = ApplicationManager.getApplication();
|
||||
AccessToken writeLock = application.acquireWriteActionLock(getClass());
|
||||
try {
|
||||
doSetupLibraries(moduleMappings, gradleProject, intellijProject);
|
||||
}
|
||||
finally {
|
||||
writeLock.finish();
|
||||
}
|
||||
}
|
||||
};
|
||||
UIUtil.invokeLaterIfNeeded(edtAction);
|
||||
}
|
||||
|
||||
private static void doSetupLibraries(@NotNull Map<GradleModule, Module> moduleMappings,
|
||||
@NotNull GradleProject gradleProject,
|
||||
@NotNull Project intellijProject)
|
||||
{
|
||||
Application application = ApplicationManager.getApplication();
|
||||
application.assertWriteAccessAllowed();
|
||||
|
||||
Map<GradleLibrary, Library> libraryMappings = registerProjectLibraries(gradleProject, intellijProject);
|
||||
if (libraryMappings == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
configureModulesLibraryDependencies(moduleMappings, libraryMappings, gradleProject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers {@link GradleProject#getLibraries() libraries} of the given gradle project at the intellij project.
|
||||
*
|
||||
* @param gradleProject target gradle project being imported
|
||||
* @param intellijProject intellij representation of the given gradle project
|
||||
* @return mapping between libraries of the given gradle and intellij projects
|
||||
*/
|
||||
@Nullable
|
||||
private static Map<GradleLibrary, Library> registerProjectLibraries(GradleProject gradleProject, Project intellijProject) {
|
||||
LibraryTable projectLibraryTable = ProjectLibraryTable.getInstance(intellijProject);
|
||||
if (projectLibraryTable == null) {
|
||||
GradleLog.LOG.warn(
|
||||
"Can't resolve external dependencies of the target gradle project (" + intellijProject + "). Reason: project "
|
||||
+ "library table is undefined"
|
||||
);
|
||||
return null;
|
||||
}
|
||||
Map<GradleLibrary, Library> libraryMappings = new HashMap<GradleLibrary, Library>();
|
||||
for (GradleLibrary gradleLibrary : gradleProject.getLibraries()) {
|
||||
Library intellijLibrary = projectLibraryTable.createLibrary(gradleLibrary.getName());
|
||||
libraryMappings.put(gradleLibrary, intellijLibrary);
|
||||
Library.ModifiableModel model = intellijLibrary.getModifiableModel();
|
||||
try {
|
||||
registerPath(gradleLibrary, model);
|
||||
}
|
||||
finally {
|
||||
model.commit();
|
||||
}
|
||||
}
|
||||
return libraryMappings;
|
||||
}
|
||||
|
||||
private static void configureModulesLibraryDependencies(@NotNull Map<GradleModule, Module> moduleMappings,
|
||||
@NotNull final Map<GradleLibrary, Library> libraryMappings,
|
||||
@NotNull GradleProject gradleProject) {
|
||||
for (GradleModule gradleModule : gradleProject.getModules()) {
|
||||
Module intellijModule = moduleMappings.get(gradleModule);
|
||||
if (intellijModule == null) {
|
||||
GradleLog.LOG.warn(String.format(
|
||||
"Can't find intellij module for the gradle module '%s'. Registered mappings: %s", gradleModule, moduleMappings
|
||||
));
|
||||
continue;
|
||||
}
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(intellijModule);
|
||||
final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel();
|
||||
GradleEntityVisitor visitor = new GradleEntityVisitorAdapter() {
|
||||
@Override
|
||||
public void visit(@NotNull GradleLibraryDependency dependency) {
|
||||
GradleLibrary gradleLibrary = dependency.getLibrary();
|
||||
Library intellijLibrary = libraryMappings.get(gradleLibrary);
|
||||
if (intellijLibrary == null) {
|
||||
GradleLog.LOG.warn(String.format(
|
||||
"Can't find registered intellij library for gradle library '%s'. Registered mappings: %s", gradleLibrary, libraryMappings
|
||||
));
|
||||
return;
|
||||
}
|
||||
LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(intellijLibrary);
|
||||
orderEntry.setExported(dependency.isExported());
|
||||
orderEntry.setScope(dependency.getScope());
|
||||
}
|
||||
};
|
||||
try {
|
||||
for (GradleDependency dependency : gradleModule.getDependencies()) {
|
||||
dependency.invite(visitor);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
moduleRootModel.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerPath(@NotNull GradleLibrary gradleLibrary, @NotNull Library.ModifiableModel model) {
|
||||
for (LibraryPathType pathType : LibraryPathType.values()) {
|
||||
String path = gradleLibrary.getPath(pathType);
|
||||
if (path != null) {
|
||||
model.addRoot(toVfsUrl(path), pathType.getRootType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String toVfsUrl(@NotNull String path) {
|
||||
return LocalFileSystem.PROTOCOL_PREFIX + path;
|
||||
}
|
||||
@@ -224,17 +394,19 @@ public class GradleModulesImporter {
|
||||
|
||||
private final Project myProject;
|
||||
private final Iterable<GradleModule> myModules;
|
||||
private final String myGradleProjectPath;
|
||||
|
||||
private ImportModulesTask(@NotNull Project project, @NotNull Iterable<GradleModule> modules) {
|
||||
private ImportModulesTask(@NotNull Project project, @NotNull Iterable<GradleModule> modules, @NotNull String gradleProjectPath) {
|
||||
myProject = project;
|
||||
myModules = modules;
|
||||
myGradleProjectPath = gradleProjectPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
myAlarm.cancelAllRequests();
|
||||
if (!myProject.isInitialized()) {
|
||||
myAlarm.addRequest(new ImportModulesTask(myProject, myModules), PROJECT_INITIALISATION_DELAY_MS);
|
||||
myAlarm.addRequest(new ImportModulesTask(myProject, myModules, myGradleProjectPath), PROJECT_INITIALISATION_DELAY_MS);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -243,8 +415,26 @@ public class GradleModulesImporter {
|
||||
result.setResult(ModuleManager.getInstance(myProject).getModifiableModel());
|
||||
}
|
||||
}.execute().getResultObject();
|
||||
|
||||
importModules(myModules, model, myProject, myGradleProjectPath);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SetupExternalLibrariesTask implements Runnable {
|
||||
|
||||
importModules(myModules, model);
|
||||
private final Map<GradleModule, Module> myModules;
|
||||
private final String myGradleProjectPath;
|
||||
private final Project myIntellijProject;
|
||||
|
||||
SetupExternalLibrariesTask(@NotNull Map<GradleModule, Module> modules, @NotNull String gradleProjectPath, Project intellijProject) {
|
||||
myModules = modules;
|
||||
myGradleProjectPath = gradleProjectPath;
|
||||
myIntellijProject = intellijProject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
setupLibraries(myModules, myIntellijProject, myGradleProjectPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-1
@@ -1,8 +1,10 @@
|
||||
package org.jetbrains.plugins.gradle.importing.model;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.util.GradleUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -39,7 +41,21 @@ public class GradleContentRoot extends AbstractGradleEntity {
|
||||
return myData.get(type);
|
||||
}
|
||||
|
||||
public void storePath(@NotNull SourceType type, @NotNull String path) {
|
||||
/**
|
||||
* Ask to remember that directory at the given path contains sources of the given type.
|
||||
*
|
||||
* @param type target sources type
|
||||
* @param path target source directory path
|
||||
* @throws IllegalArgumentException if given path points to the directory that is not located
|
||||
* under the {@link #getRootPath() content root}
|
||||
*/
|
||||
public void storePath(@NotNull SourceType type, @NotNull String path) throws IllegalArgumentException {
|
||||
if (!FileUtil.isAncestor(new File(getRootPath()), new File(path), false)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Can't register given path of type '%s' because it's out of content root.%nContent root: '%s'%nGiven path: '%s'",
|
||||
type, getRootPath(), new File(path).getAbsolutePath()
|
||||
));
|
||||
}
|
||||
myData.get(type).add(GradleUtil.toCanonicalPath(path));
|
||||
}
|
||||
|
||||
|
||||
@@ -138,6 +138,7 @@ public class GradleModule extends AbstractNamedGradleEntity implements Named {
|
||||
@Override
|
||||
public GradleModule clone() {
|
||||
GradleModule result = new GradleModule(getName(), new File(getModuleFilePath()).getParent());
|
||||
result.setInheritProjectCompileOutputPath(isInheritProjectCompileOutputPath());
|
||||
for (GradleContentRoot contentRoot : getContentRoots()) {
|
||||
result.addContentRoot(contentRoot.clone());
|
||||
}
|
||||
|
||||
+20
-1
@@ -1,8 +1,27 @@
|
||||
package org.jetbrains.plugins.gradle.importing.model;
|
||||
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Note that current enum duplicates {@link OrderRootType}. We can't use the later directly because it's not properly setup
|
||||
* for serialization/deserialization.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/10/11 6:37 PM
|
||||
*/
|
||||
public enum LibraryPathType {
|
||||
BINARY, SOURCE, JAVADOC}
|
||||
|
||||
BINARY(OrderRootType.CLASSES), SOURCE(OrderRootType.SOURCES), JAVADOC(OrderRootType.DOCUMENTATION);
|
||||
|
||||
private final transient OrderRootType myRootType;
|
||||
|
||||
LibraryPathType(@NotNull OrderRootType rootType) {
|
||||
myRootType = rootType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public OrderRootType getRootType() {
|
||||
return myRootType;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-9
@@ -1,7 +1,7 @@
|
||||
package org.jetbrains.plugins.gradle.importing.wizard;
|
||||
|
||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
|
||||
import com.intellij.ide.util.projectWizard.WizardContext;
|
||||
import com.intellij.projectImport.ProjectImportWizardStep;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -10,21 +10,20 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/2/11 3:22 PM
|
||||
*/
|
||||
public abstract class AbstractImportFromGradleWizardStep extends ModuleWizardStep {
|
||||
public abstract class AbstractImportFromGradleWizardStep extends ProjectImportWizardStep {
|
||||
|
||||
private final WizardContext myContext;
|
||||
|
||||
protected AbstractImportFromGradleWizardStep(@NotNull WizardContext context) {
|
||||
myContext = context;
|
||||
super(context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WizardContext getContext() {
|
||||
return myContext;
|
||||
@Override
|
||||
public WizardContext getWizardContext() {
|
||||
return super.getWizardContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected GradleProjectImportBuilder getBuilder() {
|
||||
return (GradleProjectImportBuilder)myContext.getProjectBuilder();
|
||||
return (GradleProjectImportBuilder)getWizardContext().getProjectBuilder();
|
||||
}
|
||||
}
|
||||
|
||||
+13
-6
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.plugins.gradle.importing.wizard;
|
||||
|
||||
import com.intellij.execution.rmi.RemoteUtil;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.ide.util.projectWizard.WizardContext;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
@@ -15,6 +16,7 @@ import com.intellij.openapi.projectRoots.JavaSdk;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.packaging.artifacts.ModifiableArtifactModel;
|
||||
import com.intellij.projectImport.ProjectImportBuilder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -84,7 +86,7 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
|
||||
ModifiableArtifactModel artifactModel)
|
||||
{
|
||||
GradleModulesImporter importer = new GradleModulesImporter();
|
||||
Map<GradleModule, Module> mappings = importer.importModules(myModuleMappings.values(), project, model);
|
||||
Map<GradleModule, Module> mappings = importer.importModules(myModuleMappings.values(), project, model, myProjectFile.getAbsolutePath());
|
||||
return new ArrayList<Module>(mappings.values());
|
||||
}
|
||||
|
||||
@@ -139,19 +141,22 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
|
||||
if (myProjectFile.isDirectory()) {
|
||||
throw new ConfigurationException(GradleBundle.message("gradle.import.text.error.directory.instead.file"));
|
||||
}
|
||||
final Ref<String> errorReason = new Ref<String>();
|
||||
try {
|
||||
// TODO den derive target project for 'import module from gradle' (for 'add module' functionality).
|
||||
Project project = ProjectManager.getInstance().getDefaultProject();
|
||||
ProgressManager.getInstance().run(new Task.Modal(project, GradleBundle.message("gradle.import.progress.text"), true) {
|
||||
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
indicator.setIndeterminate(true);
|
||||
GradleApiFacadeManager manager = ServiceManager.getService(getProject(), GradleApiFacadeManager.class);
|
||||
GradleApiFacadeManager manager = ServiceManager.getService(GradleApiFacadeManager.class);
|
||||
try {
|
||||
GradleProjectResolver resolver = manager.getFacade().getResolver();
|
||||
myGradleProject = resolver.resolveProjectInfo(myProjectFile.getAbsolutePath(), false);
|
||||
}
|
||||
catch (Exception e) {
|
||||
errorReason.set(RemoteUtil.unwrap(e).getLocalizedMessage());
|
||||
// Ignore here because it will be reported on method exit.
|
||||
GradleLog.LOG.warn("Can't resolve gradle project", e);
|
||||
}
|
||||
@@ -162,10 +167,12 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
|
||||
throw new ConfigurationException(e.getMessage(), GradleBundle.message("gradle.import.text.error.cannot.parse.project"));
|
||||
}
|
||||
if (myGradleProject == null) {
|
||||
throw new ConfigurationException(
|
||||
GradleBundle.message("gradle.import.text.error.resolve.generic", myProjectFile.getPath()),
|
||||
GradleBundle.message("gradle.import.title.error.resolve.generic")
|
||||
);
|
||||
String errorMessage = GradleBundle.message("gradle.import.text.error.resolve.generic.without.reason", myProjectFile.getPath());
|
||||
String reason = errorReason.get();
|
||||
if (reason != null) {
|
||||
errorMessage = GradleBundle.message("gradle.import.text.error.resolve.generic.with.reason", myProjectFile.getPath(), reason);
|
||||
}
|
||||
throw new ConfigurationException(errorMessage, GradleBundle.message("gradle.import.title.error.resolve.generic"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -156,7 +156,7 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza
|
||||
if (project == null) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"Can't init 'adjust importing settings' step. Reason: no project is defined. Context: '%s', builder: '%s'",
|
||||
getContext(), getBuilder()
|
||||
getWizardContext(), getBuilder()
|
||||
));
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza
|
||||
return false;
|
||||
}
|
||||
}
|
||||
getBuilder().applyProjectSettings(getContext());
|
||||
getBuilder().applyProjectSettings(getWizardContext());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -59,7 +59,7 @@ public class GradleSelectProjectStep extends AbstractImportFromGradleWizardStep
|
||||
@Override
|
||||
public void updateStep() {
|
||||
if (isPathChanged()) {
|
||||
myProjectPathComponent.setText(getBuilder().getProjectPath(getContext()));
|
||||
myProjectPathComponent.setText(getBuilder().getProjectPath(getWizardContext()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,6 @@ public class GradleSelectProjectStep extends AbstractImportFromGradleWizardStep
|
||||
}
|
||||
|
||||
private boolean isPathChanged() {
|
||||
return !StringUtil.equals(myProjectPathComponent.getText(), getBuilder().getProjectPath(getContext()));
|
||||
return !StringUtil.equals(myProjectPathComponent.getText(), getBuilder().getProjectPath(getWizardContext()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.intellij.execution.rmi.RemoteProcessSupport;
|
||||
import com.intellij.execution.runners.ProgramRunner;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkType;
|
||||
import com.intellij.openapi.projectRoots.JdkUtil;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
@@ -121,6 +122,7 @@ public class GradleApiFacadeManager {
|
||||
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(PsiBundle.class), classPath);
|
||||
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(Alarm.class), classPath);
|
||||
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(DependencyScope.class), classPath);
|
||||
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(ExtensionPointName.class), classPath);
|
||||
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(getClass()), classPath);
|
||||
for (File library : gradleLibraries) {
|
||||
classPath.add(library.getAbsolutePath());
|
||||
|
||||
@@ -25,7 +25,8 @@ public interface GradleProjectResolver extends Remote {
|
||||
* @param downloadLibraries flag that specifies if third-party libraries that are not available locally should be resolved (downloaded)
|
||||
* @return object-level representation of the target gradle project
|
||||
* @throws RemoteException in case of unexpected exception during remote communications
|
||||
* @throws IllegalArgumentException if given path doesn't point to directory that contains gradle project
|
||||
* @throws IllegalArgumentException if given path doesn't point to directory that contains gradle project or if gradle api
|
||||
* returns invalid data
|
||||
* @throws IllegalStateException if it's not possible to resolve target project info
|
||||
*/
|
||||
@NotNull
|
||||
|
||||
+32
-19
@@ -43,21 +43,13 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GradleProject resolveProjectInfo(@NotNull String projectPath, boolean downloadLibraries) throws RemoteException {
|
||||
try {
|
||||
return doResolve(projectPath, downloadLibraries);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new IllegalStateException(GradleBundle.message("gradle.import.text.error.resolve.generic", projectPath), e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private GradleProject doResolve(@NotNull String projectPath, boolean downloadLibraries) {
|
||||
public GradleProject resolveProjectInfo(@NotNull String projectPath, boolean downloadLibraries)
|
||||
throws RemoteException, IllegalArgumentException, IllegalStateException
|
||||
{
|
||||
ProjectConnection connection = getConnection(projectPath);
|
||||
IdeaProject project = connection.getModel(downloadLibraries ? IdeaProject.class : OfflineIdeaProject.class);
|
||||
GradleProject result = populateProject(project, projectPath);
|
||||
|
||||
|
||||
// We need two different steps ('create' and 'populate') in order to handle module dependencies, i.e. when one module is
|
||||
// configured to be dependency for another one, corresponding dependency module object should be available during
|
||||
// populating dependent module object.
|
||||
@@ -107,25 +99,36 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void populateModules(@NotNull Iterable<Pair<GradleModule, IdeaModule>> modules,
|
||||
private static void populateModules(@NotNull Iterable<Pair<GradleModule,IdeaModule>> modules,
|
||||
@NotNull GradleProject intellijProject)
|
||||
throws IllegalStateException
|
||||
throws IllegalArgumentException, IllegalStateException
|
||||
{
|
||||
for (Pair<GradleModule, IdeaModule> pair : modules) {
|
||||
populateModule(pair.second, pair.first, intellijProject);
|
||||
}
|
||||
}
|
||||
|
||||
private static void populateModule(@NotNull IdeaModule gradleModule, @NotNull GradleModule intellijModule,
|
||||
private static void populateModule(@NotNull IdeaModule gradleModule,
|
||||
@NotNull GradleModule intellijModule,
|
||||
@NotNull GradleProject intellijProject)
|
||||
throws IllegalStateException
|
||||
throws IllegalArgumentException, IllegalStateException
|
||||
{
|
||||
populateContentRoots(gradleModule, intellijModule);
|
||||
populateCompileOutputSettings(gradleModule.getCompilerOutput(), intellijModule);
|
||||
populateDependencies(gradleModule, intellijModule, intellijProject);
|
||||
}
|
||||
|
||||
private static void populateContentRoots(@NotNull IdeaModule gradleModule, @NotNull GradleModule intellijModule) {
|
||||
/**
|
||||
* Populates {@link GradleModule#getContentRoots() content roots} of the given intellij module on the basis of the information
|
||||
* contained at the given gradle module.
|
||||
*
|
||||
* @param gradleModule holder of the module information received from the gradle tooling api
|
||||
* @param intellijModule corresponding module from intellij gradle plugin domain
|
||||
* @throws IllegalArgumentException if given gradle module contains invalid data
|
||||
*/
|
||||
private static void populateContentRoots(@NotNull IdeaModule gradleModule, @NotNull GradleModule intellijModule)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
DomainObjectSet<? extends IdeaContentRoot> contentRoots = gradleModule.getContentRoots();
|
||||
if (contentRoots == null) {
|
||||
return;
|
||||
@@ -150,9 +153,19 @@ public class GradleProjectResolverImpl extends RemoteObject implements GradlePro
|
||||
intellijModule.addContentRoot(intellijContentRoot);
|
||||
}
|
||||
}
|
||||
|
||||
private static void populateContentRoot(@NotNull GradleContentRoot contentRoot, SourceType type,
|
||||
|
||||
/**
|
||||
* Stores information about given directories at the given content root
|
||||
*
|
||||
* @param contentRoot target paths info holder
|
||||
* @param type type of data located at the given directories
|
||||
* @param dirs directories which paths should be stored at the given content root
|
||||
* @throws IllegalArgumentException if specified by {@link GradleContentRoot#storePath(SourceType, String)}
|
||||
*/
|
||||
private static void populateContentRoot(@NotNull GradleContentRoot contentRoot,
|
||||
@NotNull SourceType type,
|
||||
@Nullable Iterable<? extends IdeaSourceDirectory> dirs)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
if (dirs == null) {
|
||||
return;
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package org.jetbrains.plugins.gradle.importing.model;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/31/11 1:33 PM
|
||||
*/
|
||||
public class GradleContentRootTest {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void pathOutOfContentRoot() {
|
||||
GradleContentRoot contentRoot = new GradleContentRoot("./my-content-root");
|
||||
contentRoot.storePath(SourceType.SOURCE, "./my-dir-out-of-content-root");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user