mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
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:
@@ -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
|
||||
@@ -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>
|
||||
|
||||
+2
-2
@@ -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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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/>
|
||||
|
||||
+18
@@ -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();
|
||||
|
||||
+67
-54
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+56
-17
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
+25
-6
@@ -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 {
|
||||
|
||||
+11
-7
@@ -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 =
|
||||
|
||||
+1
@@ -146,6 +146,7 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
|
||||
|
||||
@Override
|
||||
protected void updateContent() {
|
||||
myTreeModel.rebuild();
|
||||
}
|
||||
|
||||
private void setupToolbar() {
|
||||
|
||||
+1
@@ -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();
|
||||
|
||||
+1
-1
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user