diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLocalNodeImportHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLocalNodeImportHelper.java
index d76e3a3ab08c..b21482025706 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLocalNodeImportHelper.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleLocalNodeImportHelper.java
@@ -4,11 +4,10 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.LibraryOrderEntry;
import com.intellij.openapi.roots.ModuleOrderEntry;
import com.intellij.openapi.roots.libraries.Library;
-import com.intellij.openapi.util.Ref;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.config.GradleTextAttributes;
-import org.jetbrains.plugins.gradle.model.*;
+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.model.id.GradleEntityIdMapper;
@@ -38,6 +37,8 @@ import java.util.*;
*
*
*
+ *
+ * Thread-safe.
*
* @author Denis Zhdanov
* @since 2/10/12 11:51 AM
@@ -86,72 +87,14 @@ public class GradleLocalNodeImportHelper {
*/
@NotNull
public List deriveEntitiesToImport(@NotNull Iterable> nodes) {
- EntitiesToImport toImport = new EntitiesToImport();
+ Context context = new Context();
for (GradleProjectStructureNode> node : nodes) {
- collectEntitiesToImport(node, toImport);
+ collectEntitiesToImport(node, context);
}
- return toImport.getAll();
+ return context.getAll();
}
- private void collectEntitiesToImport(@NotNull GradleProjectStructureNode> node, @NotNull final EntitiesToImport toImport) {
- final Ref recursive = new Ref(false);
- final GradleEntityVisitor visitor = new GradleEntityVisitorAdapter() {
- @Override
- public void visit(@NotNull GradleModule module) {
- final Module intellijModule = myProjectStructureHelper.findIntellijModule(module);
- if (intellijModule != null) {
- // Already imported
- return;
- }
- toImport.modules.add(module);
- if (!recursive.get()) {
- return;
- }
- for (GradleDependency dependency : module.getDependencies()) {
- dependency.invite(this);
- }
- }
-
- @Override
- public void visit(@NotNull GradleModuleDependency dependency) {
- final ModuleOrderEntry intellijModuleDependency = myProjectStructureHelper.findIntellijModuleDependency(dependency);
- if (intellijModuleDependency != null) {
- // Already imported.
- return;
- }
- toImport.dependencies.add(dependency);
- final GradleModule gradleModule = dependency.getTarget();
- final Module intellijModule = myProjectStructureHelper.findIntellijModule(gradleModule);
- if (intellijModule != null) {
- return;
- }
- boolean r = recursive.get();
- recursive.set(true);
- try {
- gradleModule.invite(this);
- }
- finally {
- recursive.set(r);
- }
- }
-
- @Override
- public void visit(@NotNull GradleLibraryDependency dependency) {
- final LibraryOrderEntry intellijDependency
- = myProjectStructureHelper.findIntellijLibraryDependency(dependency.getOwnerModule().getName(), dependency.getName());
- if (intellijDependency != null) {
- // Already imported.
- return;
- }
- toImport.dependencies.add(dependency);
- final GradleLibrary gradleLibrary = dependency.getTarget();
- final Library intellijLibrary = myProjectStructureHelper.findIntellijLibrary(gradleLibrary);
- if (intellijLibrary == null) {
- toImport.libraries.add(gradleLibrary);
- }
- }
- };
-
+ private void collectEntitiesToImport(@NotNull GradleProjectStructureNode> node, @NotNull Context context) {
// Collect up.
for (GradleProjectStructureNode> n = node.getParent(); n != null; n = n.getParent()) {
final GradleProjectStructureNodeDescriptor> descriptor = n.getDescriptor();
@@ -165,7 +108,7 @@ public class GradleLocalNodeImportHelper {
if (id instanceof GradleEntityId) {
final Object entity = myIdMapper.mapIdToEntity((GradleEntityId)id);
if (entity instanceof GradleEntity) {
- ((GradleEntity)entity).invite(visitor);
+ ((GradleEntity)entity).invite(context.visitor);
}
}
}
@@ -180,15 +123,67 @@ public class GradleLocalNodeImportHelper {
}
}
- recursive.set(true);
+ context.recursive = true;
while (!toProcess.isEmpty()) {
final GradleEntity entity = toProcess.pop();
- entity.invite(visitor);
+ entity.invite(context.visitor);
+ }
+ }
+
+ private void collectModuleEntities(@NotNull GradleModule module, @NotNull Context context) {
+ final Module intellijModule = myProjectStructureHelper.findIntellijModule(module);
+ if (intellijModule != null) {
+ // Already imported
+ return;
+ }
+ context.modules.add(module);
+ if (!context.recursive) {
+ return;
+ }
+ for (GradleDependency dependency : module.getDependencies()) {
+ dependency.invite(context.visitor);
+ }
+ }
+
+ private void collectModuleDependencyEntities(@NotNull GradleModuleDependency dependency, @NotNull Context context) {
+ final ModuleOrderEntry intellijModuleDependency = myProjectStructureHelper.findIntellijModuleDependency(dependency);
+ if (intellijModuleDependency != null) {
+ // Already imported.
+ return;
+ }
+ context.dependencies.add(dependency);
+ final GradleModule gradleModule = dependency.getTarget();
+ final Module intellijModule = myProjectStructureHelper.findIntellijModule(gradleModule);
+ if (intellijModule != null) {
+ return;
+ }
+ boolean r = context.recursive;
+ context.recursive = true;
+ try {
+ gradleModule.invite(context.visitor);
+ }
+ finally {
+ context.recursive = r;
+ }
+ }
+
+ private void collectLibraryDependencyEntities(@NotNull GradleLibraryDependency dependency, @NotNull Context context) {
+ final LibraryOrderEntry intellijDependency
+ = myProjectStructureHelper.findIntellijLibraryDependency(dependency.getOwnerModule().getName(), dependency.getName());
+ if (intellijDependency != null) {
+ // Already imported.
+ return;
+ }
+ context.dependencies.add(dependency);
+ final GradleLibrary gradleLibrary = dependency.getTarget();
+ final Library intellijLibrary = myProjectStructureHelper.findIntellijLibrary(gradleLibrary);
+ if (intellijLibrary == null) {
+ context.libraries.add(gradleLibrary);
}
}
/**
- * Imports given 'gradle-local' entities to the current intellij projcet.
+ * Imports given 'gradle-local' entities to the current intellij project.
*
* @param entities target 'gradle-local' entities to import
*/
@@ -239,11 +234,14 @@ public class GradleLocalNodeImportHelper {
}
}
- private static class EntitiesToImport {
-
+ private class Context {
+
public final Set modules = new HashSet();
public final Set libraries = new HashSet();
public final Set dependencies = new HashSet();
+ public final CollectingVisitor visitor = new CollectingVisitor(this);
+
+ public boolean recursive;
@NotNull
public List getAll() {
@@ -254,4 +252,22 @@ public class GradleLocalNodeImportHelper {
return result;
}
}
+
+ private class CollectingVisitor implements GradleEntityVisitor {
+ @NotNull private final Context myContext;
+
+ CollectingVisitor(@NotNull Context context) {
+ myContext = context;
+ }
+
+ @Override public void visit(@NotNull GradleProject project) { }
+ @Override public void visit(@NotNull GradleModule module) { collectModuleEntities(module, myContext); }
+ @Override
+ public void visit(@NotNull GradleContentRoot contentRoot) {
+ // TODO den implement
+ }
+ @Override public void visit(@NotNull GradleLibrary library) { /* Assuming that a library may be imported only as a dependency */ }
+ @Override public void visit(@NotNull GradleModuleDependency dependency) { collectModuleDependencyEntities(dependency, myContext); }
+ @Override public void visit(@NotNull GradleLibraryDependency dependency) { collectLibraryDependencyEntities(dependency, myContext); }
+ }
}
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 9c789bdbd309..431c5083497d 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/sync/GradleProjectStructureTreeModel.java
@@ -51,9 +51,11 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
private final Map> myModules
= new HashMap>();
- private final TreeNode[] myNodeHolder = new TreeNode[1];
- private final int[] myIndexHolder = new int[1];
- private final NodeListener myNodeListener = new NodeListener();
+ private final TreeNode[] myNodeHolder = new TreeNode[1];
+ private final int[] myIndexHolder = new int[1];
+ private final NodeListener myNodeListener = new NodeListener();
+ private final ObsoleteChangesDispatcher myObsoleteChangesDispatcher = new ObsoleteChangesDispatcher();
+ private final NewChangesDispatcher myNewChangesDispatcher = new NewChangesDispatcher();
@NotNull private final Project myProject;
@NotNull private final PlatformFacade myPlatformFacade;
@@ -169,62 +171,7 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
*/
public void update(@NotNull Collection changes) {
for (GradleProjectStructureChange change : changes) {
- change.invite(new GradleProjectStructureChangeVisitorAdapter() {
- @Override
- public void visit(@NotNull GradleMismatchedLibraryPathChange change) {
- for (GradleProjectStructureNode holder : myModuleDependencies.values()) {
- for (GradleProjectStructureNode dependencyNode : holder.getChildren(GradleLibraryDependencyId.class)) {
- final GradleLibraryDependencyId id = dependencyNode.getDescriptor().getElement();
- if (change.getLibraryName().equals(id.getLibraryName())) {
- dependencyNode.addConflictChange(change);
- break;
- }
- }
- }
- }
-
- @Override
- public void visit(@NotNull GradleModulePresenceChange change) {
- final GradleModuleId id;
- final TextAttributesKey key;
- if (change.getGradleEntity() == null) {
- id = change.getIntellijEntity();
- key = GradleTextAttributes.INTELLIJ_LOCAL_CHANGE;
- }
- else {
- id = change.getGradleEntity();
- key = GradleTextAttributes.GRADLE_LOCAL_CHANGE;
- }
- assert id != null;
- final GradleProjectStructureNode moduleNode = getModuleNode(id);
- moduleNode.getDescriptor().setAttributes(key);
- nodeChanged(moduleNode);
- }
-
- @Override
- public void visit(@NotNull GradleLibraryDependencyPresenceChange change) {
- GradleLibraryDependencyId id = change.getGradleEntity();
- TextAttributesKey attributes = GradleTextAttributes.GRADLE_LOCAL_CHANGE;
- if (id == null) {
- id = change.getIntellijEntity();
- attributes = GradleTextAttributes.INTELLIJ_LOCAL_CHANGE;
- }
- assert id != null;
- final GradleProjectStructureNode dependenciesNode = getDependenciesNode(id.getModuleId());
- for (GradleProjectStructureNode node : dependenciesNode.getChildren(GradleLibraryDependencyId.class)) {
- GradleProjectStructureNodeDescriptor d = node.getDescriptor();
- if (id.equals(d.getElement())) {
- d.setAttributes(attributes);
- nodeStructureChanged(node);
- return;
- }
- }
- GradleProjectStructureNode newNode = buildNode(id, id.getLibraryName(), GradleIcons.LIB_ICON);
- newNode.getDescriptor().setAttributes(attributes);
- dependenciesNode.add(newNode);
- nodeStructureChanged(dependenciesNode);
- }
- });
+ change.invite(myNewChangesDispatcher);
}
}
@@ -243,84 +190,139 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
*/
public void processObsoleteChanges(Collection changes) {
for (GradleProjectStructureChange change : changes) {
- change.invite(new GradleProjectStructureChangeVisitor() {
- @Override
- public void visit(@NotNull GradleMismatchedLibraryPathChange change) {
- for (GradleProjectStructureNode holder : myModuleDependencies.values()) {
- for (GradleProjectStructureNode node : holder.getChildren(GradleLibraryDependencyId.class)) {
- final GradleLibraryDependencyId id = node.getDescriptor().getElement();
- if (id.getLibraryName().equals(change.getLibraryName())) {
- node.removeConflictChange(change);
- nodeChanged(node);
- break;
- }
- }
- }
- }
+ change.invite(myObsoleteChangesDispatcher);
+ }
+ }
- @Override
- public void visit(@NotNull GradleLibraryDependencyPresenceChange change) {
- // We need to remove the corresponding node then.
- GradleLibraryDependencyId id = change.getGradleEntity();
- boolean removeNode;
- if (id == null) {
- id = change.getIntellijEntity();
- assert id != null;
- removeNode = !myProjectStructureHelper.isIntellijLibraryDependencyExist(id);
- }
- else {
- removeNode = !myProjectStructureHelper.isGradleLibraryDependencyExist(id);
- }
- final GradleProjectStructureNode holder = myModuleDependencies.get(id.getModuleName());
- if (holder == null) {
- return;
- }
-
- // There are two possible cases why 'local library dependency' change is obsolete:
- // 1. Corresponding dependency has been added at the counterparty;
- // 2. The 'local dependency' has been removed;
- // We should distinguish between those situations because we need to mark the node as 'synced' at one case and
- // completely removed at another one.
-
- for (GradleProjectStructureNode node : holder.getChildren(GradleLibraryDependencyId.class)) {
- GradleProjectStructureNodeDescriptor descriptor = node.getDescriptor();
- if (!id.equals(descriptor.getElement())) {
- continue;
- }
- if (removeNode) {
- holder.remove(node);
- }
- else {
- descriptor.setAttributes(GradleTextAttributes.GRADLE_NO_CHANGE);
- holder.correctChildPositionIfNecessary(node);
- }
- return;
- }
- }
+ private void processNewProjectRenameChange(@NotNull GradleProjectRenameChange change) {
+ // TODO den implement
+ }
- @Override
- public void visit(@NotNull GradleProjectRenameChange change) {
- // TODO den implement
- }
+ private void processNewLanguageLevelChange(@NotNull GradleLanguageLevelChange change) {
+ // TODO den implement
+ }
- @Override
- public void visit(@NotNull GradleLanguageLevelChange change) {
- // TODO den implement
+ private void processNewMismatchedLibraryPathChange(@NotNull GradleMismatchedLibraryPathChange change) {
+ for (GradleProjectStructureNode holder : myModuleDependencies.values()) {
+ for (GradleProjectStructureNode dependencyNode : holder.getChildren(GradleLibraryDependencyId.class)) {
+ final GradleLibraryDependencyId id = dependencyNode.getDescriptor().getElement();
+ if (change.getLibraryName().equals(id.getLibraryName())) {
+ dependencyNode.addConflictChange(change);
+ break;
}
+ }
+ }
+ }
- @Override
- public void visit(@NotNull GradleModulePresenceChange change) {
- GradleModuleId id = change.getGradleEntity();
- if (id == null) {
- id = change.getIntellijEntity();
- }
- assert id != null;
- final GradleProjectStructureNode moduleNode = myModules.get(id.getModuleName());
- if (moduleNode != null) {
- moduleNode.getDescriptor().setAttributes(GradleTextAttributes.GRADLE_NO_CHANGE);
- }
+ private void processNewLibraryDependencyPresenceChange(@NotNull GradleLibraryDependencyPresenceChange change) {
+ GradleLibraryDependencyId id = change.getGradleEntity();
+ TextAttributesKey attributes = GradleTextAttributes.GRADLE_LOCAL_CHANGE;
+ if (id == null) {
+ id = change.getIntellijEntity();
+ attributes = GradleTextAttributes.INTELLIJ_LOCAL_CHANGE;
+ }
+ assert id != null;
+ final GradleProjectStructureNode dependenciesNode = getDependenciesNode(id.getModuleId());
+ for (GradleProjectStructureNode node : dependenciesNode.getChildren(GradleLibraryDependencyId.class)) {
+ GradleProjectStructureNodeDescriptor d = node.getDescriptor();
+ if (id.equals(d.getElement())) {
+ d.setAttributes(attributes);
+ nodeStructureChanged(node);
+ return;
+ }
+ }
+ GradleProjectStructureNode newNode = buildNode(id, id.getLibraryName(), GradleIcons.LIB_ICON);
+ newNode.getDescriptor().setAttributes(attributes);
+ dependenciesNode.add(newNode);
+ nodeStructureChanged(dependenciesNode);
+ }
+
+ private void processNewModulePresenceChange(@NotNull GradleModulePresenceChange change) {
+ final GradleModuleId id;
+ final TextAttributesKey key;
+ if (change.getGradleEntity() == null) {
+ id = change.getIntellijEntity();
+ key = GradleTextAttributes.INTELLIJ_LOCAL_CHANGE;
+ }
+ else {
+ id = change.getGradleEntity();
+ key = GradleTextAttributes.GRADLE_LOCAL_CHANGE;
+ }
+ assert id != null;
+ final GradleProjectStructureNode moduleNode = getModuleNode(id);
+ moduleNode.getDescriptor().setAttributes(key);
+ nodeChanged(moduleNode);
+ }
+
+ private void processObsoleteProjectRenameChange(@NotNull GradleProjectRenameChange change) {
+ // TODO den implement
+ }
+
+ private void processObsoleteLanguageLevelChange(@NotNull GradleLanguageLevelChange change) {
+ // TODO den implement
+ }
+
+ private void processObsoleteMismatchedLibraryPathChange(@NotNull GradleMismatchedLibraryPathChange change) {
+ for (GradleProjectStructureNode holder : myModuleDependencies.values()) {
+ for (GradleProjectStructureNode node : holder.getChildren(GradleLibraryDependencyId.class)) {
+ final GradleLibraryDependencyId id = node.getDescriptor().getElement();
+ if (id.getLibraryName().equals(change.getLibraryName())) {
+ node.removeConflictChange(change);
+ nodeChanged(node);
+ break;
}
- });
+ }
+ }
+ }
+
+ private void processObsoleteLibraryDependencyPresenceChange(@NotNull GradleLibraryDependencyPresenceChange change) {
+ // We need to remove the corresponding node then.
+ GradleLibraryDependencyId id = change.getGradleEntity();
+ boolean removeNode;
+ if (id == null) {
+ id = change.getIntellijEntity();
+ assert id != null;
+ removeNode = !myProjectStructureHelper.isIntellijLibraryDependencyExist(id);
+ }
+ else {
+ removeNode = !myProjectStructureHelper.isGradleLibraryDependencyExist(id);
+ }
+ final GradleProjectStructureNode holder = myModuleDependencies.get(id.getModuleName());
+ if (holder == null) {
+ return;
+ }
+
+ // There are two possible cases why 'local library dependency' change is obsolete:
+ // 1. Corresponding dependency has been added at the counterparty;
+ // 2. The 'local dependency' has been removed;
+ // We should distinguish between those situations because we need to mark the node as 'synced' at one case and
+ // completely removed at another one.
+
+ for (GradleProjectStructureNode node : holder.getChildren(GradleLibraryDependencyId.class)) {
+ GradleProjectStructureNodeDescriptor descriptor = node.getDescriptor();
+ if (!id.equals(descriptor.getElement())) {
+ continue;
+ }
+ if (removeNode) {
+ holder.remove(node);
+ }
+ else {
+ descriptor.setAttributes(GradleTextAttributes.GRADLE_NO_CHANGE);
+ holder.correctChildPositionIfNecessary(node);
+ }
+ return;
+ }
+ }
+
+ private void processObsoleteModulePresenceChange(@NotNull GradleModulePresenceChange change) {
+ GradleModuleId id = change.getGradleEntity();
+ if (id == null) {
+ id = change.getIntellijEntity();
+ }
+ assert id != null;
+ final GradleProjectStructureNode moduleNode = myModules.get(id.getModuleName());
+ if (moduleNode != null) {
+ moduleNode.getDescriptor().setAttributes(GradleTextAttributes.GRADLE_NO_CHANGE);
}
}
@@ -339,4 +341,22 @@ public class GradleProjectStructureTreeModel extends DefaultTreeModel {
nodesWereRemoved(node.getParent(), myIndexHolder, myNodeHolder);
}
}
+
+ private class NewChangesDispatcher implements GradleProjectStructureChangeVisitor {
+ @Override public void visit(@NotNull GradleProjectRenameChange change) { processNewProjectRenameChange(change); }
+ @Override public void visit(@NotNull GradleLanguageLevelChange change) { processNewLanguageLevelChange(change); }
+ @Override public void visit(@NotNull GradleModulePresenceChange change) { processNewModulePresenceChange(change); }
+ @Override public void visit(@NotNull GradleLibraryDependencyPresenceChange change) { processNewLibraryDependencyPresenceChange(change); }
+ @Override public void visit(@NotNull GradleMismatchedLibraryPathChange change) { processNewMismatchedLibraryPathChange(change); }
+ }
+
+ private class ObsoleteChangesDispatcher implements GradleProjectStructureChangeVisitor {
+ @Override public void visit(@NotNull GradleProjectRenameChange change) { processObsoleteProjectRenameChange(change); }
+ @Override public void visit(@NotNull GradleLanguageLevelChange change) { processObsoleteLanguageLevelChange(change); }
+ @Override public void visit(@NotNull GradleModulePresenceChange change) { processObsoleteModulePresenceChange(change); }
+ @Override public void visit(@NotNull GradleLibraryDependencyPresenceChange change) {
+ processObsoleteLibraryDependencyPresenceChange(change);
+ }
+ @Override public void visit(@NotNull GradleMismatchedLibraryPathChange change) { processObsoleteMismatchedLibraryPathChange(change); }
+ }
}