diff --git a/plugins/gradle/resources/i18n/GradleBundle.properties b/plugins/gradle/resources/i18n/GradleBundle.properties
index 2fb6c89c3dcf..ffd1725562bd 100644
--- a/plugins/gradle/resources/i18n/GradleBundle.properties
+++ b/plugins/gradle/resources/i18n/GradleBundle.properties
@@ -89,3 +89,6 @@ gradle.settings.color.text.sample.node.sync.name=node-with-same-setup
gradle.settings.color.text.sample.node.gradle.name=node-added-at-Gradle
gradle.settings.color.text.sample.node.intellij.name=node-added-at-{0}
gradle.settings.color.text.sample.node.confirmed.name=node-with-different-but-confirmed-setup
+
+gradle.run.no.sdk.text=Gradle is not configured. Do you want to configure it?
+gradle.run.no.sdk.title=Configure Gradle SDK
\ No newline at end of file
diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml
index 6798caa9da4c..02a615f25e5c 100644
--- a/plugins/gradle/src/META-INF/plugin.xml
+++ b/plugins/gradle/src/META-INF/plugin.xml
@@ -48,7 +48,7 @@
-
+
@@ -95,6 +95,9 @@
org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesDetector
+
+ org.jetbrains.plugins.gradle.config.GradleGroovyEnabler
+
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/AbstractGradleLinkedProjectAction.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/AbstractGradleLinkedProjectAction.java
index 701da05b145b..7f228ee17aa5 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/AbstractGradleLinkedProjectAction.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/AbstractGradleLinkedProjectAction.java
@@ -11,7 +11,7 @@ import org.jetbrains.plugins.gradle.config.GradleSettings;
import java.io.File;
/**
- * Common super class for gradle actions that require {@link GradleSettings#LINKED_PROJECT_FILE_PATH linked project}.
+ * Common super class for gradle actions that require {@link GradleSettings#getLinkedProjectPath()} linked project}.
*
* Not thread-safe.
*
@@ -56,7 +56,7 @@ public abstract class AbstractGradleLinkedProjectAction extends AnAction {
return null;
}
- final String path = GradleSettings.getInstance(project).LINKED_PROJECT_FILE_PATH;
+ final String path = GradleSettings.getInstance(project).getLinkedProjectPath();
if (StringUtil.isEmpty(path) || !new File(path).isFile()) {
return null;
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleLinkToProjectAction.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleLinkToProjectAction.java
index 113156d0ecba..6908d4f7b3dc 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleLinkToProjectAction.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleLinkToProjectAction.java
@@ -36,6 +36,6 @@ public class GradleLinkToProjectAction extends AnAction implements DumbAware {
if (file == null) {
return;
}
- GradleSettings.setLinkedProjectPath(file.getPath(), project);
+ GradleSettings.applyLinkedProjectPath(file.getPath(), project);
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigNotifier.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigNotifier.java
index 977c5bef1d23..e7bf3e57ab58 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigNotifier.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigNotifier.java
@@ -15,6 +15,16 @@ public interface GradleConfigNotifier {
Topic TOPIC = Topic.create("Gradle config", GradleConfigNotifier.class);
+ /**
+ * Is expected to be invoked when gradle home path is changed.
+ *
+ * Note: this callback is executed after the actual config change.
+ *
+ * @param oldPath old path (if any)
+ * @param newPath new path (if any)
+ */
+ void onGradleHomeChange(@Nullable String oldPath, @Nullable String newPath);
+
/**
* Is expected to be invoked when linked gradle project path (path of the 'build.gradle' file) is changed.
*
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigNotifierAdapter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigNotifierAdapter.java
new file mode 100644
index 000000000000..3849e3feaf32
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigNotifierAdapter.java
@@ -0,0 +1,18 @@
+package org.jetbrains.plugins.gradle.config;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Denis Zhdanov
+ * @since 3/13/12 3:53 PM
+ */
+public class GradleConfigNotifierAdapter implements GradleConfigNotifier {
+
+ @Override
+ public void onGradleHomeChange(@Nullable String oldPath, @Nullable String newPath) {
+ }
+
+ @Override
+ public void onLinkedProjectPathChange(@Nullable String oldPath, @Nullable String newPath) {
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java
index 6c9a30839205..142ae0d0a319 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java
@@ -167,7 +167,7 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
return false;
}
String newPath = myGradleHomeComponent.getPath();
- String oldPath = GradleSettings.getInstance(myProject).GRADLE_HOME;
+ String oldPath = GradleSettings.getInstance(myProject).getGradleHome();
boolean modified = newPath == null ? oldPath == null : !newPath.equals(oldPath);
if (modified) {
useNormalColorForPath();
@@ -179,7 +179,7 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
public void apply() {
useNormalColorForPath();
String path = myGradleHomeComponent.getPath();
- GradleSettings.getInstance(myProject).GRADLE_HOME = path;
+ GradleSettings.applyGradleHome(path, myProject);
// There is a possible case that user defines gradle home for particular open project. We want to apply that value
// to the default project as well if it's still non-defined.
@@ -193,7 +193,7 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
if (!StringUtil.isEmpty(path)
&& !Boolean.parseBoolean(PropertiesComponent.getInstance().getValue(NOT_PROPAGATE_GRADLE_HOME_TO_DEFAULT_PROJECT)))
{
- GradleSettings.getInstance(defaultProject).GRADLE_HOME = path;
+ GradleSettings.applyGradleHome(path, defaultProject);
}
}
@@ -201,9 +201,9 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
public void reset() {
useNormalColorForPath();
myPathManuallyModified = false;
- String valueToUse = GradleSettings.getInstance(myProject).GRADLE_HOME;
+ String valueToUse = GradleSettings.getInstance(myProject).getGradleHome();
if (StringUtil.isEmpty(valueToUse)) {
- valueToUse = GradleSettings.getInstance(ProjectManager.getInstance().getDefaultProject()).GRADLE_HOME;
+ valueToUse = GradleSettings.getInstance(ProjectManager.getInstance().getDefaultProject()).getGradleHome();
}
if (!StringUtil.isEmpty(valueToUse)) {
myGradleHomeSettingType = myLibraryManager.isGradleSdkHome(new File(valueToUse)) ?
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleGroovyEnabler.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleGroovyEnabler.java
new file mode 100644
index 000000000000..237c324647d0
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleGroovyEnabler.java
@@ -0,0 +1,140 @@
+package org.jetbrains.plugins.gradle.config;
+
+import com.intellij.openapi.components.AbstractProjectComponent;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.messages.MessageBusConnection;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.importing.GradleDependencyImporter;
+import org.jetbrains.plugins.gradle.importing.GradleLibraryImporter;
+import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
+import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
+import org.jetbrains.plugins.groovy.util.GroovyUtils;
+import org.jetbrains.plugins.groovy.util.LibrariesUtil;
+
+import java.io.File;
+import java.util.*;
+
+/**
+ * Automatically configures groovy sdk for the modules that has '*.gradle' files.
+ *
+ * Thread-safe.
+ *
+ * @author Denis Zhdanov
+ * @since 3/13/12 3:12 PM
+ */
+public class GradleGroovyEnabler extends AbstractProjectComponent {
+
+ @NotNull private final PlatformFacade myPlatformFacade;
+ @NotNull private final GradleLibraryImporter myLibraryImporter;
+ @NotNull private final GradleDependencyImporter myDependencyImporter;
+
+ public GradleGroovyEnabler(@NotNull Project project,
+ @NotNull PlatformFacade facade,
+ @NotNull GradleLibraryImporter libraryImporter,
+ @NotNull GradleDependencyImporter importer)
+ {
+ super(project);
+ myPlatformFacade = facade;
+ myLibraryImporter = libraryImporter;
+ myDependencyImporter = importer;
+ final MessageBusConnection connection = project.getMessageBus().connect(project);
+ connection.subscribe(GradleConfigNotifier.TOPIC, new GradleConfigNotifierAdapter() {
+ @Override
+ public void onGradleHomeChange(@Nullable String oldPath, @Nullable String newPath) {
+ GradleGroovyEnabler.this.onGradleHomeChange(newPath);
+ }
+ });
+ }
+
+ public void onGradleHomeChange(@Nullable String newPath) {
+ if (newPath == null) {
+ return;
+ }
+ setupGroovySdkIfNecessary(newPath);
+ }
+
+ /**
+ * Configures groovy sdk for the modules that require it (have gradle scripts but no groovy sdk).
+ *
+ * @param gradleHome gradle home to use
+ * @return groovy sdk library if the one has been created and configured;
+ * null otherwise (no module requires groovy support or all target modules already have groovy sdk)
+ */
+ @Nullable
+ public Library setupGroovySdkIfNecessary(@NotNull String gradleHome) {
+ final Collection modules = getModulesThatRequireSupport();
+ if (modules.isEmpty()) {
+ return null;
+ }
+ final Library sdk = getGroovySdk(gradleHome);
+ if (sdk == null) {
+ return null;
+ }
+ for (Module module : modules) {
+ applySdk(module, sdk);
+ }
+ return sdk;
+ }
+
+ /**
+ * @return all modules of the current project that have dedicated gradle config script but don't have groovy sdk
+ */
+ @NotNull
+ private Collection getModulesThatRequireSupport() {
+ final List result = new ArrayList();
+ for (Module module : myPlatformFacade.getModules(myProject)) {
+ // Skip module if it already has groovy support.
+ if (LibrariesUtil.hasGroovySdk(module)) {
+ continue;
+ }
+
+ // Skip module if it doesn't have a dedicated gradle script.
+ boolean needGroovy = false;
+ for (ModuleAwareContentRoot root : myPlatformFacade.getContentRoots(module)) {
+ final VirtualFile file = root.getFile();
+ if (!file.isDirectory()) {
+ continue;
+ }
+ final VirtualFile child = file.findChild(GradleConstants.DEFAULT_SCRIPT_NAME);
+ if (child != null) {
+ needGroovy = true;
+ break;
+ }
+ }
+ if (needGroovy) {
+ result.add(module);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Checks if there is groovy sdk configured at the project-level; configures the one to the groovy bundled by the gradle and returns it.
+ *
+ * @param gradleHome target gradle home to use for groovy sdk configuration
+ * @return groovy sdk library if it's possible to find/configure the one; null otherwise
+ */
+ @Nullable
+ private Library getGroovySdk(@NotNull String gradleHome) {
+ final Library[] libraries = GroovyConfigUtils.getInstance().getAllSDKLibraries(myProject);
+ if (libraries != null && libraries.length > 0) {
+ return libraries[0];
+ }
+ final File[] groovyJars = GroovyUtils.getFilesInDirectoryByPattern(gradleHome + "/lib/", GroovyConfigUtils.GROOVY_ALL_JAR_PATTERN);
+ if (groovyJars == null || groovyJars.length <= 0) {
+ return null;
+ }
+
+ return myLibraryImporter.importLibrary("groovy", Collections.singletonMap(OrderRootType.CLASSES, Arrays.asList(groovyJars)), myProject);
+ }
+
+ private void applySdk(@NotNull Module module, @NotNull Library sdk) {
+ myDependencyImporter.importLibraryDependencies(module, Collections.singleton(sdk));
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java
index d7def8e54110..2b81013aa6b5 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java
@@ -39,6 +39,7 @@ import com.intellij.psi.search.NonClasspathDirectoryScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.ui.GradleIcons;
+import org.jetbrains.plugins.gradle.util.GradleBundle;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import org.jetbrains.plugins.gradle.util.GradleLibraryManager;
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
@@ -95,7 +96,6 @@ public class GradleScriptType extends GroovyScriptType {
configuration.setScriptParameters(target);
configuration.setName(configuration.getName() + "." + target);
}
-
final CompileStepBeforeRun.MakeBeforeRunTask runTask =
RunManagerEx.getInstanceEx(file.getProject()).getBeforeRunTask(configuration, CompileStepBeforeRun.ID);
@@ -160,8 +160,8 @@ public class GradleScriptType extends GroovyScriptType {
if (libraryManager.getGradleHome(module, project) == null) {
// TODO den internationalise
int result = Messages.showOkCancelDialog(
- "Gradle is not configured. Do you want to configure it?",
- "Configure Gradle SDK",
+ GradleBundle.message("gradle.run.no.sdk.text"),
+ GradleBundle.message("gradle.run.no.sdk.title"),
GradleIcons.GRADLE_ICON
);
if (result == 0) {
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleSettings.java
index bb34e918c845..a970e5f1112d 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleSettings.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleSettings.java
@@ -49,8 +49,8 @@ public class GradleSettings implements PersistentStateComponent,
//private final AtomicReference> myAcceptedChanges
// = new AtomicReference>();
- public String LINKED_PROJECT_FILE_PATH;
- public String GRADLE_HOME;
+ private String myLinkedProjectPath;
+ private String myGradleHome;
@Override
public GradleSettings getState() {
@@ -70,10 +70,37 @@ public class GradleSettings implements PersistentStateComponent,
return ServiceManager.getService(project, GradleSettings.class);
}
- public static void setLinkedProjectPath(@Nullable String path, @NotNull Project project) {
+ @Nullable
+ public String getGradleHome() {
+ return myGradleHome;
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ public void setGradleHome(@Nullable String gradleHome) { // Necessary for the serialization.
+ myGradleHome = gradleHome;
+ }
+
+ public static void applyGradleHome(@Nullable String newPath, @NotNull Project project) {
final GradleSettings settings = getInstance(project);
- final String oldPath = settings.LINKED_PROJECT_FILE_PATH;
- settings.LINKED_PROJECT_FILE_PATH = path;
+ final String oldPath = settings.myGradleHome;
+ settings.myGradleHome = newPath;
+ project.getMessageBus().syncPublisher(GradleConfigNotifier.TOPIC).onGradleHomeChange(oldPath, newPath);
+ }
+
+ @Nullable
+ public String getLinkedProjectPath() {
+ return myLinkedProjectPath;
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ public void setLinkedProjectPath(@Nullable String linkedProjectPath) { // Necessary for the serialization.
+ myLinkedProjectPath = linkedProjectPath;
+ }
+
+ public static void applyLinkedProjectPath(@Nullable String path, @NotNull Project project) {
+ final GradleSettings settings = getInstance(project);
+ final String oldPath = settings.myLinkedProjectPath;
+ settings.myLinkedProjectPath = path;
project.getMessageBus().syncPublisher(GradleConfigNotifier.TOPIC).onLinkedProjectPathChange(oldPath, path);
}
@@ -91,6 +118,6 @@ public class GradleSettings implements PersistentStateComponent,
@Override
public String toString() {
- return "home: " + GRADLE_HOME + ", path: " + LINKED_PROJECT_FILE_PATH;
+ return "home: " + myGradleHome + ", path: " + myLinkedProjectPath;
}
}
\ No newline at end of file
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleToolWindowPanel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleToolWindowPanel.java
index bc5247db68e6..b35f692e81f9 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleToolWindowPanel.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleToolWindowPanel.java
@@ -55,7 +55,7 @@ public abstract class GradleToolWindowPanel extends SimpleToolWindowPanel {
setContent(myContent);
MessageBusConnection connection = project.getMessageBus().connect(project);
- connection.subscribe(GradleConfigNotifier.TOPIC, new GradleConfigNotifier() {
+ connection.subscribe(GradleConfigNotifier.TOPIC, new GradleConfigNotifierAdapter() {
@Override
public void onLinkedProjectPathChange(@Nullable String oldPath, @Nullable String newPath) {
update();
@@ -105,7 +105,7 @@ public abstract class GradleToolWindowPanel extends SimpleToolWindowPanel {
*/
public void update() {
final GradleSettings settings = GradleSettings.getInstance(myProject);
- String cardToShow = settings.LINKED_PROJECT_FILE_PATH == null ? NON_LINKED_CARD_NAME : CONTENT_CARD_NAME;
+ String cardToShow = settings.getLinkedProjectPath() == null ? NON_LINKED_CARD_NAME : CONTENT_CARD_NAME;
myLayout.show(myContent, cardToShow);
updateContent();
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleDependencyImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleDependencyImporter.java
similarity index 56%
rename from plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleDependencyImporter.java
rename to plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleDependencyImporter.java
index 8a4e99a7facd..d146f4167322 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleDependencyImporter.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleDependencyImporter.java
@@ -2,7 +2,10 @@ package org.jetbrains.plugins.gradle.importing;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.roots.*;
+import com.intellij.openapi.roots.DependencyScope;
+import com.intellij.openapi.roots.LibraryOrderEntry;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.util.ui.UIUtil;
@@ -10,9 +13,12 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.config.PlatformFacade;
import org.jetbrains.plugins.gradle.model.gradle.*;
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper;
-import org.jetbrains.plugins.gradle.util.GradleLog;
+import org.jetbrains.plugins.gradle.util.GradleUtil;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
/**
* Thread-safe.
@@ -20,11 +26,11 @@ import java.util.*;
* @author Denis Zhdanov
* @since 2/7/12 3:23 PM
*/
-public class GradleModuleDependencyImporter {
+public class GradleDependencyImporter {
@NotNull private final PlatformFacade myPlatformFacade;
- public GradleModuleDependencyImporter(@NotNull PlatformFacade platformFacade) {
+ public GradleDependencyImporter(@NotNull PlatformFacade platformFacade) {
myPlatformFacade = platformFacade;
}
@@ -91,61 +97,68 @@ public class GradleModuleDependencyImporter {
}
public void importLibraryDependencies(@NotNull final Iterable dependencies, @NotNull final Module module) {
+ final List infos = new ArrayList();
+ final LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject());
+ for (GradleLibraryDependency dependency : dependencies) {
+ final Library library = libraryTable.getLibraryByName(dependency.getName());
+ if (library != null) {
+ infos.add(new LibraryDependencyInfo(library, dependency.getScope(), dependency.isExported()));
+ }
+ }
+ doImportLibraryDependencies(infos, module);
+ }
+
+ @SuppressWarnings("MethodMayBeStatic")
+ public void importLibraryDependencies(@NotNull Module module, @NotNull Collection libraries) {
+ List infos = new ArrayList();
+ for (Library library : libraries) {
+ infos.add(new LibraryDependencyInfo(library, DependencyScope.PROVIDED, true));
+ }
+ doImportLibraryDependencies(infos, module);
+ }
+
+ private static void doImportLibraryDependencies(@NotNull final Iterable infos, @NotNull final Module module) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
- doImportLibraryDependencies(dependencies, module);
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ // Register library dependencies.
+ ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
+ final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel();
+ final GradleProjectEntityImportListener publisher
+ = module.getProject().getMessageBus().syncPublisher(GradleProjectEntityImportListener.TOPIC);
+ try {
+ for (LibraryDependencyInfo info : infos) {
+ publisher.onImportStart(info.library);
+ LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(info.library);
+ orderEntry.setExported(info.exported);
+ orderEntry.setScope(info.scope);
+ }
+ }
+ finally {
+ moduleRootModel.commit();
+ for (LibraryDependencyInfo info : infos) {
+ publisher.onImportEnd(info.library);
+ }
+ }
+ }
+ });
}
});
}
-
- public void doImportLibraryDependencies(@NotNull final Iterable dependencies, @NotNull final Module module) {
- // Is assumed to be called from EDT
- final LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject());
- final Map gradle2intellij = new HashMap();
- for (final GradleLibraryDependency dependency : dependencies) {
- // Try to find existing library in project libraries.
- Library library = libraryTable.getLibraryByName(dependency.getName());
- if (library != null) {
- gradle2intellij.put(dependency.getTarget(), library);
- }
- else {
- GradleLog.LOG.warn(String.format(
- "Detected situation when target library for the gradle-local library dependency doesn't exist. Dependency: %s",
- dependency
- ));
- }
- }
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- @Override
- public void run() {
- // Register library dependencies.
- ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
- final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel();
- final GradleProjectEntityImportListener publisher
- = module.getProject().getMessageBus().syncPublisher(GradleProjectEntityImportListener.TOPIC);
- try {
- for (GradleLibraryDependency dependency : dependencies) {
- final Library library = gradle2intellij.get(dependency.getTarget());
- if (library == null) {
- continue;
- }
- publisher.onImportStart(library);
- LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(library);
- orderEntry.setExported(dependency.isExported());
- orderEntry.setScope(dependency.getScope());
- }
- }
- finally {
- moduleRootModel.commit();
- for (GradleLibraryDependency dependency : dependencies) {
- if (dependency != null) {
- publisher.onImportEnd(dependency);
- }
- }
- }
- }
- });
+ private static class LibraryDependencyInfo {
+
+ @NotNull public final Library library;
+ @NotNull public final DependencyScope scope;
+ public final boolean exported;
+
+ LibraryDependencyInfo(@NotNull Library library, @NotNull DependencyScope scope, boolean exported) {
+ this.library = library;
+ this.scope = scope;
+ this.exported = exported;
+ }
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLibraryImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLibraryImporter.java
index 1f959c06899a..4dfb3f815b8e 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLibraryImporter.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLibraryImporter.java
@@ -6,9 +6,12 @@ import com.intellij.openapi.roots.JavadocOrderRootType;
import com.intellij.openapi.roots.OrderRootType;
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.JarFileSystem;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.NotNullFunction;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.config.PlatformFacade;
@@ -17,8 +20,7 @@ import org.jetbrains.plugins.gradle.model.gradle.LibraryPathType;
import org.jetbrains.plugins.gradle.util.GradleLog;
import java.io.File;
-import java.util.EnumMap;
-import java.util.Map;
+import java.util.*;
/**
* @author Denis Zhdanov
@@ -32,67 +34,104 @@ public class GradleLibraryImporter {
myPlatformFacade = platformFacade;
}
- public void importLibrary(@NotNull final GradleLibrary library, @NotNull final Project project) {
+ @NotNull
+ public Library importLibrary(@NotNull final GradleLibrary library, @NotNull final Project project) {
+ Map> libraryFiles = new HashMap>();
+ for (LibraryPathType pathType : LibraryPathType.values()) {
+ final Set paths = library.getPaths(pathType);
+ if (paths.isEmpty()) {
+ continue;
+ }
+ libraryFiles.put(Lazy.LIBRARY_ROOT_MAPPINGS.get(pathType), ContainerUtil.map(paths, new NotNullFunction() {
+ @NotNull
+ @Override
+ public File fun(String path) {
+ return new File(path);
+ }
+ }));
+ }
+ return importLibrary(library.getName(), libraryFiles, project);
+ }
+
+ @NotNull
+ public Library importLibrary(@NotNull final String libraryName,
+ @NotNull final Map> libraryFiles,
+ @NotNull final Project project)
+ {
+ final Ref result = new Ref();
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
final GradleProjectEntityImportListener publisher = project.getMessageBus().syncPublisher(GradleProjectEntityImportListener.TOPIC);
- publisher.onImportStart(library);
+ publisher.onImportStart(libraryName);
try {
- doImportLibrary(library, project);
+ result.set(doImportLibrary(libraryName, libraryFiles, project));
}
finally {
- publisher.onImportEnd(library);
+ publisher.onImportEnd(libraryName);
}
}
});
+ return result.get();
}
- private void doImportLibrary(@NotNull final GradleLibrary gradleLibrary,@NotNull Project project) {
+ @NotNull
+ private Library doImportLibrary(@NotNull final String libraryName,
+ @NotNull final Map> libraryFiles,
+ @NotNull Project project)
+ {
// Is assumed to be called from the EDT.
final LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(project);
+ final Ref result = new Ref();
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
final LibraryTable.ModifiableModel projectLibraryModel = libraryTable.getModifiableModel();
final Library intellijLibrary;
try {
- intellijLibrary = projectLibraryModel.createLibrary(gradleLibrary.getName());
+ intellijLibrary = projectLibraryModel.createLibrary(libraryName);
+ result.set(intellijLibrary);
}
finally {
projectLibraryModel.commit();
}
final Library.ModifiableModel libraryModel = intellijLibrary.getModifiableModel();
try {
- registerPaths(gradleLibrary, libraryModel);
+ registerPaths(libraryFiles, libraryModel, libraryName);
}
finally {
libraryModel.commit();
}
}
});
+ return result.get();
}
- private static void registerPaths(@NotNull GradleLibrary gradleLibrary, @NotNull Library.ModifiableModel model) {
- for (LibraryPathType pathType : LibraryPathType.values()) {
- for (String path : gradleLibrary.getPaths(pathType)) {
- VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(new File(path));
+ private static void registerPaths(@NotNull final Map> libraryFiles,
+ @NotNull Library.ModifiableModel model,
+ @NotNull String libraryName)
+ {
+ for (Map.Entry> entry : libraryFiles.entrySet()) {
+ for (File file : entry.getValue()) {
+ VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(file);
if (virtualFile == null) {
- GradleLog.LOG.warn(String.format("Can't find %s of the library '%s' at path '%s'", pathType, gradleLibrary.getName(), path));
+ GradleLog.LOG.warn(
+ String.format("Can't find %s of the library '%s' at path '%s'", entry.getKey(), libraryName, file.getAbsolutePath())
+ );
continue;
}
if (virtualFile.isDirectory()) {
- model.addRoot(virtualFile, Lazy.LIBRARY_ROOT_MAPPINGS.get(pathType));
+ model.addRoot(virtualFile, entry.getKey());
}
else {
VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(virtualFile);
if (jarRoot == null) {
GradleLog.LOG.warn(String.format(
- "Can't parse contents of the jar file at path '%s' for the library '%s''", path, gradleLibrary.getName()
+ "Can't parse contents of the jar file at path '%s' for the library '%s''", file.getAbsolutePath(), libraryName
));
continue;
}
- model.addRoot(jarRoot, Lazy.LIBRARY_ROOT_MAPPINGS.get(pathType));
+ model.addRoot(jarRoot, entry.getKey());
}
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLocalNodeImportHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLocalNodeImportHelper.java
index b901cf96fd82..e87a378e8c7c 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLocalNodeImportHelper.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLocalNodeImportHelper.java
@@ -52,14 +52,14 @@ public class GradleLocalNodeImportHelper {
@NotNull private final GradleEntityIdMapper myIdMapper;
@NotNull private final GradleModuleImporter myModuleImporter;
@NotNull private final GradleLibraryImporter myLibraryImporter;
- @NotNull private final GradleModuleDependencyImporter myModuleDependencyImporter;
+ @NotNull private final GradleDependencyImporter myModuleDependencyImporter;
@NotNull private final GradleContentRootImporter myContentRootImporter;
public GradleLocalNodeImportHelper(@NotNull GradleProjectStructureHelper projectStructureHelper,
@NotNull GradleEntityIdMapper idMapper,
@NotNull GradleModuleImporter moduleImporter,
@NotNull GradleLibraryImporter libraryImporter,
- @NotNull GradleModuleDependencyImporter moduleDependencyImporter,
+ @NotNull GradleDependencyImporter moduleDependencyImporter,
@NotNull GradleContentRootImporter contentRootImporter)
{
myProjectStructureHelper = projectStructureHelper;
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleImporter.java
index aadcd66faa85..7a95fa3ea2bc 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleImporter.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModuleImporter.java
@@ -36,10 +36,10 @@ public class GradleModuleImporter {
private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
@NotNull private final GradleContentRootImporter myContentRootImporter;
- @NotNull private final GradleModuleDependencyImporter myDependencyImporter;
+ @NotNull private final GradleDependencyImporter myDependencyImporter;
public GradleModuleImporter(@NotNull GradleContentRootImporter contentRootImporter,
- @NotNull GradleModuleDependencyImporter dependencyImporter)
+ @NotNull GradleDependencyImporter dependencyImporter)
{
myContentRootImporter = contentRootImporter;
myDependencyImporter = dependencyImporter;
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java
index 95e9e1d01124..41c0725e5078 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java
@@ -23,6 +23,8 @@ import com.intellij.util.containers.hash.HashMap;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.config.GradleGroovyEnabler;
+import org.jetbrains.plugins.gradle.config.GradleSettings;
import org.jetbrains.plugins.gradle.model.gradle.*;
import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask;
import org.jetbrains.plugins.gradle.util.GradleBundle;
@@ -298,6 +300,7 @@ public class GradleModulesImporter {
@NotNull final String gradleProjectPath)
{
final Ref gradleProjectRef = new Ref();
+ final Ref libraryToPreserve = new Ref();
final Runnable setupExternalDependenciesTask = new Runnable() {
@Override
@@ -310,15 +313,15 @@ public class GradleModulesImporter {
Application application = ApplicationManager.getApplication();
AccessToken writeLock = application.acquireWriteActionLock(getClass());
try {
- doSetupLibraries(moduleMappings, gradleProject, intellijProject);
+ doSetupLibraries(moduleMappings, gradleProject, intellijProject, libraryToPreserve.get());
}
finally {
writeLock.finish();
- }
+ }
}
};
- Runnable resolveDependenciesTask = new Runnable() {
+ final Runnable resolveDependenciesTask = new Runnable() {
@Override
public void run() {
ProgressManager.getInstance().run(
@@ -335,12 +338,26 @@ public class GradleModulesImporter {
}
};
- UIUtil.invokeLaterIfNeeded(resolveDependenciesTask);
+ Runnable setupGroovyTask = new Runnable() {
+ @Override
+ public void run() {
+ final GradleSettings settings = GradleSettings.getInstance(intellijProject);
+ final String gradleHome = settings.getGradleHome();
+ if (gradleHome != null) {
+ final GradleGroovyEnabler groovyEnabler = intellijProject.getComponent(GradleGroovyEnabler.class);
+ libraryToPreserve.set(groovyEnabler.setupGroovySdkIfNecessary(gradleHome));
+ }
+ resolveDependenciesTask.run();
+ }
+ };
+
+ UIUtil.invokeLaterIfNeeded(setupGroovyTask);
}
private static void doSetupLibraries(@NotNull Map moduleMappings,
@NotNull GradleProject gradleProject,
- @NotNull Project intellijProject)
+ @NotNull Project intellijProject,
+ @Nullable Library libraryToPreserve)
{
Application application = ApplicationManager.getApplication();
application.assertWriteAccessAllowed();
@@ -357,7 +374,9 @@ public class GradleModulesImporter {
// Clean existing libraries (if any).
try {
for (Library library : model.getLibraries()) {
- model.removeLibrary(library);
+ if (libraryToPreserve != library) {
+ model.removeLibrary(library);
+ }
}
}
finally {
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java
index faaae1600c6a..fa12623f17ca 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java
@@ -80,13 +80,17 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder mappings =
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java
index e647066e7d01..100f32edf451 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java
@@ -146,6 +146,7 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
@Override
protected void updateContent() {
+ myTreeModel.rebuild();
}
private void setupToolbar() {
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java
index 2572281fecd2..fea46379ac88 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java
@@ -78,6 +78,7 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
private Comparator myChangesComparator;
private boolean myProcessChangesAtTheSameThread;
+ @SuppressWarnings("UnusedDeclaration") // Used implicitly by IoC
public GradleProjectStructureTreeModel(@NotNull Project project, @NotNull GradleProjectStructureContext context) {
this(project, context, true);
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java
index cd1621f70b2b..b878565f40ca 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleLibraryManager.java
@@ -157,7 +157,7 @@ public class GradleLibraryManager {
project = ProjectManager.getInstance().getDefaultProject();
}
GradleSettings settings = GradleSettings.getInstance(project);
- String path = settings.GRADLE_HOME;
+ String path = settings.getGradleHome();
if (path == null) {
return null;
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java
index 80f467e60117..d8cae7bcc2bb 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java
@@ -122,10 +122,11 @@ public class GradleUtil {
*/
public static void refreshProject(@NotNull Project project) {
final GradleSettings settings = GradleSettings.getInstance(project);
- final String linkedProjectPath = settings.LINKED_PROJECT_FILE_PATH;
+ final String linkedProjectPath = settings.getLinkedProjectPath();
if (StringUtil.isEmpty(linkedProjectPath)) {
return;
}
+ assert linkedProjectPath != null;
Ref errorHolder = new Ref();
refreshProject(project, linkedProjectPath, errorHolder, true, false);
final String error = errorHolder.get();
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleLocalNodeImportHelperTest.groovy b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleLocalNodeImportHelperTest.groovy
index 3bc05c2df535..2a8002c4d15a 100644
--- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleLocalNodeImportHelperTest.groovy
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleLocalNodeImportHelperTest.groovy
@@ -23,7 +23,7 @@ public class GradleLocalNodeImportHelperTest extends AbstractGradleTest {
container.registerComponentImplementation(GradleLocalNodeImportHelper)
container.registerComponentImplementation(GradleModuleImporter)
container.registerComponentImplementation(GradleLibraryImporter)
- container.registerComponentImplementation(GradleModuleDependencyImporter)
+ container.registerComponentImplementation(GradleDependencyImporter)
container.registerComponentImplementation(GradleContentRootImporter)
}