EditorConfig documentation test
[idea/community.git] / java / idea-ui / src / com / intellij / openapi / roots / ui / configuration / artifacts / nodes / PackagingElementNode.java
1 /*
2  * Copyright 2000-2012 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.roots.ui.configuration.artifacts.nodes;
17
18 import com.intellij.ide.projectView.PresentationData;
19 import com.intellij.openapi.editor.markup.EffectType;
20 import com.intellij.openapi.editor.markup.TextAttributes;
21 import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactEditorImpl;
22 import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactProblemDescription;
23 import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemType;
24 import com.intellij.openapi.util.MultiValuesMap;
25 import com.intellij.packaging.elements.CompositePackagingElement;
26 import com.intellij.packaging.elements.PackagingElement;
27 import com.intellij.packaging.ui.ArtifactEditorContext;
28 import com.intellij.ui.JBColor;
29 import com.intellij.ui.SimpleTextAttributes;
30 import com.intellij.ui.treeStructure.SimpleNode;
31 import com.intellij.util.ArrayUtil;
32 import com.intellij.util.SmartList;
33 import com.intellij.xml.util.XmlStringUtil;
34 import org.jetbrains.annotations.NotNull;
35 import org.jetbrains.annotations.Nullable;
36
37 import java.util.*;
38
39 /**
40  * @author nik
41  */
42 public class PackagingElementNode<E extends PackagingElement<?>> extends ArtifactsTreeNode {
43   private final List<E> myPackagingElements;
44   private final Map<PackagingElement<?>, CompositePackagingElement<?>> myParentElements = new HashMap<>(1);
45   private final MultiValuesMap<PackagingElement<?>, PackagingNodeSource> myNodeSources = new MultiValuesMap<>();
46   private final CompositePackagingElementNode myParentNode;
47
48   public PackagingElementNode(@NotNull E packagingElement, ArtifactEditorContext context, @Nullable CompositePackagingElementNode parentNode,
49                               @Nullable CompositePackagingElement<?> parentElement,
50                               @NotNull Collection<PackagingNodeSource> nodeSources) {
51     super(context, parentNode, packagingElement.createPresentation(context));
52     myParentNode = parentNode;
53     myParentElements.put(packagingElement, parentElement);
54     myNodeSources.putAll(packagingElement, nodeSources);
55     myPackagingElements = new SmartList<>();
56     doAddElement(packagingElement);
57   }
58
59   private void doAddElement(E packagingElement) {
60     myPackagingElements.add(packagingElement);
61   }
62
63   @Nullable
64   public CompositePackagingElement<?> getParentElement(PackagingElement<?> element) {
65     return myParentElements.get(element);
66   }
67
68   @Nullable
69   public CompositePackagingElementNode getParentNode() {
70     return myParentNode;
71   }
72
73   public List<E> getPackagingElements() {
74     return myPackagingElements;
75   }
76
77   @Nullable
78   public E getElementIfSingle() {
79     return myPackagingElements.size() == 1 ? myPackagingElements.get(0) : null;
80   }
81
82   @NotNull
83   @Override
84   public Object[] getEqualityObjects() {
85     return ArrayUtil.toObjectArray(myPackagingElements);
86   }
87
88   @Override
89   protected SimpleNode[] buildChildren() {
90     return NO_CHILDREN;
91   }
92
93   public E getFirstElement() {
94     return myPackagingElements.get(0);
95   }
96
97   @Override
98   protected void update(@NotNull PresentationData presentation) {
99     final Collection<ArtifactProblemDescription> problems = ((ArtifactEditorImpl)myContext.getThisArtifactEditor()).getValidationManager().getProblems(this);
100     if (problems == null || problems.isEmpty()) {
101       super.update(presentation);
102       return;
103     }
104     StringBuilder buffer = new StringBuilder();
105     boolean isError = false;
106     for (ArtifactProblemDescription problem : problems) {
107       isError |= problem.getSeverity() == ProjectStructureProblemType.Severity.ERROR;
108       buffer.append(problem.getMessage(false)).append("<br>");
109     }
110     final String tooltip = XmlStringUtil.wrapInHtml(buffer);
111
112     getElementPresentation().render(presentation, addErrorHighlighting(isError, SimpleTextAttributes.REGULAR_ATTRIBUTES),
113                                     addErrorHighlighting(isError, SimpleTextAttributes.GRAY_ATTRIBUTES));
114     presentation.setTooltip(tooltip);
115   }
116
117   private static SimpleTextAttributes addErrorHighlighting(boolean error, SimpleTextAttributes attributes) {
118     final TextAttributes textAttributes = attributes.toTextAttributes();
119     textAttributes.setEffectType(EffectType.WAVE_UNDERSCORE);
120     textAttributes.setEffectColor(error ? JBColor.RED : JBColor.GRAY);
121     return SimpleTextAttributes.fromTextAttributes(textAttributes);
122   }
123
124   void addElement(PackagingElement<?> element, CompositePackagingElement parentElement, Collection<? extends PackagingNodeSource> nodeSource) {
125     doAddElement((E)element);
126     myParentElements.put(element, parentElement);
127     myNodeSources.putAll(element, nodeSource);
128   }
129
130   @NotNull
131   public Collection<PackagingNodeSource> getNodeSources() {
132     return myNodeSources.values();
133   }
134
135   @NotNull
136   public Collection<PackagingNodeSource> getNodeSource(@NotNull PackagingElement<?> element) {
137     final Collection<PackagingNodeSource> nodeSources = myNodeSources.get(element);
138     return nodeSources != null ? nodeSources : Collections.emptyList();
139   }
140
141   public ArtifactEditorContext getContext() {
142     return myContext;
143   }
144
145   @Nullable
146   public CompositePackagingElementNode findCompositeChild(@NotNull String name) {
147     final SimpleNode[] children = getChildren();
148     for (SimpleNode child : children) {
149       if (child instanceof CompositePackagingElementNode) {
150         final CompositePackagingElementNode composite = (CompositePackagingElementNode)child;
151         if (name.equals(composite.getFirstElement().getName())) {
152           return composite;
153         }
154       }
155     }
156     return null;
157   }
158
159
160   public List<PackagingElementNode<?>> getNodesByPath(List<? extends PackagingElement<?>> pathToPlace) {
161     List<PackagingElementNode<?>> result = new ArrayList<>();
162     PackagingElementNode<?> current = this;
163     int i = 0;
164     result.add(current);
165     while (current != null && i < pathToPlace.size()) {
166       final SimpleNode[] children = current.getCached();
167       if (children == null) {
168         break;
169       }
170
171       PackagingElementNode<?> next = null;
172       final PackagingElement<?> element = pathToPlace.get(i);
173
174       search:
175       for (SimpleNode child : children) {
176         if (child instanceof PackagingElementNode<?>) {
177           PackagingElementNode<?> childNode = (PackagingElementNode<?>)child;
178           for (PackagingElement<?> childElement : childNode.getPackagingElements()) {
179             if (childElement.isEqualTo(element)) {
180               next = childNode;
181               break search;
182             }
183           }
184           for (PackagingNodeSource nodeSource : childNode.getNodeSources()) {
185             if (nodeSource.getSourceElement().isEqualTo(element)) {
186               next = current;
187               break search;
188             }
189           }
190         }
191       }
192       current = next;
193       if (current != null) {
194         result.add(current);
195       }
196       i++;
197     }
198     return result;
199   }
200 }