diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml
index 50b6a4bbf64c..57605dbe1969 100644
--- a/plugins/gradle/src/META-INF/plugin.xml
+++ b/plugins/gradle/src/META-INF/plugin.xml
@@ -80,6 +80,9 @@
org.jetbrains.plugins.gradle.model.id.GradleEntityIdMapper
+
+ org.jetbrains.plugins.gradle.util.GradleProjectStructureContext
+
org.jetbrains.plugins.gradle.importing.GradleLocalNodeImportHelper
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleToolWindowPanel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleToolWindowPanel.java
index 7cc983906126..146fa370e035 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleToolWindowPanel.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleToolWindowPanel.java
@@ -9,10 +9,8 @@ import com.intellij.ui.ScrollPaneFactory;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.gradle.diff.PlatformFacade;
-import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper;
-import org.jetbrains.plugins.gradle.util.GradleBundle;
import org.jetbrains.plugins.gradle.ui.RichTextControlBuilder;
+import org.jetbrains.plugins.gradle.util.GradleBundle;
import javax.swing.*;
import java.awt.*;
@@ -44,25 +42,15 @@ public abstract class GradleToolWindowPanel extends SimpleToolWindowPanel {
private final JPanel myContent = new JPanel(myLayout);
private final Project myProject;
- private final PlatformFacade myProjectFacade;
- private final GradleProjectStructureHelper myProjectStructureHelper;
-
- protected GradleToolWindowPanel(@NotNull Project project,
- @Nullable PlatformFacade projectFacade,
- @NotNull GradleProjectStructureHelper projectStructureHelper,
- @NotNull String place)
- {
+
+ protected GradleToolWindowPanel(@NotNull Project project, @NotNull String place) {
super(true);
myProject = project;
- myProjectFacade = projectFacade;
- myProjectStructureHelper = projectStructureHelper;
final ActionManager actionManager = ActionManager.getInstance();
final ActionGroup actionGroup = (ActionGroup)actionManager.getAction(TOOL_WINDOW_TOOLBAR_ID);
ActionToolbar actionToolbar = actionManager.createActionToolbar(place, actionGroup, true);
setToolbar(actionToolbar.getComponent());
- initContent();
setContent(myContent);
- update();
MessageBusConnection connection = project.getMessageBus().connect(project);
connection.subscribe(GradleConfigNotifier.TOPIC, new GradleConfigNotifier() {
@@ -73,7 +61,7 @@ public abstract class GradleToolWindowPanel extends SimpleToolWindowPanel {
});
}
- private void initContent() {
+ public void initContent() {
final JComponent payloadControl = buildContent();
myContent.add(ScrollPaneFactory.createScrollPane(payloadControl), CONTENT_CARD_NAME);
RichTextControlBuilder builder = new RichTextControlBuilder();
@@ -83,6 +71,7 @@ public abstract class GradleToolWindowPanel extends SimpleToolWindowPanel {
builder.setText(GradleBundle.message("gradle.toolwindow.text.no.linked.project"));
final JComponent noLinkedProjectControl = builder.build();
myContent.add(noLinkedProjectControl, NON_LINKED_CARD_NAME);
+ update();
}
/**
@@ -101,16 +90,6 @@ public abstract class GradleToolWindowPanel extends SimpleToolWindowPanel {
return myProject;
}
- @NotNull
- public PlatformFacade getProjectFacade() {
- return myProjectFacade;
- }
-
- @NotNull
- public GradleProjectStructureHelper getProjectStructureHelper() {
- return myProjectStructureHelper;
- }
-
/**
* @return GUI control to be displayed at the current tab
*/
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleDiffUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleDiffUtil.java
index 16ee64b7690f..a70baef647d3 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleDiffUtil.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/GradleDiffUtil.java
@@ -8,6 +8,7 @@ import com.intellij.openapi.roots.OrderEntry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.model.gradle.*;
import org.jetbrains.plugins.gradle.model.intellij.IntellijEntityVisitor;
+import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot;
import org.jetbrains.plugins.gradle.util.GradleUtil;
import java.util.HashMap;
@@ -90,11 +91,19 @@ public class GradleDiffUtil {
@Override
public void visit(@NotNull Module module) {
context.register(new GradleModulePresenceChange(null, module));
+ for (ModuleAwareContentRoot contentRoot : context.getPlatformFacade().getContentRoots(module)) {
+ visit(contentRoot);
+ }
for (OrderEntry entry : context.getPlatformFacade().getOrderEntries(module)) {
GradleUtil.dispatch(entry, this);
}
}
+ @Override
+ public void visit(@NotNull ModuleAwareContentRoot contentRoot) {
+ // TODO den implement
+ }
+
@Override
public void visit(@NotNull LibraryOrderEntry libraryDependency) {
final String libraryName = libraryDependency.getLibraryName();
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/PlatformFacade.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/PlatformFacade.java
index 042fae1757d5..4dcd8b0b4d62 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/PlatformFacade.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/PlatformFacade.java
@@ -7,6 +7,7 @@ import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot;
import java.util.Collection;
@@ -36,7 +37,10 @@ public interface PlatformFacade {
@NotNull
Collection getModules(@NotNull Project project);
-
+
+ @NotNull
+ Collection getContentRoots(@NotNull Module module);
+
@NotNull
Collection getOrderEntries(@NotNull Module module);
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/PlatformFacadeImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/PlatformFacadeImpl.java
index 587ffa7c7500..6399ca744c4b 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/PlatformFacadeImpl.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/diff/PlatformFacadeImpl.java
@@ -4,6 +4,7 @@ import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderEntry;
@@ -12,10 +13,14 @@ import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
/**
* @author Denis Zhdanov
@@ -41,6 +46,21 @@ public class PlatformFacadeImpl implements PlatformFacade {
return Arrays.asList(ModuleManager.getInstance(project).getModules());
}
+ @NotNull
+ @Override
+ public Collection getContentRoots(@NotNull final Module module) {
+ final ContentEntry[] entries = ModuleRootManager.getInstance(module).getContentEntries();
+ if (entries == null) {
+ return Collections.emptyList();
+ }
+ return ContainerUtil.map(entries, new Function() {
+ @Override
+ public ModuleAwareContentRoot fun(ContentEntry entry) {
+ return new ModuleAwareContentRoot(module, entry);
+ }
+ });
+ }
+
@NotNull
@Override
public Collection getOrderEntries(@NotNull Module module) {
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleContentRootId.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleContentRootId.java
index e73b70937e44..918c8167ad03 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleContentRootId.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleContentRootId.java
@@ -5,6 +5,7 @@ import org.jetbrains.plugins.gradle.model.GradleEntityOwner;
import org.jetbrains.plugins.gradle.model.GradleEntityType;
import org.jetbrains.plugins.gradle.model.gradle.GradleContentRoot;
import org.jetbrains.plugins.gradle.model.gradle.GradleModule;
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext;
/**
* @author Denis Zhdanov
@@ -21,8 +22,13 @@ public class GradleContentRootId extends GradleAbstractEntityId {
myRootPath = rootPath;
}
+ @NotNull
+ public String getRootPath() {
+ return myRootPath;
+ }
+
@Override
- public Object mapToEntity(@NotNull GradleEntityMappingContext context) {
+ public Object mapToEntity(@NotNull GradleProjectStructureContext context) {
switch (getOwner()) {
case GRADLE:
final GradleModule module = context.getProjectStructureHelper().findGradleModule(myModuleName);
@@ -39,4 +45,29 @@ public class GradleContentRootId extends GradleAbstractEntityId {
}
return null;
}
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + myModuleName.hashCode();
+ result = 31 * result + myRootPath.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!super.equals(o)) return false;
+
+ GradleContentRootId that = (GradleContentRootId)o;
+
+ if (!myModuleName.equals(that.myModuleName)) return false;
+ if (!myRootPath.equals(that.myRootPath)) return false;
+
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "content root '" + myRootPath + "'";
+ }
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityId.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityId.java
index 284b3680e50d..8184f2ce6a17 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityId.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityId.java
@@ -4,9 +4,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.model.GradleEntityOwner;
import org.jetbrains.plugins.gradle.model.GradleEntityType;
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext;
/**
- * Represent unique identifier object for any gralde or intellij project structure entity (module, library, library dependency etc).
+ * Represent unique identifier object for any gradle or intellij project structure entity (module, library, library dependency etc).
*
* We need an entity id, for example, at the 'sync project structure' tree - the model needs to keep mappings
* between the existing tree nodes and corresponding project structure entities. However, we can't keep the entity as is because
@@ -28,5 +29,5 @@ public interface GradleEntityId {
void setOwner(@NotNull GradleEntityOwner owner);
@Nullable
- Object mapToEntity(@NotNull GradleEntityMappingContext context);
+ Object mapToEntity(@NotNull GradleProjectStructureContext context);
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityIdMapper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityIdMapper.java
index 7e5c93141ff4..d9d7ad393b83 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityIdMapper.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityIdMapper.java
@@ -10,8 +10,8 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.model.GradleEntityOwner;
import org.jetbrains.plugins.gradle.model.gradle.*;
import org.jetbrains.plugins.gradle.model.intellij.IntellijEntityVisitor;
-import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesModel;
-import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper;
+import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot;
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext;
import org.jetbrains.plugins.gradle.util.GradleUtil;
/**
@@ -26,12 +26,10 @@ import org.jetbrains.plugins.gradle.util.GradleUtil;
*/
public class GradleEntityIdMapper {
- @NotNull GradleEntityMappingContext myMappingContext;
+ @NotNull GradleProjectStructureContext myMappingContext;
- public GradleEntityIdMapper(@NotNull GradleProjectStructureHelper projectStructureHelper,
- @NotNull GradleProjectStructureChangesModel changesModel)
- {
- myMappingContext = new GradleEntityMappingContext(projectStructureHelper, changesModel);
+ public GradleEntityIdMapper(@NotNull GradleProjectStructureContext context) {
+ myMappingContext = context;
}
/**
@@ -91,6 +89,11 @@ public class GradleEntityIdMapper {
result.set(new GradleModuleId(GradleEntityOwner.INTELLIJ, module.getName()));
}
+ @Override
+ public void visit(@NotNull ModuleAwareContentRoot contentRoot) {
+ result.set(new GradleContentRootId(GradleEntityOwner.INTELLIJ, contentRoot.getModule().getName(), contentRoot.getUrl()));
+ }
+
@Override
public void visit(@NotNull LibraryOrderEntry libraryDependency) {
final String libraryName = libraryDependency.getLibraryName();
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleLibraryDependencyId.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleLibraryDependencyId.java
index 6ad1b6187bdc..f799606a2af0 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleLibraryDependencyId.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleLibraryDependencyId.java
@@ -3,6 +3,7 @@ package org.jetbrains.plugins.gradle.model.id;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.model.GradleEntityOwner;
import org.jetbrains.plugins.gradle.model.GradleEntityType;
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext;
/**
* @author Denis Zhdanov
@@ -15,7 +16,7 @@ public class GradleLibraryDependencyId extends GradleAbstractDependencyId {
}
@Override
- public Object mapToEntity(@NotNull GradleEntityMappingContext context) {
+ public Object mapToEntity(@NotNull GradleProjectStructureContext context) {
switch (getOwner()) {
case GRADLE: return context.getProjectStructureHelper().findGradleLibraryDependency(getOwnerModuleName(), getDependencyName());
case INTELLIJ: return context.getProjectStructureHelper().findIntellijLibraryDependency(getOwnerModuleName(), getDependencyName());
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleLibraryId.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleLibraryId.java
index 803262104548..248539a07717 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleLibraryId.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleLibraryId.java
@@ -3,6 +3,7 @@ package org.jetbrains.plugins.gradle.model.id;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.model.GradleEntityOwner;
import org.jetbrains.plugins.gradle.model.GradleEntityType;
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext;
/**
* @author Denis Zhdanov
@@ -18,7 +19,7 @@ public class GradleLibraryId extends GradleAbstractEntityId {
}
@Override
- public Object mapToEntity(@NotNull GradleEntityMappingContext context) {
+ public Object mapToEntity(@NotNull GradleProjectStructureContext context) {
switch (getOwner()) {
case GRADLE: return context.getProjectStructureHelper().findGradleLibrary(myLibraryName);
case INTELLIJ: return context.getProjectStructureHelper().findIntellijLibrary(myLibraryName);
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleModuleDependencyId.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleModuleDependencyId.java
index 342962b324a5..8182b8717b71 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleModuleDependencyId.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleModuleDependencyId.java
@@ -3,6 +3,7 @@ package org.jetbrains.plugins.gradle.model.id;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.model.GradleEntityOwner;
import org.jetbrains.plugins.gradle.model.GradleEntityType;
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext;
/**
* @author Denis Zhdanov
@@ -15,7 +16,7 @@ public class GradleModuleDependencyId extends GradleAbstractDependencyId {
}
@Override
- public Object mapToEntity(@NotNull GradleEntityMappingContext context) {
+ public Object mapToEntity(@NotNull GradleProjectStructureContext context) {
switch (getOwner()) {
case GRADLE: return context.getProjectStructureHelper().findGradleModuleDependency(getOwnerModuleName(), getDependencyName());
case INTELLIJ: return context.getProjectStructureHelper().findIntellijModuleDependency(getOwnerModuleName(), getDependencyName());
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleModuleId.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleModuleId.java
index 275887045ed8..65ffe7fe79c4 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleModuleId.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleModuleId.java
@@ -3,6 +3,7 @@ package org.jetbrains.plugins.gradle.model.id;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.model.GradleEntityOwner;
import org.jetbrains.plugins.gradle.model.GradleEntityType;
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext;
/**
* @author Denis Zhdanov
@@ -18,7 +19,7 @@ public class GradleModuleId extends GradleAbstractEntityId {
}
@Override
- public Object mapToEntity(@NotNull GradleEntityMappingContext context) {
+ public Object mapToEntity(@NotNull GradleProjectStructureContext context) {
switch (getOwner()) {
case GRADLE: return context.getProjectStructureHelper().findGradleModule(myModuleName);
case INTELLIJ: return context.getProjectStructureHelper().findIntellijModule(myModuleName);
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleProjectId.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleProjectId.java
index 1f1e869dd5e9..f1ddf43d7704 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleProjectId.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleProjectId.java
@@ -3,6 +3,7 @@ package org.jetbrains.plugins.gradle.model.id;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.model.GradleEntityOwner;
import org.jetbrains.plugins.gradle.model.GradleEntityType;
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext;
/**
* @author Denis Zhdanov
@@ -15,7 +16,7 @@ public class GradleProjectId extends GradleAbstractEntityId {
}
@Override
- public Object mapToEntity(@NotNull GradleEntityMappingContext context) {
+ public Object mapToEntity(@NotNull GradleProjectStructureContext context) {
switch (getOwner()) {
case GRADLE: return context.getChangesModel().getGradleProject();
case INTELLIJ: return context.getProjectStructureHelper().getProject();
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleSyntheticId.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleSyntheticId.java
index 1eb78d1fc595..2fb7aecd68ee 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleSyntheticId.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleSyntheticId.java
@@ -3,6 +3,7 @@ package org.jetbrains.plugins.gradle.model.id;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.model.GradleEntityOwner;
import org.jetbrains.plugins.gradle.model.GradleEntityType;
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext;
/**
* Whole 'entity id' thing is necessary for mapping 'sync project structures' tree nodes to the domain entities. However, there are
@@ -30,7 +31,7 @@ public class GradleSyntheticId extends GradleAbstractEntityId {
}
@Override
- public Object mapToEntity(@NotNull GradleEntityMappingContext context) {
+ public Object mapToEntity(@NotNull GradleProjectStructureContext context) {
return null;
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/intellij/IntellijEntityVisitor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/intellij/IntellijEntityVisitor.java
index a2fb2843d196..cee80a11d1a5 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/intellij/IntellijEntityVisitor.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/intellij/IntellijEntityVisitor.java
@@ -20,6 +20,8 @@ public interface IntellijEntityVisitor {
void visit(@NotNull Module module);
+ void visit(@NotNull ModuleAwareContentRoot contentRoot);
+
void visit(@NotNull LibraryOrderEntry libraryDependency);
void visit(@NotNull ModuleOrderEntry moduleDependency);
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/intellij/IntellijEntityVisitorAdapter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/intellij/IntellijEntityVisitorAdapter.java
deleted file mode 100644
index f0d7d2b7d851..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/intellij/IntellijEntityVisitorAdapter.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.jetbrains.plugins.gradle.model.intellij;
-
-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 org.jetbrains.annotations.NotNull;
-
-/**
- * @author Denis Zhdanov
- * @since 2/14/12 1:51 PM
- */
-public class IntellijEntityVisitorAdapter implements IntellijEntityVisitor {
- @Override
- public void visit(@NotNull Project project) {
- }
- @Override
- public void visit(@NotNull Module module) {
- }
- @Override
- public void visit(@NotNull LibraryOrderEntry libraryDependency) {
- }
- @Override
- public void visit(@NotNull ModuleOrderEntry moduleDependency) {
- }
-}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/intellij/ModuleAwareContentRoot.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/intellij/ModuleAwareContentRoot.java
new file mode 100644
index 000000000000..6ed115123607
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/intellij/ModuleAwareContentRoot.java
@@ -0,0 +1,111 @@
+package org.jetbrains.plugins.gradle.model.intellij;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ExcludeFolder;
+import com.intellij.openapi.roots.SourceFolder;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Denis Zhdanov
+ * @since 2/21/12 11:15 AM
+ */
+public class ModuleAwareContentRoot implements ContentEntry {
+
+ @NotNull private final Module myModule;
+ @NotNull private final ContentEntry myDelegate;
+
+ public ModuleAwareContentRoot(@NotNull Module module, @NotNull ContentEntry delegate) {
+ myDelegate = delegate;
+ myModule = module;
+ }
+
+ @NotNull
+ public Module getModule() {
+ return myModule;
+ }
+
+ @Override
+ @Nullable
+ public VirtualFile getFile() {
+ return myDelegate.getFile();
+ }
+
+ @Override
+ @NotNull
+ public String getUrl() {
+ return myDelegate.getUrl();
+ }
+
+ @Override
+ public SourceFolder[] getSourceFolders() {
+ return myDelegate.getSourceFolders();
+ }
+
+ @Override
+ public VirtualFile[] getSourceFolderFiles() {
+ return myDelegate.getSourceFolderFiles();
+ }
+
+ @Override
+ public ExcludeFolder[] getExcludeFolders() {
+ return myDelegate.getExcludeFolders();
+ }
+
+ @Override
+ public VirtualFile[] getExcludeFolderFiles() {
+ return myDelegate.getExcludeFolderFiles();
+ }
+
+ @Override
+ public SourceFolder addSourceFolder(@NotNull VirtualFile file, boolean isTestSource) {
+ return myDelegate.addSourceFolder(file, isTestSource);
+ }
+
+ @Override
+ public SourceFolder addSourceFolder(@NotNull VirtualFile file, boolean isTestSource, @NotNull String packagePrefix) {
+ return myDelegate.addSourceFolder(file, isTestSource, packagePrefix);
+ }
+
+ @Override
+ public SourceFolder addSourceFolder(@NotNull String url, boolean isTestSource) {
+ return myDelegate.addSourceFolder(url, isTestSource);
+ }
+
+ @Override
+ public void removeSourceFolder(@NotNull SourceFolder sourceFolder) {
+ myDelegate.removeSourceFolder(sourceFolder);
+ }
+
+ @Override
+ public void clearSourceFolders() {
+ myDelegate.clearSourceFolders();
+ }
+
+ @Override
+ public ExcludeFolder addExcludeFolder(@NotNull VirtualFile file) {
+ return myDelegate.addExcludeFolder(file);
+ }
+
+ @Override
+ public ExcludeFolder addExcludeFolder(@NotNull String url) {
+ return myDelegate.addExcludeFolder(url);
+ }
+
+ @Override
+ public void removeExcludeFolder(@NotNull ExcludeFolder excludeFolder) {
+ myDelegate.removeExcludeFolder(excludeFolder);
+ }
+
+ @Override
+ public void clearExcludeFolders() {
+ myDelegate.clearExcludeFolders();
+ }
+
+ @Override
+ public boolean isSynthetic() {
+ return myDelegate.isSynthetic();
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java
index b21feae7cbcf..149081873205 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureChangesPanel.java
@@ -10,10 +10,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.config.GradleToolWindowPanel;
import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChange;
-import org.jetbrains.plugins.gradle.diff.PlatformFacade;
import org.jetbrains.plugins.gradle.ui.GradleDataKeys;
import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNode;
import org.jetbrains.plugins.gradle.util.GradleConstants;
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
@@ -33,15 +33,12 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
private Tree myTree;
private GradleProjectStructureTreeModel myTreeModel;
- private JPanel myContent;
+ private GradleProjectStructureContext myContext;
- public GradleProjectStructureChangesPanel(@NotNull Project project,
- @NotNull GradleProjectStructureChangesModel model,
- @NotNull PlatformFacade platformFacade,
- @NotNull GradleProjectStructureHelper projectStructureHelper)
- {
- super(project, platformFacade, projectStructureHelper, GradleConstants.TOOL_WINDOW_TOOLBAR_PLACE);
- model.addListener(new GradleProjectStructureChangeListener() {
+ public GradleProjectStructureChangesPanel(@NotNull Project project, @NotNull GradleProjectStructureContext context) {
+ super(project, GradleConstants.TOOL_WINDOW_TOOLBAR_PLACE);
+ myContext = context;
+ context.getChangesModel().addListener(new GradleProjectStructureChangeListener() {
@Override
public void onChanges(@NotNull final Collection oldChanges,
@NotNull final Collection currentChanges)
@@ -55,28 +52,30 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
});
}
});
+ initContent();
}
- private void init() {
- myContent = new JPanel(new GridBagLayout());
- myTreeModel = new GradleProjectStructureTreeModel(getProject(), getProjectFacade(), getProjectStructureHelper());
+ @NotNull
+ public GradleProjectStructureTreeModel getTreeModel() {
+ return myTreeModel;
+ }
+
+ @NotNull
+ @Override
+ protected JComponent buildContent() {
+ JPanel result = new JPanel(new GridBagLayout());
+ myTreeModel = new GradleProjectStructureTreeModel(getProject(), myContext);
myTree = new Tree(myTreeModel);
applyInitialAppearance(myTree, (DefaultMutableTreeNode)myTreeModel.getRoot());
GridBagConstraints constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.BOTH;
constraints.weightx = constraints.weighty = 1;
- myContent.add(myTree, constraints);
- myContent.setBackground(myTree.getBackground());
+ result.add(myTree, constraints);
+ result.setBackground(myTree.getBackground());
CustomizationUtil.installPopupHandler(myTree, GradleConstants.ACTION_GROUP_SYNC_TREE, GradleConstants.SYNC_TREE_PLACE);
- }
-
- @NotNull
- @Override
- protected JComponent buildContent() {
- init();
- return myContent;
+ return result;
}
@Override
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java
index 7deb8d5e3f8f..fbc42dd244f0 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java
@@ -3,26 +3,24 @@ package org.jetbrains.plugins.gradle.sync;
import com.intellij.openapi.editor.colors.TextAttributesKey;
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.util.containers.hash.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.config.GradleTextAttributes;
import org.jetbrains.plugins.gradle.diff.*;
import org.jetbrains.plugins.gradle.model.id.*;
+import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot;
+import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNodeComparator;
import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNode;
import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNodeDescriptor;
+import org.jetbrains.plugins.gradle.util.GradleBundle;
import org.jetbrains.plugins.gradle.util.GradleConstants;
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext;
import org.jetbrains.plugins.gradle.util.GradleUtil;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
/**
* Model for the target project structure tree used by the gradle integration.
@@ -55,18 +53,17 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
private final ObsoleteChangesDispatcher myObsoleteChangesDispatcher = new ObsoleteChangesDispatcher();
private final NewChangesDispatcher myNewChangesDispatcher = new NewChangesDispatcher();
- @NotNull private final Project myProject;
- @NotNull private final PlatformFacade myPlatformFacade;
- @NotNull private final GradleProjectStructureHelper myProjectStructureHelper;
+ @NotNull private final Project myProject;
+ @NotNull private final PlatformFacade myPlatformFacade;
+ @NotNull private final GradleProjectStructureHelper myProjectStructureHelper;
+ @NotNull private final Comparator> myNodeComparator;
- public GradleProjectStructureTreeModel(@NotNull Project project,
- @NotNull PlatformFacade platformFacade,
- @NotNull GradleProjectStructureHelper projectStructureHelper)
- {
+ public GradleProjectStructureTreeModel(@NotNull Project project, @NotNull GradleProjectStructureContext context) {
super(null);
myProject = project;
- myPlatformFacade = platformFacade;
- myProjectStructureHelper = projectStructureHelper;
+ myPlatformFacade = context.getPlatformFacade();
+ myProjectStructureHelper = context.getProjectStructureHelper();
+ myNodeComparator = new GradleProjectStructureNodeComparator(context);
rebuild();
}
@@ -102,6 +99,17 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
final GradleProjectStructureNode moduleNode = buildNode(moduleId, moduleId.getModuleName());
myModules.put(module.getName(), moduleNode); // Assuming that module names are unique.
root.add(moduleNode);
+
+ // Content roots
+ final Collection contentRoots = myPlatformFacade.getContentRoots(module);
+ for (ContentEntry entry : contentRoots) {
+ GradleContentRootId contentRootId = GradleEntityIdMapper.mapEntityToId(entry);
+ GradleProjectStructureNode contentRootNode
+ = buildNode(contentRootId, getNodeName(contentRootId, contentRoots.size() <= 1));
+ moduleNode.add(contentRootNode);
+ }
+
+ // Dependencies
for (OrderEntry orderEntry : myPlatformFacade.getOrderEntries(module)) {
orderEntry.accept(visitor, null);
}
@@ -112,11 +120,24 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
for (GradleProjectStructureNode> dependency : dependencies) {
dependenciesNode.add(dependency);
}
- moduleNode.add(dependenciesNode);
}
setRoot(root);
}
+
+ @NotNull
+ private static String getNodeName(@NotNull GradleContentRootId id, boolean singleRoot) {
+ final String name = GradleBundle.message("gradle.import.structure.tree.node.content.root");
+ if (singleRoot) {
+ return name;
+ }
+ final String path = id.getRootPath();
+ final int i = path.lastIndexOf('/');
+ if (i < 0) {
+ return name;
+ }
+ return name + ":" + path.substring(i + 1);
+ }
@NotNull
public Project getProject() {
@@ -124,7 +145,7 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
}
private GradleProjectStructureNode buildNode(@NotNull T id, @NotNull String name) {
- final GradleProjectStructureNode result = GradleUtil.buildNode(id, name);
+ final GradleProjectStructureNode result = new GradleProjectStructureNode(GradleUtil.buildDescriptor(id, name), myNodeComparator);
result.addListener(myNodeListener);
return result;
}
@@ -136,7 +157,7 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
}
GradleProjectStructureNode moduleNode = getModuleNode(id);
GradleProjectStructureNode result
- = new GradleProjectStructureNode(GradleConstants.DEPENDENCIES_NODE_DESCRIPTOR);
+ = new GradleProjectStructureNode(GradleConstants.DEPENDENCIES_NODE_DESCRIPTOR, myNodeComparator);
result.addListener(myNodeListener);
moduleNode.add(result);
myModuleDependencies.put(id.getModuleName(), result);
@@ -155,6 +176,17 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
return moduleNode;
}
+ /**
+ * Notifies current model that particular module roots change just has happened.
+ *
+ * The model is expected to update itself if necessary.
+ */
+ public void onModuleRootsChange() {
+ for (GradleProjectStructureNode node : myModuleDependencies.values()) {
+ node.sortChildren();
+ }
+ }
+
/**
* Asks current model to update its state in accordance with the given changes.
*
@@ -379,6 +411,11 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
public void onNodeChanged(@NotNull GradleProjectStructureNode> node) {
nodeChanged(node);
}
+
+ @Override
+ public void onNodeChildrenChanged(@NotNull GradleProjectStructureNode> parent, int[] childIndices) {
+ nodesChanged(parent, childIndices);
+ }
}
private class NewChangesDispatcher implements GradleProjectStructureChangeVisitor {
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleProjectStructureNode.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleProjectStructureNode.java
index c1068610d2b4..4c409cd79035 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleProjectStructureNode.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleProjectStructureNode.java
@@ -21,33 +21,41 @@ import java.util.concurrent.CopyOnWriteArrayList;
public class GradleProjectStructureNode extends DefaultMutableTreeNode
implements Iterable>
{
-
- public static final Comparator> NODE_COMPARATOR = new Comparator>() {
- @Override
- public int compare(GradleProjectStructureNode> n1, GradleProjectStructureNode> n2) {
- TextAttributesKey a1 = n1.getDescriptor().getAttributes();
- TextAttributesKey a2 = n2.getDescriptor().getAttributes();
-
- // Put 'gradle-local' nodes at the top.
- if (a1 == GradleTextAttributes.GRADLE_LOCAL_CHANGE && a2 != GradleTextAttributes.GRADLE_LOCAL_CHANGE) {
- return -1;
- }
- else if (a1 != GradleTextAttributes.GRADLE_LOCAL_CHANGE && a2 == GradleTextAttributes.GRADLE_LOCAL_CHANGE) {
- return 1;
- }
-
- return n1.getDescriptor().getName().compareTo(n2.getDescriptor().getName());
- }
- };
private final Set myConflictChanges = new HashSet();
private final List myListeners = new CopyOnWriteArrayList();
+
+ @NotNull private final Comparator> myComparator;
+ @NotNull private final GradleProjectStructureNodeDescriptor myDescriptor;
- private final GradleProjectStructureNodeDescriptor myDescriptor;
-
+ private boolean mySkipNotification;
+
+ /**
+ * Creates new GradleProjectStructureNode object with the given descriptor and 'compare-by-name' comparator.
+ *
+ * @param descriptor target node descriptor to use within the current node
+ */
public GradleProjectStructureNode(@NotNull GradleProjectStructureNodeDescriptor descriptor) {
+ this(descriptor, new Comparator>() {
+ @Override
+ public int compare(GradleProjectStructureNode> o1, GradleProjectStructureNode> o2) {
+ return o1.getDescriptor().getName().compareTo(o2.getDescriptor().getName());
+ }
+ });
+ }
+
+ /**
+ * Creates new GradleProjectStructureNode object with the given descriptor and comparator to use for organising child nodes.
+ *
+ * @param descriptor target node descriptor to use within the current node
+ * @param comparator comparator to use for organising child nodes of the current node
+ */
+ public GradleProjectStructureNode(@NotNull GradleProjectStructureNodeDescriptor descriptor,
+ @NotNull Comparator> comparator)
+ {
super(descriptor);
myDescriptor = descriptor;
+ myComparator = comparator;
}
@NotNull
@@ -69,7 +77,7 @@ public class GradleProjectStructureNode extends Defaul
public void add(MutableTreeNode newChild) {
for (int i = 0; i < getChildCount(); i++) {
GradleProjectStructureNode> node = getChildAt(i);
- if (NODE_COMPARATOR.compare((GradleProjectStructureNode>)newChild, node) <= 0) {
+ if (myComparator.compare((GradleProjectStructureNode>)newChild, node) <= 0) {
insert(newChild, i); // Assuming that the node listeners are notified during the nested call.
return;
}
@@ -98,7 +106,7 @@ public class GradleProjectStructureNode extends Defaul
}
/**
- * Asks current node to ensure that given child node is at the 'right position' (according to the {@link #NODE_COMPARATOR}.
+ * Asks current node to ensure that given child node is at the 'right position' (according to the {@link #myComparator}.
*
* Does nothing if given node is not a child of the current node.
*
@@ -114,7 +122,7 @@ public class GradleProjectStructureNode extends Defaul
currentPosition = i;
continue;
}
- if (desiredPosition < 0 && NODE_COMPARATOR.compare(child, node) <= 0) {
+ if (desiredPosition < 0 && myComparator.compare(child, node) <= 0) {
desiredPosition = i;
if (currentPosition >= 0) {
break;
@@ -139,6 +147,34 @@ public class GradleProjectStructureNode extends Defaul
return true;
}
+ /**
+ * Asks current module to ensure that its children are ordered in accordance with the {@link #myComparator pre-configured comparator}.
+ */
+ @SuppressWarnings("unchecked")
+ public void sortChildren() {
+ List> nodes = new ArrayList>(children);
+ Collections.sort(nodes, myComparator);
+ if (nodes.equals(children)) {
+ return;
+ }
+
+ mySkipNotification = true;
+ try {
+ removeAllChildren();
+ for (GradleProjectStructureNode> node : nodes) {
+ add(node);
+ }
+ }
+ finally {
+ mySkipNotification = false;
+ }
+ int[] indices = new int[nodes.size()];
+ for (int i = 0; i < indices.length; i++) {
+ indices[i] = i;
+ }
+ onChildrenChange(indices);
+ }
+
/**
* Registers given change within the given node assuming that it is
* {@link GradleTextAttributes#GRADLE_CHANGE_CONFLICT 'conflict change'}. We need to track number of such changes per-node because
@@ -252,22 +288,40 @@ public class GradleProjectStructureNode extends Defaul
}
private void onNodeAdded(@NotNull GradleProjectStructureNode> node, int index) {
+ if (mySkipNotification) {
+ return;
+ }
for (Listener listener : myListeners) {
listener.onNodeAdded(node, index);
}
}
private void onNodeRemoved(@NotNull GradleProjectStructureNode> node, int removedChildIndex) {
+ if (mySkipNotification) {
+ return;
+ }
for (Listener listener : myListeners) {
listener.onNodeRemoved(this, node, removedChildIndex);
}
}
private void onNodeChanged(@NotNull GradleProjectStructureNode> node) {
+ if (mySkipNotification) {
+ return;
+ }
for (Listener listener : myListeners) {
listener.onNodeChanged(node);
}
}
+
+ private void onChildrenChange(@NotNull int[] indices) {
+ if (mySkipNotification) {
+ return;
+ }
+ for (Listener listener : myListeners) {
+ listener.onNodeChildrenChanged(this, indices);
+ }
+ }
public interface Listener {
void onNodeAdded(@NotNull GradleProjectStructureNode> node, int index);
@@ -275,5 +329,6 @@ public class GradleProjectStructureNode extends Defaul
@NotNull GradleProjectStructureNode> removedChild,
int removedChildIndex);
void onNodeChanged(@NotNull GradleProjectStructureNode> node);
+ void onNodeChildrenChanged(@NotNull GradleProjectStructureNode> parent, int[] childIndices);
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleProjectStructureNodeComparator.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleProjectStructureNodeComparator.java
new file mode 100644
index 000000000000..ba275db55101
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleProjectStructureNodeComparator.java
@@ -0,0 +1,167 @@
+package org.jetbrains.plugins.gradle.ui;
+
+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.ModuleSourceOrderEntry;
+import com.intellij.openapi.roots.OrderEntry;
+import com.intellij.openapi.util.Ref;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.model.GradleEntityOwner;
+import org.jetbrains.plugins.gradle.model.GradleEntityType;
+import org.jetbrains.plugins.gradle.model.gradle.*;
+import org.jetbrains.plugins.gradle.model.id.GradleEntityId;
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext;
+import org.jetbrains.plugins.gradle.model.intellij.IntellijEntityVisitor;
+import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot;
+import org.jetbrains.plugins.gradle.util.GradleUtil;
+
+import java.util.Comparator;
+
+/**
+ * Encapsulates logic of comparing 'sync project structures' tree nodes.
+ *
+ * Thread-safe.
+ *
+ * @author Denis Zhdanov
+ * @since 2/21/12 2:44 PM
+ */
+public class GradleProjectStructureNodeComparator implements Comparator> {
+
+ private static final int PROJECT_WEIGHT = 0;
+ private static final int MODULE_WEIGHT = 1;
+ private static final int CONTENT_ROOT_WEIGHT = 2;
+ private static final int SYNTHETIC_WEIGHT = 3;
+ private static final int MODULE_DEPENDENCY_WEIGHT = 4;
+ private static final int LIBRARY_DEPENDENCY_WEIGHT = 5;
+ private static final int LIBRARY_WEIGHT = 6;
+ private static final int UNKNOWN_WEIGHT = 20;
+
+ @NotNull private final GradleProjectStructureContext myContext;
+
+ public GradleProjectStructureNodeComparator(@NotNull GradleProjectStructureContext context) {
+ myContext = context;
+ }
+
+ @Override
+ public int compare(GradleProjectStructureNode> n1, GradleProjectStructureNode> n2) {
+ final GradleProjectStructureNodeDescriptor extends GradleEntityId> d1 = n1.getDescriptor();
+ final GradleEntityId id1 = d1.getElement();
+
+ final GradleProjectStructureNodeDescriptor extends GradleEntityId> d2 = n2.getDescriptor();
+ final GradleEntityId id2 = d2.getElement();
+
+ // Put 'gradle-local' nodes at the top.
+ if (id1.getOwner() == GradleEntityOwner.GRADLE && id2.getOwner() == GradleEntityOwner.INTELLIJ) {
+ return -1;
+ }
+ else if (id1.getOwner() == GradleEntityOwner.INTELLIJ && id2.getOwner() == GradleEntityOwner.GRADLE) {
+ return 1;
+ }
+
+ // Compare by weight.
+ int weight1 = getWeight(id1);
+ int weight2 = getWeight(id2);
+ if (weight1 != weight2) {
+ return weight1 - weight2;
+ }
+
+ // Compare by name.
+ return d1.getName().compareTo(d2.getName());
+ }
+
+ private int getWeight(@NotNull GradleEntityId id) {
+ if (id.getType() == GradleEntityType.SYNTHETIC) {
+ return SYNTHETIC_WEIGHT;
+ }
+ final Object entity = id.mapToEntity(myContext);
+ final Ref result = new Ref();
+ if (entity instanceof GradleEntity) {
+ ((GradleEntity)entity).invite(new GradleEntityVisitor() {
+ @Override
+ public void visit(@NotNull GradleProject project) {
+ result.set(PROJECT_WEIGHT);
+ }
+
+ @Override
+ public void visit(@NotNull GradleModule module) {
+ result.set(MODULE_WEIGHT);
+ }
+
+ @Override
+ public void visit(@NotNull GradleContentRoot contentRoot) {
+ result.set(CONTENT_ROOT_WEIGHT);
+ }
+
+ @Override
+ public void visit(@NotNull GradleLibrary library) {
+ result.set(LIBRARY_WEIGHT);
+ }
+
+ @Override
+ public void visit(@NotNull GradleModuleDependency dependency) {
+ result.set(MODULE_DEPENDENCY_WEIGHT);
+ }
+
+ @Override
+ public void visit(@NotNull GradleLibraryDependency dependency) {
+ result.set(LIBRARY_DEPENDENCY_WEIGHT);
+ }
+ });
+ }
+ else {
+ GradleUtil.dispatch(entity, new IntellijEntityVisitor() {
+ @Override
+ public void visit(@NotNull Project project) {
+ result.set(PROJECT_WEIGHT);
+ }
+
+ @Override
+ public void visit(@NotNull Module module) {
+ result.set(MODULE_WEIGHT);
+ }
+
+ @Override
+ public void visit(@NotNull ModuleAwareContentRoot contentRoot) {
+ int i = 0;
+ for (OrderEntry entry : myContext.getPlatformFacade().getOrderEntries(contentRoot.getModule())) {
+ if (entry instanceof ModuleSourceOrderEntry) {
+ result.set(i);
+ return;
+ }
+ i++;
+ }
+ result.set(UNKNOWN_WEIGHT);
+ }
+
+ @Override
+ public void visit(@NotNull LibraryOrderEntry libraryDependency) {
+ result.set(getWeight(libraryDependency.getOwnerModule(), libraryDependency));
+ }
+
+ @Override
+ public void visit(@NotNull ModuleOrderEntry moduleDependency) {
+ result.set(getWeight(moduleDependency.getOwnerModule(), moduleDependency));
+ }
+ });
+ }
+ try {
+ return result.get();
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private int getWeight(@NotNull Module module, @NotNull Object entry) {
+ int i = 0;
+ for (OrderEntry orderEntry : myContext.getPlatformFacade().getOrderEntries(module)) {
+ if (orderEntry.equals(entry)) {
+ return i;
+ }
+ i++;
+ }
+ return UNKNOWN_WEIGHT;
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleToolWindowFactory.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleToolWindowFactory.java
index 7fe40ad3f877..d364f6d13cdf 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleToolWindowFactory.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/ui/GradleToolWindowFactory.java
@@ -1,25 +1,34 @@
package org.jetbrains.plugins.gradle.ui;
-import com.intellij.openapi.components.ServiceManager;
+import com.intellij.ProjectTopics;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModuleRootEvent;
+import com.intellij.openapi.roots.ModuleRootListener;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.ui.content.impl.ContentImpl;
-import org.jetbrains.plugins.gradle.diff.PlatformFacade;
-import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesModel;
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesPanel;
-import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper;
import org.jetbrains.plugins.gradle.util.GradleBundle;
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext;
public class GradleToolWindowFactory implements ToolWindowFactory {
@Override
public void createToolWindowContent(final Project project, final ToolWindow toolWindow) {
- final GradleProjectStructureChangesModel model = project.getComponent(GradleProjectStructureChangesModel.class);
- final PlatformFacade facade = ServiceManager.getService(PlatformFacade.class);
- final GradleProjectStructureHelper helper = project.getComponent(GradleProjectStructureHelper.class);
+ final GradleProjectStructureContext context = project.getComponent(GradleProjectStructureContext.class);
- final GradleProjectStructureChangesPanel panel = new GradleProjectStructureChangesPanel(project, model, facade, helper);
+ final GradleProjectStructureChangesPanel panel = new GradleProjectStructureChangesPanel(project, context);
final String syncTitle = GradleBundle.message("gradle.sync.title.tab");
toolWindow.getContentManager().addContent(new ContentImpl(panel, syncTitle, true));
+ project.getMessageBus().connect(project).subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
+ @Override
+ public void beforeRootsChange(ModuleRootEvent event) {
+ }
+
+ @Override
+ public void rootsChanged(ModuleRootEvent event) {
+ // The general idea is to change dependencies order at the UI if they are changed at the module settings.
+ panel.getTreeModel().onModuleRootsChange();
+ }
+ });
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityMappingContext.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleProjectStructureContext.java
similarity index 51%
rename from plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityMappingContext.java
rename to plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleProjectStructureContext.java
index 64f1560efd2c..39aaed5e7c19 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/id/GradleEntityMappingContext.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleProjectStructureContext.java
@@ -1,25 +1,30 @@
-package org.jetbrains.plugins.gradle.model.id;
+package org.jetbrains.plugins.gradle.util;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.diff.PlatformFacade;
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesModel;
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper;
/**
- * Facades all services necessary for the {@link GradleEntityId#mapToEntity(GradleEntityMappingContext) 'entity id -> entity}
- * mapping.
+ * Facades all services necessary for the 'sync project changes' processing.
*
* Thread-safe.
*
* @author Denis Zhdanov
* @since 2/14/12 1:26 PM
*/
-public class GradleEntityMappingContext {
+public class GradleProjectStructureContext {
@NotNull private final GradleProjectStructureHelper myProjectStructureHelper;
+ @NotNull private final PlatformFacade myPlatformFacade;
@NotNull private final GradleProjectStructureChangesModel myChangesModel;
- public GradleEntityMappingContext(GradleProjectStructureHelper projectStructureHelper, GradleProjectStructureChangesModel changesModel) {
+ public GradleProjectStructureContext(@NotNull GradleProjectStructureHelper projectStructureHelper,
+ @NotNull PlatformFacade platformFacade,
+ @NotNull GradleProjectStructureChangesModel changesModel)
+ {
myProjectStructureHelper = projectStructureHelper;
+ myPlatformFacade = platformFacade;
myChangesModel = changesModel;
}
@@ -28,6 +33,11 @@ public class GradleEntityMappingContext {
return myProjectStructureHelper;
}
+ @NotNull
+ public PlatformFacade getPlatformFacade() {
+ return myPlatformFacade;
+ }
+
@NotNull
public GradleProjectStructureChangesModel getChangesModel() {
return myChangesModel;
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java
index 3977afeb7df3..51fa6ffc6ee5 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/util/GradleUtil.java
@@ -27,10 +27,10 @@ import org.jetbrains.plugins.gradle.config.GradleSettings;
import org.jetbrains.plugins.gradle.model.gradle.GradleProject;
import org.jetbrains.plugins.gradle.model.id.GradleEntityId;
import org.jetbrains.plugins.gradle.model.intellij.IntellijEntityVisitor;
+import org.jetbrains.plugins.gradle.model.intellij.ModuleAwareContentRoot;
import org.jetbrains.plugins.gradle.remote.GradleApiException;
import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask;
import org.jetbrains.plugins.gradle.ui.GradleIcons;
-import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNode;
import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNodeDescriptor;
import javax.swing.*;
@@ -201,7 +201,7 @@ public class GradleUtil {
});
return gradleProject.get();
}
-
+
/**
* Tries to dispatch given entity via the given visitor.
*
@@ -215,6 +215,9 @@ public class GradleUtil {
else if (entity instanceof Module) {
visitor.visit(((Module)entity));
}
+ else if (entity instanceof ModuleAwareContentRoot) {
+ visitor.visit(((ModuleAwareContentRoot)entity));
+ }
else if (entity instanceof LibraryOrderEntry) {
visitor.visit(((LibraryOrderEntry)entity));
}
@@ -227,16 +230,6 @@ public class GradleUtil {
return new GradleProjectStructureNodeDescriptor(id, name, id.getType().getIcon());
}
- @NotNull
- public static GradleProjectStructureNode buildNode(@NotNull T id) {
- return new GradleProjectStructureNode(buildDescriptor(id, id.toString()));
- }
-
- @NotNull
- public static GradleProjectStructureNode buildNode(@NotNull T id, @NotNull String name) {
- return new GradleProjectStructureNode(buildDescriptor(id, name));
- }
-
private interface TaskUnderProgress {
void execute(@NotNull ProgressIndicator indicator);
}
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/AbstractGradleTest.groovy b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/AbstractGradleTest.groovy
index d97f7288a24e..7d2bba43708c 100644
--- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/AbstractGradleTest.groovy
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/AbstractGradleTest.groovy
@@ -13,6 +13,7 @@ import org.picocontainer.defaults.DefaultPicoContainer
import org.jetbrains.plugins.gradle.diff.*
import static org.junit.Assert.fail
+import org.jetbrains.plugins.gradle.util.GradleProjectStructureContext
/**
* @author Denis Zhdanov
@@ -47,6 +48,7 @@ public abstract class AbstractGradleTest {
container.registerComponentImplementation(GradleLibraryDependencyStructureChangesCalculator)
container.registerComponentImplementation(GradleLibraryStructureChangesCalculator)
container.registerComponentImplementation(GradleEntityIdMapper)
+ container.registerComponentImplementation(GradleProjectStructureContext)
configureContainer(container)
changesModel = container.getComponentInstance(GradleProjectStructureChangesModel) as GradleProjectStructureChangesModel
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/AbstractProjectBuilder.groovy b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/AbstractProjectBuilder.groovy
index 4b6ad6712fb7..d3a4b3c72771 100644
--- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/AbstractProjectBuilder.groovy
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/AbstractProjectBuilder.groovy
@@ -16,15 +16,18 @@ public abstract class AbstractProjectBuilder extends BuilderSupport {
/** [module name; module] */
def modules = [:]
+
+ /** [module; content roots] */
+ def contentRoots = [:].withDefault { [] }
/** Holds (library name; library) pairs for the active configuration. */
def libraries = [:]
/** [module; dependency list] */
- def libraryDependencies = [:].withDefault {[]}
+ def libraryDependencies = [:].withDefault { [] }
/** [module; dependency list] */
- def moduleDependencies = [:].withDefault {[]}
+ def moduleDependencies = [:].withDefault { [] }
/**
* Holds (library name; library) pairs for the whole test. I.e. there is a possible case that we define particular configuration
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/IntellijProjectBuilder.groovy b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/IntellijProjectBuilder.groovy
index 9a694bef6d3e..85f0c6ce2507 100644
--- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/IntellijProjectBuilder.groovy
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/testutil/IntellijProjectBuilder.groovy
@@ -35,7 +35,8 @@ class IntellijProjectBuilder extends AbstractProjectBuilder {
getOrderEntries: { libraryDependencies[it] + moduleDependencies[it] },
getProjectIcon: { IconLoader.getIcon("/nodes/ideaProject.png") },
getLocalFileSystemPath: { it.path },
- getProjectLibraryTable: { projectLibraryTable }
+ getProjectLibraryTable: { projectLibraryTable },
+ getContentRoots: { contentRoots[it] }
]
/** (library name - (library root type - paths)). */
def libraryPaths = [:].withDefault { [:] }