IDEA-81764 Gradle home is not accepted as Groovy home

Groovy sdk from the gradle distribution is automatically configured for the project imported from gradle
This commit is contained in:
Denis.Zhdanov
2012-03-14 12:30:15 +04:00
parent c905ee7fd6
commit 2359dd30e4
22 changed files with 390 additions and 111 deletions
@@ -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
+4 -1
View File
@@ -48,7 +48,7 @@
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.importing.GradleModuleImporter"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.importing.GradleLibraryImporter"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.importing.GradleContentRootImporter"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.importing.GradleModuleDependencyImporter"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.importing.GradleDependencyImporter"/>
<!--Generic application services-->
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.remote.GradleApiFacadeManager"/>
@@ -95,6 +95,9 @@
<component>
<implementation-class>org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesDetector</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.plugins.gradle.config.GradleGroovyEnabler</implementation-class>
</component>
</project-components>
<actions>
@@ -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}.
* <p/>
* 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;
}
@@ -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);
}
}
@@ -15,6 +15,16 @@ public interface GradleConfigNotifier {
Topic<GradleConfigNotifier> TOPIC = Topic.create("Gradle config", GradleConfigNotifier.class);
/**
* Is expected to be invoked when gradle home path is changed.
* <p/>
* <b>Note:</b> this callback is executed <b>after</b> 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.
* <p/>
@@ -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) {
}
}
@@ -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)) ?
@@ -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.
* <p/>
* 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;
* <code>null</code> otherwise (no module requires groovy support or all target modules already have groovy sdk)
*/
@Nullable
public Library setupGroovySdkIfNecessary(@NotNull String gradleHome) {
final Collection<Module> 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<Module> getModulesThatRequireSupport() {
final List<Module> result = new ArrayList<Module>();
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; <code>null</code> 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));
}
}
@@ -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) {
@@ -49,8 +49,8 @@ public class GradleSettings implements PersistentStateComponent<GradleSettings>,
//private final AtomicReference<Set<GradleProjectStructureChange>> myAcceptedChanges
// = new AtomicReference<Set<GradleProjectStructureChange>>();
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<GradleSettings>,
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<GradleSettings>,
@Override
public String toString() {
return "home: " + GRADLE_HOME + ", path: " + LINKED_PROJECT_FILE_PATH;
return "home: " + myGradleHome + ", path: " + myLinkedProjectPath;
}
}
@@ -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();
@@ -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<GradleLibraryDependency> dependencies, @NotNull final Module module) {
final List<LibraryDependencyInfo> infos = new ArrayList<LibraryDependencyInfo>();
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<Library> libraries) {
List<LibraryDependencyInfo> infos = new ArrayList<LibraryDependencyInfo>();
for (Library library : libraries) {
infos.add(new LibraryDependencyInfo(library, DependencyScope.PROVIDED, true));
}
doImportLibraryDependencies(infos, module);
}
private static void doImportLibraryDependencies(@NotNull final Iterable<LibraryDependencyInfo> 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<GradleLibraryDependency> dependencies, @NotNull final Module module) {
// Is assumed to be called from EDT
final LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject());
final Map<GradleLibrary, Library> gradle2intellij = new HashMap<GradleLibrary, Library>();
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;
}
}
}
@@ -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<OrderRootType, Collection<File>> libraryFiles = new HashMap<OrderRootType, Collection<File>>();
for (LibraryPathType pathType : LibraryPathType.values()) {
final Set<String> paths = library.getPaths(pathType);
if (paths.isEmpty()) {
continue;
}
libraryFiles.put(Lazy.LIBRARY_ROOT_MAPPINGS.get(pathType), ContainerUtil.map(paths, new NotNullFunction<String, File>() {
@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<OrderRootType, ? extends Collection<File>> libraryFiles,
@NotNull final Project project)
{
final Ref<Library> result = new Ref<Library>();
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<OrderRootType, ? extends Collection<File>> libraryFiles,
@NotNull Project project)
{
// Is assumed to be called from the EDT.
final LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(project);
final Ref<Library> result = new Ref<Library>();
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<OrderRootType, ? extends Collection<File>> libraryFiles,
@NotNull Library.ModifiableModel model,
@NotNull String libraryName)
{
for (Map.Entry<OrderRootType, ? extends Collection<File>> 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());
}
}
}
@@ -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;
@@ -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;
@@ -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<GradleProject> gradleProjectRef = new Ref<GradleProject>();
final Ref<Library> libraryToPreserve = new Ref<Library>();
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<GradleModule, Module> 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 {
@@ -80,13 +80,17 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
ModulesProvider modulesProvider,
ModifiableArtifactModel artifactModel)
{
if (!project.isInitialized()) {
StartupManager.getInstance(project).registerPostStartupActivity(new Runnable() {
@Override
public void run() {
GradleSettings.setLinkedProjectPath(myProjectFile.getAbsolutePath(), project);
}
});
final Runnable task = new Runnable() {
@Override
public void run() {
GradleSettings.applyLinkedProjectPath(myProjectFile.getAbsolutePath(), project);
}
};
if (project.isInitialized()) {
task.run();
}
else {
StartupManager.getInstance(project).registerPostStartupActivity(task);
}
GradleModulesImporter importer = new GradleModulesImporter();
Map<GradleModule, Module> mappings =
@@ -146,6 +146,7 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
@Override
protected void updateContent() {
myTreeModel.rebuild();
}
private void setupToolbar() {
@@ -78,6 +78,7 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
private Comparator<GradleProjectStructureChange> myChangesComparator;
private boolean myProcessChangesAtTheSameThread;
@SuppressWarnings("UnusedDeclaration") // Used implicitly by IoC
public GradleProjectStructureTreeModel(@NotNull Project project, @NotNull GradleProjectStructureContext context) {
this(project, context, true);
}
@@ -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;
}
@@ -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<String> errorHolder = new Ref<String>();
refreshProject(project, linkedProjectPath, errorHolder, true, false);
final String error = errorHolder.get();
@@ -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)
}