diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactValidationManagerBase.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactProblemsHolderBase.java similarity index 84% rename from java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactValidationManagerBase.java rename to java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactProblemsHolderBase.java index 81ea40d312db..5b31da48790e 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactValidationManagerBase.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactProblemsHolderBase.java @@ -15,7 +15,7 @@ */ package com.intellij.packaging.impl.ui; -import com.intellij.packaging.ui.ArtifactValidationManager; +import com.intellij.packaging.ui.ArtifactProblemsHolder; import com.intellij.packaging.ui.ArtifactEditorContext; import com.intellij.packaging.ui.ArtifactProblemQuickFix; import org.jetbrains.annotations.NotNull; @@ -24,10 +24,10 @@ import org.jetbrains.annotations.Nullable; /** * @author nik */ -public abstract class ArtifactValidationManagerBase implements ArtifactValidationManager { +public abstract class ArtifactProblemsHolderBase implements ArtifactProblemsHolder { private ArtifactEditorContext myContext; - protected ArtifactValidationManagerBase(ArtifactEditorContext context) { + protected ArtifactProblemsHolderBase(ArtifactEditorContext context) { myContext = context; } diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactType.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactType.java index 533c2adc5657..130d0e2383e1 100644 --- a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactType.java +++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactType.java @@ -21,7 +21,7 @@ import com.intellij.packaging.elements.CompositePackagingElement; import com.intellij.packaging.elements.PackagingElement; import com.intellij.packaging.elements.PackagingElementOutputKind; import com.intellij.packaging.elements.PackagingElementResolvingContext; -import com.intellij.packaging.ui.ArtifactValidationManager; +import com.intellij.packaging.ui.ArtifactProblemsHolder; import com.intellij.packaging.ui.PackagingSourceItem; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -50,7 +50,7 @@ public abstract class ArtifactType { public String getPresentableName() { return myTitle; - } + } @NotNull public abstract Icon getIcon(); @@ -89,7 +89,7 @@ public abstract class ArtifactType { return Collections.emptyList(); } - public void checkRootElement(@NotNull CompositePackagingElement rootElement, @NotNull Artifact artifact, @NotNull ArtifactValidationManager manager) { + public void checkRootElement(@NotNull CompositePackagingElement rootElement, @NotNull Artifact artifact, @NotNull ArtifactProblemsHolder manager) { } @Nullable diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactValidationManager.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java similarity index 96% rename from java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactValidationManager.java rename to java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java index 345ca96b6562..5dc1c9f170c3 100644 --- a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactValidationManager.java +++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java @@ -22,7 +22,7 @@ import org.jetbrains.annotations.Nullable; /** * @author nik */ -public interface ArtifactValidationManager { +public interface ArtifactProblemsHolder { ArtifactEditorContext getContext(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java index d482338a23c5..33549a34a4bb 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java @@ -67,14 +67,8 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change private static final Logger LOG = Logger.getInstance("#" + ModulesConfigurator.class.getName()); private final Project myProject; - //private final ModuleStructureConfigurable myProjectRootConfigurable; - - private boolean myModified = false; - private final ProjectConfigurable myProjectConfigurable; - private final List myModuleEditors = new ArrayList(); - private final Comparator myModuleEditorComparator = new Comparator() { final ModulesAlphaComparator myModulesComparator = new ModulesAlphaComparator(); @@ -87,10 +81,12 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change return false; } }; + private boolean myModified = false; private ModifiableModuleModel myModuleModel; private ProjectFacetsConfigurator myFacetsConfigurator; private StructureConfigurableContext myContext; + private List myAllModulesChangeListeners = new ArrayList(); public ModulesConfigurator(Project project, ProjectJdksModel projectJdksModel) { myProject = project; @@ -211,6 +207,13 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change public void moduleStateChanged(final ModifiableRootModel moduleRootModel) { myProjectConfigurable.updateCircularDependencyWarning(); + for (ModuleEditor.ChangeListener listener : myAllModulesChangeListeners) { + listener.moduleStateChanged(moduleRootModel); + } + } + + public void addAllModuleChangeListener(ModuleEditor.ChangeListener listener) { + myAllModulesChangeListeners.add(listener); } public GraphGenerator createGraphGenerator() { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurable.java index 9fe5bf3afd92..d75c33ebff05 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactConfigurable.java @@ -18,7 +18,6 @@ package com.intellij.openapi.roots.ui.configuration.artifacts; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectStructureElementConfigurable; -import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.util.Comparing; @@ -41,13 +40,12 @@ public class ArtifactConfigurable extends ProjectStructureElementConfigurable chooseModules(final List modules, final String title) { ChooseModulesDialog dialog = new ChooseModulesDialog(getProject(), modules, title, null); dialog.show(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java index 0e8d5b41e6d4..0177313d2b70 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java @@ -111,7 +111,6 @@ public class ArtifactEditorImpl implements ArtifactEditorEx { }); setOutputPath(outputPath); myValidationManager = new ArtifactValidationManagerImpl(this); - myContext.setValidationManager(myValidationManager); updateShowContentCheckbox(); } @@ -174,7 +173,7 @@ public class ArtifactEditorImpl implements ArtifactEditorEx { } public void queueValidation() { - myValidationManager.queueValidation(); + myContext.queueValidation(); } public JComponent createMainComponent() { @@ -400,6 +399,10 @@ public class ArtifactEditorImpl implements ArtifactEditorEx { myLayoutTreeComponent.setRootElement(newRootElement); } + public ArtifactValidationManagerImpl getValidationManager() { + return myValidationManager; + } + private class MyDataProvider implements TypeSafeDataProvider { public void calcData(DataKey key, DataSink sink) { if (ARTIFACTS_EDITOR_KEY.equals(key)) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java new file mode 100644 index 000000000000..43ac8ce424d9 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.artifacts; + +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemDescription; +import com.intellij.packaging.elements.PackagingElement; +import com.intellij.packaging.ui.ArtifactProblemQuickFix; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public class ArtifactProblemDescription extends ProjectStructureProblemDescription { + private ArtifactProblemQuickFix myQuickFix; + private PackagingElement myPlace; + + public ArtifactProblemDescription(@NotNull String message, @NotNull Severity severity) { + super(message, severity); + } + + public ArtifactProblemDescription(@NotNull String message, @NotNull Severity severity, @Nullable ArtifactProblemQuickFix quickFix) { + super(message, severity); + myQuickFix = quickFix; + } + + public ArtifactProblemDescription(@NotNull String message, + @NotNull Severity severity, + @Nullable PackagingElement place, + @Nullable ArtifactProblemQuickFix quickFix) { + super(message, severity); + myPlace = place; + myQuickFix = quickFix; + } + + @Nullable + public ArtifactProblemQuickFix getQuickFix() { + return myQuickFix; + } + + public PackagingElement getPlace() { + return myPlace; + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java new file mode 100644 index 000000000000..0ca1c72ce258 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.artifacts; + +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemDescription; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemsHolder; +import com.intellij.packaging.elements.PackagingElement; +import com.intellij.packaging.impl.ui.ArtifactProblemsHolderBase; +import com.intellij.packaging.ui.ArtifactEditorContext; +import com.intellij.packaging.ui.ArtifactProblemQuickFix; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public class ArtifactProblemsHolderImpl extends ArtifactProblemsHolderBase { + private ProjectStructureProblemsHolder myProblemsHolder; + + public ArtifactProblemsHolderImpl(ArtifactEditorContext context, ProjectStructureProblemsHolder problemsHolder) { + super(context); + myProblemsHolder = problemsHolder; + } + + public void registerProblem(@NotNull String message, @Nullable PackagingElement place, @Nullable ArtifactProblemQuickFix quickFix) { + myProblemsHolder.registerProblem(new ArtifactProblemDescription(message, ProjectStructureProblemDescription.Severity.ERROR, place, quickFix)); + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProjectStructureElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProjectStructureElement.java index 9adc9590653a..d137641004c6 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProjectStructureElement.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProjectStructureElement.java @@ -39,15 +39,23 @@ public class ArtifactProjectStructureElement extends ProjectStructureElement { private final ArtifactsStructureConfigurableContext myArtifactsStructureContext; private final Artifact myOriginalArtifact; - public ArtifactProjectStructureElement(StructureConfigurableContext context, - ArtifactsStructureConfigurableContext artifactsStructureContext, Artifact artifact) { + ArtifactProjectStructureElement(StructureConfigurableContext context, + ArtifactsStructureConfigurableContext artifactsStructureContext, Artifact artifact) { super(context); myArtifactsStructureContext = artifactsStructureContext; myOriginalArtifact = artifactsStructureContext.getOriginalArtifact(artifact); } @Override - public void check(ProjectStructureProblemsHolder problemsHolder) { + public void check(final ProjectStructureProblemsHolder problemsHolder) { + final ArtifactEditorEx artifactEditor = (ArtifactEditorEx)myArtifactsStructureContext.getOrCreateEditor(myOriginalArtifact); + artifactEditor.getLayoutTreeComponent().saveElementProperties(); + final Artifact artifact = artifactEditor.getArtifact(); + artifact.getArtifactType().checkRootElement(artifactEditor.getRootElement(), artifact, new ArtifactProblemsHolderImpl(artifactEditor.getContext(), problemsHolder)); + } + + public Artifact getOriginalArtifact() { + return myOriginalArtifact; } @Override @@ -74,8 +82,7 @@ public class ArtifactProjectStructureElement extends ProjectStructureElement { else if (packagingElement instanceof ArtifactPackagingElement) { final Artifact usedArtifact = ((ArtifactPackagingElement)packagingElement).findArtifact(myArtifactsStructureContext); if (usedArtifact != null) { - final ArtifactProjectStructureElement artifactElement = - new ArtifactProjectStructureElement(myContext, myArtifactsStructureContext, usedArtifact); + final ArtifactProjectStructureElement artifactElement = myArtifactsStructureContext.getOrCreateArtifactElement(usedArtifact); usages.add(new UsageInArtifact(myOriginalArtifact, myArtifactsStructureContext, artifactElement, ArtifactProjectStructureElement.this, getPathFromRoot(parents, "/"), packagingElement)); } @@ -109,4 +116,5 @@ public class ArtifactProjectStructureElement extends ProjectStructureElement { public boolean highlightIfUnused() { return false; } + } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactValidationManagerImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactValidationManagerImpl.java index df03f0f63475..54c745bfdfcc 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactValidationManagerImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactValidationManagerImpl.java @@ -18,60 +18,32 @@ package com.intellij.openapi.roots.ui.configuration.artifacts; import com.intellij.openapi.Disposable; import com.intellij.openapi.roots.ui.configuration.artifacts.nodes.CompositePackagingElementNode; import com.intellij.openapi.roots.ui.configuration.artifacts.nodes.PackagingElementNode; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemDescription; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemsHolderImpl; import com.intellij.openapi.util.Disposer; -import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.elements.PackagingElement; -import com.intellij.packaging.impl.ui.ArtifactValidationManagerBase; import com.intellij.packaging.ui.ArtifactProblemQuickFix; -import com.intellij.util.ui.update.MergingUpdateQueue; -import com.intellij.util.ui.update.Update; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * @author nik */ -public class ArtifactValidationManagerImpl extends ArtifactValidationManagerBase implements Disposable { - private MergingUpdateQueue myValidationQueue; +public class ArtifactValidationManagerImpl implements Disposable { private ArtifactErrorPanel myErrorPanel; private final ArtifactEditorImpl myArtifactEditor; private Map, String> myErrorsForNodes = new HashMap, String>(); private Map, String> myErrorsForElements = new HashMap, String>(); ArtifactValidationManagerImpl(ArtifactEditorImpl artifactEditor) { - super(artifactEditor.getContext()); Disposer.register(artifactEditor, this); myArtifactEditor = artifactEditor; myErrorPanel = new ArtifactErrorPanel(artifactEditor); - final JComponent mainComponent = artifactEditor.getMainComponent(); - myValidationQueue = new MergingUpdateQueue("ArtifactValidation", 300, false, mainComponent, this, mainComponent); - } - - private void runValidation() { - myErrorPanel.clearError(); - myErrorsForNodes.clear(); - myErrorsForElements.clear(); - - myArtifactEditor.getLayoutTreeComponent().saveElementProperties(); - final Artifact artifact = myArtifactEditor.getArtifact(); - artifact.getArtifactType().checkRootElement(myArtifactEditor.getRootElement(), artifact, this); - - myArtifactEditor.getLayoutTreeComponent().updateTreeNodesPresentation(); - } - - public void registerProblem(@NotNull String message, @Nullable PackagingElement place, @Nullable ArtifactProblemQuickFix quickFix) { - if (place != null) { - final LayoutTree layoutTree = myArtifactEditor.getLayoutTreeComponent().getLayoutTree(); - myErrorsForElements.put(place, message); - final List> nodes = layoutTree.findNodes(Collections.singletonList(place)); - for (PackagingElementNode node : nodes) { - addNodeToErrorsWithParents(node, message); - } - } - myErrorPanel.showError(message, quickFix); } private void addNodeToErrorsWithParents(PackagingElementNode node, String message) { @@ -87,14 +59,6 @@ public class ArtifactValidationManagerImpl extends ArtifactValidationManagerBase public void dispose() { } - public void queueValidation() { - myValidationQueue.queue(new Update("validate") { - public void run() { - runValidation(); - } - }); - } - public JComponent getMainErrorPanel() { return myErrorPanel.getMainPanel(); } @@ -110,4 +74,33 @@ public class ArtifactValidationManagerImpl extends ArtifactValidationManagerBase public String getProblem(PackagingElementNode node) { return myErrorsForNodes.get(node); } + + public void updateProblems(@Nullable ProjectStructureProblemsHolderImpl holder) { + myErrorPanel.clearError(); + myErrorsForNodes.clear(); + myErrorsForElements.clear(); + if (holder != null) { + final List problemDescriptions = holder.getProblemDescriptions(); + if (problemDescriptions != null) { + for (ProjectStructureProblemDescription description : problemDescriptions) { + final String message = description.getMessage(); + ArtifactProblemQuickFix quickFix = null; + if (description instanceof ArtifactProblemDescription) { + quickFix = ((ArtifactProblemDescription)description).getQuickFix(); + final PackagingElement place = ((ArtifactProblemDescription)description).getPlace(); + if (place != null) { + final LayoutTree layoutTree = myArtifactEditor.getLayoutTreeComponent().getLayoutTree(); + myErrorsForElements.put(place, message); + final List> nodes = layoutTree.findNodes(Collections.singletonList(place)); + for (PackagingElementNode node : nodes) { + addNodeToErrorsWithParents(node, message); + } + } + } + myErrorPanel.showError(message, quickFix); + } + } + } + myArtifactEditor.getLayoutTreeComponent().updateTreeNodesPresentation(); + } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java index ba8911c93c32..914dfd05bed7 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java @@ -27,6 +27,8 @@ import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ui.configuration.ModuleEditor; import com.intellij.openapi.roots.ui.configuration.projectRoot.BaseStructureConfigurable; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement; @@ -64,7 +66,15 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable { public void artifactAdded(@NotNull Artifact artifact) { final MyNode node = addArtifactNode(artifact); selectNodeInTree(node); - myContext.getDaemonAnalyzer().queueUpdate(new ArtifactProjectStructureElement(myContext, myPackagingEditorContext, artifact)); + myContext.getDaemonAnalyzer().queueUpdate(myPackagingEditorContext.getOrCreateArtifactElement(artifact)); + } + }); + + context.getModulesConfigurator().addAllModuleChangeListener(new ModuleEditor.ChangeListener() { + public void moduleStateChanged(ModifiableRootModel moduleRootModel) { + for (ProjectStructureElement element : getProjectStructureElements()) { + myContext.getDaemonAnalyzer().queueUpdate(element, true, false); + } } }); } @@ -87,13 +97,13 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable { protected Collection getProjectStructureElements() { final List elements = new ArrayList(); for (Artifact artifact : myPackagingEditorContext.getArtifactModel().getArtifacts()) { - elements.add(new ArtifactProjectStructureElement(myContext, myPackagingEditorContext, artifact)); + elements.add(myPackagingEditorContext.getOrCreateArtifactElement(artifact)); } return elements; } private MyNode addArtifactNode(final Artifact artifact) { - final MyNode node = new MyNode(new ArtifactConfigurable(artifact, myPackagingEditorContext, TREE_UPDATER, myContext)); + final MyNode node = new MyNode(new ArtifactConfigurable(artifact, myPackagingEditorContext, TREE_UPDATER)); addNode(node, myRoot); return node; } @@ -216,7 +226,7 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable { @Override protected void removeArtifact(Artifact artifact) { myPackagingEditorContext.getOrCreateModifiableArtifactModel().removeArtifact(artifact); - myContext.getDaemonAnalyzer().removeElement(new ArtifactProjectStructureElement(myContext, myPackagingEditorContext, artifact)); + myContext.getDaemonAnalyzer().removeElement(myPackagingEditorContext.getOrCreateArtifactElement(artifact)); } protected void processRemovedItems() { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurableContext.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurableContext.java index 6c1f7bccb579..a11097eaedda 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurableContext.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurableContext.java @@ -49,4 +49,9 @@ public interface ArtifactsStructureConfigurableContext extends PackagingElementR @Nullable ModifiableModuleModel getModifiableModuleModel(); + + void queueValidation(Artifact artifact); + + @NotNull + ArtifactProjectStructureElement getOrCreateArtifactElement(@NotNull Artifact artifact); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurableContextImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurableContextImpl.java index 2fa3ffd9f5a7..6da61b401a33 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurableContextImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurableContextImpl.java @@ -15,11 +15,16 @@ */ package com.intellij.openapi.roots.ui.configuration.artifacts; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ui.configuration.FacetsProvider; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureDaemonAnalyzerListener; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemsHolderImpl; import com.intellij.openapi.util.Disposer; import com.intellij.packaging.artifacts.*; import com.intellij.packaging.elements.CompositePackagingElement; @@ -34,7 +39,7 @@ import java.util.Map; /** * @author nik */ -class ArtifactsStructureConfigurableContextImpl implements ArtifactsStructureConfigurableContext { +public class ArtifactsStructureConfigurableContextImpl implements ArtifactsStructureConfigurableContext { private ModifiableArtifactModel myModifiableModel; private final ManifestFilesInfo myManifestFilesInfo = new ManifestFilesInfo(); private ArtifactAdapter myModifiableModelListener; @@ -43,6 +48,7 @@ class ArtifactsStructureConfigurableContextImpl implements ArtifactsStructureCon private Map> myModifiableRoots = new HashMap>(); private Map myArtifactEditors = new HashMap(); private Map myEditorSettings = new HashMap(); + private Map myArtifactElements = new HashMap(); private final ArtifactEditorSettings myDefaultSettings; public ArtifactsStructureConfigurableContextImpl(StructureConfigurableContext context, Project project, @@ -51,6 +57,31 @@ class ArtifactsStructureConfigurableContextImpl implements ArtifactsStructureCon myModifiableModelListener = modifiableModelListener; myContext = context; myProject = project; + context.getDaemonAnalyzer().addListener(new ProjectStructureDaemonAnalyzerListener() { + public void usagesCollected(@NotNull ProjectStructureElement containingElement) { + } + + public void problemsChanged(@NotNull ProjectStructureElement element) { + if (element instanceof ArtifactProjectStructureElement) { + final Artifact originalArtifact = ((ArtifactProjectStructureElement)element).getOriginalArtifact(); + final ArtifactEditorImpl artifactEditor = myArtifactEditors.get(originalArtifact); + if (artifactEditor != null) { + updateProblems(originalArtifact, artifactEditor); + } + } + } + + public void allProblemsChanged() { + for (Map.Entry entry : myArtifactEditors.entrySet()) { + updateProblems(entry.getKey(), entry.getValue()); + } + } + }); + } + + private void updateProblems(Artifact originalArtifact, ArtifactEditorImpl artifactEditor) { + final ProjectStructureProblemsHolderImpl holder = myContext.getDaemonAnalyzer().getProblemsHolder(getOrCreateArtifactElement(originalArtifact)); + artifactEditor.getValidationManager().updateProblems(holder); } @NotNull @@ -78,6 +109,10 @@ class ArtifactsStructureConfigurableContextImpl implements ArtifactsStructureCon return myContext.getModulesConfigurator().getModuleModel(); } + public void queueValidation(Artifact artifact) { + myContext.getDaemonAnalyzer().queueUpdate(getOrCreateArtifactElement(artifact), true, false); + } + public CompositePackagingElement getRootElement(@NotNull Artifact artifact) { artifact = getOriginalArtifact(artifact); if (myModifiableModel != null) { @@ -98,14 +133,18 @@ class ArtifactsStructureConfigurableContextImpl implements ArtifactsStructureCon return root; } - public void editLayout(@NotNull Artifact artifact, Runnable action) { - artifact = getOriginalArtifact(artifact); - final ModifiableArtifact modifiableArtifact = getOrCreateModifiableArtifactModel().getOrCreateModifiableArtifact(artifact); - if (modifiableArtifact.getRootElement() == artifact.getRootElement()) { - modifiableArtifact.setRootElement(getOrCreateModifiableRootElement(artifact)); - } - action.run(); - myContext.getDaemonAnalyzer().queueUpdate(new ArtifactProjectStructureElement(myContext, this, artifact)); + public void editLayout(@NotNull final Artifact artifact, final Runnable action) { + final Artifact originalArtifact = getOriginalArtifact(artifact); + new WriteAction() { + protected void run(final Result result) { + final ModifiableArtifact modifiableArtifact = getOrCreateModifiableArtifactModel().getOrCreateModifiableArtifact(originalArtifact); + if (modifiableArtifact.getRootElement() == originalArtifact.getRootElement()) { + modifiableArtifact.setRootElement(getOrCreateModifiableRootElement(originalArtifact)); + } + action.run(); + } + }.execute(); + myContext.getDaemonAnalyzer().queueUpdate(getOrCreateArtifactElement(originalArtifact)); } public ArtifactEditorImpl getOrCreateEditor(Artifact artifact) { @@ -175,6 +214,7 @@ class ArtifactsStructureConfigurableContextImpl implements ArtifactsStructureCon if (myModifiableModel != null) { myModifiableModel.dispose(); } + myArtifactElements.clear(); } public void saveEditorSettings() { @@ -184,4 +224,14 @@ class ArtifactsStructureConfigurableContextImpl implements ArtifactsStructureCon myEditorSettings.put(pointer, artifactEditor.createSettings()); } } + + @NotNull + public ArtifactProjectStructureElement getOrCreateArtifactElement(@NotNull Artifact artifact) { + ArtifactProjectStructureElement element = myArtifactElements.get(getOriginalArtifact(artifact)); + if (element == null) { + element = new ArtifactProjectStructureElement(myContext, this, artifact); + myArtifactElements.put(artifact, element); + } + return element; + } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/ArtifactEditorFindUsagesActionBase.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/ArtifactEditorFindUsagesActionBase.java index 7b0efce581fd..3840f7af69a5 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/ArtifactEditorFindUsagesActionBase.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/actions/ArtifactEditorFindUsagesActionBase.java @@ -19,7 +19,6 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; -import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactProjectStructureElement; import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactsStructureConfigurableContext; import com.intellij.openapi.roots.ui.configuration.artifacts.nodes.ArtifactsTreeNode; import com.intellij.openapi.roots.ui.configuration.projectRoot.FindUsagesInProjectStructureActionBase; @@ -67,7 +66,7 @@ public abstract class ArtifactEditorFindUsagesActionBase extends FindUsagesInPro return new LibraryProjectStructureElement(context, (Library)sourceObject); } else if (sourceObject instanceof Artifact) { - return new ArtifactProjectStructureElement(context, myArtifactContext, (Artifact)sourceObject); + return myArtifactContext.getOrCreateArtifactElement((Artifact)sourceObject); } return null; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/nodes/PackagingElementNode.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/nodes/PackagingElementNode.java index cc7e19c8d1c6..7135ef9cb8cc 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/nodes/PackagingElementNode.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/nodes/PackagingElementNode.java @@ -18,7 +18,7 @@ package com.intellij.openapi.roots.ui.configuration.artifacts.nodes; import com.intellij.ide.projectView.PresentationData; import com.intellij.openapi.editor.markup.EffectType; import com.intellij.openapi.editor.markup.TextAttributes; -import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactEditorContextImpl; +import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactEditorImpl; import com.intellij.openapi.util.MultiValuesMap; import com.intellij.packaging.elements.CompositePackagingElement; import com.intellij.packaging.elements.PackagingElement; @@ -55,7 +55,7 @@ public class PackagingElementNode> extends Artifac private void doAddElement(E packagingElement) { myPackagingElements.add(packagingElement); - ((ArtifactEditorContextImpl)myContext).getValidationManager().elementAddedToNode(this, packagingElement); + ((ArtifactEditorImpl)myContext.getThisArtifactEditor()).getValidationManager().elementAddedToNode(this, packagingElement); } @Nullable @@ -93,7 +93,7 @@ public class PackagingElementNode> extends Artifac @Override protected void update(PresentationData presentation) { - final String message = ((ArtifactEditorContextImpl)myContext).getValidationManager().getProblem(this); + final String message = ((ArtifactEditorImpl)myContext.getThisArtifactEditor()).getValidationManager().getProblem(this); if (message == null) { super.update(presentation); return; @@ -104,7 +104,7 @@ public class PackagingElementNode> extends Artifac presentation.setTooltip(message); } - private SimpleTextAttributes addErrorHighlighting(SimpleTextAttributes attributes) { + private static SimpleTextAttributes addErrorHighlighting(SimpleTextAttributes attributes) { final TextAttributes textAttributes = attributes.toTextAttributes(); textAttributes.setEffectType(EffectType.WAVE_UNDERSCORE); textAttributes.setEffectColor(Color.RED); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java index decbe7b96728..589ca1fe4f44 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java @@ -30,10 +30,7 @@ import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; -import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureDaemonAnalyzer; -import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement; -import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemDescription; -import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemsHolder; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.*; import com.intellij.openapi.ui.MasterDetailsComponent; import com.intellij.openapi.ui.NamedConfigurable; import com.intellij.openapi.util.ActionCallback; @@ -77,8 +74,20 @@ public abstract class BaseStructureConfigurable extends MasterDetailsComponent i public void init(StructureConfigurableContext context) { myContext = context; - myContext.getDaemonAnalyzer().addListener(new Runnable() { - public void run() { + myContext.getDaemonAnalyzer().addListener(new ProjectStructureDaemonAnalyzerListener() { + public void usagesCollected(@NotNull ProjectStructureElement containingElement) { + updateTree(); + } + + public void problemsChanged(@NotNull ProjectStructureElement element) { + updateTree(); + } + + public void allProblemsChanged() { + updateTree(); + } + + private void updateTree() { if (!myTree.isShowing()) return; myTree.revalidate(); @@ -173,7 +182,7 @@ public abstract class BaseStructureConfigurable extends MasterDetailsComponent i if (projectStructureElement != null) { final ProjectStructureDaemonAnalyzer daemonAnalyzer = myContext.getDaemonAnalyzer(); final boolean unused = daemonAnalyzer.isUnused(projectStructureElement); - final ProjectStructureProblemsHolder problemsHolder = daemonAnalyzer.getProblemsHolder(projectStructureElement); + final ProjectStructureProblemsHolderImpl problemsHolder = daemonAnalyzer.getProblemsHolder(projectStructureElement); if (problemsHolder == null) { daemonAnalyzer.queueUpdate(projectStructureElement, true, false); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java index 31f7dbe02158..0fb2837e350b 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java @@ -34,10 +34,10 @@ public class LibraryProjectStructureElement extends ProjectStructureElement { final LibraryEx library = (LibraryEx)myLibrary; final String libraryName = myLibrary.getName();//todo[nik] get modified name? if (!library.allPathsValid(OrderRootType.CLASSES)) { - problemsHolder.addError(ProjectBundle.message("project.roots.tooltip.library.misconfigured", libraryName)); + problemsHolder.registerError(ProjectBundle.message("project.roots.tooltip.library.misconfigured", libraryName)); } else if (!library.allPathsValid(JavadocOrderRootType.getInstance()) || !library.allPathsValid(OrderRootType.SOURCES)) { - problemsHolder.addWarning(ProjectBundle.message("project.roots.tooltip.library.misconfigured", libraryName)); + problemsHolder.registerWarning(ProjectBundle.message("project.roots.tooltip.library.misconfigured", libraryName)); } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java index 839556a404d0..7eef60439e94 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java @@ -34,7 +34,7 @@ public class ModuleProjectStructureElement extends ProjectStructureElement { final Module[] all = moduleModel.getModules(); for (Module each : all) { if (each != myModule && myContext.getRealName(each).equals(myContext.getRealName(myModule))) { - problemsHolder.addError(ProjectBundle.message("project.roots.module.duplicate.name.message")); + problemsHolder.registerError(ProjectBundle.message("project.roots.module.duplicate.name.message")); break; } } @@ -45,9 +45,9 @@ public class ModuleProjectStructureElement extends ProjectStructureElement { for (OrderEntry entry : entries) { if (!entry.isValid()){ if (entry instanceof JdkOrderEntry && ((JdkOrderEntry)entry).getJdkName() == null) { - problemsHolder.addError(ProjectBundle.message("project.roots.module.jdk.problem.message")); + problemsHolder.registerError(ProjectBundle.message("project.roots.module.jdk.problem.message")); } else { - problemsHolder.addError(ProjectBundle.message("project.roots.library.problem.message", entry.getPresentableName())); + problemsHolder.registerError(ProjectBundle.message("project.roots.library.problem.message", entry.getPresentableName())); } } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java index aa5b46984392..53aa63981541 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java @@ -7,9 +7,11 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.MultiValuesMap; +import com.intellij.util.EventDispatcher; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.*; @@ -20,12 +22,12 @@ import java.util.concurrent.atomic.AtomicBoolean; */ public class ProjectStructureDaemonAnalyzer implements Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.projectRoot.validation.ProjectStructureDaemonAnalyzer"); - private Map myProblemHolders = new HashMap(); + private Map myProblemHolders = new HashMap(); private MultiValuesMap mySourceElement2Usages = new MultiValuesMap(); private MultiValuesMap myContainingElement2Usages = new MultiValuesMap(); private Set myElementWithNotCalculatedUsages = new HashSet(); private MergingUpdateQueue myAnalyzerQueue; - private List myListeners = new ArrayList(); + private final EventDispatcher myDispatcher = EventDispatcher.create(ProjectStructureDaemonAnalyzerListener.class); private final AtomicBoolean myStopped = new AtomicBoolean(false); public ProjectStructureDaemonAnalyzer(StructureConfigurableContext context) { @@ -45,7 +47,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { } private void doCheck(final ProjectStructureElement element) { - final ProjectStructureProblemsHolder problemsHolder = new ProjectStructureProblemsHolder(); + final ProjectStructureProblemsHolderImpl problemsHolder = new ProjectStructureProblemsHolderImpl(); new ReadAction() { protected void run(final Result result) { if (myStopped.get()) return; @@ -64,18 +66,11 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { LOG.debug("updating problems for " + element); } myProblemHolders.put(element, problemsHolder); - fireProblemsUpdated(); + myDispatcher.getMulticaster().problemsChanged(element); } }); } - private void fireProblemsUpdated() { - Runnable[] listeners = myListeners.toArray(new Runnable[myListeners.size()]); - for (Runnable listener : listeners) { - listener.run(); - } - } - private void doCollectUsages(final ProjectStructureElement element) { final List usages = new ReadAction>() { protected void run(final Result> result) { @@ -96,7 +91,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { LOG.debug("updating usages for " + element); } updateUsages(element, usages); - fireProblemsUpdated(); + myDispatcher.getMulticaster().usagesCollected(element); } }); } @@ -137,7 +132,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { } } removeUsagesInElement(element); - fireProblemsUpdated(); + myDispatcher.getMulticaster().problemsChanged(element); } public boolean isUnused(ProjectStructureElement element) { @@ -180,7 +175,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { public void clearAllProblems() { myProblemHolders.clear(); - fireProblemsUpdated(); + myDispatcher.getMulticaster().allProblemsChanged(); } public void dispose() { @@ -188,7 +183,8 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { myAnalyzerQueue.cancelAllUpdates(); } - public ProjectStructureProblemsHolder getProblemsHolder(ProjectStructureElement element) { + @Nullable + public ProjectStructureProblemsHolderImpl getProblemsHolder(ProjectStructureElement element) { return myProblemHolders.get(element); } @@ -197,14 +193,13 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { for (ProjectStructureElement element : elements) { updateUsages(element, element.getUsagesInElement()); } - fireProblemsUpdated(); final Collection usages = mySourceElement2Usages.get(selected); return usages != null ? usages : Collections.emptyList(); } - public void addListener(Runnable runnable) { - LOG.debug("listener added " + runnable); - myListeners.add(runnable); + public void addListener(ProjectStructureDaemonAnalyzerListener listener) { + LOG.debug("listener added " + listener); + myDispatcher.addListener(listener); } public void reset() { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzerListener.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzerListener.java new file mode 100644 index 000000000000..1ca027639b40 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzerListener.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; + +import org.jetbrains.annotations.NotNull; + +import java.util.EventListener; + +/** + * @author nik + */ +public interface ProjectStructureDaemonAnalyzerListener extends EventListener { + + void usagesCollected(@NotNull ProjectStructureElement containingElement); + + void problemsChanged(@NotNull ProjectStructureElement element); + + void allProblemsChanged(); +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java index fa12df0d06e6..8f36da05fd63 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java @@ -15,6 +15,8 @@ */ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; +import org.jetbrains.annotations.NotNull; + /** * @author nik */ @@ -22,7 +24,7 @@ public class ProjectStructureProblemDescription { private String myMessage; private final Severity mySeverity; - public ProjectStructureProblemDescription(String message, Severity severity) { + public ProjectStructureProblemDescription(@NotNull String message, @NotNull Severity severity) { myMessage = message; mySeverity = severity; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java index 35727828aa5f..9094b4ac654c 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java @@ -1,57 +1,29 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; -import com.intellij.util.SmartList; -import com.intellij.util.StringBuilderSpinAllocator; -import org.jetbrains.annotations.Nullable; - -import java.util.List; +import org.jetbrains.annotations.NotNull; /** * @author nik */ -public class ProjectStructureProblemsHolder { - private List myProblemDescriptions; +public interface ProjectStructureProblemsHolder { + void registerError(@NotNull String message); - public void addError(String message) { - addProblem(message, ProjectStructureProblemDescription.Severity.ERROR); - } + void registerWarning(@NotNull String message); - public void addWarning(String message) { - addProblem(message, ProjectStructureProblemDescription.Severity.WARNING); - } - - public void addProblem(String description, ProjectStructureProblemDescription.Severity severity) { - if (myProblemDescriptions == null) { - myProblemDescriptions = new SmartList(); - } - myProblemDescriptions.add(new ProjectStructureProblemDescription(description, severity)); - } - - @Nullable - public ProjectStructureProblemDescription.Severity getSeverity() { - if (myProblemDescriptions == null || myProblemDescriptions.isEmpty()) { - return null; - } - for (ProjectStructureProblemDescription description : myProblemDescriptions) { - if (description.getSeverity() == ProjectStructureProblemDescription.Severity.ERROR) { - return ProjectStructureProblemDescription.Severity.ERROR; - } - } - return ProjectStructureProblemDescription.Severity.WARNING; - } - - public String composeTooltipMessage() { - final StringBuilder buf = StringBuilderSpinAllocator.alloc(); - try { - if (myProblemDescriptions != null) { - for (ProjectStructureProblemDescription problemDescription : myProblemDescriptions) { - buf.append(problemDescription.getMessage()).append("\n"); - } - } - return buf.toString(); - } - finally { - StringBuilderSpinAllocator.dispose(buf); - } - } + void registerProblem(@NotNull ProjectStructureProblemDescription description); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java new file mode 100644 index 000000000000..425f2668fab8 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java @@ -0,0 +1,63 @@ +package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; + +import com.intellij.util.SmartList; +import com.intellij.util.StringBuilderSpinAllocator; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * @author nik + */ +public class ProjectStructureProblemsHolderImpl implements ProjectStructureProblemsHolder { + private List myProblemDescriptions; + + public void registerError(@NotNull String message) { + registerProblem(new ProjectStructureProblemDescription(message, ProjectStructureProblemDescription.Severity.ERROR)); + } + + public void registerWarning(@NotNull String message) { + registerProblem(new ProjectStructureProblemDescription(message, ProjectStructureProblemDescription.Severity.WARNING)); + } + + public void registerProblem(final @NotNull ProjectStructureProblemDescription description) { + if (myProblemDescriptions == null) { + myProblemDescriptions = new SmartList(); + } + myProblemDescriptions.add(description); + } + + @Nullable + public ProjectStructureProblemDescription.Severity getSeverity() { + if (myProblemDescriptions == null || myProblemDescriptions.isEmpty()) { + return null; + } + for (ProjectStructureProblemDescription description : myProblemDescriptions) { + if (description.getSeverity() == ProjectStructureProblemDescription.Severity.ERROR) { + return ProjectStructureProblemDescription.Severity.ERROR; + } + } + return ProjectStructureProblemDescription.Severity.WARNING; + } + + public String composeTooltipMessage() { + final StringBuilder buf = StringBuilderSpinAllocator.alloc(); + try { + if (myProblemDescriptions != null) { + for (ProjectStructureProblemDescription problemDescription : myProblemDescriptions) { + buf.append(problemDescription.getMessage()).append("\n"); + } + } + return buf.toString(); + } + finally { + StringBuilderSpinAllocator.dispose(buf); + } + } + + @Nullable + public List getProblemDescriptions() { + return myProblemDescriptions; + } +}