From 4d8516a2438399b54ff4a909028047b27c4852ea Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 19 Oct 2009 17:52:27 +0400 Subject: [PATCH 01/14] crlfs --- .../hierarchy/HierarchyViewTestBase.java | 178 +++++++++--------- 1 file changed, 89 insertions(+), 89 deletions(-) diff --git a/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java b/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java index 28c9ba1331a7..6e9ed3895605 100755 --- a/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java +++ b/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java @@ -1,89 +1,89 @@ -package com.intellij.testFramework.codeInsight.hierarchy; - -import com.intellij.codeInsight.CodeInsightTestCase; -import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; -import com.intellij.ide.hierarchy.HierarchyTreeStructure; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.JDOMUtil; -import org.jdom.Document; -import org.jdom.Element; - -import java.io.File; -import java.util.*; - -/** - * Checks tree structure for Type Hierarchy (Ctrl+H), Call Hierarchy (Ctrl+Alt+H), Method Hierarchy (Ctrl+Shift+H). - */ -public abstract class HierarchyViewTestBase extends CodeInsightTestCase { - - protected abstract String getBasePath(); - - protected void doHierarchyTest(final Computable treeStructureComputable, final String... fileNames) - throws Exception { - final String[] relFilePaths = new String[fileNames.length]; - for (int i = 0; i < fileNames.length; i++) { - relFilePaths[i] = "/" + getBasePath() + "/" + fileNames[i]; - } - configureByFiles(null, relFilePaths); - - final String verificationFilePath = getTestDataPath() + "/" + getBasePath() + "/" + getTestName(false) + "_verification.xml"; - checkHierarchyTreeStructure(treeStructureComputable.compute(), JDOMUtil.loadDocument(new File(verificationFilePath))); - } - - private static void checkHierarchyTreeStructure(final HierarchyTreeStructure treeStructure, final Document document) { - checkNodeDescriptorRecursively(treeStructure, (HierarchyNodeDescriptor)treeStructure.getRootElement(), document.getRootElement()); - } - - private static void checkNodeDescriptorRecursively(final HierarchyTreeStructure treeStructure, - final HierarchyNodeDescriptor descriptor, - final Element expectedElement) { - descriptor.update(); - checkBaseNode(treeStructure, descriptor, expectedElement); - checkContent(descriptor, expectedElement); - checkChildren(treeStructure, descriptor, expectedElement); - } - - private static void checkBaseNode(final HierarchyTreeStructure treeStructure, - final HierarchyNodeDescriptor descriptor, - final Element expectedElement) { - final String baseAttrValue = expectedElement.getAttributeValue("base"); - final HierarchyNodeDescriptor baseDescriptor = treeStructure.getBaseDescriptor(); - final boolean mustBeBase = "true".equalsIgnoreCase(baseAttrValue); - assertTrue("Incorrect base node", mustBeBase ? baseDescriptor == descriptor : baseDescriptor != descriptor); - } - - private static void checkContent(final HierarchyNodeDescriptor descriptor, final Element expectedElement) { - assertEquals(expectedElement.getAttributeValue("text"), descriptor.getHighlightedText().getText()); - } - - private static void checkChildren(final HierarchyTreeStructure treeStructure, - final HierarchyNodeDescriptor descriptor, - final Element element) { - final Object[] children = treeStructure.getChildElements(descriptor); - //noinspection unchecked - final List expectedChildren = new ArrayList(element.getChildren()); - assertEquals("Children of " + descriptor.getHighlightedText().getText(), expectedChildren.size(), children.length); - - Arrays.sort(children, new Comparator() { - public int compare(final Object first, final Object second) { - return ((HierarchyNodeDescriptor)first).getHighlightedText().getText() - .compareTo(((HierarchyNodeDescriptor)second).getHighlightedText().getText()); - } - }); - - Collections.sort(expectedChildren, new Comparator() { - public int compare(final Element first, final Element second) { - return first.getAttributeValue("text").compareTo(second.getAttributeValue("text")); - } - }); - - //noinspection unchecked - final Iterator iterator = expectedChildren.iterator(); - for (Object child : children) { - checkNodeDescriptorRecursively(treeStructure, ((HierarchyNodeDescriptor)child), iterator.next()); - } - } - -} - - +package com.intellij.testFramework.codeInsight.hierarchy; + +import com.intellij.codeInsight.CodeInsightTestCase; +import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; +import com.intellij.ide.hierarchy.HierarchyTreeStructure; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.JDOMUtil; +import org.jdom.Document; +import org.jdom.Element; + +import java.io.File; +import java.util.*; + +/** + * Checks tree structure for Type Hierarchy (Ctrl+H), Call Hierarchy (Ctrl+Alt+H), Method Hierarchy (Ctrl+Shift+H). + */ +public abstract class HierarchyViewTestBase extends CodeInsightTestCase { + + protected abstract String getBasePath(); + + protected void doHierarchyTest(final Computable treeStructureComputable, final String... fileNames) + throws Exception { + final String[] relFilePaths = new String[fileNames.length]; + for (int i = 0; i < fileNames.length; i++) { + relFilePaths[i] = "/" + getBasePath() + "/" + fileNames[i]; + } + configureByFiles(null, relFilePaths); + + final String verificationFilePath = getTestDataPath() + "/" + getBasePath() + "/" + getTestName(false) + "_verification.xml"; + checkHierarchyTreeStructure(treeStructureComputable.compute(), JDOMUtil.loadDocument(new File(verificationFilePath))); + } + + private static void checkHierarchyTreeStructure(final HierarchyTreeStructure treeStructure, final Document document) { + checkNodeDescriptorRecursively(treeStructure, (HierarchyNodeDescriptor)treeStructure.getRootElement(), document.getRootElement()); + } + + private static void checkNodeDescriptorRecursively(final HierarchyTreeStructure treeStructure, + final HierarchyNodeDescriptor descriptor, + final Element expectedElement) { + descriptor.update(); + checkBaseNode(treeStructure, descriptor, expectedElement); + checkContent(descriptor, expectedElement); + checkChildren(treeStructure, descriptor, expectedElement); + } + + private static void checkBaseNode(final HierarchyTreeStructure treeStructure, + final HierarchyNodeDescriptor descriptor, + final Element expectedElement) { + final String baseAttrValue = expectedElement.getAttributeValue("base"); + final HierarchyNodeDescriptor baseDescriptor = treeStructure.getBaseDescriptor(); + final boolean mustBeBase = "true".equalsIgnoreCase(baseAttrValue); + assertTrue("Incorrect base node", mustBeBase ? baseDescriptor == descriptor : baseDescriptor != descriptor); + } + + private static void checkContent(final HierarchyNodeDescriptor descriptor, final Element expectedElement) { + assertEquals(expectedElement.getAttributeValue("text"), descriptor.getHighlightedText().getText()); + } + + private static void checkChildren(final HierarchyTreeStructure treeStructure, + final HierarchyNodeDescriptor descriptor, + final Element element) { + final Object[] children = treeStructure.getChildElements(descriptor); + //noinspection unchecked + final List expectedChildren = new ArrayList(element.getChildren()); + assertEquals("Children of " + descriptor.getHighlightedText().getText(), expectedChildren.size(), children.length); + + Arrays.sort(children, new Comparator() { + public int compare(final Object first, final Object second) { + return ((HierarchyNodeDescriptor)first).getHighlightedText().getText() + .compareTo(((HierarchyNodeDescriptor)second).getHighlightedText().getText()); + } + }); + + Collections.sort(expectedChildren, new Comparator() { + public int compare(final Element first, final Element second) { + return first.getAttributeValue("text").compareTo(second.getAttributeValue("text")); + } + }); + + //noinspection unchecked + final Iterator iterator = expectedChildren.iterator(); + for (Object child : children) { + checkNodeDescriptorRecursively(treeStructure, ((HierarchyNodeDescriptor)child), iterator.next()); + } + } + +} + + From d752170f8cb02f7b7627ed5b1d5b22938efd0f76 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 19 Oct 2009 18:01:55 +0400 Subject: [PATCH 02/14] JspxCompletionTest fixed --- .../completion/ExtendedTagInsertHandler.java | 9 +++++++-- .../impl/providers/URLReference.java | 17 ++++++++++++----- .../psi/impl/source/xml/XmlDoctypeImpl.java | 3 ++- .../com/intellij/xml/XmlSchemaProvider.java | 19 +++++++++++++++++-- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/xml/impl/src/com/intellij/codeInsight/completion/ExtendedTagInsertHandler.java b/xml/impl/src/com/intellij/codeInsight/completion/ExtendedTagInsertHandler.java index 65b560a451f8..d935312f634e 100644 --- a/xml/impl/src/com/intellij/codeInsight/completion/ExtendedTagInsertHandler.java +++ b/xml/impl/src/com/intellij/codeInsight/completion/ExtendedTagInsertHandler.java @@ -134,8 +134,13 @@ public class ExtendedTagInsertHandler extends XmlTagInsertHandler { if (myNamespace == null) { return null; } - final XmlSchemaProvider provider = XmlSchemaProvider.getAvailableProvider(file); - return provider == null ? null : provider.getDefaultPrefix(myNamespace, file); + for (XmlSchemaProvider provider : XmlSchemaProvider.getAvailableProviders(file)) { + String prefix = provider.getDefaultPrefix(myNamespace, file); + if (prefix != null) { + return prefix; + } + } + return null; } protected Set getNamespaces(final XmlFile file) { diff --git a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/URLReference.java b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/URLReference.java index 4ccc5f9dc191..e8c65f185c38 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/URLReference.java +++ b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/URLReference.java @@ -11,10 +11,11 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.codeInsight.daemon.impl.quickfix.*; import com.intellij.javaee.ExternalResourceManager; import com.intellij.javaee.ExternalResourceManagerEx; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.XmlAttribute; @@ -32,6 +33,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.HashSet; import java.util.Set; /** @@ -180,12 +182,17 @@ public class URLReference implements PsiReference, QuickFixProvider, EmptyResolv return myElement.getManager().areElementsEquivalent(resolve(),element); } + @NotNull public Object[] getVariants() { final XmlFile file = (XmlFile)myElement.getContainingFile(); - final XmlSchemaProvider provider = XmlSchemaProvider.getAvailableProvider(file); - if (provider != null) { - final Set strings = provider.getAvailableNamespaces(file, null); - return ArrayUtil.toObjectArray(strings); + Set list = new HashSet(); + for (XmlSchemaProvider provider : Extensions.getExtensions(XmlSchemaProvider.EP_NAME)) { + if (provider.isAvailable(file)) { + list.addAll(provider.getAvailableNamespaces(file, null)); + } + } + if (!list.isEmpty()) { + return ArrayUtil.toObjectArray(list); } String[] resourceUrls = ExternalResourceManager.getInstance().getResourceUrls(null, true); final XmlDocument document = file.getDocument(); diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlDoctypeImpl.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlDoctypeImpl.java index b1fd03fb051e..93640437e49b 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlDoctypeImpl.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlDoctypeImpl.java @@ -195,9 +195,10 @@ public class XmlDoctypeImpl extends XmlElementImpl implements XmlDoctype, XmlEle if (dtdUrlElement != null) { uriRefs = new PsiReference[1]; uriRefs[0] = new URLReference(XmlDoctypeImpl.this) { + @NotNull public Object[] getVariants() { return (docTypePublic != null)? - super.getVariants(): PsiReference.EMPTY_ARRAY; + super.getVariants(): EMPTY_ARRAY; } public String getCanonicalText() { return extractValue(dtdUrlElement); diff --git a/xml/openapi/src/com/intellij/xml/XmlSchemaProvider.java b/xml/openapi/src/com/intellij/xml/XmlSchemaProvider.java index a9c8a471cf9d..8f5704584595 100644 --- a/xml/openapi/src/com/intellij/xml/XmlSchemaProvider.java +++ b/xml/openapi/src/com/intellij/xml/XmlSchemaProvider.java @@ -20,16 +20,19 @@ import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; -import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.DumbAware; -import com.intellij.psi.PsiFile; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; import com.intellij.psi.xml.XmlFile; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collections; +import java.util.List; import java.util.Set; /** @@ -66,6 +69,10 @@ public abstract class XmlSchemaProvider { return findSchema(url, module, baseFile); } + /** + * @see #getAvailableProviders(com.intellij.psi.xml.XmlFile) + */ + @Deprecated @Nullable public static XmlSchemaProvider getAvailableProvider(final @NotNull XmlFile file) { for (XmlSchemaProvider provider: Extensions.getExtensions(EP_NAME)) { @@ -76,6 +83,14 @@ public abstract class XmlSchemaProvider { return null; } + public static List getAvailableProviders(final @NotNull XmlFile file) { + return ContainerUtil.findAll(Extensions.getExtensions(EP_NAME), new Condition() { + public boolean value(XmlSchemaProvider xmlSchemaProvider) { + return xmlSchemaProvider.isAvailable(file); + } + }); + } + @Nullable public abstract XmlFile getSchema(@NotNull @NonNls String url, @Nullable Module module, @NotNull final PsiFile baseFile); From 3ae3867c05502c5b9106c1a693e0c8f6236741ec Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Mon, 19 Oct 2009 19:33:19 +0400 Subject: [PATCH 03/14] Rollback enabling "serializable class with no UID" by default. In its current incarnation it generates more harm than good showing all UI components and Exception inheritors, which rarely going to have UID in reality. --- .../SerializableHasSerialVersionUIDFieldInspection.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerialVersionUIDFieldInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerialVersionUIDFieldInspection.java index 9eb3c59638b9..2a83ba2ce9ac 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerialVersionUIDFieldInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerialVersionUIDFieldInspection.java @@ -27,11 +27,6 @@ import org.jetbrains.annotations.NotNull; public class SerializableHasSerialVersionUIDFieldInspection extends SerializableInspection { - @Override - public boolean isEnabledByDefault() { - return true; - } - @Override @NotNull public String getID() { @@ -92,4 +87,4 @@ public class SerializableHasSerialVersionUIDFieldInspection registerClassError(aClass); } } -} \ No newline at end of file +} From 346a1f3a4f54940082eddc1cd754757aa209b66a Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Thu, 1 Oct 2009 18:40:37 +0400 Subject: [PATCH 04/14] do not reset on project structure configuration apply --- .../facet/impl/ProjectFacetsConfigurator.java | 12 +- .../ui/configuration/AnnotationsEditor.java | 12 +- .../ui/configuration/BuildElementsEditor.java | 48 +-- .../ui/configuration/ClasspathEditor.java | 72 ++++- .../ui/configuration/ClasspathPanel.java | 83 ++--- .../configuration/ContentEntriesEditor.java | 14 +- ...tModuleConfigurationEditorFactoryImpl.java | 10 +- .../DefaultModuleEditorsProvider.java | 9 +- .../JavaContentEntriesEditor.java | 7 +- .../roots/ui/configuration/JavadocEditor.java | 12 +- .../LanguageLevelConfigurable.java | 18 +- .../roots/ui/configuration/ModuleEditor.java | 63 ++-- .../configuration/ModuleJdkConfigurable.java | 28 +- .../ui/configuration/ModulesConfigurator.java | 58 +++- .../roots/ui/configuration/OutputEditor.java | 14 +- .../ProjectStructureConfigurable.java | 10 +- .../ArtifactsStructureConfigurable.java | 2 + .../libraryEditor/LibraryTableEditor.java | 6 +- .../BaseLibrariesConfigurable.java | 1 + .../ModuleStructureConfigurable.java | 12 +- .../StructureConfigurableContext.java | 301 ++++++++++++++++++ .../intellij/peer/impl/PeerFactoryImpl.java | 8 +- .../src/com/intellij/peer/PeerFactory.java | 6 +- .../openapi/roots/ModifiableRootModel.java | 2 + .../impl/ModuleConfigurationStateImpl.java | 14 +- .../openapi/roots/impl/RootModelImpl.java | 4 + .../CommonContentEntriesEditor.java | 25 +- .../configuration/ModuleElementsEditor.java | 18 +- 28 files changed, 639 insertions(+), 230 deletions(-) rename {java/idea-ui => platform/lang-impl}/src/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java (81%) diff --git a/java/idea-ui/src/com/intellij/facet/impl/ProjectFacetsConfigurator.java b/java/idea-ui/src/com/intellij/facet/impl/ProjectFacetsConfigurator.java index 5443a36cad96..33f15ad9f06d 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ProjectFacetsConfigurator.java +++ b/java/idea-ui/src/com/intellij/facet/impl/ProjectFacetsConfigurator.java @@ -60,9 +60,19 @@ public class ProjectFacetsConfigurator implements FacetsProvider, ModuleEditor.C private final Project myProject; private UserDataHolderBase myProjectData = new UserDataHolderBase(); - public ProjectFacetsConfigurator(final StructureConfigurableContext context, Project project) { + public ProjectFacetsConfigurator(final StructureConfigurableContext context, Project project, ProjectFacetsConfigurator facetsConfigurator) { myContext = context; myProject = project; + + if (facetsConfigurator != null) { + initFrom(facetsConfigurator); + } + } + + private void initFrom(ProjectFacetsConfigurator facetsConfigurator) { + myFacet2Info.putAll(facetsConfigurator.myFacet2Info); + myInfo2Facet.putAll(facetsConfigurator.myInfo2Facet); + myTreeModels.putAll(facetsConfigurator.myTreeModels); } public List removeFacet(Facet facet) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/AnnotationsEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/AnnotationsEditor.java index 10e076e8f097..0223d7ed9fde 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/AnnotationsEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/AnnotationsEditor.java @@ -17,9 +17,7 @@ package com.intellij.openapi.roots.ui.configuration; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.AnnotationOrderRootType; import com.intellij.openapi.roots.ui.util.CellAppearance; import com.intellij.openapi.roots.ui.util.CellAppearanceUtils; @@ -31,9 +29,9 @@ import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.TableUtil; +import com.intellij.util.ArrayUtil; import com.intellij.util.ui.ItemRemovable; import com.intellij.util.ui.Table; -import com.intellij.util.ArrayUtil; import javax.swing.*; import javax.swing.border.Border; @@ -58,8 +56,8 @@ public class AnnotationsEditor extends ModuleElementsEditor { public static final String NAME = ProjectBundle.message("project.roots.external.annotations.tab.title"); public static final Icon ICON = IconLoader.getIcon("/modules/annotation.png"); - public AnnotationsEditor(Project project, ModifiableRootModel model) { - super(project, model); + public AnnotationsEditor(final ModuleConfigurationState state) { + super(state); } public String getHelpTopic() { @@ -82,7 +80,7 @@ public class AnnotationsEditor extends ModuleElementsEditor { final TableItem item = ((MyTableModel)myTable.getModel()).getTableItemAt(row); urls[row] = item.getUrl(); } - myModel.setRootUrls(AnnotationOrderRootType.getInstance(), urls); + getModel().setRootUrls(AnnotationOrderRootType.getInstance(), urls); } public JComponent createComponentImpl() { @@ -143,7 +141,7 @@ public class AnnotationsEditor extends ModuleElementsEditor { protected DefaultTableModel createModel() { final MyTableModel tableModel = new MyTableModel(); - final String[] urls = myModel.getRootUrls(AnnotationOrderRootType.getInstance()); + final String[] urls = getModel().getRootUrls(AnnotationOrderRootType.getInstance()); for (String javadocUrl : urls) { tableModel.addTableItem(new TableItem(javadocUrl)); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/BuildElementsEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/BuildElementsEditor.java index 0d2f18d2e8b7..9f97d0e072dc 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/BuildElementsEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/BuildElementsEditor.java @@ -24,10 +24,8 @@ package com.intellij.openapi.roots.ui.configuration; import com.intellij.ide.util.BrowseFilesListener; import com.intellij.openapi.fileChooser.FileChooserDescriptor; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.CompilerModuleExtension; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtil; @@ -57,11 +55,9 @@ public class BuildElementsEditor extends ModuleElementsEditor { private JCheckBox myCbExcludeOutput; private JLabel myOutputLabel; private JLabel myTestOutputLabel; - public CompilerModuleExtension myCompilerExtension; - protected BuildElementsEditor(final Project project, final ModifiableRootModel model) { - super(project, model); - myCompilerExtension = myModel.getModuleExtension(CompilerModuleExtension.class); + protected BuildElementsEditor(final ModuleConfigurationState state) { + super(state); } public JComponent createComponentImpl() { @@ -82,21 +78,21 @@ public class BuildElementsEditor extends ModuleElementsEditor { myOutputPathPanel = createOutputPathPanel(ProjectBundle.message("module.paths.output.title"), new CommitPathRunnable() { public void saveUrl(String url) { - if (myCompilerExtension.isCompilerOutputPathInherited()) return; //do not override settings if any - myCompilerExtension.setCompilerOutputPath(url); + if (getCompilerExtension().isCompilerOutputPathInherited()) return; //do not override settings if any + getCompilerExtension().setCompilerOutputPath(url); } }); myTestsOutputPathPanel = createOutputPathPanel(ProjectBundle.message("module.paths.test.output.title"), new CommitPathRunnable() { public void saveUrl(String url) { - if (myCompilerExtension.isCompilerOutputPathInherited()) return; //do not override settings if any - myCompilerExtension.setCompilerOutputPathForTests(url); + if (getCompilerExtension().isCompilerOutputPathInherited()) return; //do not override settings if any + getCompilerExtension().setCompilerOutputPathForTests(url); } }); - myCbExcludeOutput = new JCheckBox(ProjectBundle.message("module.paths.exclude.output.checkbox"), myCompilerExtension.isExcludeOutput()); + myCbExcludeOutput = new JCheckBox(ProjectBundle.message("module.paths.exclude.output.checkbox"), getCompilerExtension().isExcludeOutput()); myCbExcludeOutput.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { - myCompilerExtension.setExcludeOutput(myCbExcludeOutput.isSelected()); + getCompilerExtension().setExcludeOutput(myCbExcludeOutput.isSelected()); } }); @@ -130,7 +126,7 @@ public class BuildElementsEditor extends ModuleElementsEditor { updateOutputPathPresentation(); //compiler settings - final boolean outputPathInherited = myCompilerExtension.isCompilerOutputPathInherited(); + final boolean outputPathInherited = getCompilerExtension().isCompilerOutputPathInherited(); myInheritCompilerOutput.setSelected(outputPathInherited); myPerModuleCompilerOutput.setSelected(!outputPathInherited); enableCompilerSettings(!outputPathInherited); @@ -142,26 +138,26 @@ public class BuildElementsEditor extends ModuleElementsEditor { } private void updateOutputPathPresentation() { - if (myCompilerExtension.isCompilerOutputPathInherited()) { + if (getCompilerExtension().isCompilerOutputPathInherited()) { final String baseUrl = ProjectStructureConfigurable.getInstance(myProject).getProjectConfig().getCompilerOutputUrl(); - moduleCompileOutputChanged(baseUrl, myModel.getModule().getName()); + moduleCompileOutputChanged(baseUrl, getModel().getModule().getName()); } else { - final VirtualFile compilerOutputPath = myCompilerExtension.getCompilerOutputPath(); + final VirtualFile compilerOutputPath = getCompilerExtension().getCompilerOutputPath(); if (compilerOutputPath != null) { myOutputPathPanel.setText(FileUtil.toSystemDependentName(compilerOutputPath.getPath())); } else { - final String compilerOutputUrl = myCompilerExtension.getCompilerOutputUrl(); + final String compilerOutputUrl = getCompilerExtension().getCompilerOutputUrl(); if (compilerOutputUrl != null) { myOutputPathPanel.setText(FileUtil.toSystemDependentName(VfsUtil.urlToPath(compilerOutputUrl))); } } - final VirtualFile testsOutputPath = myCompilerExtension.getCompilerOutputPathForTests(); + final VirtualFile testsOutputPath = getCompilerExtension().getCompilerOutputPathForTests(); if (testsOutputPath != null) { myTestsOutputPathPanel.setText(FileUtil.toSystemDependentName(testsOutputPath.getPath())); } else { - final String testsOutputUrl = myCompilerExtension.getCompilerOutputUrlForTests(); + final String testsOutputUrl = getCompilerExtension().getCompilerOutputUrlForTests(); if (testsOutputUrl != null) { myTestsOutputPathPanel.setText(FileUtil.toSystemDependentName(VfsUtil.urlToPath(testsOutputUrl))); } @@ -175,7 +171,7 @@ public class BuildElementsEditor extends ModuleElementsEditor { UIUtil.setEnabled(myTestsOutputPathPanel, enabled, true); UIUtil.setEnabled(myTestOutputLabel, enabled, true); myCbExcludeOutput.setEnabled(enabled); - myCompilerExtension.inheritCompilerOutputPath(!enabled); + getCompilerExtension().inheritCompilerOutputPath(!enabled); updateOutputPathPresentation(); } @@ -187,7 +183,7 @@ public class BuildElementsEditor extends ModuleElementsEditor { final Runnable commitRunnable = new Runnable() { public void run() { - if (!myModel.isWritable()) { + if (!getModel().isWritable()) { return; } final String path = textField.getText().trim(); @@ -225,7 +221,7 @@ public class BuildElementsEditor extends ModuleElementsEditor { public void saveData() { myOutputPathPanel.commit(); myTestsOutputPathPanel.commit(); - myCompilerExtension.commit(); + getCompilerExtension().commit(); } public String getDisplayName() { @@ -245,11 +241,11 @@ public class BuildElementsEditor extends ModuleElementsEditor { public void moduleStateChanged() { //if content enties tree was changed - myCbExcludeOutput.setSelected(myCompilerExtension.isExcludeOutput()); + myCbExcludeOutput.setSelected(getCompilerExtension().isExcludeOutput()); } public void moduleCompileOutputChanged(final String baseUrl, final String moduleName) { - if (myCompilerExtension.isCompilerOutputPathInherited()) { + if (getCompilerExtension().isCompilerOutputPathInherited()) { if (baseUrl != null) { myOutputPathPanel.setText(FileUtil.toSystemDependentName(VfsUtil.urlToPath(baseUrl + "/" + CompilerModuleExtension .PRODUCTION + "/" + moduleName))); @@ -263,6 +259,10 @@ public class BuildElementsEditor extends ModuleElementsEditor { } } + public CompilerModuleExtension getCompilerExtension() { + return getModel().getModuleExtension(CompilerModuleExtension.class); + } + private static interface CommitPathRunnable { void saveUrl(String url); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java index d9a160edee94..2da12ffe5071 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java @@ -15,11 +15,12 @@ */ package com.intellij.openapi.roots.ui.configuration; +import com.intellij.ProjectTopics; +import com.intellij.openapi.Disposable; import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.impl.storage.ClasspathStorage; import com.intellij.openapi.roots.impl.storage.ClasspathStorageProvider; import com.intellij.openapi.util.IconLoader; @@ -37,18 +38,23 @@ import java.util.Map; * Date: Oct 4, 2003 * Time: 6:54:57 PM */ -public class ClasspathEditor extends ModuleElementsEditor { +public class ClasspathEditor extends ModuleElementsEditor implements ModuleRootListener { public static final String NAME = ProjectBundle.message("modules.classpath.title"); public static final Icon ICON = IconLoader.getIcon("/modules/classpath.png"); private ClasspathPanel myPanel; - private final ModulesProvider myModulesProvider; private ClasspathFormatPanel myClasspathFormatPanel; - public ClasspathEditor(Project project, ModifiableRootModel model, final ModulesProvider modulesProvider) { - super(project, model); - myModulesProvider = modulesProvider; + public ClasspathEditor(final ModuleConfigurationState state) { + super(state); + + final Disposable disposable = new Disposable() { + public void dispose() {} + }; + + state.getProject().getMessageBus().connect(disposable).subscribe(ProjectTopics.PROJECT_ROOTS, this); + registerDisposable(disposable); } public boolean isModified() { @@ -83,12 +89,12 @@ public class ClasspathEditor extends ModuleElementsEditor { super.canApply(); if (myClasspathFormatPanel != null) { final String storageID = myClasspathFormatPanel.getSelectedClasspathFormat(); - ClasspathStorage.getProvider(storageID).assertCompatible(myModel); + ClasspathStorage.getProvider(storageID).assertCompatible(getModel()); } } public JComponent createComponentImpl() { - myPanel = new ClasspathPanel(myProject, myModel, myModulesProvider); + myPanel = new ClasspathPanel(getState()); myPanel.addListener(new OrderPanelListener() { public void entryMoved() { @@ -101,7 +107,12 @@ public class ClasspathEditor extends ModuleElementsEditor { panel.add(myPanel, BorderLayout.CENTER); final ModuleJdkConfigurable jdkConfigurable = - new ModuleJdkConfigurable(this, myModel, ProjectStructureConfigurable.getInstance(myProject).getProjectJdksModel()); + new ModuleJdkConfigurable(this, ProjectStructureConfigurable.getInstance(myProject).getProjectJdksModel()) { + @Override + protected ModifiableRootModel getRootModel() { + return getState().getRootModel(); + } + }; panel.add(jdkConfigurable.createComponent(), BorderLayout.NORTH); jdkConfigurable.reset(); registerDisposable(jdkConfigurable); @@ -117,7 +128,7 @@ public class ClasspathEditor extends ModuleElementsEditor { public void flushChangesToModel() { List entries = myPanel.getEntries(); - myModel.rearrangeOrderEntries(entries.toArray(new OrderEntry[entries.size()])); + getModel().rearrangeOrderEntries(entries.toArray(new OrderEntry[entries.size()])); } public void selectOrderEntry(@NotNull final OrderEntry entry) { @@ -130,6 +141,37 @@ public class ClasspathEditor extends ModuleElementsEditor { } } + public void beforeRootsChange(ModuleRootEvent event) { + } + + public void rootsChanged(ModuleRootEvent event) { + myPanel.rootsChanged(); + } + + public Sdk setSdk(final Sdk newJDK) { + final ModifiableRootModel model = getModel(); + final Sdk oldSdk = model.getSdk(); + + //final List entries = myPanel.getEntries(); + //for (OrderEntry entry : entries) { + // if (entry instanceof JdkOrderEntry) { + // + // } + //} + + if (newJDK != null) { + model.setSdk(newJDK); + } + else { + model.inheritSdk(); + } + + myPanel.forceInitFromModel(); + flushChangesToModel(); + + return oldSdk; + } + private class ClasspathFormatPanel extends JPanel { private final JComboBox cbClasspathFormat; @@ -168,7 +210,7 @@ public class ClasspathEditor extends ModuleElementsEditor { @NotNull private String getModuleClasspathFormat() { - return ClasspathStorage.getStorageType(myModel.getModule()); + return ClasspathStorage.getStorageType(getModel().getModule()); } boolean isModified () { @@ -177,8 +219,8 @@ public class ClasspathEditor extends ModuleElementsEditor { void apply () throws ConfigurationException { final String storageID = getSelectedClasspathFormat(); - ClasspathStorage.getProvider(storageID).assertCompatible(myModel); - ClasspathStorage.setStorageType(myModel, storageID); + ClasspathStorage.getProvider(storageID).assertCompatible(getModel()); + ClasspathStorage.setStorageType(getModel(), storageID); } } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java index 13776cfca81e..31e63740def3 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java @@ -77,22 +77,19 @@ import java.util.List; public class ClasspathPanel extends JPanel { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.ClasspathPanel"); - private final Project myProject; - private final ModifiableRootModel myRootModel; - private final ModulesProvider myModulesProvider; private final Table myEntryTable; private final MyTableModel myModel; private final EventDispatcher myListeners = EventDispatcher.create(OrderPanelListener.class); private PopupAction[] myPopupActions = null; private Icon[] myIcons = null; private JButton myEditButton; + private ModuleConfigurationState myState; - protected ClasspathPanel(Project project, ModifiableRootModel rootModel, final ModulesProvider modulesProvider) { + protected ClasspathPanel(ModuleConfigurationState state) { super(new BorderLayout()); - myProject = project; - myRootModel = rootModel; - myModulesProvider = modulesProvider; - myModel = new MyTableModel(rootModel); + + myState = state; + myModel = new MyTableModel(state); myEntryTable = new Table(myModel); myEntryTable.setShowGrid(false); myEntryTable.setDragEnabled(false); @@ -216,7 +213,7 @@ public class ClasspathPanel extends JPanel { private void navigate(boolean openLibraryEditor) { final int selectedRow = myEntryTable.getSelectedRow(); final OrderEntry entry = myModel.getItemAt(selectedRow).getEntry(); - final ProjectStructureConfigurable rootConfigurable = ProjectStructureConfigurable.getInstance(myProject); + final ProjectStructureConfigurable rootConfigurable = ProjectStructureConfigurable.getInstance(myState.getProject()); if (entry instanceof ModuleOrderEntry){ Module module = ((ModuleOrderEntry)entry).getModule(); if (module != null) { @@ -334,7 +331,8 @@ public class ClasspathPanel extends JPanel { if (orderEntry == null) { continue; } - myRootModel.removeOrderEntry(orderEntry); + ModuleStructureConfigurable.getInstance(myState.getProject()).getContext().clearCaches(orderEntry); + getRootModel().removeOrderEntry(orderEntry); } final int[] selectedRows = myEntryTable.getSelectedRows(); myModel.fireTableDataChanged(); @@ -362,7 +360,7 @@ public class ClasspathPanel extends JPanel { final LibraryTableModifiableModelProvider provider; final LibraryTable table = library.getTable(); if (table == null) { - final LibraryTable moduleLibraryTable = myRootModel.getModuleLibraryTable(); + final LibraryTable moduleLibraryTable = getRootModel().getModuleLibraryTable(); provider = new LibraryTableModifiableModelProvider() { public LibraryTable.ModifiableModel getModifiableModel() { return moduleLibraryTable.getModifiableModel(); @@ -382,13 +380,13 @@ public class ClasspathPanel extends JPanel { }; } else { - provider = ProjectStructureConfigurable.getInstance(myProject).getContext().createModifiableModelProvider(table.getTableLevel(), false); + provider = ProjectStructureConfigurable.getInstance(myState.getProject()).getContext().createModifiableModelProvider(table.getTableLevel(), false); } final LibraryTableEditor editor = LibraryTableEditor.editLibrary(provider, library); - editor.addFileChooserContext(LangDataKeys.MODULE_CONTEXT, myRootModel.getModule()); + editor.addFileChooserContext(LangDataKeys.MODULE_CONTEXT, getRootModel().getModule()); editor.openDialog(ClasspathPanel.this, Collections.singletonList(library), true); myEntryTable.repaint(); - ModuleStructureConfigurable.getInstance(myProject).getTree().repaint(); + ModuleStructureConfigurable.getInstance(myState.getProject()).getTree().repaint(); } }); return panel; @@ -408,6 +406,14 @@ public class ClasspathPanel extends JPanel { ); } + private ModifiableRootModel getRootModel() { + return myState.getRootModel(); + } + + public void rootsChanged() { + forceInitFromModel(); + } + private abstract class ButtonAction implements ActionListener { public final void actionPerformed(ActionEvent e) { execute(); @@ -478,7 +484,7 @@ public class ClasspathPanel extends JPanel { if (chosen.size() == 0) { return; } - final ModuleStructureConfigurable rootConfigurable = ModuleStructureConfigurable.getInstance(myProject); + final ModuleStructureConfigurable rootConfigurable = ModuleStructureConfigurable.getInstance(myState.getProject()); //int insertionIndex = myEntryTable.getSelectedRow(); for (ItemType item : chosen) { //myModel.addItemAt(createTableItem(item), insertionIndex++); @@ -511,12 +517,12 @@ public class ClasspathPanel extends JPanel { private void initPopupActions() { if (myPopupActions == null) { - final StructureConfigurableContext context = ProjectStructureConfigurable.getInstance(myProject).getContext(); + final StructureConfigurableContext context = ProjectStructureConfigurable.getInstance(myState.getProject()).getContext(); int actionIndex = 1; final List actions = new ArrayList(Arrays.asList( new ChooseAndAddAction(actionIndex++, ProjectBundle.message("classpath.add.simple.module.library.action"), Icons.JAR_ICON) { protected TableItem createTableItem(final Library item) { - final OrderEntry[] entries = myRootModel.getOrderEntries(); + final OrderEntry[] entries = getRootModel().getOrderEntries(); for (OrderEntry entry : entries) { if (entry instanceof LibraryOrderEntry) { final LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)entry; @@ -530,12 +536,12 @@ public class ClasspathPanel extends JPanel { } protected ChooserDialog createChooserDialog() { - return new ChooseModuleLibrariesDialog(ClasspathPanel.this, myRootModel.getModuleLibraryTable(), null); + return new ChooseModuleLibrariesDialog(ClasspathPanel.this, getRootModel().getModuleLibraryTable(), null); } }, new ChooseAndAddAction(actionIndex++, ProjectBundle.message("classpath.add.module.library.action"), Icons.JAR_ICON) { protected TableItem createTableItem(final Library item) { - final OrderEntry[] entries = myRootModel.getOrderEntries(); + final OrderEntry[] entries = getRootModel().getOrderEntries(); for (OrderEntry entry : entries) { if (entry instanceof LibraryOrderEntry) { final LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)entry; @@ -549,7 +555,7 @@ public class ClasspathPanel extends JPanel { } protected ChooserDialog createChooserDialog() { - return new CreateModuleLibraryDialog(ClasspathPanel.this, myRootModel.getModuleLibraryTable()); + return new CreateModuleLibraryDialog(ClasspathPanel.this, getRootModel().getModuleLibraryTable()); } }, new ChooseNamedLibraryAction(actionIndex++, ProjectBundle.message("classpath.add.project.library.action"), context.getProjectLibrariesProvider(true)), @@ -562,7 +568,7 @@ public class ClasspathPanel extends JPanel { actions.add(new ChooseAndAddAction(actionIndex, ProjectBundle.message("classpath.add.module.dependency.action"), StdModuleTypes.JAVA.getNodeIcon(false)) { protected TableItem createTableItem(final Module item) { - return new ModuleItem(myRootModel.addModuleOrderEntry(item)); + return new ModuleItem(getRootModel().addModuleOrderEntry(item)); } protected ChooserDialog createChooserDialog() { final List chooseItems = getDependencyModules(); @@ -632,7 +638,7 @@ public class ClasspathPanel extends JPanel { TableUtil.scrollSelectionToVisible(myEntryTable); } } - IdeFocusManager.getInstance(myProject).requestFocus(myEntryTable, true); + IdeFocusManager.getInstance(myState.getProject()).requestFocus(myEntryTable, true); } private int moveRow(final int row, final int increment) { @@ -665,7 +671,7 @@ public class ClasspathPanel extends JPanel { } } - private void forceInitFromModel() { + void forceInitFromModel() { final int[] selection = myEntryTable.getSelectedRows(); myModel.clear(); myModel.init(); @@ -682,10 +688,11 @@ public class ClasspathPanel extends JPanel { filtered.add(((ModuleOrderEntry)entry).getModuleName()); } } - final Module self = myModulesProvider.getModule(myRootModel.getModule().getName()); + final ModulesProvider modulesProvider = myState.getModulesProvider(); + final Module self = modulesProvider.getModule(getRootModel().getModule().getName()); filtered.add(self.getName()); - final Module[] modules = myModulesProvider.getModules(); + final Module[] modules = modulesProvider.getModules(); final List elements = new ArrayList(modules.length); for (final Module module : modules) { if (!filtered.contains(module.getName())) { @@ -800,15 +807,19 @@ public class ClasspathPanel extends JPanel { public static final int ITEM_COLUMN = 1; public static final int SCOPE_COLUMN = 2; private final List myItems = new ArrayList(); - private final ModifiableRootModel myRootModel; + private ModuleConfigurationState myState; - public MyTableModel(final ModifiableRootModel rootModel) { - myRootModel = rootModel; + public MyTableModel(final ModuleConfigurationState state) { + myState = state; init(); } + private ModifiableRootModel getModel() { + return myState.getRootModel(); + } + public void init() { - final OrderEntry[] orderEntries = myRootModel.getOrderEntries(); + final OrderEntry[] orderEntries = getModel().getOrderEntries(); boolean hasJdkOrderEntry = false; for (final OrderEntry orderEntry : orderEntries) { if (orderEntry instanceof JdkOrderEntry) { @@ -1108,7 +1119,7 @@ public class ClasspathPanel extends JPanel { @Nullable protected TableItem createTableItem(final Library item) { // clear invalid order entry corresponding to added library if any - final OrderEntry[] orderEntries = myRootModel.getOrderEntries(); + final OrderEntry[] orderEntries = getRootModel().getOrderEntries(); for (OrderEntry orderEntry : orderEntries) { if (orderEntry instanceof LibraryOrderEntry ) { if (item.getName().equals(((LibraryOrderEntry)orderEntry).getLibraryName())) { @@ -1117,12 +1128,12 @@ public class ClasspathPanel extends JPanel { ProjectBundle.message("classpath.title.adding.dependency")); return null; } else { - myRootModel.removeOrderEntry(orderEntry); + getRootModel().removeOrderEntry(orderEntry); } } } } - return new LibItem(myRootModel.addLibraryEntry(item)); + return new LibItem(getRootModel().addLibraryEntry(item)); } protected ChooserDialog createChooserDialog() { @@ -1130,7 +1141,7 @@ public class ClasspathPanel extends JPanel { } private Collection getAlreadyAddedLibraries() { - final OrderEntry[] orderEntries = myRootModel.getOrderEntries(); + final OrderEntry[] orderEntries = getRootModel().getOrderEntries(); final Set result = new HashSet(orderEntries.length); for (OrderEntry orderEntry : orderEntries) { if (orderEntry instanceof LibraryOrderEntry && orderEntry.isValid()) { @@ -1148,14 +1159,14 @@ public class ClasspathPanel extends JPanel { private boolean myIsOk; MyChooserDialog(){ - myEditor = LibraryTableEditor.editLibraryTable(myLibraryTableModelProvider, myProject); + myEditor = LibraryTableEditor.editLibraryTable(myLibraryTableModelProvider, myState.getProject()); Disposer.register(this, myEditor); } public List getChosenElements() { final List chosen = new ArrayList(Arrays.asList(myEditor.getSelectedLibraries())); chosen.removeAll(getAlreadyAddedLibraries()); - final Module module = myRootModel.getModule(); + final Module module = getRootModel().getModule(); final Project project = module.getProject(); return chosen; } @@ -1176,7 +1187,7 @@ public class ClasspathPanel extends JPanel { private class MyFindUsagesAction extends FindUsagesInProjectStructureActionBase { private MyFindUsagesAction() { - super(myEntryTable, myProject); + super(myEntryTable, myState.getProject()); } protected boolean isEnabled() { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ContentEntriesEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ContentEntriesEditor.java index 3bc48aa59d46..2e28599df647 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ContentEntriesEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ContentEntriesEditor.java @@ -16,8 +16,7 @@ package com.intellij.openapi.roots.ui.configuration; import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.LanguageLevelModuleExtension; import javax.swing.*; import java.awt.*; @@ -30,8 +29,8 @@ import java.awt.*; public class ContentEntriesEditor extends JavaContentEntriesEditor { private LanguageLevelConfigurable myLanguageLevelConfigurable; - public ContentEntriesEditor(Project project, String moduleName, ModifiableRootModel model, ModulesProvider modulesProvider) { - super(project, moduleName, model, modulesProvider); + public ContentEntriesEditor(String moduleName, final ModuleConfigurationState state) { + super(moduleName, state); } public void disposeUIResources() { @@ -44,7 +43,12 @@ public class ContentEntriesEditor extends JavaContentEntriesEditor { } protected void addAdditionalSettingsToPanel(final JPanel mainPanel) { - myLanguageLevelConfigurable = new LanguageLevelConfigurable(myModel); + myLanguageLevelConfigurable = new LanguageLevelConfigurable() { + @Override + public LanguageLevelModuleExtension getLanguageLevelExtension() { + return getModel().getModuleExtension(LanguageLevelModuleExtension.class); + } + }; mainPanel.add(myLanguageLevelConfigurable.createComponent(), BorderLayout.NORTH); myLanguageLevelConfigurable.reset(); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactoryImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactoryImpl.java index 09039a39e1d4..ee578546e195 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactoryImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactoryImpl.java @@ -28,23 +28,23 @@ public class DefaultModuleConfigurationEditorFactoryImpl extends DefaultModuleCo final ModifiableRootModel rootModel = state.getRootModel(); final Module module = rootModel.getModule(); final String moduleName = module.getName(); - return new ContentEntriesEditor(state.getProject(), moduleName, rootModel, state.getModulesProvider()); + return new ContentEntriesEditor(moduleName, state); } public ModuleConfigurationEditor createClasspathEditor(ModuleConfigurationState state) { - return new ClasspathEditor(state.getProject(), state.getRootModel(), state.getModulesProvider()); + return new ClasspathEditor(state); } public ModuleConfigurationEditor createJavadocEditor(ModuleConfigurationState state) { - return new JavadocEditor(state.getProject(), state.getRootModel()); + return new JavadocEditor(state); } public ModuleConfigurationEditor createOutputEditor(ModuleConfigurationState state) { - return new OutputEditor(state.getProject(), state.getRootModel()); + return new OutputEditor(state); } @Deprecated public ModuleConfigurationEditor createCompilerOutputEditor(ModuleConfigurationState state) { - return new BuildElementsEditor(state.getProject(), state.getRootModel()); + return new BuildElementsEditor(state); } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleEditorsProvider.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleEditorsProvider.java index 7e7d61540646..7055698803e6 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleEditorsProvider.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleEditorsProvider.java @@ -18,7 +18,6 @@ package com.intellij.openapi.roots.ui.configuration; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleComponent; import com.intellij.openapi.module.ModuleConfigurationEditor; -import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import org.jetbrains.annotations.NotNull; @@ -41,12 +40,10 @@ public class DefaultModuleEditorsProvider implements ModuleComponent, ModuleConf ModifiableRootModel rootModel = state.getRootModel(); Module module = rootModel.getModule(); String moduleName = module.getName(); - ModulesProvider provider = state.getModulesProvider(); - Project project = state.getProject(); List editors = new ArrayList(); - editors.add(new ContentEntriesEditor(project, moduleName, rootModel, provider)); - editors.add(new OutputEditor(project, rootModel)); - editors.add(new ClasspathEditor(project, rootModel, provider)); + editors.add(new ContentEntriesEditor(moduleName, state)); + editors.add(new OutputEditor(state)); + editors.add(new ClasspathEditor(state)); return editors.toArray(new ModuleConfigurationEditor[editors.size()]); } } \ No newline at end of file diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java index a31d340aa5ce..70492ad3ab8f 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java @@ -25,7 +25,6 @@ import com.intellij.openapi.progress.util.SmoothProgressAdapter; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.ContentEntry; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; @@ -40,12 +39,12 @@ import java.util.List; import java.util.Map; public class JavaContentEntriesEditor extends CommonContentEntriesEditor { - public JavaContentEntriesEditor(Project project, String moduleName, ModifiableRootModel model, ModulesProvider modulesProvider) { - super(project, moduleName, model, modulesProvider); + public JavaContentEntriesEditor(String moduleName, ModuleConfigurationState state) { + super(moduleName, state); } protected ContentEntryEditor createContentEntryEditor(ContentEntry contentEntry) { - return new JavaContentEntryEditor(contentEntry, myModel); + return new JavaContentEntryEditor(contentEntry, getModel()); } protected ContentEntryTreeEditor createContentEntryTreeEditor(Project project) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavadocEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavadocEditor.java index 9de38caf0413..9b70f57c1018 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavadocEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavadocEditor.java @@ -17,11 +17,9 @@ package com.intellij.openapi.roots.ui.configuration; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.projectRoots.ui.Util; import com.intellij.openapi.roots.JavadocOrderRootType; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ui.util.CellAppearance; import com.intellij.openapi.roots.ui.util.CellAppearanceUtils; import com.intellij.openapi.roots.ui.util.SimpleTextCellAppearance; @@ -32,9 +30,9 @@ import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.ui.ColoredTableCellRenderer; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.TableUtil; +import com.intellij.util.ArrayUtil; import com.intellij.util.ui.ItemRemovable; import com.intellij.util.ui.Table; -import com.intellij.util.ArrayUtil; import javax.swing.*; import javax.swing.border.Border; @@ -60,8 +58,8 @@ public class JavadocEditor extends ModuleElementsEditor { public static final String NAME = ProjectBundle.message("module.javadoc.title"); public static final Icon ICON = IconLoader.getIcon("/modules/javadoc.png"); - public JavadocEditor(Project project, ModifiableRootModel model) { - super(project, model); + public JavadocEditor(ModuleConfigurationState state) { + super(state); } public String getHelpTopic() { @@ -84,7 +82,7 @@ public class JavadocEditor extends ModuleElementsEditor { final TableItem item = ((MyTableModel)myTable.getModel()).getTableItemAt(row); urls[row] = item.getUrl(); } - myModel.setRootUrls(JavadocOrderRootType.getInstance(), urls); + getModel().setRootUrls(JavadocOrderRootType.getInstance(), urls); } public JComponent createComponentImpl() { @@ -148,7 +146,7 @@ public class JavadocEditor extends ModuleElementsEditor { protected DefaultTableModel createModel() { final MyTableModel tableModel = new MyTableModel(); - final String[] javadocUrls = myModel.getRootUrls(JavadocOrderRootType.getInstance()); + final String[] javadocUrls = getModel().getRootUrls(JavadocOrderRootType.getInstance()); for (String javadocUrl : javadocUrls) { tableModel.addTableItem(new TableItem(javadocUrl)); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java index 1ca6585b3d5c..14f6fc74ef52 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java @@ -20,7 +20,6 @@ import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.UnnamedConfigurable; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.LanguageLevelModuleExtension; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.pom.java.LanguageLevel; import javax.swing.*; @@ -32,18 +31,16 @@ import java.awt.event.ActionListener; * User: anna * Date: 06-Jun-2006 */ -public class LanguageLevelConfigurable implements UnnamedConfigurable { +public abstract class LanguageLevelConfigurable implements UnnamedConfigurable { private LanguageLevelCombo myLanguageLevelCombo; private JPanel myPanel = new JPanel(new GridBagLayout()); - public LanguageLevelModuleExtension myLanguageLevelExtension; - public LanguageLevelConfigurable(ModifiableRootModel rootModule) { - myLanguageLevelExtension = rootModule.getModuleExtension(LanguageLevelModuleExtension.class); + public LanguageLevelConfigurable() { myLanguageLevelCombo = new LanguageLevelCombo(); myLanguageLevelCombo.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { final Object languageLevel = myLanguageLevelCombo.getSelectedItem(); - myLanguageLevelExtension.setLanguageLevel(languageLevel instanceof LanguageLevel ? (LanguageLevel)languageLevel : null); + getLanguageLevelExtension().setLanguageLevel(languageLevel instanceof LanguageLevel ? (LanguageLevel)languageLevel : null); } }); myLanguageLevelCombo.insertItemAt(LanguageLevelCombo.USE_PROJECT_LANGUAGE_LEVEL, 0); @@ -56,20 +53,21 @@ public class LanguageLevelConfigurable implements UnnamedConfigurable { } public boolean isModified() { - return myLanguageLevelExtension.isChanged(); + return getLanguageLevelExtension().isChanged(); } public void apply() throws ConfigurationException { - myLanguageLevelExtension.commit(); + getLanguageLevelExtension().commit(); } public void reset() { - myLanguageLevelCombo.setSelectedItem(myLanguageLevelExtension.getLanguageLevel()); + myLanguageLevelCombo.setSelectedItem(getLanguageLevelExtension().getLanguageLevel()); } public void disposeUIResources() { myPanel = null; myLanguageLevelCombo = null; - myLanguageLevelExtension = null; } + + public abstract LanguageLevelModuleExtension getLanguageLevelExtension(); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java index 510a854ecb60..c2c035a86485 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java @@ -32,7 +32,6 @@ import com.intellij.openapi.roots.impl.ModuleRootManagerImpl; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.util.ActionCallback; -import com.intellij.openapi.util.Disposer; import com.intellij.ui.TabbedPaneWrapper; import com.intellij.ui.navigation.History; import com.intellij.ui.navigation.Place; @@ -56,7 +55,7 @@ import java.util.List; * Time: 6:29:56 PM */ @SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod"}) -public class ModuleEditor implements Place.Navigator { +public abstract class ModuleEditor implements Place.Navigator, Disposable { private final Project myProject; private JPanel myGenericSettingsPanel; @@ -77,18 +76,10 @@ public class ModuleEditor implements Place.Navigator { private History myHistory; - private final ProjectFacetsConfigurator myFacetsConfigurator; - private final Disposable myDisposable = new Disposable() { - public void dispose() { - } - }; - - public ModuleEditor(Project project, ModulesProvider modulesProvider, ProjectFacetsConfigurator facetsConfigurator, + public ModuleEditor(Project project, ModulesProvider modulesProvider, @NotNull Module module) { myProject = project; myModulesProvider = modulesProvider; - myFacetsConfigurator = facetsConfigurator; - addChangeListener(facetsConfigurator); myModule = module; myName = module.getName(); } @@ -105,6 +96,7 @@ public class ModuleEditor implements Place.Navigator { setSelectedTabName(selectedTab); } + public abstract ProjectFacetsConfigurator getFacetsConfigurator(); public interface ChangeListener extends EventListener { void moduleStateChanged(ModifiableRootModel moduleRootModel); @@ -185,8 +177,17 @@ public class ModuleEditor implements Place.Navigator { } public ModuleConfigurationState createModuleConfigurationState() { - return new ModuleConfigurationStateImpl(myProject, myModulesProvider, getModifiableRootModelProxy(), - myFacetsConfigurator); + return new ModuleConfigurationStateImpl(myProject, myModulesProvider) { + @Override + public ModifiableRootModel getRootModel() { + return getModifiableRootModel(); + } + + @Override + public FacetsProvider getFacetsProvider() { + return getFacetsConfigurator(); + } + }; } private void processEditorsProvider(final ModuleConfigurationEditorProvider provider, final ModuleConfigurationState state) { @@ -206,7 +207,7 @@ public class ModuleEditor implements Place.Navigator { myGenericSettingsPanel.add(northPanel, BorderLayout.NORTH); - myTabbedPane = new TabbedPaneWrapper(myDisposable); + myTabbedPane = new TabbedPaneWrapper(this); for (ModuleConfigurationEditor editor : myEditors) { myTabbedPane.addTab(editor.getDisplayName(), editor.getIcon(), editor.createComponent(), null); @@ -283,9 +284,8 @@ public class ModuleEditor implements Place.Navigator { } } - public ModifiableRootModel dispose() { + public void dispose() { try { - Disposer.dispose(myDisposable); for (final ModuleConfigurationEditor myEditor : myEditors) { myEditor.disposeUIResources(); } @@ -297,10 +297,11 @@ public class ModuleEditor implements Place.Navigator { myTabbedPane = null; } + if (myModifiableRootModel != null) { + myModifiableRootModel.dispose(); + } myGenericSettingsPanel = null; - - return myModifiableRootModel; } finally { myModifiableRootModel = null; @@ -308,19 +309,25 @@ public class ModuleEditor implements Place.Navigator { } } - public ModifiableRootModel applyAndDispose() throws ConfigurationException { - for (ModuleConfigurationEditor editor : myEditors) { - if (editor instanceof ModuleElementsEditor) { - ((ModuleElementsEditor)editor).canApply(); + public ModifiableRootModel apply() throws ConfigurationException { + try { + for (ModuleConfigurationEditor editor : myEditors) { + if (editor instanceof ModuleElementsEditor) { + ((ModuleElementsEditor)editor).canApply(); + } } - } - for (ModuleConfigurationEditor editor : myEditors) { - editor.saveData(); - editor.apply(); - } + for (ModuleConfigurationEditor editor : myEditors) { + editor.saveData(); + editor.apply(); + } - return dispose(); + return myModifiableRootModel; + } + finally { + myModifiableRootModel = null; + myModifiableRootModelProxy = null; + } } public String getName() { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleJdkConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleJdkConfigurable.java index 17d23aa97954..91552be593e2 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleJdkConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleJdkConfigurable.java @@ -42,10 +42,9 @@ import java.awt.event.ActionListener; * User: anna * Date: 05-Jun-2006 */ -public class ModuleJdkConfigurable implements Disposable { +public abstract class ModuleJdkConfigurable implements Disposable { private JdkComboBox myCbModuleJdk; private Sdk mySelectedModuleJdk = null; - private final ModifiableRootModel myRootModel; private JPanel myJdkPanel; private ClasspathEditor myModuleEditor; private final ProjectJdksModel myJdksModel; @@ -68,9 +67,8 @@ public class ModuleJdkConfigurable implements Disposable { } }; - public ModuleJdkConfigurable(ClasspathEditor moduleEditor, ModifiableRootModel model, ProjectJdksModel jdksModel) { + public ModuleJdkConfigurable(ClasspathEditor moduleEditor, ProjectJdksModel jdksModel) { myModuleEditor = moduleEditor; - myRootModel = model; myJdksModel = jdksModel; myJdksModel.addListener(myListener); init(); @@ -94,11 +92,13 @@ public class ModuleJdkConfigurable implements Disposable { private void reloadModel() { myFreeze = true; - myCbModuleJdk.reloadModel(new JdkComboBox.ProjectJdkComboBoxItem(), myRootModel.getModule().getProject()); + myCbModuleJdk.reloadModel(new JdkComboBox.ProjectJdkComboBoxItem(), getRootModel().getModule().getProject()); reset(); myFreeze = false; } + protected abstract ModifiableRootModel getRootModel(); + private void init() { myJdkPanel = new JPanel(new GridBagLayout()); myCbModuleJdk = new JdkComboBox(myJdksModel); @@ -106,14 +106,14 @@ public class ModuleJdkConfigurable implements Disposable { myCbModuleJdk.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (myFreeze) return; - final Sdk oldJdk = myRootModel.getSdk(); + final Sdk oldJdk = getRootModel().getSdk(); mySelectedModuleJdk = myCbModuleJdk.getSelectedJdk(); final Sdk selectedModuleJdk = getSelectedModuleJdk(); if (selectedModuleJdk != null) { - myRootModel.setSdk(selectedModuleJdk); + getRootModel().setSdk(selectedModuleJdk); } else { - myRootModel.inheritSdk(); + getRootModel().inheritSdk(); } clearCaches(oldJdk, selectedModuleJdk); myModuleEditor.flushChangesToModel(); @@ -124,7 +124,7 @@ public class ModuleJdkConfigurable implements Disposable { myJdkPanel.add(myCbModuleJdk, new GridBagConstraints(1, 0, 1, 1, 0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(6, 6, 12, 0), 0, 0)); - final Project project = myRootModel.getModule().getProject(); + final Project project = getRootModel().getModule().getProject(); final JButton setUpButton = myCbModuleJdk .createSetupButton(project, myJdksModel, new JdkComboBox.ProjectJdkComboBoxItem(), new Condition(){ public boolean value(Sdk jdk) { @@ -146,16 +146,16 @@ public class ModuleJdkConfigurable implements Disposable { myJdkPanel.add(setUpButton, new GridBagConstraints(2, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 4, 7, 0), 0, 0)); - myCbModuleJdk.appendEditButton(myRootModel.getModule().getProject(), myJdkPanel, new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 1.0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 4, 7, 0), 0, 0) , new Computable() { + myCbModuleJdk.appendEditButton(getRootModel().getModule().getProject(), myJdkPanel, new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 1.0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 4, 7, 0), 0, 0) , new Computable() { @Nullable public Sdk compute() { - return myRootModel.getSdk(); + return getRootModel().getSdk(); } }); } private void clearCaches(final Sdk oldJdk, final Sdk selectedModuleJdk) { - final Module module = myRootModel.getModule(); + final Module module = getRootModel().getModule(); final Project project = module.getProject(); final StructureConfigurableContext context = ModuleStructureConfigurable.getInstance(project).getContext(); context.getDaemonAnalyzer().queueUpdate(new ModuleProjectStructureElement(context, module)); @@ -163,8 +163,8 @@ public class ModuleJdkConfigurable implements Disposable { public void reset() { myFreeze = true; - final String jdkName = myRootModel.getSdkName(); - if (jdkName != null && !myRootModel.isSdkInherited()) { + final String jdkName = getRootModel().getSdkName(); + if (jdkName != null && !getRootModel().isSdkInherited()) { mySelectedModuleJdk = myJdksModel.findSdk(jdkName); if (mySelectedModuleJdk != null) { myCbModuleJdk.setSelectedJdk(mySelectedModuleJdk); 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 536f82414bcc..af831c50b300 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 @@ -23,6 +23,7 @@ import com.intellij.facet.impl.ui.FacetEditorImpl; import com.intellij.ide.util.newProjectWizard.AddModuleWizard; import com.intellij.ide.util.projectWizard.ModuleBuilder; import com.intellij.ide.util.projectWizard.ProjectBuilder; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; @@ -44,6 +45,7 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ModuleProj import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Disposer; import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.artifacts.ModifiableArtifactModel; import com.intellij.projectImport.ProjectImportBuilder; @@ -106,10 +108,7 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { for (final ModuleEditor moduleEditor : myModuleEditors) { - final ModifiableRootModel model = moduleEditor.dispose(); - if (model != null) { - model.dispose(); - } + Disposer.dispose(moduleEditor); } myModuleEditors.clear(); @@ -171,10 +170,7 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { - for (final ModuleEditor moduleEditor : myModuleEditors) { - moduleEditor.removeChangeListener(ModulesConfigurator.this); - } - myModuleEditors.clear(); + assert myModuleEditors.isEmpty(); final Module[] modules = myModuleModel.getModules(); if (modules.length > 0) { for (Module module : modules) { @@ -189,9 +185,24 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change } public void createModuleEditor(final Module module) { - final ModuleEditor moduleEditor = new ModuleEditor(myProject, this, myFacetsConfigurator, module); + final ModuleEditor moduleEditor = new ModuleEditor(myProject, this, module) { + @Override + public ProjectFacetsConfigurator getFacetsConfigurator() { + return myFacetsConfigurator; + } + }; + + final ProjectFacetsConfigurator configurator = myFacetsConfigurator; + moduleEditor.addChangeListener(configurator); myModuleEditors.add(moduleEditor); + moduleEditor.addChangeListener(this); + Disposer.register(moduleEditor, new Disposable() { + public void dispose() { + moduleEditor.removeChangeListener(ModulesConfigurator.this); + moduleEditor.removeChangeListener(configurator); + } + }); } public void moduleStateChanged(final ModifiableRootModel moduleRootModel) { @@ -217,7 +228,7 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change myFacetsConfigurator.applyEditors(); final List models = new ArrayList(myModuleEditors.size()); for (final ModuleEditor moduleEditor : myModuleEditors) { - final ModifiableRootModel model = moduleEditor.applyAndDispose(); + final ModifiableRootModel model = moduleEditor.apply(); if (model != null) { models.add(model); } @@ -234,10 +245,25 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change finally { myFacetsConfigurator.disposeEditors(); ModuleStructureConfigurable.getInstance(myProject).getFacetEditorFacade().clearMaps(); + + for (final ModuleEditor moduleEditor : myModuleEditors) { + moduleEditor.removeChangeListener(myFacetsConfigurator); + } + myFacetsConfigurator = createFacetsConfigurator(); myModuleModel = ModuleManager.getInstance(myProject).getModifiableModel(); + + final ProjectFacetsConfigurator configurator = myFacetsConfigurator; + + for (final ModuleEditor moduleEditor : myModuleEditors) { + moduleEditor.addChangeListener(configurator); + Disposer.register(moduleEditor, new Disposable() { + public void dispose() { + moduleEditor.removeChangeListener(configurator); + } + }); + } } - ApplicationManager.getApplication().saveAll(); } }); @@ -245,13 +271,11 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change throw ex[0]; } - ApplicationManager.getApplication().saveAll(); - myModified = false; } private ProjectFacetsConfigurator createFacetsConfigurator() { - return new ProjectFacetsConfigurator(myContext, myProject); + return new ProjectFacetsConfigurator(myContext, myProject, myFacetsConfigurator); } public void setModified(final boolean modified) { @@ -383,10 +407,12 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change final ModifiableRootModel modifiableRootModel = moduleEditor.getModifiableRootModelProxy(); modifiableRootModels.add(modifiableRootModel); } + // destroyProcess editor - final ModifiableRootModel model = selectedEditor.dispose(); - ModuleDeleteProvider.removeModule(moduleToRemove, model, modifiableRootModels, myModuleModel); + ModuleDeleteProvider.removeModule(moduleToRemove, null, modifiableRootModels, myModuleModel); processModuleCountChanged(); + Disposer.dispose(selectedEditor); + return true; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/OutputEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/OutputEditor.java index c3555596d185..9200e54a6c81 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/OutputEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/OutputEditor.java @@ -22,9 +22,7 @@ */ package com.intellij.openapi.roots.ui.configuration; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; -import com.intellij.openapi.roots.ModifiableRootModel; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -36,11 +34,11 @@ public class OutputEditor extends ModuleElementsEditor { private final JavadocEditor myJavadocEditor; private final AnnotationsEditor myAnnotationsEditor; - protected OutputEditor(final Project project, final ModifiableRootModel model) { - super(project, model); - myCompilerOutputEditor = new BuildElementsEditor(project, model); - myJavadocEditor = new JavadocEditor(project, model); - myAnnotationsEditor = new AnnotationsEditor(project, model); + protected OutputEditor(final ModuleConfigurationState state) { + super(state); + myCompilerOutputEditor = new BuildElementsEditor(state); + myJavadocEditor = new JavadocEditor(state); + myAnnotationsEditor = new AnnotationsEditor(state); } protected JComponent createComponentImpl() { @@ -95,4 +93,4 @@ public class OutputEditor extends ModuleElementsEditor { public String getHelpTopic() { return "projectStructure.modules.paths"; } -} \ No newline at end of file +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java index cab3a388b307..c152bd469688 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java @@ -267,14 +267,8 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se } } - //cleanup - myContext.getDaemonAnalyzer().clearCaches(); - SwingUtilities.invokeLater(new Runnable(){ - public void run() { - if (myWasUiDisposed) return; - reset(); - } - }); + myContext.clearCaches(false); + myContext.resetLibraries(); } public void reset() { 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 ae92071004e4..ec74c1d97200 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 @@ -188,6 +188,8 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable { }.execute(); myPackagingEditorContext.resetModifiableModel(); } + + reset(); // TODO: fix to not reset on apply! } @Override diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableEditor.java index bf94deea873b..4078ff173e64 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTableEditor.java @@ -314,7 +314,7 @@ public class LibraryTableEditor implements Disposable { } private Object[] getSelectedElements() { - if (myTreeBuilder.isDisposed()) return ArrayUtil.EMPTY_OBJECT_ARRAY; + if (myTreeBuilder == null || myTreeBuilder.isDisposed()) return ArrayUtil.EMPTY_OBJECT_ARRAY; final TreePath[] selectionPaths = myTreeBuilder.getTree().getSelectionPaths(); if (selectionPaths == null) { return ArrayUtil.EMPTY_OBJECT_ARRAY; @@ -351,7 +351,7 @@ public class LibraryTableEditor implements Disposable { @Nullable private Library getSelectedLibrary() { - if (myTreeBuilder.getTreeStructure() instanceof LibraryTreeStructure) { + if (myTreeBuilder != null && myTreeBuilder.getTreeStructure() instanceof LibraryTreeStructure) { return ((LibraryTreeStructure)myTreeBuilder.getTreeStructure()).getLibrary(); } else { return convertElementToLibrary(getSelectedElement()); @@ -423,7 +423,7 @@ public class LibraryTableEditor implements Disposable { } public void dispose() { - + myTreeBuilder = null; } private class AddLibraryAction implements ActionListener { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java index dc1a06c1a672..9c91062c1b97 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java @@ -195,6 +195,7 @@ public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurabl if (table != null) { getModelProvider(true).getModifiableModel().removeLibrary(library); myContext.getDaemonAnalyzer().removeElement(new LibraryProjectStructureElement(myContext, library)); + // TODO: myContext.invalidateModules(myContext.myLibraryDependencyCache.get(library.getName())); } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java index 2fb605327e4e..cbf368626556 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java @@ -311,6 +311,7 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple ((DefaultTreeModel)myTree.getModel()).reload(parent); } myContext.getDaemonAnalyzer().removeElement(new LibraryProjectStructureElement(myContext, library)); + // TODO: myContext.invalidateModules(myContext.myLibraryDependencyCache.get(library.getName())); } } @@ -321,8 +322,6 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple } public void reset() { - myContext.reset(); - super.reset(); } @@ -342,6 +341,7 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple public void disposeUIResources() { super.disposeUIResources(); myFacetEditorFacade.clearMaps(); + myContext.clearCaches(true); myContext.myModulesConfigurator.disposeUIResources(); ModuleStructureConfigurable.super.disposeUIResources(); } @@ -456,6 +456,14 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple } modelProxy.addLibraryEntry(library); myContext.getDaemonAnalyzer().queueUpdate(new ModuleProjectStructureElement(myContext, module)); + /* TODO + Set modules = myContext.myLibraryDependencyCache.get(library.getName()); + if (modules == null) { + modules = new HashSet(); + myContext.myLibraryDependencyCache.put(library.getName(), modules); + } + modules.add(module.getName()); + */ myTree.repaint(); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java index cae23c6c7e3e..af39f2b98be8 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java @@ -38,6 +38,21 @@ import java.util.Map; public class StructureConfigurableContext implements Disposable { private final ProjectStructureDaemonAnalyzer myDaemonAnalyzer; + private static final Logger LOG = Logger.getInstance("#" + StructureConfigurableContext.class.getName()); + + public enum ValidityLevel { VALID, WARNING, ERROR } + + public static final String NO_JDK = ProjectBundle.message("project.roots.module.jdk.problem.message"); + public static final String DUPLICATE_MODULE_NAME = ProjectBundle.message("project.roots.module.duplicate.name.message"); + @NonNls public static final String DELETED_LIBRARIES = "lib"; + + public final Map> myLibraryDependencyCache = new HashMap>(); + public final Map> myJdkDependencyCache = new HashMap>(); + public final Map>> myValidityCache = new HashMap>>(); + public final Map myLibraryPathValidityCache = new HashMap(); //can be invalidated on startup only + public final Map> myModulesDependencyCache = new HashMap>(); + + private final ModuleManager myModuleManager; public final ModulesConfigurator myModulesConfigurator; public final Map myLevel2Providers = new THashMap(); private final Project myProject; @@ -58,13 +73,299 @@ public class StructureConfigurableContext implements Disposable { return myDaemonAnalyzer; } + @Nullable + public Set getCachedDependencies(final Object selectedObject, boolean force) { + if (selectedObject instanceof Library){ + final Library library = (Library)selectedObject; + if (myLibraryDependencyCache.containsKey(library.getName())){ + return myLibraryDependencyCache.get(library.getName()); + } + } else if (selectedObject instanceof Sdk){ + final Sdk projectJdk = (Sdk)selectedObject; + if (myJdkDependencyCache.containsKey(projectJdk)){ + return myJdkDependencyCache.get(projectJdk); + } + } else if (selectedObject instanceof Module) { + final Module module = (Module)selectedObject; + if (myModulesDependencyCache.containsKey(module)) { + return myModulesDependencyCache.get(module); + } + } + if (force){ + LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); + final Set dep = getDependencies(selectedObject); + updateCache(selectedObject, dep); + return dep; + } else { + myUpdateDependenciesAlarm.addRequest(new Runnable(){ + public void run() { + final Set dep = getDependencies(selectedObject); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (!myDisposed) { + updateCache(selectedObject, dep); + fireOnCacheChanged(); + } + } + }); + } + }, 100); + return null; + } + } + + private void updateCache(final Object selectedObject, final Set dep) { + if (selectedObject instanceof Library) { + myLibraryDependencyCache.put(((Library)selectedObject).getName(), dep); + } + else if (selectedObject instanceof Sdk) { + myJdkDependencyCache.put((Sdk)selectedObject, dep); + } + else if (selectedObject instanceof Module) { + myModulesDependencyCache.put((Module)selectedObject, dep); + } + } + + private Set getDependencies(final Condition condition) { + final Set result = new TreeSet(); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final Module[] modules = myModulesConfigurator.getModules(); + for (final Module module : modules) { + final ModuleEditor moduleEditor = myModulesConfigurator.getModuleEditor(module); + if (moduleEditor != null) { + final OrderEntry[] entries = moduleEditor.getOrderEntries(); + for (OrderEntry entry : entries) { + if (myDisposed) return; + if (condition.value(entry)) { + result.add(module.getName()); + break; + } + } + } + } + } + }); + return result; + } + + @Nullable + private Set getDependencies(final Object selectedObject) { + if (selectedObject instanceof Module) { + return getDependencies(new Condition() { + public boolean value(final OrderEntry orderEntry) { + return orderEntry instanceof ModuleOrderEntry && Comparing.equal(((ModuleOrderEntry)orderEntry).getModule(), selectedObject); + } + }); + } + else if (selectedObject instanceof Library) { + Library library = (Library)selectedObject; + if (library.getTable() == null) { //module library navigation + HashSet deps = new HashSet(); + Module module = ((LibraryImpl)library).getModule(); + if (module != null) { + deps.add(module.getName()); + } + return deps; + } + return getDependencies(new Condition() { + @SuppressWarnings({"SimplifiableIfStatement"}) + public boolean value(final OrderEntry orderEntry) { + if (orderEntry instanceof LibraryOrderEntry){ + final LibraryImpl library = (LibraryImpl)((LibraryOrderEntry)orderEntry).getLibrary(); + if (Comparing.equal(library, selectedObject)) return true; + return library != null && Comparing.equal(library.getSource(), selectedObject); + } + return false; + } + }); + } + else if (selectedObject instanceof Sdk) { + return getDependencies(new Condition() { + public boolean value(final OrderEntry orderEntry) { + return orderEntry instanceof JdkOrderEntry && Comparing.equal(((JdkOrderEntry)orderEntry).getJdk(), selectedObject); + } + }); + } + return null; + } + public void dispose() { + clearCaches(true); + myDisposed = true; + } + + public void invalidateModules(final Set modules) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (modules != null) { + for (String module : modules) { + myValidityCache.remove(myModuleManager.findModuleByName(module)); + } + } + } + }); + } + public void invalidateModuleName(final Module module) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + final Map> problems = myValidityCache.remove(module); + if (problems != null) { + fireOnCacheChanged(); + } + } + }); } public ModulesConfigurator getModulesConfigurator() { return myModulesConfigurator; } + public void clearCaches(final boolean cleanCacheUpdaters) { + myJdkDependencyCache.clear(); + myLibraryDependencyCache.clear(); + myValidityCache.clear(); + myLibraryPathValidityCache.clear(); + myModulesDependencyCache.clear(); + + fireOnCacheChanged(); + if (cleanCacheUpdaters) { + myCacheUpdaters.clear(); + } + } + + public void clearCaches(final Module module, final List chosen) { + LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); + for (Library library : chosen) { + myLibraryDependencyCache.remove(library.getName()); + } + myValidityCache.remove(module); + fireOnCacheChanged(); + } + + public void clearCaches(final Module module, final Sdk oldJdk, final Sdk selectedModuleJdk) { + LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); + myJdkDependencyCache.remove(oldJdk); + myJdkDependencyCache.remove(selectedModuleJdk); + myValidityCache.remove(module); + fireOnCacheChanged(); + } + + public void clearCaches(final OrderEntry entry) { + LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); + if (entry instanceof ModuleOrderEntry) { + final Module module = ((ModuleOrderEntry)entry).getModule(); + myValidityCache.remove(module); + myModulesDependencyCache.remove(module); + } else if (entry instanceof JdkOrderEntry) { + invalidateModules(myJdkDependencyCache.remove(((JdkOrderEntry)entry).getJdk())); + } else if (entry instanceof LibraryOrderEntry) { + invalidateModules(myLibraryDependencyCache.remove(((LibraryOrderEntry)entry).getLibraryName())); + } + fireOnCacheChanged(); + } + + public ValidityLevel isInvalid(final Object object) { + if (object instanceof Module){ + final Module module = (Module)object; + if (myValidityCache.containsKey(module)) { + boolean valid = myValidityCache.get(module) == null; + return valid ? ValidityLevel.VALID : ValidityLevel.ERROR; + } + myUpdateDependenciesAlarm.addRequest(new Runnable(){ + public void run() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + updateModuleValidityCache(module); + } + }); + } + }, 100); + } else if (object instanceof LibraryEx) { + final LibraryEx library = (LibraryEx)object; + if (myLibraryPathValidityCache.containsKey(library)) return myLibraryPathValidityCache.get(library); + myUpdateDependenciesAlarm.addRequest(new Runnable(){ + public void run() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + updateLibraryValidityCache(library); + } + }); + } + }, 100); + } + return ValidityLevel.VALID; + } + + private void updateLibraryValidityCache(final LibraryEx library) { + if (myLibraryPathValidityCache.containsKey(library)) return; //do not check twice + ValidityLevel level = ValidityLevel.VALID; + if (!(library.allPathsValid(JavadocOrderRootType.getInstance()) && library.allPathsValid(OrderRootType.SOURCES))) { + level = ValidityLevel.WARNING; + } + if (!library.allPathsValid(OrderRootType.CLASSES)) { + level = ValidityLevel.ERROR; + } + + final ValidityLevel finalLevel = level; + SwingUtilities.invokeLater(new Runnable(){ + public void run() { + if (!myDisposed){ + myLibraryPathValidityCache.put(library, finalLevel); + fireOnCacheChanged(); + } + } + }); + } + + private void updateModuleValidityCache(final Module module) { + if (myValidityCache.containsKey(module)) return; //do not check twice + + if (myDisposed) return; + + Map> problems = null; + final ModifiableModuleModel moduleModel = myModulesConfigurator.getModuleModel(); + final Module[] all = moduleModel.getModules(); + for (Module each : all) { + if (each != module && getRealName(each).equals(getRealName(module))) { + problems = new HashMap>(); + problems.put(DUPLICATE_MODULE_NAME, null); + break; + } + } + + final ModuleRootModel rootModel = myModulesConfigurator.getRootModel(module); + if (rootModel == null) return; //already disposed + final OrderEntry[] entries = rootModel.getOrderEntries(); + for (OrderEntry entry : entries) { + if (myDisposed) return; + if (!entry.isValid()){ + if (problems == null) { + problems = new HashMap>(); + } + if (entry instanceof JdkOrderEntry && ((JdkOrderEntry)entry).getJdkName() == null) { + problems.put(NO_JDK, null); + } else { + Set deletedLibraries = problems.get(DELETED_LIBRARIES); + if (deletedLibraries == null){ + deletedLibraries = new HashSet(); + problems.put(DELETED_LIBRARIES, deletedLibraries); + } + deletedLibraries.add(entry.getPresentableName()); + } + } + } + final Map> finalProblems = problems; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (!myDisposed) { + myValidityCache.put(module, finalProblems); + fireOnCacheChanged(); + } + } + }); + } + public Module[] getModules() { return myModulesConfigurator.getModules(); } diff --git a/java/idea-ui/src/com/intellij/peer/impl/PeerFactoryImpl.java b/java/idea-ui/src/com/intellij/peer/impl/PeerFactoryImpl.java index 55d179ee27fd..86ffcacadda7 100644 --- a/java/idea-ui/src/com/intellij/peer/impl/PeerFactoryImpl.java +++ b/java/idea-ui/src/com/intellij/peer/impl/PeerFactoryImpl.java @@ -36,9 +36,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkType; import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ui.configuration.JavaContentEntriesEditor; -import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState; import com.intellij.openapi.ui.DialogWrapperPeerFactory; import com.intellij.openapi.ui.PackageChooser; import com.intellij.openapi.ui.SplitterProportionsData; @@ -251,9 +250,8 @@ public class PeerFactoryImpl extends PeerFactory { return projectJdk; } - public ModuleConfigurationEditor createModuleConfigurationEditor(final Project project, final String moduleName, final ModifiableRootModel model, - final ModulesProvider modulesProvider) { - return new JavaContentEntriesEditor(project, moduleName, model, modulesProvider); + public ModuleConfigurationEditor createModuleConfigurationEditor(final String moduleName, ModuleConfigurationState state) { + return new JavaContentEntriesEditor(moduleName, state); } } \ No newline at end of file diff --git a/java/openapi/src/com/intellij/peer/PeerFactory.java b/java/openapi/src/com/intellij/peer/PeerFactory.java index 6d815ff88df0..f74654ce0fb5 100644 --- a/java/openapi/src/com/intellij/peer/PeerFactory.java +++ b/java/openapi/src/com/intellij/peer/PeerFactory.java @@ -29,8 +29,7 @@ import com.intellij.openapi.module.ModuleConfigurationEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkType; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState; import com.intellij.openapi.ui.DialogWrapperPeerFactory; import com.intellij.openapi.vcs.FileStatusFactory; import com.intellij.openapi.vcs.actions.VcsContextFactory; @@ -89,6 +88,5 @@ public abstract class PeerFactory { public abstract Sdk createProjectJdk(String name, final String version, final String homePath, SdkType sdkType); - public abstract ModuleConfigurationEditor createModuleConfigurationEditor(Project project, String moduleName, ModifiableRootModel model, - ModulesProvider modulesProvider); + public abstract ModuleConfigurationEditor createModuleConfigurationEditor(String moduleName, ModuleConfigurationState state); } \ No newline at end of file diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ModifiableRootModel.java b/platform/lang-api/src/com/intellij/openapi/roots/ModifiableRootModel.java index c4965ebfb689..23177170a3d5 100644 --- a/platform/lang-api/src/com/intellij/openapi/roots/ModifiableRootModel.java +++ b/platform/lang-api/src/com/intellij/openapi/roots/ModifiableRootModel.java @@ -171,4 +171,6 @@ public interface ModifiableRootModel extends ModuleRootModel { void replaceEntryOfType(Class entryClass, T entry); String getSdkName(); + + boolean isDisposed(); } diff --git a/java/idea-ui/src/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java similarity index 81% rename from java/idea-ui/src/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java rename to platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java index 75cc4e3cf13e..10cb8e3c15c0 100644 --- a/java/idea-ui/src/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleConfigurationStateImpl.java @@ -15,24 +15,21 @@ */ package com.intellij.openapi.module.impl; +import com.intellij.facet.impl.DefaultFacetsProvider; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ui.configuration.FacetsProvider; import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.openapi.util.UserDataHolderBase; +import org.jetbrains.annotations.Nullable; public class ModuleConfigurationStateImpl extends UserDataHolderBase implements ModuleConfigurationState { private final ModulesProvider myProvider; - private final ModifiableRootModel myRootModel; private final Project myProject; - private final FacetsProvider myFacetsProvider; - public ModuleConfigurationStateImpl(Project project, ModulesProvider provider, ModifiableRootModel rootModel, - final FacetsProvider facetsProvider) { - myFacetsProvider = facetsProvider; + public ModuleConfigurationStateImpl(Project project, ModulesProvider provider) { myProvider = provider; - myRootModel = rootModel; myProject = project; } @@ -41,11 +38,12 @@ public class ModuleConfigurationStateImpl extends UserDataHolderBase implements } public FacetsProvider getFacetsProvider() { - return myFacetsProvider; + return DefaultFacetsProvider.INSTANCE; } + @Nullable public ModifiableRootModel getRootModel() { - return myRootModel; + return null; } public Project getProject() { diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java index 957be06cdb23..d7c8ea7966e6 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java @@ -537,6 +537,10 @@ public class RootModelImpl implements ModifiableRootModel { return addContentEntry(new ContentEntryImpl(url, this)); } + public boolean isDisposed() { + return myDisposed; + } + private ContentEntry addContentEntry(ContentEntry e) { if (myContent.contains(e)) { for (ContentEntry contentEntry : getContentEntries()) { diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java index ee6594aeb882..4a12bc19a0c8 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java @@ -28,8 +28,8 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.ContentEntry; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootModel; +import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ui.componentsList.components.ScrollablePanel; import com.intellij.openapi.roots.ui.componentsList.layout.VerticalStackLayout; import com.intellij.openapi.roots.ui.configuration.actions.IconWithTextAction; @@ -75,11 +75,13 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { private VirtualFile myLastSelectedDir = null; private final String myModuleName; private final ModulesProvider myModulesProvider; + private ModuleConfigurationState myState; - public CommonContentEntriesEditor(Project project, String moduleName, ModifiableRootModel model, ModulesProvider modulesProvider) { - super(project, model); + public CommonContentEntriesEditor(String moduleName, ModuleConfigurationState state) { + super(state); + myState = state; myModuleName = moduleName; - myModulesProvider = modulesProvider; + myModulesProvider = state.getModulesProvider(); final VirtualFileManagerAdapter fileManagerListener = new VirtualFileManagerAdapter() { public void afterRefreshFinish(boolean asynchronous) { final Module module = getModule(); @@ -101,6 +103,11 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { }); } + @Override + protected ModifiableRootModel getModel() { + return myState.getRootModel(); + } + public String getHelpTopic() { return "projectStructure.modules.sources"; } @@ -163,7 +170,7 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { mainPanel.add(innerPanel, BorderLayout.SOUTH); } - final ContentEntry[] contentEntries = myModel.getContentEntries(); + final ContentEntry[] contentEntries = getModel().getContentEntries(); if (contentEntries.length > 0) { for (final ContentEntry contentEntry : contentEntries) { addContentEntryPanel(contentEntry); @@ -256,7 +263,7 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { @Nullable private ContentEntry getAdjacentContentEntry(ContentEntry contentEntry, int delta) { - final ContentEntry[] contentEntries = myModel.getContentEntries(); + final ContentEntry[] contentEntries = getModel().getContentEntries(); for (int idx = 0; idx < contentEntries.length; idx++) { ContentEntry entry = contentEntries[idx]; if (contentEntry.equals(entry)) { @@ -276,14 +283,14 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { if (isAlreadyAdded(file)) { continue; } - final ContentEntry contentEntry = myModel.addContentEntry(file); + final ContentEntry contentEntry = getModel().addContentEntry(file); contentEntries.add(contentEntry); } return contentEntries; } private boolean isAlreadyAdded(VirtualFile file) { - final VirtualFile[] contentRoots = myModel.getContentRoots(); + final VirtualFile[] contentRoots = getModel().getContentRoots(); for (VirtualFile contentRoot : contentRoots) { if (contentRoot.equals(file)) { return true; @@ -412,4 +419,4 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java index e136279c1be0..47ec811603ad 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java @@ -35,15 +35,15 @@ import java.util.List; */ public abstract class ModuleElementsEditor implements ModuleConfigurationEditor { protected final Project myProject; - protected final ModifiableRootModel myModel; protected JComponent myComponent; private final List myDisposables = new ArrayList(); protected History myHistory; + private ModuleConfigurationState myState; - protected ModuleElementsEditor(Project project, ModifiableRootModel model) { - myProject = project; - myModel = model; + protected ModuleElementsEditor(ModuleConfigurationState state) { + myProject = state.getProject(); + myState = state; } public void setHistory(final History history) { @@ -51,7 +51,15 @@ public abstract class ModuleElementsEditor implements ModuleConfigurationEditor } public boolean isModified() { - return myModel != null && myModel.isChanged(); + return getModel() != null && getModel().isChanged(); + } + + protected ModifiableRootModel getModel() { + return myState.getRootModel(); + } + + protected ModuleConfigurationState getState() { + return myState; } public void canApply() throws ConfigurationException {} From 9501176d2fb779b024d609903e3e8462140cb6d1 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Thu, 15 Oct 2009 15:45:09 +0400 Subject: [PATCH 05/14] Modifiable model merge fixes --- .../ui/configuration/ClasspathEditor.java | 7 - .../ui/configuration/ClasspathPanel.java | 8 +- .../configuration/ModuleJdkConfigurable.java | 20 +- .../ProjectStructureConfigurable.java | 2 +- .../ModuleStructureConfigurable.java | 1 - .../StructureConfigurableContext.java | 303 +----------------- 6 files changed, 13 insertions(+), 328 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java index 2da12ffe5071..44393bdb50b7 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathEditor.java @@ -152,13 +152,6 @@ public class ClasspathEditor extends ModuleElementsEditor implements ModuleRootL final ModifiableRootModel model = getModel(); final Sdk oldSdk = model.getSdk(); - //final List entries = myPanel.getEntries(); - //for (OrderEntry entry : entries) { - // if (entry instanceof JdkOrderEntry) { - // - // } - //} - if (newJDK != null) { model.setSdk(newJDK); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java index 31e63740def3..447e1d08e0f2 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ClasspathPanel.java @@ -331,14 +331,14 @@ public class ClasspathPanel extends JPanel { if (orderEntry == null) { continue; } - ModuleStructureConfigurable.getInstance(myState.getProject()).getContext().clearCaches(orderEntry); + getRootModel().removeOrderEntry(orderEntry); } final int[] selectedRows = myEntryTable.getSelectedRows(); myModel.fireTableDataChanged(); TableUtil.selectRows(myEntryTable, selectedRows); - final StructureConfigurableContext context = ModuleStructureConfigurable.getInstance(myProject).getContext(); - context.getDaemonAnalyzer().queueUpdate(new ModuleProjectStructureElement(context, myRootModel.getModule())); + final StructureConfigurableContext context = ModuleStructureConfigurable.getInstance(myState.getProject()).getContext(); + context.getDaemonAnalyzer().queueUpdate(new ModuleProjectStructureElement(context, getRootModel().getModule())); } }); @@ -500,7 +500,7 @@ public class ClasspathPanel extends JPanel { TableUtil.scrollSelectionToVisible(myEntryTable); final StructureConfigurableContext context = rootConfigurable.getContext(); - context.getDaemonAnalyzer().queueUpdate(new ModuleProjectStructureElement(context, myRootModel.getModule())); + context.getDaemonAnalyzer().queueUpdate(new ModuleProjectStructureElement(context, getRootModel().getModule())); } finally { if (dialog instanceof ChooseNamedLibraryAction.MyChooserDialog) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleJdkConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleJdkConfigurable.java index 91552be593e2..728167753479 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleJdkConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleJdkConfigurable.java @@ -106,17 +106,11 @@ public abstract class ModuleJdkConfigurable implements Disposable { myCbModuleJdk.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (myFreeze) return; - final Sdk oldJdk = getRootModel().getSdk(); - mySelectedModuleJdk = myCbModuleJdk.getSelectedJdk(); - final Sdk selectedModuleJdk = getSelectedModuleJdk(); - if (selectedModuleJdk != null) { - getRootModel().setSdk(selectedModuleJdk); - } - else { - getRootModel().inheritSdk(); - } - clearCaches(oldJdk, selectedModuleJdk); - myModuleEditor.flushChangesToModel(); + + final Sdk newJdk = myCbModuleJdk.getSelectedJdk(); + myModuleEditor.setSdk(newJdk); + + clearCaches(); } }); myJdkPanel.add(new JLabel(ProjectBundle.message("module.libraries.target.jdk.module.radio")), @@ -154,7 +148,7 @@ public abstract class ModuleJdkConfigurable implements Disposable { }); } - private void clearCaches(final Sdk oldJdk, final Sdk selectedModuleJdk) { + private void clearCaches() { final Module module = getRootModel().getModule(); final Project project = module.getProject(); final StructureConfigurableContext context = ModuleStructureConfigurable.getInstance(project).getContext(); @@ -170,7 +164,7 @@ public abstract class ModuleJdkConfigurable implements Disposable { myCbModuleJdk.setSelectedJdk(mySelectedModuleJdk); } else { myCbModuleJdk.setInvalidJdk(jdkName); - clearCaches(null, null); + clearCaches(); } } else { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java index c152bd469688..3abc96473c9a 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java @@ -267,7 +267,7 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se } } - myContext.clearCaches(false); + myContext.getDaemonAnalyzer().clearCaches(); myContext.resetLibraries(); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java index cbf368626556..de6421576fec 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java @@ -341,7 +341,6 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple public void disposeUIResources() { super.disposeUIResources(); myFacetEditorFacade.clearMaps(); - myContext.clearCaches(true); myContext.myModulesConfigurator.disposeUIResources(); ModuleStructureConfigurable.super.disposeUIResources(); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java index af39f2b98be8..c8a45db598b7 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java @@ -38,21 +38,6 @@ import java.util.Map; public class StructureConfigurableContext implements Disposable { private final ProjectStructureDaemonAnalyzer myDaemonAnalyzer; - private static final Logger LOG = Logger.getInstance("#" + StructureConfigurableContext.class.getName()); - - public enum ValidityLevel { VALID, WARNING, ERROR } - - public static final String NO_JDK = ProjectBundle.message("project.roots.module.jdk.problem.message"); - public static final String DUPLICATE_MODULE_NAME = ProjectBundle.message("project.roots.module.duplicate.name.message"); - @NonNls public static final String DELETED_LIBRARIES = "lib"; - - public final Map> myLibraryDependencyCache = new HashMap>(); - public final Map> myJdkDependencyCache = new HashMap>(); - public final Map>> myValidityCache = new HashMap>>(); - public final Map myLibraryPathValidityCache = new HashMap(); //can be invalidated on startup only - public final Map> myModulesDependencyCache = new HashMap>(); - - private final ModuleManager myModuleManager; public final ModulesConfigurator myModulesConfigurator; public final Map myLevel2Providers = new THashMap(); private final Project myProject; @@ -73,299 +58,13 @@ public class StructureConfigurableContext implements Disposable { return myDaemonAnalyzer; } - @Nullable - public Set getCachedDependencies(final Object selectedObject, boolean force) { - if (selectedObject instanceof Library){ - final Library library = (Library)selectedObject; - if (myLibraryDependencyCache.containsKey(library.getName())){ - return myLibraryDependencyCache.get(library.getName()); - } - } else if (selectedObject instanceof Sdk){ - final Sdk projectJdk = (Sdk)selectedObject; - if (myJdkDependencyCache.containsKey(projectJdk)){ - return myJdkDependencyCache.get(projectJdk); - } - } else if (selectedObject instanceof Module) { - final Module module = (Module)selectedObject; - if (myModulesDependencyCache.containsKey(module)) { - return myModulesDependencyCache.get(module); - } - } - if (force){ - LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); - final Set dep = getDependencies(selectedObject); - updateCache(selectedObject, dep); - return dep; - } else { - myUpdateDependenciesAlarm.addRequest(new Runnable(){ - public void run() { - final Set dep = getDependencies(selectedObject); - SwingUtilities.invokeLater(new Runnable() { - public void run() { - if (!myDisposed) { - updateCache(selectedObject, dep); - fireOnCacheChanged(); - } - } - }); - } - }, 100); - return null; - } - } - - private void updateCache(final Object selectedObject, final Set dep) { - if (selectedObject instanceof Library) { - myLibraryDependencyCache.put(((Library)selectedObject).getName(), dep); - } - else if (selectedObject instanceof Sdk) { - myJdkDependencyCache.put((Sdk)selectedObject, dep); - } - else if (selectedObject instanceof Module) { - myModulesDependencyCache.put((Module)selectedObject, dep); - } - } - - private Set getDependencies(final Condition condition) { - final Set result = new TreeSet(); - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - final Module[] modules = myModulesConfigurator.getModules(); - for (final Module module : modules) { - final ModuleEditor moduleEditor = myModulesConfigurator.getModuleEditor(module); - if (moduleEditor != null) { - final OrderEntry[] entries = moduleEditor.getOrderEntries(); - for (OrderEntry entry : entries) { - if (myDisposed) return; - if (condition.value(entry)) { - result.add(module.getName()); - break; - } - } - } - } - } - }); - return result; - } - - @Nullable - private Set getDependencies(final Object selectedObject) { - if (selectedObject instanceof Module) { - return getDependencies(new Condition() { - public boolean value(final OrderEntry orderEntry) { - return orderEntry instanceof ModuleOrderEntry && Comparing.equal(((ModuleOrderEntry)orderEntry).getModule(), selectedObject); - } - }); - } - else if (selectedObject instanceof Library) { - Library library = (Library)selectedObject; - if (library.getTable() == null) { //module library navigation - HashSet deps = new HashSet(); - Module module = ((LibraryImpl)library).getModule(); - if (module != null) { - deps.add(module.getName()); - } - return deps; - } - return getDependencies(new Condition() { - @SuppressWarnings({"SimplifiableIfStatement"}) - public boolean value(final OrderEntry orderEntry) { - if (orderEntry instanceof LibraryOrderEntry){ - final LibraryImpl library = (LibraryImpl)((LibraryOrderEntry)orderEntry).getLibrary(); - if (Comparing.equal(library, selectedObject)) return true; - return library != null && Comparing.equal(library.getSource(), selectedObject); - } - return false; - } - }); - } - else if (selectedObject instanceof Sdk) { - return getDependencies(new Condition() { - public boolean value(final OrderEntry orderEntry) { - return orderEntry instanceof JdkOrderEntry && Comparing.equal(((JdkOrderEntry)orderEntry).getJdk(), selectedObject); - } - }); - } - return null; - } - public void dispose() { - clearCaches(true); - myDisposed = true; - } - - public void invalidateModules(final Set modules) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - if (modules != null) { - for (String module : modules) { - myValidityCache.remove(myModuleManager.findModuleByName(module)); - } - } - } - }); - } - public void invalidateModuleName(final Module module) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - final Map> problems = myValidityCache.remove(module); - if (problems != null) { - fireOnCacheChanged(); - } - } - }); } public ModulesConfigurator getModulesConfigurator() { return myModulesConfigurator; } - public void clearCaches(final boolean cleanCacheUpdaters) { - myJdkDependencyCache.clear(); - myLibraryDependencyCache.clear(); - myValidityCache.clear(); - myLibraryPathValidityCache.clear(); - myModulesDependencyCache.clear(); - - fireOnCacheChanged(); - if (cleanCacheUpdaters) { - myCacheUpdaters.clear(); - } - } - - public void clearCaches(final Module module, final List chosen) { - LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); - for (Library library : chosen) { - myLibraryDependencyCache.remove(library.getName()); - } - myValidityCache.remove(module); - fireOnCacheChanged(); - } - - public void clearCaches(final Module module, final Sdk oldJdk, final Sdk selectedModuleJdk) { - LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); - myJdkDependencyCache.remove(oldJdk); - myJdkDependencyCache.remove(selectedModuleJdk); - myValidityCache.remove(module); - fireOnCacheChanged(); - } - - public void clearCaches(final OrderEntry entry) { - LOG.assertTrue(ApplicationManager.getApplication().isDispatchThread()); - if (entry instanceof ModuleOrderEntry) { - final Module module = ((ModuleOrderEntry)entry).getModule(); - myValidityCache.remove(module); - myModulesDependencyCache.remove(module); - } else if (entry instanceof JdkOrderEntry) { - invalidateModules(myJdkDependencyCache.remove(((JdkOrderEntry)entry).getJdk())); - } else if (entry instanceof LibraryOrderEntry) { - invalidateModules(myLibraryDependencyCache.remove(((LibraryOrderEntry)entry).getLibraryName())); - } - fireOnCacheChanged(); - } - - public ValidityLevel isInvalid(final Object object) { - if (object instanceof Module){ - final Module module = (Module)object; - if (myValidityCache.containsKey(module)) { - boolean valid = myValidityCache.get(module) == null; - return valid ? ValidityLevel.VALID : ValidityLevel.ERROR; - } - myUpdateDependenciesAlarm.addRequest(new Runnable(){ - public void run() { - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - updateModuleValidityCache(module); - } - }); - } - }, 100); - } else if (object instanceof LibraryEx) { - final LibraryEx library = (LibraryEx)object; - if (myLibraryPathValidityCache.containsKey(library)) return myLibraryPathValidityCache.get(library); - myUpdateDependenciesAlarm.addRequest(new Runnable(){ - public void run() { - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - updateLibraryValidityCache(library); - } - }); - } - }, 100); - } - return ValidityLevel.VALID; - } - - private void updateLibraryValidityCache(final LibraryEx library) { - if (myLibraryPathValidityCache.containsKey(library)) return; //do not check twice - ValidityLevel level = ValidityLevel.VALID; - if (!(library.allPathsValid(JavadocOrderRootType.getInstance()) && library.allPathsValid(OrderRootType.SOURCES))) { - level = ValidityLevel.WARNING; - } - if (!library.allPathsValid(OrderRootType.CLASSES)) { - level = ValidityLevel.ERROR; - } - - final ValidityLevel finalLevel = level; - SwingUtilities.invokeLater(new Runnable(){ - public void run() { - if (!myDisposed){ - myLibraryPathValidityCache.put(library, finalLevel); - fireOnCacheChanged(); - } - } - }); - } - - private void updateModuleValidityCache(final Module module) { - if (myValidityCache.containsKey(module)) return; //do not check twice - - if (myDisposed) return; - - Map> problems = null; - final ModifiableModuleModel moduleModel = myModulesConfigurator.getModuleModel(); - final Module[] all = moduleModel.getModules(); - for (Module each : all) { - if (each != module && getRealName(each).equals(getRealName(module))) { - problems = new HashMap>(); - problems.put(DUPLICATE_MODULE_NAME, null); - break; - } - } - - final ModuleRootModel rootModel = myModulesConfigurator.getRootModel(module); - if (rootModel == null) return; //already disposed - final OrderEntry[] entries = rootModel.getOrderEntries(); - for (OrderEntry entry : entries) { - if (myDisposed) return; - if (!entry.isValid()){ - if (problems == null) { - problems = new HashMap>(); - } - if (entry instanceof JdkOrderEntry && ((JdkOrderEntry)entry).getJdkName() == null) { - problems.put(NO_JDK, null); - } else { - Set deletedLibraries = problems.get(DELETED_LIBRARIES); - if (deletedLibraries == null){ - deletedLibraries = new HashSet(); - problems.put(DELETED_LIBRARIES, deletedLibraries); - } - deletedLibraries.add(entry.getPresentableName()); - } - } - } - final Map> finalProblems = problems; - SwingUtilities.invokeLater(new Runnable() { - public void run() { - if (!myDisposed) { - myValidityCache.put(module, finalProblems); - fireOnCacheChanged(); - } - } - }); - } - public Module[] getModules() { return myModulesConfigurator.getModules(); } @@ -454,4 +153,4 @@ public class StructureConfigurableContext implements Disposable { resetLibraries(); myModulesConfigurator.resetModuleEditors(); } -} +} \ No newline at end of file From caf9a2d4abed402965e34c373d21a4da249c18aa Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Mon, 19 Oct 2009 15:14:46 +0400 Subject: [PATCH 06/14] modifiable root model: stateless content entry editor --- .../JavaContentEntriesEditor.java | 10 ++- .../configuration/JavaContentEntryEditor.java | 27 +++--- .../configuration/JavaContentRootPanel.java | 22 ++--- .../CommonContentEntriesEditor.java | 78 +++++++++-------- .../ui/configuration/ContentEntryEditor.java | 84 ++++++++++++------- .../ui/configuration/ContentRootPanel.java | 34 ++++---- 6 files changed, 155 insertions(+), 100 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java index 70492ad3ab8f..127cf945ee6f 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntriesEditor.java @@ -25,6 +25,7 @@ import com.intellij.openapi.progress.util.SmoothProgressAdapter; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; @@ -43,8 +44,13 @@ public class JavaContentEntriesEditor extends CommonContentEntriesEditor { super(moduleName, state); } - protected ContentEntryEditor createContentEntryEditor(ContentEntry contentEntry) { - return new JavaContentEntryEditor(contentEntry, getModel()); + protected ContentEntryEditor createContentEntryEditor(final String contentEntryUrl) { + return new JavaContentEntryEditor(contentEntryUrl) { + @Override + protected ModifiableRootModel getModel() { + return JavaContentEntriesEditor.this.getModel(); + } + }; } protected ContentEntryTreeEditor createContentEntryTreeEditor(Project project) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntryEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntryEditor.java index cde7f8ae3170..52583a151a8a 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntryEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentEntryEditor.java @@ -17,22 +17,27 @@ package com.intellij.openapi.roots.ui.configuration; import com.intellij.openapi.roots.CompilerModuleExtension; import com.intellij.openapi.roots.ContentEntry; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ExcludeFolder; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.Nullable; -public class JavaContentEntryEditor extends ContentEntryEditor { +public abstract class JavaContentEntryEditor extends ContentEntryEditor { private final CompilerModuleExtension myCompilerExtension; - public JavaContentEntryEditor(ContentEntry contentEntry, ModifiableRootModel rootModel) { - super(contentEntry, rootModel); - myCompilerExtension = rootModel.getModuleExtension(CompilerModuleExtension.class); + public JavaContentEntryEditor(final String contentEntryUrl) { + super(contentEntryUrl); + myCompilerExtension = getModel().getModuleExtension(CompilerModuleExtension.class); } protected ContentRootPanel createContentRootPane() { - return new JavaContentRootPanel(myContentEntry, this); + return new JavaContentRootPanel(this) { + @Nullable + @Override + protected ContentEntry getContentEntry() { + return JavaContentEntryEditor.this.getContentEntry(); + } + }; } @Nullable @@ -45,7 +50,7 @@ public class JavaContentEntryEditor extends ContentEntryEditor { myCompilerExtension.setExcludeOutput(true); } if (isExplodedDirectory) { - myRootModel.setExcludeExplodedDirectory(true); + getModel().setExcludeExplodedDirectory(true); } return null; } @@ -58,7 +63,7 @@ public class JavaContentEntryEditor extends ContentEntryEditor { myCompilerExtension.setExcludeOutput(false); } if (isExplodedDirectory(file)) { - myRootModel.setExcludeExplodedDirectory(false); + getModel().setExcludeExplodedDirectory(false); } super.doRemoveExcludeFolder(excludeFolder, file); } @@ -79,7 +84,7 @@ public class JavaContentEntryEditor extends ContentEntryEditor { } if (myCompilerExtension.isCompilerOutputPathInherited()) { - final String compilerOutput = ProjectStructureConfigurable.getInstance(myRootModel.getModule().getProject()).getProjectConfig().getCompilerOutputUrl(); + final String compilerOutput = ProjectStructureConfigurable.getInstance(getModel().getModule().getProject()).getProjectConfig().getCompilerOutputUrl(); if (file != null && Comparing.equal(compilerOutput, file.getUrl())) { return true; } @@ -89,7 +94,7 @@ public class JavaContentEntryEditor extends ContentEntryEditor { } private boolean isExplodedDirectory(VirtualFile file) { - final VirtualFile explodedDir = myRootModel.getExplodedDirectory(); + final VirtualFile explodedDir = getModel().getExplodedDirectory(); if (explodedDir != null) { if (explodedDir.equals(file)) { return true; diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentRootPanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentRootPanel.java index 2e54148008ea..d875a699f408 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentRootPanel.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavaContentRootPanel.java @@ -16,10 +16,9 @@ package com.intellij.openapi.roots.ui.configuration; import com.intellij.openapi.project.ProjectBundle; -import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.ContentFolder; -import com.intellij.openapi.roots.SourceFolder; import com.intellij.openapi.roots.ExcludeFolder; +import com.intellij.openapi.roots.SourceFolder; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.vfs.VirtualFile; @@ -29,14 +28,15 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.util.ArrayList; +import java.util.List; -public class JavaContentRootPanel extends ContentRootPanel { +public abstract class JavaContentRootPanel extends ContentRootPanel { private static final Color SOURCES_COLOR = new Color(0x0A50A1); private static final Icon ADD_PREFIX_ICON = IconLoader.getIcon("/modules/setPackagePrefix.png"); private static final Icon ADD_PREFIX_ROLLOVER_ICON = IconLoader.getIcon("/modules/setPackagePrefixRollover.png"); - public JavaContentRootPanel(ContentEntry contentEntry, ActionCallback callback) { - super(contentEntry, callback); + public JavaContentRootPanel(ActionCallback callback) { + super(callback); } @Nullable @@ -52,7 +52,7 @@ public class JavaContentRootPanel extends ContentRootPanel { ProjectBundle.message("module.paths.package.prefix.tooltip"), new Runnable() { public void run() { final String message = ProjectBundle.message("module.paths.package.prefix.prompt", - toRelativeDisplayPath(folder.getUrl(), myContentEntry.getUrl() + ":")); + toRelativeDisplayPath(folder.getUrl(), getContentEntry().getUrl() + ":")); final String prefix = Messages.showInputDialog(JavaContentRootPanel.this, message, ProjectBundle.message("module.paths.package.prefix.title"), Messages.getQuestionIcon(), folder.getPackagePrefix(), null); if (prefix != null) { @@ -68,10 +68,10 @@ public class JavaContentRootPanel extends ContentRootPanel { } protected void addFolderGroupComponents() { - final java.util.List sources = new ArrayList(); - final java.util.List testSources = new ArrayList(); - final java.util.List excluded = new ArrayList(); - final SourceFolder[] sourceFolders = myContentEntry.getSourceFolders(); + final List sources = new ArrayList(); + final List testSources = new ArrayList(); + final List excluded = new ArrayList(); + final SourceFolder[] sourceFolders = getContentEntry().getSourceFolders(); for (SourceFolder folder : sourceFolders) { if (folder.isSynthetic()) { continue; @@ -88,7 +88,7 @@ public class JavaContentRootPanel extends ContentRootPanel { } } - final ExcludeFolder[] excludeFolders = myContentEntry.getExcludeFolders(); + final ExcludeFolder[] excludeFolders = getContentEntry().getExcludeFolders(); for (final ExcludeFolder excludeFolder : excludeFolders) { if (!excludeFolder.isSynthetic()) { excluded.add(excludeFolder); diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java index 4a12bc19a0c8..5048f1910bd8 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java @@ -69,8 +69,8 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { private ContentEntryTreeEditor myRootTreeEditor; private MyContentEntryEditorListener myContentEntryEditorListener; protected JPanel myEditorsPanel; - private final Map myEntryToEditorMap = new HashMap(); - private ContentEntry mySelectedEntry; + private final Map myEntryToEditorMap = new HashMap(); + private String mySelectedEntryUrl; private VirtualFile myLastSelectedDir = null; private final String myModuleName; @@ -86,7 +86,7 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { public void afterRefreshFinish(boolean asynchronous) { final Module module = getModule(); if (module == null || module.isDisposed() || module.getProject().isDisposed()) return; - for (final ContentEntry contentEntry : myEntryToEditorMap.keySet()) { + for (final String contentEntry : myEntryToEditorMap.keySet()) { final ContentEntryEditor editor = myEntryToEditorMap.get(contentEntry); if (editor != null) { editor.update(); @@ -173,9 +173,9 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { final ContentEntry[] contentEntries = getModel().getContentEntries(); if (contentEntries.length > 0) { for (final ContentEntry contentEntry : contentEntries) { - addContentEntryPanel(contentEntry); + addContentEntryPanel(contentEntry.getUrl()); } - selectContentEntry(contentEntries[0]); + selectContentEntry(contentEntries[0].getUrl()); } return mainPanel; @@ -195,7 +195,7 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { return myModulesProvider.getModule(myModuleName); } - protected void addContentEntryPanel(final ContentEntry contentEntry) { + protected void addContentEntryPanel(final String contentEntry) { final ContentEntryEditor contentEntryEditor = createContentEntryEditor(contentEntry); contentEntryEditor.initUI(); contentEntryEditor.addContentEntryEditorListener(myContentEntryEditorListener); @@ -215,22 +215,22 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { myEditorsPanel.add(component); } - protected abstract ContentEntryEditor createContentEntryEditor(ContentEntry contentEntry); + protected abstract ContentEntryEditor createContentEntryEditor(String contentEntryUrl); - void selectContentEntry(ContentEntry contentEntry) { - if (mySelectedEntry != null && mySelectedEntry.equals(contentEntry)) { + void selectContentEntry(final String contentEntryUrl) { + if (mySelectedEntryUrl != null && mySelectedEntryUrl.equals(contentEntryUrl)) { return; } try { - if (mySelectedEntry != null) { - ContentEntryEditor editor = myEntryToEditorMap.get(mySelectedEntry); + if (mySelectedEntryUrl != null) { + ContentEntryEditor editor = myEntryToEditorMap.get(mySelectedEntryUrl); if (editor != null) { editor.setSelected(false); } } - if (contentEntry != null) { - ContentEntryEditor editor = myEntryToEditorMap.get(contentEntry); + if (contentEntryUrl != null) { + ContentEntryEditor editor = myEntryToEditorMap.get(contentEntryUrl); if (editor != null) { editor.setSelected(true); final JComponent component = editor.getComponent(); @@ -246,7 +246,7 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { } } finally { - mySelectedEntry = contentEntry; + mySelectedEntryUrl = contentEntryUrl; } } @@ -257,21 +257,21 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { } @Nullable - private ContentEntry getNextContentEntry(ContentEntry contentEntry) { - return getAdjacentContentEntry(contentEntry, 1); + private String getNextContentEntry(final String contentEntryUrl) { + return getAdjacentContentEntry(contentEntryUrl, 1); } @Nullable - private ContentEntry getAdjacentContentEntry(ContentEntry contentEntry, int delta) { + private String getAdjacentContentEntry(final String contentEntryUrl, int delta) { final ContentEntry[] contentEntries = getModel().getContentEntries(); for (int idx = 0; idx < contentEntries.length; idx++) { ContentEntry entry = contentEntries[idx]; - if (contentEntry.equals(entry)) { + if (contentEntryUrl.equals(entry.getUrl())) { int nextEntryIndex = (idx + delta) % contentEntries.length; if (nextEntryIndex < 0) { nextEntryIndex += contentEntries.length; } - return nextEntryIndex == idx ? null : contentEntries[nextEntryIndex]; + return nextEntryIndex == idx ? null : contentEntries[nextEntryIndex].getUrl(); } } return null; @@ -304,46 +304,46 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { protected void addContentEntryPanels(ContentEntry[] contentEntriesArray) { for (ContentEntry contentEntry : contentEntriesArray) { - addContentEntryPanel(contentEntry); + addContentEntryPanel(contentEntry.getUrl()); } myEditorsPanel.revalidate(); myEditorsPanel.repaint(); - selectContentEntry(contentEntriesArray[contentEntriesArray.length - 1]); + selectContentEntry(contentEntriesArray[contentEntriesArray.length - 1].getUrl()); } private final class MyContentEntryEditorListener extends ContentEntryEditorListenerAdapter { public void editingStarted(ContentEntryEditor editor) { - selectContentEntry(editor.getContentEntry()); + selectContentEntry(editor.getContentEntryUrl()); } public void beforeEntryDeleted(ContentEntryEditor editor) { - final ContentEntry entry = editor.getContentEntry(); - if (mySelectedEntry != null && mySelectedEntry.equals(entry)) { + final String entryUrl = editor.getContentEntryUrl(); + if (mySelectedEntryUrl != null && mySelectedEntryUrl.equals(entryUrl)) { myRootTreeEditor.setContentEntryEditor(null); } - final ContentEntry nextContentEntry = getNextContentEntry(entry); - removeContentEntryPanel(entry); - selectContentEntry(nextContentEntry); + final String nextContentEntryUrl = getNextContentEntry(entryUrl); + removeContentEntryPanel(entryUrl); + selectContentEntry(nextContentEntryUrl); editor.removeContentEntryEditorListener(this); } public void navigationRequested(ContentEntryEditor editor, VirtualFile file) { - if (mySelectedEntry != null && mySelectedEntry.equals(editor.getContentEntry())) { + if (mySelectedEntryUrl != null && mySelectedEntryUrl.equals(editor.getContentEntryUrl())) { myRootTreeEditor.requestFocus(); myRootTreeEditor.select(file); } else { - selectContentEntry(editor.getContentEntry()); + selectContentEntry(editor.getContentEntryUrl()); myRootTreeEditor.requestFocus(); myRootTreeEditor.select(file); } } - private void removeContentEntryPanel(final ContentEntry contentEntry) { - ContentEntryEditor editor = myEntryToEditorMap.get(contentEntry); + private void removeContentEntryPanel(final String contentEntryUrl) { + ContentEntryEditor editor = myEntryToEditorMap.get(contentEntryUrl); if (editor != null) { myEditorsPanel.remove(editor.getComponent()); - myEntryToEditorMap.remove(contentEntry); + myEntryToEditorMap.remove(contentEntryUrl); myEditorsPanel.revalidate(); myEditorsPanel.repaint(); } @@ -374,10 +374,22 @@ public abstract class CommonContentEntriesEditor extends ModuleElementsEditor { } } + @Nullable + private ContentEntry getContentEntry(final String url) { + final ContentEntry[] entries = getModel().getContentEntries(); + for (final ContentEntry entry : entries) { + if (entry.getUrl().equals(url)) return entry; + } + + return null; + } + private void validateContentEntriesCandidates(VirtualFile[] files) throws Exception { for (final VirtualFile file : files) { // check for collisions with already existing entries - for (final ContentEntry contentEntry : myEntryToEditorMap.keySet()) { + for (final String contentEntryUrl : myEntryToEditorMap.keySet()) { + final ContentEntry contentEntry = getContentEntry(contentEntryUrl); + if (contentEntry == null) continue; final VirtualFile contentEntryFile = contentEntry.getFile(); if (contentEntryFile == null) { continue; // skip invalid entry diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java index 723ed2664c3b..b01384dc68d4 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentEntryEditor.java @@ -39,14 +39,13 @@ import java.util.EventListener; */ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallback { - protected final ContentEntry myContentEntry; - protected final ModifiableRootModel myRootModel; private boolean myIsSelected; private ContentRootPanel myContentRootPanel; private JPanel myMainPanel; protected EventDispatcher myEventDispatcher; + private String myContentEntryUrl; - public static interface ContentEntryEditorListener extends EventListener{ + public interface ContentEntryEditorListener extends EventListener{ void editingStarted(ContentEntryEditor editor); void beforeEntryDeleted(ContentEntryEditor editor); void sourceFolderAdded(ContentEntryEditor editor, SourceFolder folder); @@ -57,9 +56,12 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb void packagePrefixSet(ContentEntryEditor editor, SourceFolder folder); } - public ContentEntryEditor(ContentEntry contentEntry, ModifiableRootModel rootModel) { - myContentEntry = contentEntry; - myRootModel = rootModel; + public ContentEntryEditor(final String contentEntryUrl) { + myContentEntryUrl = contentEntryUrl; + } + + public String getContentEntryUrl() { + return myContentEntryUrl; } public void initUI() { @@ -85,16 +87,27 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb update(); } + @Nullable + protected ContentEntry getContentEntry() { + final ContentEntry[] entries = getModel().getContentEntries(); + for (ContentEntry entry : entries) { + if (entry.getUrl().equals(myContentEntryUrl)) return entry; + } + + return null; + } + + protected abstract ModifiableRootModel getModel(); public void deleteContentEntry() { final int answer = Messages.showYesNoDialog(ProjectBundle.message("module.paths.remove.content.prompt", - VirtualFileManager.extractPath(myContentEntry.getUrl()).replace('/', File.separatorChar)), + VirtualFileManager.extractPath(myContentEntryUrl).replace('/', File.separatorChar)), ProjectBundle.message("module.paths.remove.content.title"), Messages.getQuestionIcon()); if (answer != 0) { // no return; } myEventDispatcher.getMulticaster().beforeEntryDeleted(this); - myRootModel.removeContentEntry(myContentEntry); + getModel().removeContentEntry(getContentEntry()); } public void deleteContentFolder(ContentEntry contentEntry, ContentFolder folder) { @@ -147,10 +160,6 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb return myMainPanel; } - public ContentEntry getContentEntry() { - return myContentEntry; - } - public void update() { if (myContentRootPanel != null) { myMainPanel.remove(myContentRootPanel); @@ -164,15 +173,21 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb protected abstract ContentRootPanel createContentRootPane(); + @Nullable public SourceFolder addSourceFolder(VirtualFile file, boolean isTestSource) { - final SourceFolder sourceFolder = myContentEntry.addSourceFolder(file, isTestSource); - try { - return sourceFolder; - } - finally { - myEventDispatcher.getMulticaster().sourceFolderAdded(this, sourceFolder); - update(); + final ContentEntry contentEntry = getContentEntry(); + if (contentEntry != null) { + final SourceFolder sourceFolder = contentEntry.addSourceFolder(file, isTestSource); + try { + return sourceFolder; + } + finally { + myEventDispatcher.getMulticaster().sourceFolderAdded(this, sourceFolder); + update(); + } } + + return null; } public void removeSourceFolder(SourceFolder sourceFolder) { @@ -188,9 +203,11 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb } protected void doRemoveSourceFolder(SourceFolder sourceFolder) { - myContentEntry.removeSourceFolder(sourceFolder); + final ContentEntry contentEntry = getContentEntry(); + if (contentEntry != null) contentEntry.removeSourceFolder(sourceFolder); } + @Nullable public ExcludeFolder addExcludeFolder(VirtualFile file) { try { return doAddExcludeFolder(file); @@ -203,7 +220,12 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb @Nullable protected ExcludeFolder doAddExcludeFolder(VirtualFile file) { - return myContentEntry.addExcludeFolder(file); + final ContentEntry contentEntry = getContentEntry(); + if (contentEntry != null) { + return contentEntry.addExcludeFolder(file); + } + + return null; } public void removeExcludeFolder(ExcludeFolder excludeFolder) { @@ -219,7 +241,8 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb protected void doRemoveExcludeFolder(ExcludeFolder excludeFolder, VirtualFile file) { if (!excludeFolder.isSynthetic()) { - myContentEntry.removeExcludeFolder(excludeFolder); + final ContentEntry contentEntry = getContentEntry(); + if (contentEntry != null) contentEntry.removeExcludeFolder(excludeFolder); } } @@ -238,10 +261,11 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb } public boolean isUnderExcludedDirectory(final VirtualFile file) { - if (myContentEntry == null) { + final ContentEntry contentEntry = getContentEntry(); + if (contentEntry == null) { return false; } - final ExcludeFolder[] excludeFolders = myContentEntry.getExcludeFolders(); + final ExcludeFolder[] excludeFolders = contentEntry.getExcludeFolders(); for (ExcludeFolder excludeFolder : excludeFolders) { final VirtualFile excludedDir = excludeFolder.getFile(); if (excludedDir == null) { @@ -254,11 +278,13 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb return false; } + @Nullable public ExcludeFolder getExcludeFolder(VirtualFile file) { - if (myContentEntry == null) { + final ContentEntry contentEntry = getContentEntry(); + if (contentEntry == null) { return null; } - final ExcludeFolder[] excludeFolders = myContentEntry.getExcludeFolders(); + final ExcludeFolder[] excludeFolders = contentEntry.getExcludeFolders(); for (final ExcludeFolder excludeFolder : excludeFolders) { final VirtualFile f = excludeFolder.getFile(); if (f == null) { @@ -271,11 +297,13 @@ public abstract class ContentEntryEditor implements ContentRootPanel.ActionCallb return null; } + @Nullable public SourceFolder getSourceFolder(VirtualFile file) { - if (myContentEntry == null) { + final ContentEntry contentEntry = getContentEntry(); + if (contentEntry == null) { return null; } - final SourceFolder[] sourceFolders = myContentEntry.getSourceFolders(); + final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); for (SourceFolder sourceFolder : sourceFolders) { final VirtualFile f = sourceFolder.getFile(); if (f == null) { diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java index 85606fb85ece..f8d09d474f24 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java @@ -62,25 +62,26 @@ public abstract class ContentRootPanel extends JPanel { private static final Icon DELETE_FOLDER_ICON = IconLoader.getIcon("/modules/deleteContentFolder.png"); private static final Icon DELETE_FOLDER_ROLLOVER_ICON = IconLoader.getIcon("/modules/deleteContentFolderRollover.png"); - protected final ContentEntry myContentEntry; protected final ActionCallback myCallback; private JComponent myHeader; private JComponent myBottom; private final Map myComponentToForegroundMap = new HashMap(); - public static interface ActionCallback { + public interface ActionCallback { void deleteContentEntry(); void deleteContentFolder(ContentEntry contentEntry, ContentFolder contentFolder); void navigateFolder(ContentEntry contentEntry, ContentFolder contentFolder); void setPackagePrefix(SourceFolder folder, String prefix); } - public ContentRootPanel(ContentEntry contentEntry, ActionCallback callback) { + public ContentRootPanel(ActionCallback callback) { super(new GridBagLayout()); - myContentEntry = contentEntry; myCallback = callback; } + @Nullable + protected abstract ContentEntry getContentEntry(); + public void initUI() { myHeader = createHeader(); this.add(myHeader, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 8, 0), 0, 0)); @@ -98,10 +99,10 @@ public abstract class ContentRootPanel extends JPanel { private JComponent createHeader() { final JPanel panel = new JPanel(new GridBagLayout()); - final JLabel headerLabel = new JLabel(toDisplayPath(myContentEntry.getUrl())); + final JLabel headerLabel = new JLabel(toDisplayPath(getContentEntry().getUrl())); headerLabel.setFont(headerLabel.getFont().deriveFont(Font.BOLD)); headerLabel.setOpaque(false); - if (myContentEntry.getFile() == null) { + if (getContentEntry().getFile() == null) { headerLabel.setForeground(Color.RED); } final IconActionComponent deleteIconComponent = new IconActionComponent(DELETE_ROOT_ICON, DELETE_ROOT_ROLLOVER_ICON, @@ -163,7 +164,7 @@ public abstract class ContentRootPanel extends JPanel { private JComponent createFolderComponent(final ContentFolder folder, Color foreground) { final VirtualFile folderFile = folder.getFile(); - final VirtualFile contentEntryFile = myContentEntry.getFile(); + final VirtualFile contentEntryFile = getContentEntry().getFile(); final String packagePrefix = folder instanceof SourceFolder? ((SourceFolder)folder).getPackagePrefix() : ""; if (folderFile != null && contentEntryFile != null) { String path = folderFile.equals(contentEntryFile)? "." :VfsUtil.getRelativePath(folderFile, contentEntryFile, File.separatorChar); @@ -174,14 +175,14 @@ public abstract class ContentRootPanel extends JPanel { hyperlinkLabel.setMinimumSize(new Dimension(0, 0)); hyperlinkLabel.addHyperlinkListener(new HyperlinkListener() { public void hyperlinkUpdate(HyperlinkEvent e) { - myCallback.navigateFolder(myContentEntry, folder); + myCallback.navigateFolder(getContentEntry(), folder); } }); registerTextComponent(hyperlinkLabel, foreground); return new UnderlinedPathLabel(hyperlinkLabel); } else { - String path = toRelativeDisplayPath(folder.getUrl(), myContentEntry.getUrl()); + String path = toRelativeDisplayPath(folder.getUrl(), getContentEntry().getUrl()); if (packagePrefix.length() > 0) { path = path + " (" + packagePrefix + ")"; } @@ -195,7 +196,7 @@ public abstract class ContentRootPanel extends JPanel { private JComponent createFolderDeleteComponent(final ContentFolder folder) { final String tooltipText; - if (folder.getFile() != null && myContentEntry.getFile() != null) { + if (folder.getFile() != null && getContentEntry().getFile() != null) { if (folder instanceof SourceFolder) { tooltipText = ((SourceFolder)folder).isTestSource() ? ProjectBundle.message("module.paths.unmark.tests.tooltip") @@ -213,7 +214,7 @@ public abstract class ContentRootPanel extends JPanel { } return new IconActionComponent(DELETE_FOLDER_ICON, DELETE_FOLDER_ROLLOVER_ICON, tooltipText, new Runnable() { public void run() { - myCallback.deleteContentFolder(myContentEntry, folder); + myCallback.deleteContentFolder(getContentEntry(), folder); } }); } @@ -223,10 +224,11 @@ public abstract class ContentRootPanel extends JPanel { } public boolean isUnderExcludedDirectory(final VirtualFile file) { - if (myContentEntry == null) { + final ContentEntry contentEntry = getContentEntry(); + if (contentEntry == null) { return false; } - final ExcludeFolder[] excludeFolders = myContentEntry.getExcludeFolders(); + final ExcludeFolder[] excludeFolders = contentEntry.getExcludeFolders(); for (ExcludeFolder excludeFolder : excludeFolders) { final VirtualFile excludedDir = excludeFolder.getFile(); if (excludedDir == null) { @@ -239,11 +241,13 @@ public abstract class ContentRootPanel extends JPanel { return false; } + @Nullable public ExcludeFolder getExcludeFolder(VirtualFile file) { - if (myContentEntry == null) { + final ContentEntry contentEntry = getContentEntry(); + if (contentEntry == null) { return null; } - final ExcludeFolder[] excludeFolders = myContentEntry.getExcludeFolders(); + final ExcludeFolder[] excludeFolders = contentEntry.getExcludeFolders(); for (final ExcludeFolder excludeFolder : excludeFolders) { final VirtualFile f = excludeFolder.getFile(); if (f == null) { From 8f0124a8c4cd4e65eac687b020755f370c7873a4 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Mon, 19 Oct 2009 19:55:17 +0400 Subject: [PATCH 07/14] modifiable root model: fix libraries --- .../ProjectStructureConfigurable.java | 3 +- .../BaseLibrariesConfigurable.java | 14 ++++---- .../BaseStructureConfigurable.java | 7 ++-- .../projectRoot/LibrariesModifiableModel.java | 32 ++++++++++++------- .../StructureConfigurableContext.java | 7 ++-- 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java index 3abc96473c9a..8b0433e65354 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java @@ -268,7 +268,6 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se } myContext.getDaemonAnalyzer().clearCaches(); - myContext.resetLibraries(); } public void reset() { @@ -319,7 +318,7 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se for (Configurable each : myName2Config) { each.disposeUIResources(); } - + myContext.clear(); myName2Config.clear(); myModuleConfigurator.getFacetsConfigurator().clearMaps(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java index 9c91062c1b97..4377f3a0e5af 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseLibrariesConfigurable.java @@ -27,12 +27,14 @@ import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.impl.libraries.LibraryImpl; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; -import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; import com.intellij.openapi.roots.ui.configuration.LibraryTableModifiableModelProvider; import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryTableEditor; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.LibraryProjectStructureElement; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement; -import com.intellij.openapi.ui.*; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.NamedConfigurable; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -96,8 +98,7 @@ public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurabl } protected void loadTree() { - final LibraryTable libraryTable = LibraryTablesRegistrar.getInstance().getLibraryTableByLevel(myLevel, myProject); - createLibrariesNode(myContext.createModifiableModelProvider(myLevel, false), new LibrariesModifiableModel(libraryTable, myProject)); + createLibrariesNode(myContext.createModifiableModelProvider(myLevel, false)); } @NotNull @@ -117,8 +118,8 @@ public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurabl return result; } - private void createLibrariesNode(final LibraryTableModifiableModelProvider modelProvider, final LibrariesModifiableModel provider) { - final Library[] libraries = provider.getLibraries(); + private void createLibrariesNode(final LibraryTableModifiableModelProvider modelProvider) { + final Library[] libraries = modelProvider.getModifiableModel().getLibraries(); for (Library library : libraries) { myRoot.add(new MyNode(new LibraryConfigurable(modelProvider, library, myProject, TREE_UPDATER))); } @@ -159,7 +160,6 @@ public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurabl } public void dispose() { - myContext.myLevel2Providers.clear(); } protected AnAction createCopyAction() { 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 ba5f858e6add..374b6eaa0cbe 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 @@ -38,6 +38,7 @@ import com.intellij.openapi.ui.MasterDetailsComponent; import com.intellij.openapi.ui.NamedConfigurable; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Disposer; import com.intellij.packaging.artifacts.Artifact; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; @@ -208,11 +209,7 @@ public abstract class BaseStructureConfigurable extends MasterDetailsComponent i myAutoScrollHandler.cancelAllRequests(); - SwingUtilities.invokeLater(new Runnable() { - public void run() { - dispose(); - } - }); + Disposer.dispose(this); } protected void addCollapseExpandActions(final List result) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesModifiableModel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesModifiableModel.java index 769d7455c914..1069297a465f 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesModifiableModel.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesModifiableModel.java @@ -35,16 +35,17 @@ public class LibrariesModifiableModel implements LibraryTable.ModifiableModel { private final Map myLibrary2EditorMap = new HashMap(); private final Set myRemovedLibraries = new HashSet(); - private final LibraryTable.ModifiableModel myLibrariesModifiableModel; + private LibraryTable.ModifiableModel myLibrariesModifiableModel; private final Project myProject; + private LibraryTable myTable; public LibrariesModifiableModel(final LibraryTable table, final Project project) { myProject = project; - myLibrariesModifiableModel = table.getModifiableModel(); + myTable = table; } public Library createLibrary(String name) { - final Library library = myLibrariesModifiableModel.createLibrary(name); + final Library library = getLibrariesModifiableModel().createLibrary(name); //createLibraryEditor(library); final BaseLibrariesConfigurable configurable = ProjectStructureConfigurable.getInstance(myProject).getConfigurableFor(library); configurable.createLibraryNode(library); @@ -52,11 +53,11 @@ public class LibrariesModifiableModel implements LibraryTable.ModifiableModel { } public void removeLibrary(@NotNull Library library) { - if (myLibrariesModifiableModel.getLibraryByName(library.getName()) == null) return; + if (getLibrariesModifiableModel().getLibraryByName(library.getName()) == null) return; myRemovedLibraries.add(library); removeLibraryEditor(library); - myLibrariesModifiableModel.removeLibrary(library); + getLibrariesModifiableModel().removeLibrary(library); } public void commit() { @@ -65,31 +66,32 @@ public class LibrariesModifiableModel implements LibraryTable.ModifiableModel { @NotNull public Iterator getLibraryIterator() { - return myLibrariesModifiableModel.getLibraryIterator(); + return getLibrariesModifiableModel().getLibraryIterator(); } public Library getLibraryByName(@NotNull String name) { - return myLibrariesModifiableModel.getLibraryByName(name); + return getLibrariesModifiableModel().getLibraryByName(name); } @NotNull public Library[] getLibraries() { - return myLibrariesModifiableModel.getLibraries(); + return getLibrariesModifiableModel().getLibraries(); } public boolean isChanged() { for (LibraryEditor libraryEditor : myLibrary2EditorMap.values()) { if (libraryEditor.hasChanges()) return true; } - return myLibrariesModifiableModel.isChanged(); + return getLibrariesModifiableModel().isChanged(); } public void deferredCommit(){ for (LibraryEditor libraryEditor : new ArrayList(myLibrary2EditorMap.values())) { - libraryEditor.commit(); + libraryEditor.commit(); // TODO: is seems like commit will recreate the editor, but it should not } if (!(myLibrary2EditorMap.isEmpty() && myRemovedLibraries.isEmpty())) { - myLibrariesModifiableModel.commit(); + getLibrariesModifiableModel().commit(); + myLibrariesModifiableModel = null; } myLibrary2EditorMap.clear(); myRemovedLibraries.clear(); @@ -136,4 +138,12 @@ public class LibrariesModifiableModel implements LibraryTable.ModifiableModel { public Library.ModifiableModel getLibraryModifiableModel(final Library library) { return getLibraryEditor(library).getModel(); } + + private LibraryTable.ModifiableModel getLibrariesModifiableModel() { + if (myLibrariesModifiableModel == null) { + myLibrariesModifiableModel = myTable.getModifiableModel(); + } + + return myLibrariesModifiableModel; + } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java index c8a45db598b7..5b17b815e8ed 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/StructureConfigurableContext.java @@ -129,7 +129,6 @@ public class StructureConfigurableContext implements Disposable { @Nullable public Library getLibrary(final String libraryName, final String libraryLevel) { /* the null check is added only to prevent NPE when called from getLibrary */ - if (myLevel2Providers.isEmpty()) resetLibraries(); final LibrariesModifiableModel model = myLevel2Providers.get(libraryLevel); return model == null ? null : findLibraryModel(libraryName, model); } @@ -149,8 +148,12 @@ public class StructureConfigurableContext implements Disposable { public void reset() { - myDaemonAnalyzer.reset(); resetLibraries(); myModulesConfigurator.resetModuleEditors(); + myDaemonAnalyzer.reset(); // should be called after resetLibraries! + } + + public void clear() { + myLevel2Providers.clear(); } } \ No newline at end of file From 0c2deecd406913485c13a228de801b6b2b745939 Mon Sep 17 00:00:00 2001 From: Alexander Doroshko Date: Mon, 19 Oct 2009 20:29:53 +0400 Subject: [PATCH 08/14] update HierarchyNodeDescriptors before sorting --- .../codeInsight/hierarchy/HierarchyViewTestBase.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java b/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java index 6e9ed3895605..249b5125bdd9 100755 --- a/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java +++ b/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java @@ -31,13 +31,14 @@ public abstract class HierarchyViewTestBase extends CodeInsightTestCase { } private static void checkHierarchyTreeStructure(final HierarchyTreeStructure treeStructure, final Document document) { - checkNodeDescriptorRecursively(treeStructure, (HierarchyNodeDescriptor)treeStructure.getRootElement(), document.getRootElement()); + final HierarchyNodeDescriptor rootNodeDescriptor = (HierarchyNodeDescriptor)treeStructure.getRootElement(); + rootNodeDescriptor.update(); + checkNodeDescriptorRecursively(treeStructure, rootNodeDescriptor, document.getRootElement()); } private static void checkNodeDescriptorRecursively(final HierarchyTreeStructure treeStructure, final HierarchyNodeDescriptor descriptor, final Element expectedElement) { - descriptor.update(); checkBaseNode(treeStructure, descriptor, expectedElement); checkContent(descriptor, expectedElement); checkChildren(treeStructure, descriptor, expectedElement); @@ -64,6 +65,10 @@ public abstract class HierarchyViewTestBase extends CodeInsightTestCase { final List expectedChildren = new ArrayList(element.getChildren()); assertEquals("Children of " + descriptor.getHighlightedText().getText(), expectedChildren.size(), children.length); + for (Object child : children) { + ((HierarchyNodeDescriptor)child).update(); + } + Arrays.sort(children, new Comparator() { public int compare(final Object first, final Object second) { return ((HierarchyNodeDescriptor)first).getHighlightedText().getText() From 21c828e805ef014c2b3102f4351a2cbbbcf0c86c Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Mon, 19 Oct 2009 21:23:28 +0400 Subject: [PATCH 09/14] Optimization: check if the list is sorted while checking the list for invalid elements. --- .../openapi/editor/impl/HighlighterList.java | 16 ++++++++++++++-- .../com/intellij/util/containers/SortedList.java | 4 ++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/HighlighterList.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/HighlighterList.java index 68fba2652284..a4d0e8bcd8f0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/HighlighterList.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/HighlighterList.java @@ -26,19 +26,30 @@ import java.util.Iterator; import java.util.List; public abstract class HighlighterList { - private final List mySegmentHighlighters = new SortedList(MY_RANGE_COMPARATOR) { + private final SortedList mySegmentHighlighters = new SortedList(MY_RANGE_COMPARATOR) { @Override protected void sort(List delegate) { Iterator it = delegate.iterator(); + boolean needSort = false; + RangeHighlighterImpl lastHighlighter = null; while (it.hasNext()) { RangeHighlighterImpl highlighter = it.next(); if (!highlighter.isValid()) { + needSort = true; it.remove(); } + + if (lastHighlighter != null) { + if (!needSort) needSort = MY_RANGE_COMPARATOR.compare(lastHighlighter, highlighter) > 0; + } + + lastHighlighter = highlighter; } - super.sort(delegate); + if (needSort) { + super.sort(delegate); + } } }; @@ -65,6 +76,7 @@ public abstract class HighlighterList { myDocumentListener = new DocumentAdapter() { public void documentChanged(DocumentEvent e) { myIsDirtied = true; + mySegmentHighlighters.markDirty(); } }; myDoc = doc; diff --git a/platform/util/src/com/intellij/util/containers/SortedList.java b/platform/util/src/com/intellij/util/containers/SortedList.java index 9e915645d95a..f5233320daed 100644 --- a/platform/util/src/com/intellij/util/containers/SortedList.java +++ b/platform/util/src/com/intellij/util/containers/SortedList.java @@ -63,6 +63,10 @@ public class SortedList extends AbstractList{ } } + public void markDirty() { + mySorted = false; + } + protected void sort(List delegate) { Collections.sort(myDelegate, myComparator); } From 29ad3e617c4c8252d4af5488b4612db01bfe4c8f Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 15 Oct 2009 17:37:53 +0400 Subject: [PATCH 10/14] extract method: break&continue statements inside selected cycle should not treated as exit statements from method --- .../psi/controlFlow/ControlFlowUtil.java | 16 +++++++++++++--- .../extractMethod/ContinueInside.java | 12 ++++++++++++ .../extractMethod/ContinueInside_after.java | 17 +++++++++++++++++ .../intellij/refactoring/ExtractMethodTest.java | 6 +++++- 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/refactoring/extractMethod/ContinueInside.java create mode 100644 java/java-tests/testData/refactoring/extractMethod/ContinueInside_after.java diff --git a/java/java-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java b/java/java-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java index a751630b5bb5..d85b2e576931 100644 --- a/java/java-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java +++ b/java/java-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java @@ -264,7 +264,7 @@ public class ControlFlowUtil { } @Override public void visitBranchingInstruction(BranchingInstruction instruction, int offset, int nextOffset) { - processGoto(flow, start, end, exitPoints, exitStatements, instruction.offset, classesFilter, findStatement(flow, offset)); + processGoto(flow, start, end, exitPoints, exitStatements, instruction, classesFilter, findStatement(flow, offset)); } // call/return do not incur exit points @@ -297,8 +297,9 @@ public class ControlFlowUtil { private static void processGoto(ControlFlow flow, int start, int end, IntArrayList exitPoints, - Collection exitStatements, int gotoOffset, Class[] classesFilter, final PsiStatement statement) { + Collection exitStatements, BranchingInstruction instruction, Class[] classesFilter, final PsiStatement statement) { if (statement == null) return; + int gotoOffset = instruction.offset; if (start > gotoOffset || gotoOffset >= end || isElementOfClass(statement, classesFilter)) { // process chain of goto's gotoOffset = promoteThroughGotoChain(flow, gotoOffset); @@ -306,7 +307,16 @@ public class ControlFlowUtil { if (!exitPoints.contains(gotoOffset) && (gotoOffset >= end || gotoOffset < start)) { exitPoints.add(gotoOffset); } - processGotoStatement(classesFilter, exitStatements, statement); + if (gotoOffset >= end || gotoOffset < start) { + processGotoStatement(classesFilter, exitStatements, statement); + } else { + boolean isReturn = instruction instanceof GoToInstruction && ((GoToInstruction)instruction).isReturn; + final Instruction gotoInstruction = flow.getInstructions().get(gotoOffset); + isReturn |= gotoInstruction instanceof GoToInstruction && ((GoToInstruction)gotoInstruction).isReturn; + if (isReturn) { + processGotoStatement(classesFilter, exitStatements, statement); + } + } } } diff --git a/java/java-tests/testData/refactoring/extractMethod/ContinueInside.java b/java/java-tests/testData/refactoring/extractMethod/ContinueInside.java new file mode 100644 index 000000000000..892e22d93a9c --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/ContinueInside.java @@ -0,0 +1,12 @@ +class Test { + String foo(String[] args) { + + for(String arg : args) { + if (arg == null) continue; + System.out.println(arg); + } + if (args.length == 0) return null; + + return null; + } +} diff --git a/java/java-tests/testData/refactoring/extractMethod/ContinueInside_after.java b/java/java-tests/testData/refactoring/extractMethod/ContinueInside_after.java new file mode 100644 index 000000000000..a8e17f76c123 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/ContinueInside_after.java @@ -0,0 +1,17 @@ +class Test { + String foo(String[] args) { + + if (newMethod(args)) return null; + + return null; + } + + private boolean newMethod(String[] args) { + for(String arg : args) { + if (arg == null) continue; + System.out.println(arg); + } + if (args.length == 0) return true; + return false; + } +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java index 6602b68e390b..7a39171d37ce 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java @@ -74,6 +74,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase { doExitPointsTest(false); } + public void testContinueInside() throws Exception { + doTest(); + } + public void testBooleanExpression() throws Exception { doTest(); } @@ -496,4 +500,4 @@ public class ExtractMethodTest extends LightCodeInsightTestCase { return true; } -} \ No newline at end of file +} From 373fa2287c9727882cbddaf648d90a7bdd7b9485 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 16 Oct 2009 12:46:01 +0400 Subject: [PATCH 11/14] clear sorting tag if collection is modified --- platform/util/src/com/intellij/util/containers/SortedList.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/util/src/com/intellij/util/containers/SortedList.java b/platform/util/src/com/intellij/util/containers/SortedList.java index f5233320daed..f2a88eb6acd7 100644 --- a/platform/util/src/com/intellij/util/containers/SortedList.java +++ b/platform/util/src/com/intellij/util/containers/SortedList.java @@ -37,11 +37,13 @@ public class SortedList extends AbstractList{ @Override public T remove(final int index) { + mySorted = false; return myDelegate.remove(index); } @Override public boolean remove(Object o) { + mySorted = false; ensureSorted(); final int i = Collections.binarySearch(myDelegate, (T)o, myComparator); if (i >= 0) { From a9a83720824945a32fcf65b1f378073b16139f24 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 16 Oct 2009 14:29:15 +0400 Subject: [PATCH 12/14] move static members with static non-demand imports to preseve non-demand (IDEADEV-40862) --- .../move/moveMembers/MoveJavaMemberHandler.java | 10 +++++----- .../refactoring/util/RefactoringUtil.java | 15 +++++++++++++++ .../moveMembers/explicitStaticImport/after/A.java | 7 +++++++ .../moveMembers/explicitStaticImport/after/B.java | 3 +++ .../moveMembers/explicitStaticImport/after/C.java | 2 ++ .../explicitStaticImport/before/A.java | 7 +++++++ .../explicitStaticImport/before/B.java | 2 ++ .../explicitStaticImport/before/C.java | 3 +++ .../com/intellij/refactoring/MoveMembersTest.java | 4 ++++ 9 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/after/A.java create mode 100644 java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/after/B.java create mode 100644 java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/after/C.java create mode 100644 java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/before/A.java create mode 100644 java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/before/B.java create mode 100644 java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/before/C.java diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java index b3e99edc2b93..c6cbb328dcd3 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java @@ -71,7 +71,7 @@ public class MoveJavaMemberHandler implements MoveMemberHandler { return null; } - private boolean isInMovedElement(PsiElement element, Set membersToMove) { + private static boolean isInMovedElement(PsiElement element, Set membersToMove) { for (PsiMember member : membersToMove) { if (PsiTreeUtil.isAncestor(member, element, false)) return true; } @@ -86,7 +86,7 @@ public class MoveJavaMemberHandler implements MoveMemberHandler { PsiExpression qualifier = refExpr.getQualifierExpression(); if (qualifier != null) { if (usage.qualifierClass != null) { - changeQualifier(refExpr, usage.qualifierClass); + changeQualifier(refExpr, usage.qualifierClass, usage.member); } else { refExpr.setQualifierExpression(null); @@ -94,7 +94,7 @@ public class MoveJavaMemberHandler implements MoveMemberHandler { } else { // no qualifier if (usage.qualifierClass != null) { - changeQualifier(refExpr, usage.qualifierClass); + changeQualifier(refExpr, usage.qualifierClass, usage.member); } } return true; @@ -136,11 +136,11 @@ public class MoveJavaMemberHandler implements MoveMemberHandler { ChangeContextUtil.decodeContextInfo(scope, null, null); } - private void changeQualifier(PsiReferenceExpression refExpr, PsiClass aClass) throws IncorrectOperationException { + private static void changeQualifier(PsiReferenceExpression refExpr, PsiClass aClass, PsiMember member) throws IncorrectOperationException { if (RefactoringUtil.hasOnDemandStaticImport(refExpr, aClass)) { refExpr.setQualifierExpression(null); } - else { + else if (!RefactoringUtil.hasStaticImportOn(refExpr, member.getContainingClass(), member)){ PsiElementFactory factory = JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory(); refExpr.setQualifierExpression(factory.createReferenceExpression(aClass)); } diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java index bf5f069f3bbd..520dcbca2446 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java @@ -224,6 +224,21 @@ public class RefactoringUtil { return false; } + public static boolean hasStaticImportOn(final PsiReferenceExpression expr, final PsiClass aClass, final PsiMember member) { + if (expr.getContainingFile() instanceof PsiJavaFile) { + final PsiImportList importList = ((PsiJavaFile)expr.getContainingFile()).getImportList(); + if (importList != null) { + final PsiImportStaticStatement[] importStaticStatements = importList.getImportStaticStatements(); + for(PsiImportStaticStatement stmt: importStaticStatements) { + if (!stmt.isOnDemand() && stmt.resolveTargetClass() == aClass && Comparing.strEqual(stmt.getReferenceName(), member.getName())) { + return true; + } + } + } + } + return false; + } + public static PsiElement replaceElementsWithMap(PsiElement replaceIn, final Map elementsToReplace) throws IncorrectOperationException { for(Map.Entry e: elementsToReplace.entrySet()) { if (e.getKey() == replaceIn) { diff --git a/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/after/A.java b/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/after/A.java new file mode 100644 index 000000000000..87b235aa59c4 --- /dev/null +++ b/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/after/A.java @@ -0,0 +1,7 @@ +import static B.Z; + +public class A { + public static void main(String[] args) { + System.out.println("Z = " + Z); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/after/B.java b/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/after/B.java new file mode 100644 index 000000000000..b8f95e54521b --- /dev/null +++ b/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/after/B.java @@ -0,0 +1,3 @@ +public class B { + public static final String Z = "z"; +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/after/C.java b/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/after/C.java new file mode 100644 index 000000000000..f5ef01c9cadf --- /dev/null +++ b/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/after/C.java @@ -0,0 +1,2 @@ +public class C { +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/before/A.java b/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/before/A.java new file mode 100644 index 000000000000..5b919addb09b --- /dev/null +++ b/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/before/A.java @@ -0,0 +1,7 @@ +import static C.Z; + +public class A { + public static void main(String[] args) { + System.out.println("Z = " + Z); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/before/B.java b/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/before/B.java new file mode 100644 index 000000000000..ebbe4dc08cb2 --- /dev/null +++ b/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/before/B.java @@ -0,0 +1,2 @@ +public class B { +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/before/C.java b/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/before/C.java new file mode 100644 index 000000000000..a2d0e76e213b --- /dev/null +++ b/java/java-tests/testData/refactoring/moveMembers/explicitStaticImport/before/C.java @@ -0,0 +1,3 @@ +public class C { + public static final String Z = "z"; +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MoveMembersTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MoveMembersTest.java index c83b33c99492..a1a50b4cc934 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/MoveMembersTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/MoveMembersTest.java @@ -69,6 +69,10 @@ public class MoveMembersTest extends MultiFileTestCase { doTest("C", "B", 0); } + public void testExplicitStaticImport() throws Exception { + doTest("C", "B", 0); + } + public void testProtectedConstructor() throws Exception { doTest("pack1.A", "pack1.C", 0); } From 113efc1bd8d42853529975dbdc945af49b9f14a7 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 19 Oct 2009 20:19:18 +0400 Subject: [PATCH 13/14] push down: static import preserve (IDEADEV-33557) --- .../source/tree/JavaChangeUtilSupport.java | 3 +- .../tree/java/PsiReferenceExpressionImpl.java | 4 + .../memberPushDown/PushDownConflicts.java | 21 +++-- .../memberPushDown/PushDownProcessor.java | 24 +++++- .../moveMembers/MoveJavaMemberHandler.java | 2 +- .../refactoring/util/RefactoringUtil.java | 4 +- .../innerclassReference/after/Test.java | 4 +- .../staticImports/after/p1/Usage.java | 4 +- .../staticImportOfPushedMethod/after/a/A.java | 3 + .../staticImportOfPushedMethod/after/b/B.java | 7 ++ .../staticImportOfPushedMethod/after/u/U.java | 7 ++ .../before/a/A.java | 5 ++ .../before/b/B.java | 4 + .../before/u/U.java | 7 ++ .../after/a/A.java | 4 + .../after/b/B.java | 9 ++ .../after/u/U.java | 4 + .../before/a/A.java | 7 ++ .../before/b/B.java | 4 + .../before/u/U.java | 4 + .../refactoring/PushDownImportsTest.java | 82 +++++++++++++++++++ 21 files changed, 199 insertions(+), 14 deletions(-) create mode 100644 java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/after/a/A.java create mode 100644 java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/after/b/B.java create mode 100644 java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/after/u/U.java create mode 100644 java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/before/a/A.java create mode 100644 java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/before/b/B.java create mode 100644 java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/before/u/U.java create mode 100644 java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/after/a/A.java create mode 100644 java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/after/b/B.java create mode 100644 java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/after/u/U.java create mode 100644 java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/before/a/A.java create mode 100644 java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/before/b/B.java create mode 100644 java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/before/u/U.java create mode 100644 java/java-tests/testSrc/com/intellij/refactoring/PushDownImportsTest.java diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaChangeUtilSupport.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaChangeUtilSupport.java index 6eab2b61a584..1bc212c954c8 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaChangeUtilSupport.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaChangeUtilSupport.java @@ -282,11 +282,12 @@ public class JavaChangeUtilSupport implements TreeGenerator, TreeCopyHandler { else { final PsiMember refMember = element.getCopyableUserData(REFERENCED_MEMBER_KEY); if (refMember != null) { + LOG.assertTrue(ref instanceof PsiReferenceExpression); element.putCopyableUserData(REFERENCED_MEMBER_KEY, null); PsiElement refElement1 = ref.resolve(); if (refMember != refElement1 && !refMember.getManager().areElementsEquivalent(refMember, refElement1)) { try { - ref = (PsiJavaCodeReferenceElement) ref.bindToElement(refMember); + ref = (PsiJavaCodeReferenceElement) ((PsiReferenceExpression)ref).bindToElementViaStaticImport(refMember.getContainingClass()); } catch (IncorrectOperationException e) { // TODO[yole] ignore? diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java index 5e8813b0a266..8cb2b20f6a6f 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java @@ -84,6 +84,10 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements if (getQualifierExpression() != null) { throw new IncorrectOperationException("Reference is qualified: "+getText()); } + if (!isPhysical()) { + // don't qualify reference: the isReferenceTo() check fails anyway, whether we have a static import for this member or not + return this; + } String staticName = getReferenceName(); PsiFile containingFile = getContainingFile(); PsiImportList importList = null; diff --git a/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java b/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java index 2450af3dcc64..c233598aa2d6 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownConflicts.java @@ -71,7 +71,7 @@ public class PushDownConflicts { } } - public void checkTargetClassConflicts(PsiClass targetClass) { + public void checkTargetClassConflicts(PsiClass targetClass, boolean checkStatic) { for (final PsiMember movedMember : myMovedMembers) { checkMemberPlacementInTargetClassConflict(targetClass, movedMember); } @@ -84,13 +84,24 @@ public class PushDownConflicts { final PsiExpression qualifier = referenceExpression.getQualifierExpression(); if (qualifier != null) { final PsiType qualifierType = qualifier.getType(); + PsiClass aClass = null; if (qualifierType instanceof PsiClassType) { - final PsiClass aClass = ((PsiClassType)qualifierType).resolve(); - if (!InheritanceUtil.isInheritorOrSelf(aClass, targetClass, true)) { - myConflicts.putValue(aClass, RefactoringBundle.message("pushed.members.will.not.be.visible.from.certain.call.sites")); - break Members; + aClass = ((PsiClassType)qualifierType).resolve(); + } + else { + if (!checkStatic) continue; + if (qualifier instanceof PsiReferenceExpression) { + final PsiElement resolved = ((PsiReferenceExpression)qualifier).resolve(); + if (resolved instanceof PsiClass) { + aClass = (PsiClass)resolved; + } } } + + if (!InheritanceUtil.isInheritorOrSelf(aClass, targetClass, true)) { + myConflicts.putValue(aClass, RefactoringBundle.message("pushed.members.will.not.be.visible.from.certain.call.sites")); + break Members; + } } } } diff --git a/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownProcessor.java b/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownProcessor.java index 332c64846a52..d365bba88e98 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPushDown/PushDownProcessor.java @@ -23,6 +23,7 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; +import com.intellij.psi.impl.source.codeStyle.JavaCodeStyleManagerImpl; import com.intellij.psi.search.searches.ClassInheritorsSearch; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; @@ -41,6 +42,8 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; import java.util.Set; public class PushDownProcessor extends BaseRefactoringProcessor { @@ -93,7 +96,7 @@ public class PushDownProcessor extends BaseRefactoringProcessor { for (UsageInfo usage : usagesIn) { final PsiElement element = usage.getElement(); if (element instanceof PsiClass) { - pushDownConflicts.checkTargetClassConflicts((PsiClass)element); + pushDownConflicts.checkTargetClassConflicts((PsiClass)element, usagesIn.length > 1); } } @@ -318,6 +321,22 @@ public class PushDownProcessor extends BaseRefactoringProcessor { } for (MemberInfo memberInfo : myMemberInfos) { final PsiMember member = memberInfo.getMember(); + final List refsToRebind = new ArrayList(); + final PsiModifierList list = member.getModifierList(); + LOG.assertTrue(list != null); + if (list.hasModifierProperty(PsiModifier.STATIC)) { + for (final PsiReference reference : ReferencesSearch.search(member)) { + final PsiElement element = reference.getElement(); + if (element instanceof PsiReferenceExpression) { + final PsiExpression qualifierExpression = ((PsiReferenceExpression)element).getQualifierExpression(); + if (qualifierExpression instanceof PsiReferenceExpression && !(((PsiReferenceExpression)qualifierExpression).resolve() instanceof PsiClass)) { + continue; + } + } + refsToRebind.add(reference); + } + } + PsiMember newMember = null; if (member instanceof PsiField) { ((PsiField)member).normalizeDeclaration(); @@ -357,6 +376,9 @@ public class PushDownProcessor extends BaseRefactoringProcessor { if (newMember != null) { decodeRefs(newMember, targetClass); + for (PsiReference psiReference : refsToRebind) { + JavaCodeStyleManagerImpl.getInstance(myProject).shortenClassReferences(psiReference.bindToElement(newMember)); + } final JavaRefactoringListenerManager listenerManager = JavaRefactoringListenerManager.getInstance(newMember.getProject()); ((JavaRefactoringListenerManagerImpl)listenerManager).fireMemberMoved(myClass, newMember); } diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java index c6cbb328dcd3..4bb95d065179 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java @@ -140,7 +140,7 @@ public class MoveJavaMemberHandler implements MoveMemberHandler { if (RefactoringUtil.hasOnDemandStaticImport(refExpr, aClass)) { refExpr.setQualifierExpression(null); } - else if (!RefactoringUtil.hasStaticImportOn(refExpr, member.getContainingClass(), member)){ + else if (!RefactoringUtil.hasStaticImportOn(refExpr, member)){ PsiElementFactory factory = JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory(); refExpr.setQualifierExpression(factory.createReferenceExpression(aClass)); } diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java index 520dcbca2446..2437bc0ef0ce 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java @@ -224,13 +224,13 @@ public class RefactoringUtil { return false; } - public static boolean hasStaticImportOn(final PsiReferenceExpression expr, final PsiClass aClass, final PsiMember member) { + public static boolean hasStaticImportOn(final PsiElement expr, final PsiMember member) { if (expr.getContainingFile() instanceof PsiJavaFile) { final PsiImportList importList = ((PsiJavaFile)expr.getContainingFile()).getImportList(); if (importList != null) { final PsiImportStaticStatement[] importStaticStatements = importList.getImportStaticStatements(); for(PsiImportStaticStatement stmt: importStaticStatements) { - if (!stmt.isOnDemand() && stmt.resolveTargetClass() == aClass && Comparing.strEqual(stmt.getReferenceName(), member.getName())) { + if (!stmt.isOnDemand() && stmt.resolveTargetClass() == member.getContainingClass() && Comparing.strEqual(stmt.getReferenceName(), member.getName())) { return true; } } diff --git a/java/java-tests/testData/refactoring/inlineSuperClass/innerclassReference/after/Test.java b/java/java-tests/testData/refactoring/inlineSuperClass/innerclassReference/after/Test.java index e6944fd23326..a1cb4a0fd266 100644 --- a/java/java-tests/testData/refactoring/inlineSuperClass/innerclassReference/after/Test.java +++ b/java/java-tests/testData/refactoring/inlineSuperClass/innerclassReference/after/Test.java @@ -1,11 +1,11 @@ class Test { public void contextChild() { - Test.StInner inner1 = new Test.StInner(); + StInner inner1 = new StInner(); Test.InstInner inner2 = this.new InstInner(); } void foo() { - Test.StInner inner1 = new Test.StInner(); + StInner inner1 = new StInner(); Test.InstInner inner2 = this.new InstInner(); } diff --git a/java/java-tests/testData/refactoring/inlineToAnonymousClass/multifile/staticImports/after/p1/Usage.java b/java/java-tests/testData/refactoring/inlineToAnonymousClass/multifile/staticImports/after/p1/Usage.java index 33cd4c4d2e7e..205e3f136b28 100644 --- a/java/java-tests/testData/refactoring/inlineToAnonymousClass/multifile/staticImports/after/p1/Usage.java +++ b/java/java-tests/testData/refactoring/inlineToAnonymousClass/multifile/staticImports/after/p1/Usage.java @@ -1,11 +1,11 @@ package p1; -import p2.Statics; +import static p2.Statics.PUB_CONST; public class Usage { public void test() { Object i = new Object() { - public int myInt = Statics.PUB_CONST; + public int myInt = PUB_CONST; }; } } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/after/a/A.java b/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/after/a/A.java new file mode 100644 index 000000000000..7e84311b2f58 --- /dev/null +++ b/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/after/a/A.java @@ -0,0 +1,3 @@ +package a; +public class A { +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/after/b/B.java b/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/after/b/B.java new file mode 100644 index 000000000000..4f246d6d6e75 --- /dev/null +++ b/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/after/b/B.java @@ -0,0 +1,7 @@ +package b; +import a.*; + +public class B extends A { + public static void foo(){ + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/after/u/U.java b/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/after/u/U.java new file mode 100644 index 000000000000..83024532ec02 --- /dev/null +++ b/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/after/u/U.java @@ -0,0 +1,7 @@ +package u; +import static b.B.foo; +public class U { + public static void main(String[] args) { + foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/before/a/A.java b/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/before/a/A.java new file mode 100644 index 000000000000..d801300027dd --- /dev/null +++ b/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/before/a/A.java @@ -0,0 +1,5 @@ +package a; +public class A { + public static void foo(){ + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/before/b/B.java b/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/before/b/B.java new file mode 100644 index 000000000000..3b5dac600a86 --- /dev/null +++ b/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/before/b/B.java @@ -0,0 +1,4 @@ +package b; +import a.*; + +public class B extends A {} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/before/u/U.java b/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/before/u/U.java new file mode 100644 index 000000000000..3e4a0344a325 --- /dev/null +++ b/java/java-tests/testData/refactoring/pushDown/staticImportOfPushedMethod/before/u/U.java @@ -0,0 +1,7 @@ +package u; +import static a.A.foo; +public class U { + public static void main(String[] args) { + foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/after/a/A.java b/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/after/a/A.java new file mode 100644 index 000000000000..eb5ae9fe2af0 --- /dev/null +++ b/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/after/a/A.java @@ -0,0 +1,4 @@ +package a; +import static u.U.C; +public class A { +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/after/b/B.java b/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/after/b/B.java new file mode 100644 index 000000000000..fcc2b89da8d8 --- /dev/null +++ b/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/after/b/B.java @@ -0,0 +1,9 @@ +package b; +import a.*; +import static u.U.C; + +public class B extends A { + public static void foo(){ + System.out.println(C); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/after/u/U.java b/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/after/u/U.java new file mode 100644 index 000000000000..603ed14b7ebe --- /dev/null +++ b/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/after/u/U.java @@ -0,0 +1,4 @@ +package u; +public class U { + public static final String C = "CONSTANT"; +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/before/a/A.java b/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/before/a/A.java new file mode 100644 index 000000000000..905c150e31ea --- /dev/null +++ b/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/before/a/A.java @@ -0,0 +1,7 @@ +package a; +import static u.U.C; +public class A { + public static void foo(){ + System.out.println(C); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/before/b/B.java b/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/before/b/B.java new file mode 100644 index 000000000000..3b5dac600a86 --- /dev/null +++ b/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/before/b/B.java @@ -0,0 +1,4 @@ +package b; +import a.*; + +public class B extends A {} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/before/u/U.java b/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/before/u/U.java new file mode 100644 index 000000000000..603ed14b7ebe --- /dev/null +++ b/java/java-tests/testData/refactoring/pushDown/staticImportsInsidePushedMethod/before/u/U.java @@ -0,0 +1,4 @@ +package u; +public class U { + public static final String C = "CONSTANT"; +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PushDownImportsTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PushDownImportsTest.java new file mode 100644 index 000000000000..fabea7231deb --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/refactoring/PushDownImportsTest.java @@ -0,0 +1,82 @@ +/* + * User: anna + * Date: 20-Aug-2008 + */ +package com.intellij.refactoring; + +import com.intellij.JavaTestUtil; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.memberPushDown.PushDownProcessor; +import com.intellij.refactoring.util.DocCommentPolicy; +import com.intellij.refactoring.util.classMembers.MemberInfo; + +//push first method from class a.A to class b.B +public class PushDownImportsTest extends MultiFileTestCase { + protected String getTestRoot() { + return "/refactoring/pushDown/"; + } + + @Override + protected String getTestDataPath() { + return JavaTestUtil.getJavaTestDataPath(); + } + + protected Sdk getTestProjectJdk() { + return JavaSdkImpl.getMockJdk15("java 1.5"); + } + + private void doTest() throws Exception { + doTest(false); + } + + private void doTest(final boolean fail) throws Exception { + try { + doTest(new PerformAction() { + public void performAction(final VirtualFile rootDir, final VirtualFile rootAfter) throws Exception { + final PsiClass srcClass = myJavaFacade.findClass("a.A"); + assertTrue("Source class not found", srcClass != null); + + final PsiClass targetClass = myJavaFacade.findClass("b.B"); + assertTrue("Target class not found", targetClass != null); + + final PsiMethod[] methods = srcClass.getMethods(); + assertTrue("No methods found", methods.length > 0); + final MemberInfo[] membersToMove = new MemberInfo[1]; + final MemberInfo memberInfo = new MemberInfo(methods[0]); + memberInfo.setChecked(true); + membersToMove[0] = memberInfo; + + new PushDownProcessor(getProject(), membersToMove, srcClass, new DocCommentPolicy(DocCommentPolicy.ASIS)).run(); + + + //LocalFileSystem.getInstance().refresh(false); + //FileDocumentManager.getInstance().saveAllDocuments(); + } + }); + } + catch (RuntimeException e) { + if (fail) { + return; + } + else { + throw e; + } + } + if (fail) { + fail("Conflict was not detected"); + } + } + + + public void testStaticImportsInsidePushedMethod() throws Exception { + doTest(); + } + + public void testStaticImportOfPushedMethod() throws Exception { + doTest(); + } +} \ No newline at end of file From 605515bb262266143c08b864f956176e4bbfd3f7 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 19 Oct 2009 21:33:29 +0400 Subject: [PATCH 14/14] revert --- platform/util/src/com/intellij/util/containers/SortedList.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/platform/util/src/com/intellij/util/containers/SortedList.java b/platform/util/src/com/intellij/util/containers/SortedList.java index f2a88eb6acd7..f5233320daed 100644 --- a/platform/util/src/com/intellij/util/containers/SortedList.java +++ b/platform/util/src/com/intellij/util/containers/SortedList.java @@ -37,13 +37,11 @@ public class SortedList extends AbstractList{ @Override public T remove(final int index) { - mySorted = false; return myDelegate.remove(index); } @Override public boolean remove(Object o) { - mySorted = false; ensureSorted(); final int i = Collections.binarySearch(myDelegate, (T)o, myComparator); if (i >= 0) {