2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com
.intellij
.packageDependencies
;
19 import com
.intellij
.ide
.IdeBundle
;
20 import com
.intellij
.ide
.impl
.ContentManagerWatcher
;
21 import com
.intellij
.openapi
.components
.State
;
22 import com
.intellij
.openapi
.components
.Storage
;
23 import com
.intellij
.openapi
.diagnostic
.Logger
;
24 import com
.intellij
.openapi
.project
.Project
;
25 import com
.intellij
.openapi
.startup
.StartupManager
;
26 import com
.intellij
.openapi
.util
.*;
27 import com
.intellij
.openapi
.wm
.ToolWindow
;
28 import com
.intellij
.openapi
.wm
.ToolWindowAnchor
;
29 import com
.intellij
.openapi
.wm
.ToolWindowId
;
30 import com
.intellij
.openapi
.wm
.ToolWindowManager
;
31 import com
.intellij
.psi
.PsiFile
;
32 import com
.intellij
.psi
.search
.scope
.packageSet
.*;
33 import com
.intellij
.ui
.content
.Content
;
34 import com
.intellij
.ui
.content
.ContentManager
;
35 import org
.jdom
.Element
;
36 import org
.jetbrains
.annotations
.NonNls
;
37 import org
.jetbrains
.annotations
.NotNull
;
38 import org
.jetbrains
.annotations
.Nullable
;
44 name
="DependencyValidationManager",
48 file
= "$PROJECT_FILE$"
51 public class DependencyValidationManagerImpl
extends DependencyValidationManager
{
52 private static final Logger LOG
= Logger
.getInstance("#com.intellij.packageDependencies.DependencyValidationManagerImpl");
54 private final List
<DependencyRule
> myRules
= new ArrayList
<DependencyRule
>();
56 public boolean SKIP_IMPORT_STATEMENTS
= false;
58 private final Project myProject
;
59 private ContentManager myContentManager
;
60 @NonNls private static final String DENY_RULE_KEY
= "deny_rule";
61 @NonNls private static final String FROM_SCOPE_KEY
= "from_scope";
62 @NonNls private static final String TO_SCOPE_KEY
= "to_scope";
63 @NonNls private static final String IS_DENY_KEY
= "is_deny";
64 @NonNls private static final String UNNAMED_SCOPE
= "unnamed_scope";
65 @NonNls private static final String VALUE
= "value";
68 private static final Icon SHARED_SCOPES
= IconLoader
.getIcon("/ide/sharedScope.png");
70 private final Map
<String
, PackageSet
> myUnnamedScopes
= new HashMap
<String
, PackageSet
>();
72 public DependencyValidationManagerImpl(final Project project
) {
75 StartupManager
.getInstance(project
).runWhenProjectIsInitialized(new Runnable() {
77 final ToolWindowManager toolWindowManager
= ToolWindowManager
.getInstance(myProject
);
78 if (toolWindowManager
== null) return;
79 ToolWindow toolWindow
= toolWindowManager
.registerToolWindow(ToolWindowId
.DEPENDENCIES
,
81 ToolWindowAnchor
.BOTTOM
,
83 myContentManager
= toolWindow
.getContentManager();
85 toolWindow
.setIcon(IconLoader
.getIcon("/general/toolWindowInspection.png"));
86 new ContentManagerWatcher(toolWindow
, myContentManager
);
94 public List
<NamedScope
> getPredefinedScopes() {
95 final List
<NamedScope
> predifinedScopes
= new ArrayList
<NamedScope
>();
96 final CustomScopesProvider
[] scopesProviders
= myProject
.getExtensions(CustomScopesProvider
.CUSTOM_SCOPES_PROVIDER
);
97 if (scopesProviders
!= null) {
98 for (CustomScopesProvider scopesProvider
: scopesProviders
) {
99 predifinedScopes
.addAll(scopesProvider
.getCustomScopes());
102 return predifinedScopes
;
105 public boolean hasRules() {
106 return !myRules
.isEmpty();
110 public DependencyRule
getViolatorDependencyRule(PsiFile from
, PsiFile to
) {
111 for (DependencyRule dependencyRule
: myRules
) {
112 if (dependencyRule
.isForbiddenToUse(from
, to
)) return dependencyRule
;
119 public DependencyRule
[] getViolatorDependencyRules(PsiFile from
, PsiFile to
) {
120 ArrayList
<DependencyRule
> result
= new ArrayList
<DependencyRule
>();
121 for (DependencyRule dependencyRule
: myRules
) {
122 if (dependencyRule
.isForbiddenToUse(from
, to
)) {
123 result
.add(dependencyRule
);
126 return result
.toArray(new DependencyRule
[result
.size()]);
131 DependencyRule
[] getApplicableRules(PsiFile file
) {
132 ArrayList
<DependencyRule
> result
= new ArrayList
<DependencyRule
>();
133 for (DependencyRule dependencyRule
: myRules
) {
134 if (dependencyRule
.isApplicable(file
)) {
135 result
.add(dependencyRule
);
138 return result
.toArray(new DependencyRule
[result
.size()]);
141 public boolean skipImportStatements() {
142 return SKIP_IMPORT_STATEMENTS
;
145 public void setSkipImportStatements(final boolean skip
) {
146 SKIP_IMPORT_STATEMENTS
= skip
;
149 public Map
<String
, PackageSet
> getUnnamedScopes() {
150 return myUnnamedScopes
;
153 public DependencyRule
[] getAllRules() {
154 return myRules
.toArray(new DependencyRule
[myRules
.size()]);
157 public void removeAllRules() {
161 public void addRule(DependencyRule rule
) {
162 appendUnnamedScope(rule
.getFromScope());
163 appendUnnamedScope(rule
.getToScope());
167 private void appendUnnamedScope(final NamedScope fromScope
) {
168 if (getScope(fromScope
.getName()) == null) {
169 final PackageSet packageSet
= fromScope
.getValue();
170 if (packageSet
!= null && !myUnnamedScopes
.containsKey(packageSet
.getText())) {
171 myUnnamedScopes
.put(packageSet
.getText(), packageSet
);
176 public void addContent(Content content
) {
177 myContentManager
.addContent(content
);
178 myContentManager
.setSelectedContent(content
);
179 ToolWindowManager
.getInstance(myProject
).getToolWindow(ToolWindowId
.DEPENDENCIES
).activate(null);
182 public void closeContent(Content content
) {
183 myContentManager
.removeContent(content
, true);
186 public String
getDisplayName() {
187 return IdeBundle
.message("shared.scopes.node.text");
190 public Icon
getIcon() {
191 return SHARED_SCOPES
;
195 public void loadState(final Element element
) {
197 DefaultJDOMExternalizer
.readExternal(this, element
);
199 catch (InvalidDataException e
) {
202 super.loadState(element
);
204 myUnnamedScopes
.clear();
205 final List unnamedScopes
= element
.getChildren(UNNAMED_SCOPE
);
206 final PackageSetFactory packageSetFactory
= PackageSetFactory
.getInstance();
207 for (Object unnamedScope
: unnamedScopes
) {
209 final String packageSet
= ((Element
)unnamedScope
).getAttributeValue(VALUE
);
210 myUnnamedScopes
.put(packageSet
, packageSetFactory
.compile(packageSet
));
212 catch (ParsingException e
) {
218 List rules
= element
.getChildren(DENY_RULE_KEY
);
219 for (Object rule1
: rules
) {
220 DependencyRule rule
= readRule((Element
)rule1
);
228 public Element
getState() {
229 Element element
= super.getState();
231 DefaultJDOMExternalizer
.writeExternal(this, element
);
233 catch (WriteExternalException e
) {
236 final List
<String
> unnamedScopes
= new ArrayList
<String
>(myUnnamedScopes
.keySet());
237 Collections
.sort(unnamedScopes
);
238 for (final String unnamedScope
: unnamedScopes
) {
239 Element unnamedElement
= new Element(UNNAMED_SCOPE
);
240 unnamedElement
.setAttribute(VALUE
, unnamedScope
);
241 element
.addContent(unnamedElement
);
244 for (DependencyRule rule
: myRules
) {
245 Element ruleElement
= writeRule(rule
);
246 if (ruleElement
!= null) {
247 element
.addContent(ruleElement
);
254 public NamedScope
getScope(@Nullable final String name
) {
255 final NamedScope scope
= super.getScope(name
);
257 final PackageSet packageSet
= myUnnamedScopes
.get(name
);
258 if (packageSet
!= null) {
259 return new NamedScope
.UnnamedScope(packageSet
);
262 //compatibility for predefined scopes: rename Project -> All
263 if (scope
== null && Comparing
.strEqual(name
, "Project")) {
264 return super.getScope("All");
270 private static Element
writeRule(DependencyRule rule
) {
271 NamedScope fromScope
= rule
.getFromScope();
272 NamedScope toScope
= rule
.getToScope();
273 if (fromScope
== null || toScope
== null) return null;
274 Element ruleElement
= new Element(DENY_RULE_KEY
);
275 ruleElement
.setAttribute(FROM_SCOPE_KEY
, fromScope
.getName());
276 ruleElement
.setAttribute(TO_SCOPE_KEY
, toScope
.getName());
277 ruleElement
.setAttribute(IS_DENY_KEY
, Boolean
.valueOf(rule
.isDenyRule()).toString());
282 private DependencyRule
readRule(Element ruleElement
) {
283 String fromScope
= ruleElement
.getAttributeValue(FROM_SCOPE_KEY
);
284 String toScope
= ruleElement
.getAttributeValue(TO_SCOPE_KEY
);
285 String denyRule
= ruleElement
.getAttributeValue(IS_DENY_KEY
);
286 if (fromScope
== null || toScope
== null || denyRule
== null) return null;
287 final NamedScope fromNamedScope
= getScope(fromScope
);
288 final NamedScope toNamedScope
= getScope(toScope
);
289 if (fromNamedScope
== null || toNamedScope
== null) return null;
290 return new DependencyRule(fromNamedScope
, toNamedScope
, Boolean
.valueOf(denyRule
).booleanValue());