mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git.labs.intellij.net:idea/community
This commit is contained in:
@@ -3,6 +3,7 @@ package org.jetbrains.jps.model;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -10,7 +11,7 @@ import java.util.Map;
|
||||
*/
|
||||
public interface JpsEncodingProjectConfiguration extends JpsElement {
|
||||
@Nullable
|
||||
String getEncoding(@NotNull String url);
|
||||
String getEncoding(@NotNull File file);
|
||||
|
||||
@Nullable
|
||||
String getProjectEncoding();
|
||||
|
||||
+32
-3
@@ -1,11 +1,17 @@
|
||||
package org.jetbrains.jps.model.impl;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.JpsElementChildRole;
|
||||
import org.jetbrains.jps.model.JpsEncodingConfigurationService;
|
||||
import org.jetbrains.jps.model.JpsEncodingProjectConfiguration;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
import org.jetbrains.jps.model.ex.JpsElementBase;
|
||||
import org.jetbrains.jps.model.ex.JpsElementChildRoleBase;
|
||||
import org.jetbrains.jps.util.JpsPathUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -13,7 +19,8 @@ import java.util.Map;
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class JpsEncodingProjectConfigurationImpl extends JpsElementBase<JpsEncodingProjectConfigurationImpl> implements JpsEncodingProjectConfiguration {
|
||||
public class JpsEncodingProjectConfigurationImpl extends JpsElementBase<JpsEncodingProjectConfigurationImpl>
|
||||
implements JpsEncodingProjectConfiguration {
|
||||
public static final JpsElementChildRole<JpsEncodingProjectConfiguration> ROLE = JpsElementChildRoleBase.create("encoding configuration");
|
||||
private final Map<String, String> myUrlToEncoding = new HashMap<String, String>();
|
||||
private final String myProjectEncoding;
|
||||
@@ -23,9 +30,30 @@ public class JpsEncodingProjectConfigurationImpl extends JpsElementBase<JpsEncod
|
||||
myProjectEncoding = projectEncoding;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getEncoding(@NotNull String url) {
|
||||
return myUrlToEncoding.get(url);
|
||||
public String getEncoding(@NotNull File file) {
|
||||
if (!myUrlToEncoding.isEmpty()) {
|
||||
|
||||
File current = file;
|
||||
while (current != null) {
|
||||
String encoding = myUrlToEncoding.get(JpsPathUtil.pathToUrl(FileUtilRt.toSystemIndependentName(current.getPath())));
|
||||
|
||||
if (encoding != null) {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
current = FileUtilRt.getParentFile(current);
|
||||
}
|
||||
}
|
||||
|
||||
if (myProjectEncoding != null) {
|
||||
return myProjectEncoding;
|
||||
}
|
||||
|
||||
final JpsModel model = getModel();
|
||||
assert model != null;
|
||||
return JpsEncodingConfigurationService.getInstance().getGlobalEncoding(model.getGlobal());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -34,6 +62,7 @@ public class JpsEncodingProjectConfigurationImpl extends JpsElementBase<JpsEncod
|
||||
return Collections.unmodifiableMap(myUrlToEncoding);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getProjectEncoding() {
|
||||
return myProjectEncoding;
|
||||
|
||||
+3
-1
@@ -92,7 +92,9 @@ public class JpsProjectSerializationTest extends JpsSerializationTestCase {
|
||||
JpsEncodingProjectConfiguration configuration = service.getEncodingConfiguration(myProject);
|
||||
assertNotNull(configuration);
|
||||
assertEquals("UTF-8", configuration.getProjectEncoding());
|
||||
assertEquals("windows-1251", configuration.getEncoding(getUrl("util")));
|
||||
assertEquals("windows-1251", configuration.getEncoding(new File(getAbsolutePath("util"))));
|
||||
assertEquals("windows-1251", configuration.getEncoding(new File(getAbsolutePath("util/foo/bar/file.txt"))));
|
||||
assertEquals("UTF-8", configuration.getEncoding(new File(getAbsolutePath("other"))));
|
||||
}
|
||||
|
||||
public void testSaveProject() {
|
||||
|
||||
@@ -46,6 +46,7 @@ public class FilePathImpl implements FilePath {
|
||||
private boolean myIsDirectory;
|
||||
private final boolean myLocal;
|
||||
|
||||
//private FilePathImpl(@NotNull VirtualFile virtualParent,
|
||||
private FilePathImpl(@NotNull VirtualFile virtualParent,
|
||||
@NotNull String name,
|
||||
final boolean isDirectory,
|
||||
@@ -88,7 +89,7 @@ public class FilePathImpl implements FilePath {
|
||||
}
|
||||
private FilePathImpl(@NotNull File file, final boolean isDirectory, boolean local) {
|
||||
myFile = file;
|
||||
assert myFile.isAbsolute();
|
||||
//assert myFile.isAbsolute() || ! local;
|
||||
myName = file.getName();
|
||||
myIsDirectory = isDirectory;
|
||||
myLocal = local;
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@ public class PublicConstructorInspection extends BaseInspection {
|
||||
@Override
|
||||
public void visitClass(PsiClass aClass) {
|
||||
super.visitClass(aClass);
|
||||
if (!aClass.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
if (aClass.isInterface() || !aClass.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
return;
|
||||
}
|
||||
final PsiMethod[] constructors = aClass.getConstructors();
|
||||
|
||||
+15
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2011 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2006-2012 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,6 +23,9 @@ import com.intellij.codeInspection.reference.RefClass;
|
||||
import com.intellij.codeInspection.reference.RefEntity;
|
||||
import com.intellij.codeInspection.reference.RefModule;
|
||||
import com.intellij.codeInspection.ui.SingleIntegerFieldOptionsPanel;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseGlobalInspection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -39,17 +42,13 @@ public class ModuleWithTooFewClassesInspection extends BaseGlobalInspection {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return InspectionGadgetsBundle.message(
|
||||
"module.with.too.few.classes.display.name");
|
||||
return InspectionGadgetsBundle.message("module.with.too.few.classes.display.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public CommonProblemDescriptor[] checkElement(
|
||||
RefEntity refEntity,
|
||||
AnalysisScope analysisScope,
|
||||
InspectionManager inspectionManager,
|
||||
GlobalInspectionContext globalInspectionContext) {
|
||||
public CommonProblemDescriptor[] checkElement(RefEntity refEntity, AnalysisScope analysisScope, InspectionManager inspectionManager,
|
||||
GlobalInspectionContext globalInspectionContext) {
|
||||
if (!(refEntity instanceof RefModule)) {
|
||||
return null;
|
||||
}
|
||||
@@ -67,10 +66,13 @@ public class ModuleWithTooFewClassesInspection extends BaseGlobalInspection {
|
||||
if (numClasses >= limit || numClasses == 0) {
|
||||
return null;
|
||||
}
|
||||
final String errorString = InspectionGadgetsBundle.message(
|
||||
"module.with.too.few.classes.problem.descriptor",
|
||||
refModule.getName(), Integer.valueOf(numClasses),
|
||||
Integer.valueOf(limit));
|
||||
final Project project = globalInspectionContext.getProject();
|
||||
final Module[] modules = ModuleManager.getInstance(project).getModules();
|
||||
if (modules.length == 1) {
|
||||
return null;
|
||||
}
|
||||
final String errorString = InspectionGadgetsBundle.message("module.with.too.few.classes.problem.descriptor",
|
||||
refModule.getName(), Integer.valueOf(numClasses), Integer.valueOf(limit));
|
||||
return new CommonProblemDescriptor[]{
|
||||
inspectionManager.createProblemDescriptor(errorString)
|
||||
};
|
||||
@@ -78,9 +80,6 @@ public class ModuleWithTooFewClassesInspection extends BaseGlobalInspection {
|
||||
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
return new SingleIntegerFieldOptionsPanel(
|
||||
InspectionGadgetsBundle.message(
|
||||
"module.with.too.few.classes.min.option"),
|
||||
this, "limit");
|
||||
return new SingleIntegerFieldOptionsPanel(InspectionGadgetsBundle.message("module.with.too.few.classes.min.option"), this, "limit");
|
||||
}
|
||||
}
|
||||
+11
-9
@@ -26,6 +26,7 @@ import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -145,7 +146,7 @@ public class UnclearBinaryExpressionInspection extends BaseInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendText(PsiInstanceOfExpression instanceofExpression, boolean parentheses, StringBuilder out) {
|
||||
private static void appendText(PsiInstanceOfExpression instanceofExpression, boolean parentheses, @NonNls StringBuilder out) {
|
||||
if (parentheses) {
|
||||
out.append('(');
|
||||
}
|
||||
@@ -287,16 +288,17 @@ public class UnclearBinaryExpressionInspection extends BaseInspection {
|
||||
return;
|
||||
}
|
||||
final PsiExpression rhs = expression.getRExpression();
|
||||
if (!(mightBeConfusingExpression(rhs))) {
|
||||
if (!mightBeConfusingExpression(rhs)) {
|
||||
return;
|
||||
}
|
||||
if (rhs instanceof PsiAssignmentExpression) {
|
||||
final PsiAssignmentExpression nestedAssignment = (PsiAssignmentExpression)rhs;
|
||||
final IElementType nestedTokenType = nestedAssignment.getOperationTokenType();
|
||||
final IElementType tokenType = expression.getOperationTokenType();
|
||||
if (nestedTokenType.equals(tokenType)) {
|
||||
return;
|
||||
}
|
||||
if (!(rhs instanceof PsiAssignmentExpression)) {
|
||||
return;
|
||||
}
|
||||
final PsiAssignmentExpression nestedAssignment = (PsiAssignmentExpression)rhs;
|
||||
final IElementType nestedTokenType = nestedAssignment.getOperationTokenType();
|
||||
final IElementType tokenType = expression.getOperationTokenType();
|
||||
if (nestedTokenType.equals(tokenType)) {
|
||||
return;
|
||||
}
|
||||
registerError(expression);
|
||||
}
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package com.siyeh.igtest.classlayout.public_constructor;
|
||||
|
||||
public interface PublicInterface {}
|
||||
+5
@@ -50,4 +50,9 @@ public class UnclearBinaryExpression {
|
||||
void more(int i) {
|
||||
i = i += i = 1;
|
||||
}
|
||||
|
||||
void noMore() {
|
||||
String s;
|
||||
s = ":asdf" + "5s";
|
||||
}
|
||||
}
|
||||
|
||||
+38
-55
@@ -1,18 +1,18 @@
|
||||
package org.jetbrains.plugins.gradle.manage;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ContentEntry;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleContentRoot;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.SourceType;
|
||||
import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot;
|
||||
import org.jetbrains.plugins.gradle.util.GradleUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
@@ -28,76 +28,59 @@ public class GradleContentRootManager {
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
public void importContentRoots(@NotNull final Iterable<GradleContentRoot> contentRoots, @NotNull final Module module) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doImportContentRoots(contentRoots, module);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void doImportContentRoots(@NotNull final Iterable<GradleContentRoot> contentRoots, @NotNull final Module module) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void importContentRoots(@NotNull final Collection<GradleContentRoot> contentRoots, @NotNull final Module module) {
|
||||
if (contentRoots.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), contentRoots, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
final ModifiableRootModel model = moduleRootManager.getModifiableModel();
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), contentRoots, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (GradleContentRoot contentRoot : contentRoots) {
|
||||
ContentEntry contentEntry = model.addContentEntry(toVfsUrl(contentRoot.getRootPath()));
|
||||
for (String path : contentRoot.getPaths(SourceType.SOURCE)) {
|
||||
contentEntry.addSourceFolder(toVfsUrl(path), false);
|
||||
}
|
||||
for (String path : contentRoot.getPaths(SourceType.TEST)) {
|
||||
contentEntry.addSourceFolder(toVfsUrl(path), true);
|
||||
}
|
||||
for (String path : contentRoot.getPaths(SourceType.EXCLUDED)) {
|
||||
contentEntry.addExcludeFolder(toVfsUrl(path));
|
||||
}
|
||||
}
|
||||
try {
|
||||
for (GradleContentRoot contentRoot : contentRoots) {
|
||||
ContentEntry contentEntry = model.addContentEntry(toVfsUrl(contentRoot.getRootPath()));
|
||||
for (String path : contentRoot.getPaths(SourceType.SOURCE)) {
|
||||
contentEntry.addSourceFolder(toVfsUrl(path), false);
|
||||
}
|
||||
for (String path : contentRoot.getPaths(SourceType.TEST)) {
|
||||
contentEntry.addSourceFolder(toVfsUrl(path), true);
|
||||
}
|
||||
for (String path : contentRoot.getPaths(SourceType.EXCLUDED)) {
|
||||
contentEntry.addExcludeFolder(toVfsUrl(path));
|
||||
}
|
||||
finally {
|
||||
model.commit();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
finally {
|
||||
model.commit();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static String toVfsUrl(@NotNull String path) {
|
||||
return LocalFileSystem.PROTOCOL_PREFIX + path;
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
public void removeContentRoots(@NotNull final Iterable<ModuleAwareContentRoot> contentRoots) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
public void removeContentRoots(@NotNull final Collection<ModuleAwareContentRoot> contentRoots) {
|
||||
if (contentRoots.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Project project = contentRoots.iterator().next().getModule().getProject();
|
||||
GradleUtil.executeProjectChangeAction(project, contentRoots, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (final ModuleAwareContentRoot contentRoot : contentRoots) {
|
||||
GradleUtil.executeProjectChangeAction(contentRoot.getModule().getProject(), contentRoot, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(contentRoot.getModule());
|
||||
ModifiableRootModel model = moduleRootManager.getModifiableModel();
|
||||
try {
|
||||
model.removeContentEntry(contentRoot);
|
||||
}
|
||||
finally {
|
||||
model.commit();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
for (ModuleAwareContentRoot contentRoot : contentRoots) {
|
||||
final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(contentRoot.getModule());
|
||||
ModifiableRootModel model = moduleRootManager.getModifiableModel();
|
||||
try {
|
||||
model.removeContentEntry(contentRoot);
|
||||
}
|
||||
});
|
||||
finally {
|
||||
model.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+86
-105
@@ -1,20 +1,16 @@
|
||||
package org.jetbrains.plugins.gradle.manage;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
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.GradleUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Thread-safe.
|
||||
@@ -23,17 +19,19 @@ import java.util.List;
|
||||
* @since 2/7/12 3:23 PM
|
||||
*/
|
||||
public class GradleDependencyManager {
|
||||
|
||||
@NotNull private final PlatformFacade myPlatformFacade;
|
||||
|
||||
public GradleDependencyManager(@NotNull PlatformFacade platformFacade) {
|
||||
@NotNull private final PlatformFacade myPlatformFacade;
|
||||
@NotNull private final GradleLibraryManager myLibraryManager;
|
||||
|
||||
public GradleDependencyManager(@NotNull PlatformFacade platformFacade, @NotNull GradleLibraryManager manager) {
|
||||
myPlatformFacade = platformFacade;
|
||||
myLibraryManager = manager;
|
||||
}
|
||||
|
||||
public void importDependency(@NotNull GradleDependency dependency, @NotNull Module module) {
|
||||
importDependencies(Collections.singleton(dependency), module);
|
||||
}
|
||||
|
||||
|
||||
public void importDependencies(@NotNull Iterable<GradleDependency> dependencies, @NotNull Module module) {
|
||||
final List<GradleModuleDependency> moduleDependencies = new ArrayList<GradleModuleDependency>();
|
||||
final List<GradleLibraryDependency> libraryDependencies = new ArrayList<GradleLibraryDependency>();
|
||||
@@ -56,19 +54,12 @@ public class GradleDependencyManager {
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
public void importModuleDependencies(@NotNull final Iterable<GradleModuleDependency> dependencies, @NotNull final Module module) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doImportModuleDependencies(dependencies, module);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void doImportModuleDependencies(@NotNull final Iterable<GradleModuleDependency> dependencies,
|
||||
@NotNull final Module module)
|
||||
{
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void importModuleDependencies(@NotNull final Collection<GradleModuleDependency> dependencies, @NotNull final Module module) {
|
||||
if (dependencies.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), dependencies, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
@@ -77,12 +68,20 @@ public class GradleDependencyManager {
|
||||
final GradleProjectStructureHelper projectStructureHelper = module.getProject().getComponent(GradleProjectStructureHelper.class);
|
||||
for (GradleModuleDependency dependency : dependencies) {
|
||||
final String moduleName = dependency.getName();
|
||||
final Module intellijModuleDependency = projectStructureHelper.findIntellijModule(moduleName);
|
||||
if (intellijModuleDependency == null) {
|
||||
final Module intellijModule = projectStructureHelper.findIntellijModule(moduleName);
|
||||
if (intellijModule == null) {
|
||||
assert false;
|
||||
continue;
|
||||
}
|
||||
final ModuleOrderEntry orderEntry = moduleRootModel.addModuleOrderEntry(intellijModuleDependency);
|
||||
else if (intellijModule.equals(module)) {
|
||||
// Gradle api returns recursive module dependencies (a module depends on itself) for 'gradle' project.
|
||||
continue;
|
||||
}
|
||||
|
||||
ModuleOrderEntry orderEntry = projectStructureHelper.findIntellijModuleDependency(dependency, moduleRootModel);
|
||||
if (orderEntry == null) {
|
||||
orderEntry = moduleRootModel.addModuleOrderEntry(intellijModule);
|
||||
}
|
||||
orderEntry.setScope(dependency.getScope());
|
||||
orderEntry.setExported(dependency.isExported());
|
||||
}
|
||||
@@ -93,97 +92,79 @@ public class GradleDependencyManager {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private static void doImportLibraryDependencies(@NotNull final Iterable<LibraryDependencyInfo> infos, @NotNull final Module module) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), dependencies, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), infos, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel();
|
||||
try {
|
||||
for (LibraryDependencyInfo info : infos) {
|
||||
LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(info.library);
|
||||
orderEntry.setExported(info.exported);
|
||||
orderEntry.setScope(info.scope);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
moduleRootModel.commit();
|
||||
}
|
||||
}
|
||||
});
|
||||
LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject());
|
||||
Set<GradleLibrary> librariesToImport = new HashSet<GradleLibrary>();
|
||||
for (GradleLibraryDependency dependency : dependencies) {
|
||||
final Library library = libraryTable.getLibraryByName(dependency.getName());
|
||||
if (library == null) {
|
||||
librariesToImport.add(dependency.getTarget());
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!librariesToImport.isEmpty()) {
|
||||
myLibraryManager.importLibraries(librariesToImport, module.getProject());
|
||||
}
|
||||
|
||||
for (GradleLibraryDependency dependency : dependencies) {
|
||||
GradleProjectStructureHelper helper = module.getProject().getComponent(GradleProjectStructureHelper.class);
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel();
|
||||
try {
|
||||
libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject());
|
||||
final Library library = libraryTable.getLibraryByName(dependency.getName());
|
||||
if (library == null) {
|
||||
assert false;
|
||||
continue;
|
||||
}
|
||||
LibraryOrderEntry orderEntry = helper.findIntellijLibraryDependency(dependency.getName(), moduleRootModel);
|
||||
if (orderEntry == null) {
|
||||
// We need to get the most up-to-date Library object due to our project model restrictions.
|
||||
orderEntry = moduleRootModel.addLibraryEntry(library);
|
||||
}
|
||||
orderEntry.setExported(dependency.isExported());
|
||||
orderEntry.setScope(dependency.getScope());
|
||||
}
|
||||
finally {
|
||||
moduleRootModel.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
public void removeDependencies(@NotNull final Iterable<ExportableOrderEntry> dependencies) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (final ExportableOrderEntry dependency : dependencies) {
|
||||
final Module module = dependency.getOwnerModule();
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), dependency, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel();
|
||||
try {
|
||||
// The thing is that intellij created order entry objects every time new modifiable model is created,
|
||||
// that's why we can't use target dependency object as is but need to get a reference to the current
|
||||
// entry object from the model instead.
|
||||
for (OrderEntry entry : moduleRootModel.getOrderEntries()) {
|
||||
if (entry.getPresentableName().equals(dependency.getPresentableName())) {
|
||||
moduleRootModel.removeOrderEntry(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
moduleRootModel.commit();
|
||||
}
|
||||
}
|
||||
});
|
||||
public void removeDependencies(@NotNull final Collection<ExportableOrderEntry> dependencies) {
|
||||
if (dependencies.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final ExportableOrderEntry dependency : dependencies) {
|
||||
final Module module = dependency.getOwnerModule();
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), dependency, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel();
|
||||
try {
|
||||
// The thing is that intellij created order entry objects every time new modifiable model is created,
|
||||
// that's why we can't use target dependency object as is but need to get a reference to the current
|
||||
// entry object from the model instead.
|
||||
for (OrderEntry entry : moduleRootModel.getOrderEntries()) {
|
||||
if (entry.getPresentableName().equals(dependency.getPresentableName())) {
|
||||
moduleRootModel.removeOrderEntry(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
finally {
|
||||
moduleRootModel.commit();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
package org.jetbrains.plugins.gradle.manage;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
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;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.LibraryPathType;
|
||||
import org.jetbrains.plugins.gradle.util.GradleLog;
|
||||
import org.jetbrains.plugins.gradle.util.GradleUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
@@ -34,8 +32,13 @@ public class GradleLibraryManager {
|
||||
myPlatformFacade = platformFacade;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Library importLibrary(@NotNull final GradleLibrary library, @NotNull final Project project) {
|
||||
public void importLibraries(@NotNull Collection<? extends GradleLibrary> libraries, @NotNull Project project) {
|
||||
for (GradleLibrary library : libraries) {
|
||||
importLibrary(library, project);
|
||||
}
|
||||
}
|
||||
|
||||
public void 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);
|
||||
@@ -50,47 +53,22 @@ public class GradleLibraryManager {
|
||||
}
|
||||
}));
|
||||
}
|
||||
return importLibrary(library.getName(), libraryFiles, project);
|
||||
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)
|
||||
public void 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 GradleProjectEntityChangeListener publisher = project.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC);
|
||||
publisher.onChangeStart(libraryName);
|
||||
try {
|
||||
result.set(doImportLibrary(libraryName, libraryFiles, project));
|
||||
}
|
||||
finally {
|
||||
publisher.onChangeEnd(libraryName);
|
||||
}
|
||||
}
|
||||
});
|
||||
return result.get();
|
||||
}
|
||||
|
||||
@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() {
|
||||
GradleUtil.executeProjectChangeAction(project, libraryName, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Is assumed to be called from the EDT.
|
||||
final LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(project);
|
||||
final LibraryTable.ModifiableModel projectLibraryModel = libraryTable.getModifiableModel();
|
||||
final Library intellijLibrary;
|
||||
try {
|
||||
intellijLibrary = projectLibraryModel.createLibrary(libraryName);
|
||||
result.set(intellijLibrary);
|
||||
}
|
||||
finally {
|
||||
projectLibraryModel.commit();
|
||||
@@ -104,7 +82,6 @@ public class GradleLibraryManager {
|
||||
}
|
||||
}
|
||||
});
|
||||
return result.get();
|
||||
}
|
||||
|
||||
private static void registerPaths(@NotNull final Map<OrderRootType, ? extends Collection<File>> libraryFiles,
|
||||
@@ -115,9 +92,9 @@ public class GradleLibraryManager {
|
||||
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'", entry.getKey(), libraryName, file.getAbsolutePath())
|
||||
);
|
||||
//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()) {
|
||||
@@ -137,7 +114,7 @@ public class GradleLibraryManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void removeLibraries(@NotNull List<Library> libraries) {
|
||||
public void removeLibraries(@NotNull List<? extends Library> libraries) {
|
||||
// TODO den implement
|
||||
//LibraryTable table = library.getTable();
|
||||
//table.removeLibrary(library);
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.plugins.gradle.util.GradleLog;
|
||||
import org.jetbrains.plugins.gradle.util.GradleUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -50,7 +51,13 @@ public class GradleModuleManager {
|
||||
importModules(Collections.singleton(module), project, false);
|
||||
}
|
||||
|
||||
public void importModules(@NotNull final Iterable<GradleModule> modules, @NotNull final Project project, final boolean recursive) {
|
||||
public void importModules(@NotNull final Collection<? extends GradleModule> modules,
|
||||
@NotNull final Project project,
|
||||
final boolean recursive)
|
||||
{
|
||||
if (modules.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!project.isInitialized()) {
|
||||
myAlarm.addRequest(new ImportModulesTask(project, modules, recursive), PROJECT_INITIALISATION_DELAY_MS);
|
||||
return;
|
||||
@@ -65,7 +72,7 @@ public class GradleModuleManager {
|
||||
@Override
|
||||
public void run() {
|
||||
final ModuleManager moduleManager = ModuleManager.getInstance(project);
|
||||
final GradleProjectEntityChangeListener publisher
|
||||
final GradleProjectEntityChangeListener publisher
|
||||
= project.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC);
|
||||
for (GradleModule module : modules) {
|
||||
publisher.onChangeStart(module);
|
||||
@@ -121,7 +128,7 @@ public class GradleModuleManager {
|
||||
});
|
||||
}
|
||||
|
||||
private static void removeExistingModulesConfigs(@NotNull Iterable<GradleModule> modules) {
|
||||
private static void removeExistingModulesConfigs(@NotNull Collection<? extends GradleModule> modules) {
|
||||
for (GradleModule module : modules) {
|
||||
// Remove existing '*.iml' file if necessary.
|
||||
final String moduleFilePath = module.getModuleFilePath();
|
||||
@@ -136,43 +143,37 @@ public class GradleModuleManager {
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
public void removeModules(@NotNull final Iterable<Module> modules) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
public void removeModules(@NotNull final Collection<? extends Module> modules) {
|
||||
if (modules.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Project project = modules.iterator().next().getProject();
|
||||
GradleUtil.executeProjectChangeAction(project, modules, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (final Module module : modules) {
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), module, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ModuleManager moduleManager = ModuleManager.getInstance(module.getProject());
|
||||
String path = module.getModuleFilePath();
|
||||
moduleManager.disposeModule(module);
|
||||
File file = new File(path);
|
||||
if (file.isFile()) {
|
||||
boolean success = file.delete();
|
||||
if (!success) {
|
||||
GradleLog.LOG.warn("Can't remove module file at '" + path + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
for (Module module : modules) {
|
||||
ModuleManager moduleManager = ModuleManager.getInstance(module.getProject());
|
||||
String path = module.getModuleFilePath();
|
||||
moduleManager.disposeModule(module);
|
||||
File file = new File(path);
|
||||
if (file.isFile()) {
|
||||
boolean success = file.delete();
|
||||
if (!success) {
|
||||
GradleLog.LOG.warn("Can't remove module file at '" + path + "'");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class ImportModulesTask implements Runnable {
|
||||
|
||||
private final Project myProject;
|
||||
private final Iterable<GradleModule> myModules;
|
||||
private final boolean myRecursive;
|
||||
private final Project myProject;
|
||||
private final Collection<? extends GradleModule> myModules;
|
||||
private final boolean myRecursive;
|
||||
|
||||
ImportModulesTask(@NotNull Project project, @NotNull Iterable<GradleModule> modules, boolean recursive) {
|
||||
ImportModulesTask(@NotNull Project project, @NotNull Collection<? extends GradleModule> modules, boolean recursive) {
|
||||
myProject = project;
|
||||
myModules = modules;
|
||||
myRecursive = recursive;
|
||||
@@ -192,5 +193,4 @@ public class GradleModuleManager {
|
||||
importModules(myModules, myProject, myRecursive);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,564 +0,0 @@
|
||||
package org.jetbrains.plugins.gradle.manage;
|
||||
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.module.ModifiableModuleModel;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.module.StdModuleTypes;
|
||||
import com.intellij.openapi.roots.impl.ModifiableModelCommitter;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Alarm;
|
||||
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.model.gradle.*;
|
||||
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesModel;
|
||||
import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask;
|
||||
import org.jetbrains.plugins.gradle.util.GradleBundle;
|
||||
import org.jetbrains.plugins.gradle.util.GradleLog;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Encapsulates functionality of creating IntelliJ IDEA modules on the basis of {@link GradleModule gradle modules}.
|
||||
* <p/>
|
||||
* Not thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/26/11 10:01 AM
|
||||
*/
|
||||
// TODO den remove
|
||||
public class GradleModulesImporter {
|
||||
|
||||
private static final Map<LibraryPathType, OrderRootType> LIBRARY_ROOT_MAPPINGS
|
||||
= new EnumMap<LibraryPathType, OrderRootType>(LibraryPathType.class);
|
||||
static {
|
||||
LIBRARY_ROOT_MAPPINGS.put(LibraryPathType.BINARY, OrderRootType.CLASSES);
|
||||
LIBRARY_ROOT_MAPPINGS.put(LibraryPathType.SOURCE, OrderRootType.SOURCES);
|
||||
LIBRARY_ROOT_MAPPINGS.put(LibraryPathType.DOC, JavadocOrderRootType.getInstance());
|
||||
assert LibraryPathType.values().length == LIBRARY_ROOT_MAPPINGS.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* We can't modify project modules (add/remove) until it's initialised, so, we delay that activity. Current constant
|
||||
* holds number of milliseconds to wait between 'after project initialisation' processing attempts.
|
||||
*/
|
||||
private static final int PROJECT_INITIALISATION_DELAY_MS = (int)TimeUnit.SECONDS.toMillis(1);
|
||||
|
||||
private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
|
||||
|
||||
/**
|
||||
* Entry point for the whole 'import modules' procedure.
|
||||
*
|
||||
* @param modules module info containers received from the gradle api
|
||||
* @param project project that should host the modules
|
||||
* @param model modules model
|
||||
* @param gradleProjectPath file system path to the gradle project file being imported
|
||||
* @return mappings between the given gradle modules and newly created intellij modules
|
||||
*/
|
||||
@NotNull
|
||||
public Map<GradleModule, Module> importModules(@NotNull final Iterable<GradleModule> modules, @Nullable final Project project,
|
||||
@Nullable final ModifiableModuleModel model, @NotNull String gradleProjectPath)
|
||||
{
|
||||
if (project == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
removeExistingModulesSettings(modules);
|
||||
if (!project.isInitialized()) {
|
||||
myAlarm.addRequest(new ImportModulesTask(project, modules, gradleProjectPath), PROJECT_INITIALISATION_DELAY_MS);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
if (model == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return importModules(modules, model, project, gradleProjectPath);
|
||||
}
|
||||
|
||||
private static void removeExistingModulesSettings(@NotNull Iterable<GradleModule> modules) {
|
||||
for (GradleModule module : modules) {
|
||||
// Remove existing '*.iml' file if necessary.
|
||||
final String moduleFilePath = module.getModuleFilePath();
|
||||
File file = new File(moduleFilePath);
|
||||
if (file.isFile()) {
|
||||
boolean success = file.delete();
|
||||
if (!success) {
|
||||
GradleLog.LOG.warn("Can't remove existing module file at '" + moduleFilePath + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<GradleModule, Module> importModules(@NotNull final Iterable<GradleModule> modules,
|
||||
@NotNull final ModifiableModuleModel model,
|
||||
@NotNull final Project intellijProject,
|
||||
@NotNull final String gradleProjectPath)
|
||||
{
|
||||
final Map<GradleModule, Module> result = new HashMap<GradleModule, Module>();
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Application application = ApplicationManager.getApplication();
|
||||
AccessToken writeLock = application.acquireWriteActionLock(getClass());
|
||||
try {
|
||||
final List<ModifiableRootModel> rootModels = new ArrayList<ModifiableRootModel>();
|
||||
final GradleProjectEntityChangeListener publisher =
|
||||
intellijProject.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC);
|
||||
for (GradleModule module : modules) {
|
||||
publisher.onChangeStart(module);
|
||||
}
|
||||
try {
|
||||
Map<GradleModule, Module> moduleMappings = doImportModules(modules, model, rootModels);
|
||||
result.putAll(moduleMappings);
|
||||
myAlarm.cancelAllRequests();
|
||||
myAlarm.addRequest(
|
||||
new SetupExternalLibrariesTask(moduleMappings, gradleProjectPath, intellijProject),
|
||||
PROJECT_INITIALISATION_DELAY_MS
|
||||
);
|
||||
}
|
||||
finally {
|
||||
ModifiableRootModel[] modelsAsArray = rootModels.toArray(new ModifiableRootModel[rootModels.size()]);
|
||||
ModifiableModelCommitter.multiCommit(modelsAsArray, model);
|
||||
for (GradleModule module : modules) {
|
||||
publisher.onChangeEnd(module);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
writeLock.finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actual implementation of {@link #importModules(Iterable, Project, ModifiableModuleModel, String)}.
|
||||
* Insists on all arguments to be ready to use.
|
||||
*
|
||||
* @param modules modules to import
|
||||
* @param model modules model
|
||||
* @param rootModels holder for the module root modules. Is expected to be populated during the current method processing
|
||||
* @return mappings between the given gradle modules and corresponding intellij modules
|
||||
*/
|
||||
@NotNull
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
private Map<GradleModule, Module> doImportModules(@NotNull Iterable<GradleModule> modules,
|
||||
@NotNull ModifiableModuleModel model,
|
||||
@NotNull List<ModifiableRootModel> rootModels)
|
||||
{
|
||||
Map<GradleModule, Module> result = new HashMap<GradleModule, Module>();
|
||||
for (GradleModule moduleToImport : modules) {
|
||||
Module createdModule = createModule(moduleToImport, model);
|
||||
result.put(moduleToImport, createdModule);
|
||||
}
|
||||
for (GradleModule moduleToImport : modules) {
|
||||
ModifiableRootModel rootModel = configureModule(moduleToImport, result);
|
||||
rootModels.add(rootModel);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to create module objects for all modules at first and then configure them. That is necessary for setting up
|
||||
* module dependencies.
|
||||
*
|
||||
* @param module gradle module to import
|
||||
* @param model module model
|
||||
* @return newly created IJ module
|
||||
*/
|
||||
@NotNull
|
||||
private static Module createModule(@NotNull GradleModule module, @NotNull ModifiableModuleModel model) {
|
||||
Application application = ApplicationManager.getApplication();
|
||||
application.assertWriteAccessAllowed();
|
||||
final String moduleFilePath = module.getModuleFilePath();
|
||||
return model.newModule(moduleFilePath, StdModuleTypes.JAVA.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies module settings received from the gradle api (encapsulate at the given {@link GradleModule} object) to the
|
||||
* target intellij module (retrieved from the given module mappings).
|
||||
*
|
||||
* @param module target gradle module which corresponding intellij module should be configured
|
||||
* @param modules gradle module to intellij modules mappings. Is assumed to have a value for the given gradle modules used as a key
|
||||
* @return module roots model used during configuration
|
||||
*/
|
||||
@NotNull
|
||||
private static ModifiableRootModel configureModule(@NotNull GradleModule module, @NotNull Map<GradleModule, Module> modules) {
|
||||
Application application = ApplicationManager.getApplication();
|
||||
application.assertWriteAccessAllowed();
|
||||
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(modules.get(module));
|
||||
ModifiableRootModel rootModel = moduleRootManager.getModifiableModel();
|
||||
configureModule(module, rootModel, modules);
|
||||
return rootModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains actual logic of {@link #configureModule(GradleModule, Map)}.
|
||||
*
|
||||
* @param module target module settings holder
|
||||
* @param model intellij module setting manager
|
||||
* @param modules modules mappings
|
||||
*/
|
||||
private static void configureModule(@NotNull GradleModule module, @NotNull final ModifiableRootModel model,
|
||||
@NotNull final Map<GradleModule, Module> modules)
|
||||
{
|
||||
// Ensure that dependencies are clear.
|
||||
final Object key = new Object();
|
||||
final Object dummy = new Object();
|
||||
RootPolicy<Object> policy = new RootPolicy<Object>() {
|
||||
@Override
|
||||
public Object visitModuleSourceOrderEntry(ModuleSourceOrderEntry moduleSourceOrderEntry, Object value) {
|
||||
return key;
|
||||
}
|
||||
};
|
||||
for (OrderEntry orderEntry : model.getOrderEntries()) {
|
||||
// Don't remove 'module source' order entry (configured automatically on module creation).
|
||||
if (key != orderEntry.accept(policy, dummy)) {
|
||||
model.removeOrderEntry(orderEntry);
|
||||
}
|
||||
}
|
||||
|
||||
// Configure SDK.
|
||||
model.inheritSdk();
|
||||
|
||||
// Compile output.
|
||||
CompilerModuleExtension compilerExtension = model.getModuleExtension(CompilerModuleExtension.class);
|
||||
compilerExtension.inheritCompilerOutputPath(module.isInheritProjectCompileOutputPath());
|
||||
if (!module.isInheritProjectCompileOutputPath()) {
|
||||
String compileOutputPath = module.getCompileOutputPath(SourceType.SOURCE);
|
||||
String testCompileOutputPath = module.getCompileOutputPath(SourceType.TEST);
|
||||
if (StringUtil.isEmpty(compileOutputPath) || StringUtil.isEmpty(testCompileOutputPath)) {
|
||||
GradleLog.LOG.warn(String.format(
|
||||
"Module '%s' doesn't inherit project compile output path but has incomplete local setup. Falling back to the project "
|
||||
+ "compile output path. Local compile output path: '%s', local test compile output path: '%s'",
|
||||
module.getName(), compileOutputPath, testCompileOutputPath
|
||||
));
|
||||
compilerExtension.inheritCompilerOutputPath(true);
|
||||
}
|
||||
else {
|
||||
compilerExtension.setCompilerOutputPath(compileOutputPath);
|
||||
compilerExtension.setCompilerOutputPathForTests(testCompileOutputPath);
|
||||
}
|
||||
}
|
||||
|
||||
// Content roots.
|
||||
for (GradleContentRoot contentRoot : module.getContentRoots()) {
|
||||
ContentEntry contentEntry = model.addContentEntry(toVfsUrl(contentRoot.getRootPath()));
|
||||
for (String path : contentRoot.getPaths(SourceType.SOURCE)) {
|
||||
contentEntry.addSourceFolder(toVfsUrl(path), false);
|
||||
}
|
||||
for (String path : contentRoot.getPaths(SourceType.TEST)) {
|
||||
contentEntry.addSourceFolder(toVfsUrl(path), true);
|
||||
}
|
||||
for (String path : contentRoot.getPaths(SourceType.EXCLUDED)) {
|
||||
contentEntry.addExcludeFolder(toVfsUrl(path));
|
||||
}
|
||||
}
|
||||
|
||||
// Module dependencies.
|
||||
for (GradleDependency dependency : module.getDependencies()) {
|
||||
dependency.invite(new GradleEntityVisitorAdapter() {
|
||||
@Override
|
||||
public void visit(@NotNull GradleModuleDependency dependency) {
|
||||
ModuleOrderEntry orderEntry = model.addModuleOrderEntry(modules.get(dependency.getTarget()));
|
||||
orderEntry.setExported(dependency.isExported());
|
||||
orderEntry.setScope(dependency.getScope());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves (downloads if necessary) external libraries necessary for the gradle project located at the given path and configures
|
||||
* them for the corresponding intellij project.
|
||||
* <p/>
|
||||
* <b>Note:</b> is assumed to be executed under write action.
|
||||
*
|
||||
* @param moduleMappings gradle-intellij module mappings
|
||||
* @param intellijProject intellij project for the target gradle project
|
||||
* @param gradleProjectPath file system path to the target gradle project
|
||||
*/
|
||||
private static void setupLibraries(@NotNull final Map<GradleModule, Module> moduleMappings,
|
||||
@NotNull final Project intellijProject,
|
||||
@NotNull final String gradleProjectPath)
|
||||
{
|
||||
final Ref<GradleProject> gradleProjectRef = new Ref<GradleProject>();
|
||||
final Ref<Library> libraryToPreserve = new Ref<Library>();
|
||||
|
||||
final Runnable setupExternalDependenciesTask = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final GradleProject gradleProject = gradleProjectRef.get();
|
||||
if (gradleProject == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Application application = ApplicationManager.getApplication();
|
||||
AccessToken writeLock = application.acquireWriteActionLock(getClass());
|
||||
try {
|
||||
doSetupLibraries(moduleMappings, gradleProject, intellijProject, libraryToPreserve.get());
|
||||
}
|
||||
finally {
|
||||
writeLock.finish();
|
||||
}
|
||||
|
||||
if (intellijProject.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Force refresh the infrastructure in order to apply newly introduce intellij project structure changes
|
||||
final GradleProjectStructureChangesModel changesModel = intellijProject.getComponent(GradleProjectStructureChangesModel.class);
|
||||
if (changesModel != null) {
|
||||
final GradleProject project = changesModel.getGradleProject();
|
||||
if (project != null) {
|
||||
changesModel.update(project);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
final Runnable resolveDependenciesTask = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProgressManager.getInstance().run(
|
||||
new Task.Backgroundable(intellijProject, GradleBundle.message("gradle.library.resolve.progress.text"), false) {
|
||||
@Override
|
||||
public void run(@NotNull final ProgressIndicator indicator) {
|
||||
GradleResolveProjectTask task = new GradleResolveProjectTask(intellijProject, gradleProjectPath, true);
|
||||
task.execute(indicator);
|
||||
GradleProject projectWithResolvedLibraries = task.getGradleProject();
|
||||
gradleProjectRef.set(projectWithResolvedLibraries);
|
||||
ApplicationManager.getApplication().invokeLater(setupExternalDependenciesTask, ModalityState.NON_MODAL);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
UIUtil.invokeLaterIfNeeded(resolveDependenciesTask);
|
||||
}
|
||||
|
||||
private static void doSetupLibraries(@NotNull Map<GradleModule, Module> moduleMappings,
|
||||
@NotNull GradleProject gradleProject,
|
||||
@NotNull Project intellijProject,
|
||||
@Nullable Library libraryToPreserve) {
|
||||
if (intellijProject.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
Application application = ApplicationManager.getApplication();
|
||||
application.assertWriteAccessAllowed();
|
||||
|
||||
LibraryTable projectLibraryTable = ProjectLibraryTable.getInstance(intellijProject);
|
||||
if (projectLibraryTable == null) {
|
||||
GradleLog.LOG.warn(
|
||||
"Can't resolve external dependencies of the target gradle project (" + intellijProject + "). Reason: project "
|
||||
+ "library table is undefined"
|
||||
);
|
||||
return;
|
||||
}
|
||||
LibraryTable.ModifiableModel model = projectLibraryTable.getModifiableModel();
|
||||
// Clean existing libraries (if any).
|
||||
try {
|
||||
for (Library library : model.getLibraries()) {
|
||||
if (libraryToPreserve != library) {
|
||||
model.removeLibrary(library);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
model.commit();
|
||||
}
|
||||
|
||||
model = projectLibraryTable.getModifiableModel();
|
||||
List<ModifiableRootModel> modelsToCommit = new ArrayList<ModifiableRootModel>();
|
||||
Map<GradleLibrary, Library> libraryMappings = registerProjectLibraries(gradleProject, model);
|
||||
final GradleProjectEntityChangeListener publisher
|
||||
= intellijProject.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC);
|
||||
try {
|
||||
if (libraryMappings == null) {
|
||||
return;
|
||||
}
|
||||
for (GradleLibrary library : libraryMappings.keySet()) {
|
||||
publisher.onChangeStart(library);
|
||||
}
|
||||
modelsToCommit.addAll(configureModulesLibraryDependencies(moduleMappings, libraryMappings, gradleProject));
|
||||
}
|
||||
finally {
|
||||
model.commit();
|
||||
ProjectRootManager projectRootManager = ProjectRootManager.getInstance(intellijProject);
|
||||
ModifiableRootModel[] modelsAsArray = modelsToCommit.toArray(new ModifiableRootModel[modelsToCommit.size()]);
|
||||
if (modelsAsArray.length > 0) {
|
||||
ModifiableModelCommitter.multiCommit(modelsAsArray, ModuleManager.getInstance(modelsAsArray[0].getProject()).getModifiableModel());
|
||||
}
|
||||
if (libraryMappings != null) {
|
||||
for (GradleLibrary library : libraryMappings.keySet()) {
|
||||
publisher.onChangeEnd(library);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers {@link GradleProject#getLibraries() libraries} of the given gradle project at the intellij project.
|
||||
*
|
||||
* @param gradleProject target gradle project being imported
|
||||
* @param librariesModel model that manages project libraries
|
||||
* @return mapping between libraries of the given gradle and intellij projects
|
||||
*/
|
||||
@Nullable
|
||||
private static Map<GradleLibrary, Library> registerProjectLibraries(@NotNull GradleProject gradleProject,
|
||||
@NotNull LibraryTable.ModifiableModel librariesModel)
|
||||
{
|
||||
Map<GradleLibrary, Library> libraryMappings = new HashMap<GradleLibrary, Library>();
|
||||
for (GradleLibrary gradleLibrary : gradleProject.getLibraries()) {
|
||||
Library intellijLibrary = librariesModel.createLibrary(gradleLibrary.getName());
|
||||
libraryMappings.put(gradleLibrary, intellijLibrary);
|
||||
Library.ModifiableModel model = intellijLibrary.getModifiableModel();
|
||||
try {
|
||||
registerPath(gradleLibrary, model);
|
||||
}
|
||||
finally {
|
||||
model.commit();
|
||||
}
|
||||
}
|
||||
return libraryMappings;
|
||||
}
|
||||
|
||||
private static Collection<ModifiableRootModel> configureModulesLibraryDependencies(
|
||||
@NotNull Map<GradleModule, Module> moduleMappings,
|
||||
@NotNull final Map<GradleLibrary, Library> libraryMappings,
|
||||
@NotNull GradleProject gradleProject)
|
||||
{
|
||||
List<ModifiableRootModel> result = new ArrayList<ModifiableRootModel>();
|
||||
for (GradleModule gradleModule : gradleProject.getModules()) {
|
||||
Module intellijModule = moduleMappings.get(gradleModule);
|
||||
if (intellijModule == null) {
|
||||
GradleLog.LOG.warn(String.format(
|
||||
"Can't find intellij module for the gradle module '%s'. Registered mappings: %s", gradleModule, moduleMappings
|
||||
));
|
||||
continue;
|
||||
}
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(intellijModule);
|
||||
final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel();
|
||||
result.add(moduleRootModel);
|
||||
GradleEntityVisitor visitor = new GradleEntityVisitorAdapter() {
|
||||
@Override
|
||||
public void visit(@NotNull GradleLibraryDependency dependency) {
|
||||
GradleLibrary gradleLibrary = dependency.getTarget();
|
||||
Library intellijLibrary = libraryMappings.get(gradleLibrary);
|
||||
if (intellijLibrary == null) {
|
||||
GradleLog.LOG.warn(String.format(
|
||||
"Can't find registered intellij library for gradle library '%s'. Registered mappings: %s", gradleLibrary, libraryMappings
|
||||
));
|
||||
return;
|
||||
}
|
||||
LibraryOrderEntry orderEntry = moduleRootModel.addLibraryEntry(intellijLibrary);
|
||||
orderEntry.setExported(dependency.isExported());
|
||||
orderEntry.setScope(dependency.getScope());
|
||||
}
|
||||
};
|
||||
for (GradleDependency dependency : gradleModule.getDependencies()) {
|
||||
dependency.invite(visitor);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void registerPath(@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));
|
||||
if (virtualFile == null) {
|
||||
GradleLog.LOG.warn(String.format("Can't find %s of the library '%s' at path '%s'", pathType, gradleLibrary.getName(), path));
|
||||
continue;
|
||||
}
|
||||
if (virtualFile.isDirectory()) {
|
||||
model.addRoot(virtualFile, LIBRARY_ROOT_MAPPINGS.get(pathType));
|
||||
}
|
||||
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()
|
||||
));
|
||||
continue;
|
||||
}
|
||||
model.addRoot(jarRoot, LIBRARY_ROOT_MAPPINGS.get(pathType));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String toVfsUrl(@NotNull String path) {
|
||||
return LocalFileSystem.PROTOCOL_PREFIX + path;
|
||||
}
|
||||
|
||||
private class ImportModulesTask implements Runnable {
|
||||
|
||||
private final Project myProject;
|
||||
private final Iterable<GradleModule> myModules;
|
||||
private final String myGradleProjectPath;
|
||||
|
||||
ImportModulesTask(@NotNull Project project, @NotNull Iterable<GradleModule> modules, @NotNull String gradleProjectPath) {
|
||||
myProject = project;
|
||||
myModules = modules;
|
||||
myGradleProjectPath = gradleProjectPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
myAlarm.cancelAllRequests();
|
||||
if (!myProject.isInitialized()) {
|
||||
myAlarm.addRequest(
|
||||
new ImportModulesTask(myProject, myModules, myGradleProjectPath),
|
||||
PROJECT_INITIALISATION_DELAY_MS
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final ModifiableModuleModel model = new ReadAction<ModifiableModuleModel>() {
|
||||
protected void run(Result<ModifiableModuleModel> result) throws Throwable {
|
||||
result.setResult(ModuleManager.getInstance(myProject).getModifiableModel());
|
||||
}
|
||||
}.execute().getResultObject();
|
||||
|
||||
importModules(myModules, model, myProject, myGradleProjectPath);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SetupExternalLibrariesTask implements Runnable {
|
||||
|
||||
private final Map<GradleModule, Module> myModules;
|
||||
private final String myGradleProjectPath;
|
||||
private final Project myIntellijProject;
|
||||
|
||||
SetupExternalLibrariesTask(@NotNull Map<GradleModule, Module> modules,
|
||||
@NotNull String gradleProjectPath,
|
||||
@NotNull Project intellijProject)
|
||||
{
|
||||
myModules = modules;
|
||||
myGradleProjectPath = gradleProjectPath;
|
||||
myIntellijProject = intellijProject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
setupLibraries(myModules, myIntellijProject, myGradleProjectPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
+130
-40
@@ -4,11 +4,18 @@ import com.intellij.ide.util.projectWizard.WizardContext;
|
||||
import com.intellij.openapi.module.ModifiableModuleModel;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.projectRoots.JavaSdk;
|
||||
import com.intellij.openapi.projectRoots.SdkTypeId;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
|
||||
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
@@ -16,14 +23,17 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.packaging.artifacts.ModifiableArtifactModel;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.projectImport.ProjectImportBuilder;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import icons.GradleIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.gradle.config.GradleConfigurable;
|
||||
import org.jetbrains.plugins.gradle.config.GradleSettings;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleEntity;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleModule;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleProject;
|
||||
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper;
|
||||
import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask;
|
||||
import org.jetbrains.plugins.gradle.util.GradleBundle;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
import org.jetbrains.plugins.gradle.util.GradleLog;
|
||||
@@ -31,7 +41,10 @@ import org.jetbrains.plugins.gradle.util.GradleUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* GoF builder for gradle-backed projects.
|
||||
@@ -42,12 +55,22 @@ import java.util.*;
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProject> {
|
||||
|
||||
/** @see #setModuleMappings(Map) */
|
||||
private final Map<GradleModule/*origin*/, GradleModule/*adjusted*/> myModuleMappings = new HashMap<GradleModule, GradleModule>();
|
||||
|
||||
private GradleProject myGradleProject;
|
||||
@NotNull private final GradleModuleManager myModuleManager;
|
||||
@NotNull private final GradleLibraryManager myLibraryManager;
|
||||
@NotNull private final GradleDependencyManager myDependencyManager;
|
||||
|
||||
private GradleProject myGradleProject;
|
||||
private GradleConfigurable myConfigurable;
|
||||
|
||||
public GradleProjectImportBuilder(@NotNull GradleModuleManager moduleManager,
|
||||
@NotNull GradleLibraryManager libraryManager,
|
||||
@NotNull GradleDependencyManager manager)
|
||||
{
|
||||
myModuleManager = moduleManager;
|
||||
myLibraryManager = libraryManager;
|
||||
myDependencyManager = manager;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
@@ -93,12 +116,13 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
|
||||
}
|
||||
myConfigurable.setLinkedGradleProjectPath(pathToUse);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Module> commit(final Project project,
|
||||
ModifiableModuleModel model,
|
||||
ModulesProvider modulesProvider,
|
||||
ModifiableArtifactModel artifactModel) {
|
||||
ModifiableArtifactModel artifactModel)
|
||||
{
|
||||
System.setProperty(GradleConstants.NEWLY_IMPORTED_PROJECT, Boolean.TRUE.toString());
|
||||
final GradleProject gradleProject = getGradleProject();
|
||||
if (gradleProject != null) {
|
||||
@@ -114,15 +138,107 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
|
||||
GradleSettings.applyLinkedProjectPath(myConfigurable.getLinkedProjectPath(), project);
|
||||
GradleSettings.applyPreferLocalInstallationToWrapper(myConfigurable.isPreferLocalInstallationToWrapper(), project);
|
||||
GradleSettings.applyGradleHome(myConfigurable.getGradleHomePath(), project);
|
||||
|
||||
if (gradleProject != null) {
|
||||
GradleUtil.executeProjectChangeAction(project, project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProjectRootManagerEx.getInstanceEx(project).mergeRootsChangesDuring(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myModuleManager.importModules(gradleProject.getModules(), project, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
final Runnable resolveDependenciesTask = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProgressManager.getInstance().run(
|
||||
new Task.Backgroundable(project, GradleBundle.message("gradle.library.resolve.progress.text"), false) {
|
||||
@Override
|
||||
public void run(@NotNull final ProgressIndicator indicator) {
|
||||
String linkedProjectPath = myConfigurable.getLinkedProjectPath();
|
||||
assert linkedProjectPath != null;
|
||||
GradleResolveProjectTask task = new GradleResolveProjectTask(project, linkedProjectPath, true);
|
||||
task.execute(indicator);
|
||||
GradleProject projectWithResolvedLibraries = task.getGradleProject();
|
||||
if (projectWithResolvedLibraries == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setupLibraries(projectWithResolvedLibraries, project);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
UIUtil.invokeLaterIfNeeded(resolveDependenciesTask);
|
||||
}
|
||||
}
|
||||
});
|
||||
GradleModulesImporter importer = new GradleModulesImporter();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
File projectFile = getProjectFile();
|
||||
assert projectFile != null;
|
||||
Map<GradleModule, Module> mappings =
|
||||
importer.importModules(myModuleMappings.values(), project, model, projectFile.getAbsolutePath());
|
||||
return new ArrayList<Module>(mappings.values());
|
||||
/**
|
||||
* The whole import sequence looks like below:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* <ol>
|
||||
* <li>Get project view from the gradle tooling api without resolving dependencies (downloading libraries);</li>
|
||||
* <li>Allow to adjust project settings before importing;</li>
|
||||
* <li>Create IJ project and modules;</li>
|
||||
* <li>Ask gradle tooling api to resolve library dependencies (download the if necessary);</li>
|
||||
* <li>Configure libraries used by the gradle project at intellij;</li>
|
||||
* <li>Configure library dependencies;</li>
|
||||
* </ol>
|
||||
* </pre>
|
||||
* <p/>
|
||||
*
|
||||
* @param projectWithResolvedLibraries gradle project with resolved libraries (libraries have already been downloaded and
|
||||
* are available at file system under gradle service directory)
|
||||
* @param project current intellij project which should be configured by libraries and module library
|
||||
* dependencies information available at the given gradle project
|
||||
*/
|
||||
private void setupLibraries(final GradleProject projectWithResolvedLibraries, final Project project) {
|
||||
final Set<? extends GradleLibrary> libraries = projectWithResolvedLibraries.getLibraries();
|
||||
GradleUtil.executeProjectChangeAction(project, libraries, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProjectRootManagerEx.getInstanceEx(project).mergeRootsChangesDuring(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Clean existing libraries (if any).
|
||||
LibraryTable projectLibraryTable = ProjectLibraryTable.getInstance(project);
|
||||
if (projectLibraryTable == null) {
|
||||
GradleLog.LOG.warn(
|
||||
"Can't resolve external dependencies of the target gradle project (" + project + "). Reason: project "
|
||||
+ "library table is undefined"
|
||||
);
|
||||
return;
|
||||
}
|
||||
LibraryTable.ModifiableModel model = projectLibraryTable.getModifiableModel();
|
||||
try {
|
||||
for (Library library : model.getLibraries()) {
|
||||
model.removeLibrary(library);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
model.commit();
|
||||
}
|
||||
|
||||
// Register libraries.
|
||||
myLibraryManager.importLibraries(projectWithResolvedLibraries.getLibraries(), project);
|
||||
GradleProjectStructureHelper helper = project.getComponent(GradleProjectStructureHelper.class);
|
||||
for (GradleModule module : projectWithResolvedLibraries.getModules()) {
|
||||
Module intellijModule = helper.findIntellijModule(module);
|
||||
assert intellijModule != null;
|
||||
myDependencyManager.importDependencies(module.getDependencies(), intellijModule);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -206,32 +322,6 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
|
||||
context.setProjectJdk(myGradleProject.getSdk());
|
||||
}
|
||||
|
||||
/**
|
||||
* The whole import sequence looks like below:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* <ol>
|
||||
* <li>Get project view from the gradle tooling api without resolving dependencies (downloading libraries);</li>
|
||||
* <li>Allow to adjust project settings before importing;</li>
|
||||
* <li>Create IJ project and modules;</li>
|
||||
* <li>Ask gradle tooling api to resolve library dependencies (download the if necessary);</li>
|
||||
* <li>Configure modules dependencies;</li>
|
||||
* </ol>
|
||||
* </pre>
|
||||
* <p/>
|
||||
* {@link GradleEntity} guarantees correct {@link #equals(Object)}/{@link #hashCode()} implementation, so, we expect
|
||||
* to get {@link GradleModule modules} that are the same in terms of {@link #equals(Object)} on subsequent calls. However,
|
||||
* end-user is allowed to change their settings before the importing (e.g. module name), so, we need to map modules with
|
||||
* resolved libraries to the modules from project 'view'. That's why end-user adjusts settings of the cloned modules.
|
||||
* Given collection holds mappings between them.
|
||||
*
|
||||
* @param mappings origin-adjusted modules mappings
|
||||
*/
|
||||
public void setModuleMappings(@NotNull Map<GradleModule/*origin module*/, GradleModule/*adjusted module*/> mappings) {
|
||||
myModuleMappings.clear();
|
||||
myModuleMappings.putAll(mappings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to get {@link Project} instance to use. Basically, there are two alternatives -
|
||||
* {@link WizardContext#getProject() project from the current wizard context} and
|
||||
|
||||
+1
-6
@@ -188,15 +188,11 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza
|
||||
List<GradleModule> modules = new ArrayList<GradleModule>(project.getModules());
|
||||
Collections.sort(modules, Named.COMPARATOR);
|
||||
List<MutableTreeNode> moduleNodes = new ArrayList<MutableTreeNode>();
|
||||
Map<GradleModule, GradleModule> moduleMappings = new HashMap<GradleModule, GradleModule>();
|
||||
|
||||
GradleEntityCloneContext cloneContext = new GradleEntityCloneContext();
|
||||
for (GradleModule module : modules) {
|
||||
GradleModule moduleCopy = module.clone(cloneContext);
|
||||
moduleMappings.put(module, moduleCopy);
|
||||
GradleProjectStructureNode<GradleEntityId> moduleNode = buildNode(module, entity2nodes, counter++);
|
||||
moduleNodes.add(moduleNode);
|
||||
for (GradleContentRoot contentRoot : moduleCopy.getContentRoots()) {
|
||||
for (GradleContentRoot contentRoot : module.getContentRoots()) {
|
||||
moduleNode.add(buildNode(contentRoot, entity2nodes, counter++));
|
||||
}
|
||||
Collection<GradleDependency> dependencies = module.getDependencies();
|
||||
@@ -263,7 +259,6 @@ public class GradleAdjustImportSettingsStep extends AbstractImportFromGradleWiza
|
||||
}
|
||||
|
||||
myTree.expandPath(new TreePath(root.getPath()));
|
||||
builder.setModuleMappings(moduleMappings);
|
||||
}
|
||||
|
||||
private GradleProjectStructureNode<GradleEntityId> buildNode(
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ public class GradleApiFacadeImpl extends RemoteServer implements GradleApiFacade
|
||||
try {
|
||||
I stub = (I)UnicastRemoteObject.exportObject(proxy, 0);
|
||||
I stored = (I)myRemotes.putIfAbsent(implClass, stub);
|
||||
return stored == null ? result : stored;
|
||||
return stored == null ? stub : stored;
|
||||
}
|
||||
catch (RemoteException e) {
|
||||
Object raceResult = myRemotes.get(implClass);
|
||||
|
||||
+28
-4
@@ -3,10 +3,7 @@ package org.jetbrains.plugins.gradle.sync;
|
||||
import com.intellij.openapi.components.AbstractProjectComponent;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.LibraryOrderEntry;
|
||||
import com.intellij.openapi.roots.ModuleOrderEntry;
|
||||
import com.intellij.openapi.roots.OrderEntry;
|
||||
import com.intellij.openapi.roots.RootPolicy;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
@@ -177,6 +174,21 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public LibraryOrderEntry findIntellijLibraryDependency(@NotNull final String libraryName,
|
||||
@NotNull ModifiableRootModel model)
|
||||
{
|
||||
for (OrderEntry entry : model.getOrderEntries()) {
|
||||
if (entry instanceof LibraryOrderEntry) {
|
||||
LibraryOrderEntry candidate = (LibraryOrderEntry)entry;
|
||||
if (libraryName.equals(candidate.getLibraryName())) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GradleLibrary findGradleLibrary(@NotNull final String libraryName) {
|
||||
final GradleProject project = myModel.getGradleProject();
|
||||
@@ -268,6 +280,18 @@ public class GradleProjectStructureHelper extends AbstractProjectComponent {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ModuleOrderEntry findIntellijModuleDependency(@NotNull GradleModuleDependency dependency, @NotNull ModifiableRootModel model) {
|
||||
for (OrderEntry entry : model.getOrderEntries()) {
|
||||
if (entry instanceof ModuleOrderEntry) {
|
||||
ModuleOrderEntry candidate = (ModuleOrderEntry)entry;
|
||||
if (dependency.getName().equals(candidate.getModuleName())) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,9 @@ public abstract class AbstractGradleTask implements GradleTask {
|
||||
catch (Throwable e) {
|
||||
setState(GradleTaskState.FAILED);
|
||||
myError.set(e);
|
||||
LOG.warn(e);
|
||||
if (myIntellijProject == null || !myIntellijProject.isDisposed()) {
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -503,23 +503,34 @@ public class GradleUtil {
|
||||
return INSTALLATION_MANAGER.getValue().getGradleHome(project) != null;
|
||||
}
|
||||
|
||||
|
||||
public static void executeProjectChangeAction(@NotNull Project project, @NotNull Object entityToChange, @NotNull Runnable task) {
|
||||
executeProjectChangeAction(project, Collections.singleton(entityToChange), task);
|
||||
}
|
||||
|
||||
public static void executeProjectChangeAction(@NotNull Project project, @NotNull Iterable<?> entitiesToChange, @NotNull Runnable task) {
|
||||
final GradleProjectEntityChangeListener publisher = project.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC);
|
||||
for (Object e : entitiesToChange) {
|
||||
publisher.onChangeStart(e);
|
||||
}
|
||||
try {
|
||||
task.run();
|
||||
}
|
||||
finally {
|
||||
for (Object e : entitiesToChange) {
|
||||
publisher.onChangeEnd(e);
|
||||
public static void executeProjectChangeAction(@NotNull final Project project, @NotNull final Iterable<?> entitiesToChange, @NotNull final Runnable task) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final GradleProjectEntityChangeListener publisher = project.getMessageBus().syncPublisher(GradleProjectEntityChangeListener.TOPIC);
|
||||
for (Object e : entitiesToChange) {
|
||||
publisher.onChangeStart(e);
|
||||
}
|
||||
try {
|
||||
task.run();
|
||||
}
|
||||
finally {
|
||||
for (Object e : entitiesToChange) {
|
||||
publisher.onChangeEnd(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private interface TaskUnderProgress {
|
||||
|
||||
@@ -54,23 +54,26 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
|
||||
}
|
||||
|
||||
public FileAnnotation annotate(final VirtualFile file) throws VcsException {
|
||||
final VcsRevisionDescription currentRevision = ((SvnDiffProvider) myVcs.getDiffProvider()).getCurrentRevisionDescription(file);
|
||||
if (currentRevision == null) {
|
||||
final SvnDiffProvider provider = (SvnDiffProvider)myVcs.getDiffProvider();
|
||||
final SVNRevision currentRevision = ((SvnRevisionNumber)provider.getCurrentRevision(file)).getRevision();
|
||||
final VcsRevisionDescription lastChangedRevision = provider.getCurrentRevisionDescription(file);
|
||||
if (lastChangedRevision == null) {
|
||||
throw new VcsException("Can not get current revision for file " + file.getPath());
|
||||
}
|
||||
final SvnRevisionNumber lastChangedRevision = (SvnRevisionNumber)currentRevision.getRevisionNumber();
|
||||
if (! lastChangedRevision.getRevision().isValid()) {
|
||||
final SVNRevision svnRevision = ((SvnRevisionNumber)lastChangedRevision.getRevisionNumber()).getRevision();
|
||||
if (! svnRevision.isValid()) {
|
||||
throw new VcsException("Can not get last changed revision for file: " + file.getPath() + "\nPlease run svn info for this file and file an issue.");
|
||||
}
|
||||
final SVNRevision svnRevision = lastChangedRevision.getRevision();
|
||||
return annotate(file, new SvnFileRevision(myVcs, svnRevision, svnRevision, null, null, null, null, null, file.getCharset()), true);
|
||||
return annotate(file, new SvnFileRevision(myVcs, currentRevision, currentRevision, null, null, null, null, null, file.getCharset()),
|
||||
lastChangedRevision.getRevisionNumber(), true);
|
||||
}
|
||||
|
||||
public FileAnnotation annotate(final VirtualFile file, final VcsFileRevision revision) throws VcsException {
|
||||
return annotate(file, revision, false);
|
||||
return annotate(file, revision, revision.getRevisionNumber(), false);
|
||||
}
|
||||
|
||||
private FileAnnotation annotate(final VirtualFile file, final VcsFileRevision revision, final boolean loadExternally) throws VcsException {
|
||||
private FileAnnotation annotate(final VirtualFile file, final VcsFileRevision revision, final VcsRevisionNumber lastChangedRevision,
|
||||
final boolean loadExternally) throws VcsException {
|
||||
if (file.isDirectory()) {
|
||||
throw new VcsException(SvnBundle.message("exception.text.cannot.annotate.directory"));
|
||||
}
|
||||
@@ -94,7 +97,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
|
||||
contents = LoadTextUtil.getTextByBinaryPresentation(bytes, file, false).toString();
|
||||
}
|
||||
|
||||
final SvnFileAnnotation result = new SvnFileAnnotation(myVcs, file, contents, revision.getRevisionNumber());
|
||||
final SvnFileAnnotation result = new SvnFileAnnotation(myVcs, file, contents, lastChangedRevision);
|
||||
|
||||
SVNWCClient wcClient = myVcs.createWCClient();
|
||||
info = wcClient.doInfo(ioFile, SVNRevision.UNDEFINED);
|
||||
@@ -229,7 +232,8 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
|
||||
charset == null ? CharsetToolkit.UTF8_CHARSET : charset).toString();
|
||||
SVNLogClient client = myVcs.createLogClient();
|
||||
setLogClientOptions(client);
|
||||
final SvnRemoteFileAnnotation result = new SvnRemoteFileAnnotation(myVcs, contents, revision.getRevisionNumber(), pair.getFirst(), pair.getSecond().getPath(), current);
|
||||
final SvnRemoteFileAnnotation result = new SvnRemoteFileAnnotation(myVcs, contents, revision.getRevisionNumber(), pair.getFirst(),
|
||||
pair.getSecond().getPath(), current);
|
||||
final ISVNAnnotateHandler annotateHandler = createAnnotationHandler(ProgressManager.getInstance().getProgressIndicator(), result);
|
||||
|
||||
final boolean calculateMergeinfo = SvnConfiguration.getInstance(myVcs.getProject()).SHOW_MERGE_SOURCES_IN_ANNOTATE &&
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.ui.ColorUtil;
|
||||
import com.intellij.xml.XmlBundle;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -451,22 +452,7 @@ public class ColorSampleLookupValue implements LookupValueWithUIHint, DeferredUs
|
||||
}
|
||||
String hexValue = text.charAt(0) == '#' ? text : getHexCodeForColorName(text.toLowerCase());
|
||||
if (hexValue != null) {
|
||||
String hexValue2 = hexValue.substring(1);
|
||||
if (hexValue2.length() == 3) {
|
||||
StringBuilder buf = new StringBuilder(6);
|
||||
buf.append(hexValue2.charAt(0)).append(hexValue2.charAt(0));
|
||||
buf.append(hexValue2.charAt(1)).append(hexValue2.charAt(1));
|
||||
buf.append(hexValue2.charAt(2)).append(hexValue2.charAt(2));
|
||||
|
||||
hexValue2 = buf.toString();
|
||||
}
|
||||
|
||||
try {
|
||||
return Color.decode("0x" + hexValue2);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
//ignore
|
||||
}
|
||||
return ColorUtil.fromHex(hexValue, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user