IDEA-76142: Gradle support - cannot update IDEA projects once one of build.gradle...
[idea/community.git] / plugins / gradle / src / org / jetbrains / plugins / gradle / importing / wizard / adjust / GradleProjectStructureFactory.java
1 package org.jetbrains.plugins.gradle.importing.wizard.adjust;
2
3 import com.intellij.openapi.application.ex.ApplicationInfoEx;
4 import com.intellij.openapi.util.IconLoader;
5 import com.intellij.openapi.util.Ref;
6 import org.jetbrains.annotations.NotNull;
7 import org.jetbrains.plugins.gradle.model.*;
8 import org.jetbrains.plugins.gradle.ui.GradleIcons;
9 import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNode;
10 import org.jetbrains.plugins.gradle.ui.GradleProjectStructureNodeDescriptor;
11 import org.jetbrains.plugins.gradle.util.GradleBundle;
12
13 import javax.swing.tree.DefaultTreeModel;
14 import java.beans.PropertyChangeEvent;
15 import java.beans.PropertyChangeListener;
16 import java.util.Collection;
17
18 /**
19  * Allows to build various entities related to the 'project structure' view elements.
20  * <p/>
21  * Thread-safe.
22  * <p/>
23  * This class is not singleton but offers single-point-of-usage field - {@link #INSTANCE}.
24  * 
25  * @author Denis Zhdanov
26  * @since 8/12/11 2:52 PM
27  */
28 public class GradleProjectStructureFactory {
29
30   /** Shared instance of the current (stateless) class. */
31   public static final GradleProjectStructureFactory INSTANCE = new GradleProjectStructureFactory();
32
33   @SuppressWarnings("MethodMayBeStatic")
34   @NotNull
35   public <T extends GradleEntity> GradleProjectStructureNodeDescriptor buildDescriptor(@NotNull T entity) {
36     final Ref<GradleProjectStructureNodeDescriptor<GradleEntity>> result = new Ref<GradleProjectStructureNodeDescriptor<GradleEntity>>();
37     entity.invite(new GradleEntityVisitor() {
38       @Override
39       public void visit(@NotNull GradleProject project) {
40         result.set(new GradleProjectStructureNodeDescriptor<GradleEntity>(
41           project, project.getName(), IconLoader.getIcon(ApplicationInfoEx.getInstanceEx().getSmallIconUrl())
42         ));
43       }
44
45       @Override
46       public void visit(@NotNull GradleModule module) {
47         result.set(new GradleProjectStructureNodeDescriptor<GradleEntity>(module, module.getName(), GradleIcons.MODULE_ICON));
48       }
49
50       @Override
51       public void visit(@NotNull GradleContentRoot contentRoot) {
52         result.set(new GradleProjectStructureNodeDescriptor<GradleEntity>(
53           contentRoot,
54           GradleBundle.message("gradle.import.structure.tree.node.content.root"), GradleIcons.CONTENT_ROOT_ICON
55         )); 
56       }
57
58       @Override
59       public void visit(@NotNull GradleLibrary library) {
60         result.set(new GradleProjectStructureNodeDescriptor<GradleEntity>(library, library.getName(), GradleIcons.LIB_ICON));
61       }
62
63       @Override
64       public void visit(@NotNull GradleModuleDependency dependency) {
65         visit(dependency.getTarget());
66       }
67
68       @Override
69       public void visit(@NotNull GradleLibraryDependency dependency) {
70         visit(dependency.getTarget());
71       }
72     });
73     return result.get();
74   }
75
76   @SuppressWarnings("MethodMayBeStatic")
77   @NotNull
78   public GradleProjectStructureNodeSettings buildSettings(@NotNull GradleEntity entity,
79                                                           @NotNull final DefaultTreeModel treeModel,
80                                                           @NotNull final Collection<GradleProjectStructureNode> treeNodes)
81   {
82     final Ref<GradleProjectStructureNodeSettings> result = new Ref<GradleProjectStructureNodeSettings>();
83     entity.invite(new GradleEntityVisitor() {
84       @Override
85       public void visit(@NotNull GradleProject project) {
86         setupController(project, treeModel, treeNodes);
87         result.set(new GradleProjectSettings(project));
88       }
89
90       @Override
91       public void visit(@NotNull GradleModule module) {
92         setupController(module, treeModel, treeNodes);
93         result.set(new GradleModuleSettings(module)); 
94       }
95
96       @Override
97       public void visit(@NotNull GradleContentRoot contentRoot) {
98         result.set(new GradleContentRootSettings(contentRoot));
99       }
100
101       @Override
102       public void visit(@NotNull GradleLibrary library) {
103         setupController(library, treeModel, treeNodes);
104         result.set(new GradleLibrarySettings(library)); 
105       }
106
107       @Override
108       public void visit(@NotNull GradleModuleDependency dependency) {
109         setupController(dependency, treeModel, treeNodes);
110         result.set(new GradleModuleDependencySettings(dependency));
111       }
112
113       @Override
114       public void visit(@NotNull GradleLibraryDependency dependency) {
115         setupController(dependency, treeModel, treeNodes);
116         result.set(new GradleLibraryDependencySettings(dependency));
117       }
118     });
119     return result.get();
120   }
121
122   /**
123    * Configures controller that delegates entity state change to all corresponding nodes.
124    * 
125    * @param entity          target entity to wrap
126    * @param model           model of the target tree
127    * @param treeNodes       tree nodes that represent the given entity
128    */
129   @SuppressWarnings("unchecked")
130   private static void setupController(@NotNull final GradleEntity entity, @NotNull final DefaultTreeModel model,
131                                        @NotNull final Collection<GradleProjectStructureNode> treeNodes)
132   {
133     
134     entity.addPropertyChangeListener(new PropertyChangeListener() {
135       @Override
136       public void propertyChange(PropertyChangeEvent evt) {
137         if (!Named.NAME_PROPERTY.equals(evt.getPropertyName())) {
138           return;
139         }
140         for (GradleProjectStructureNode node : treeNodes) {
141           node.getDescriptor().setName(evt.getNewValue().toString());
142           model.nodeChanged(node);
143         }
144       }
145     });
146   }
147 }