diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibraryRootsComponentForm.form b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibraryRootsComponentForm.form index a93ec4db125b..88a7a26bf53c 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibraryRootsComponentForm.form +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibraryRootsComponentForm.form @@ -1,6 +1,6 @@
- + @@ -11,7 +11,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -98,6 +98,12 @@ + + + + + + diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureDialogCellAppearanceUtils.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureDialogCellAppearanceUtils.java new file mode 100644 index 000000000000..b43b082decea --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureDialogCellAppearanceUtils.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration; + +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.ui.configuration.libraries.LibraryPresentationManager; +import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; +import com.intellij.openapi.roots.ui.util.CellAppearance; +import com.intellij.openapi.roots.ui.util.OrderEntryCellAppearanceUtils; +import com.intellij.openapi.roots.ui.util.SimpleTextCellAppearance; + +import javax.swing.*; + +/** + * @author nik + */ +//todo[nik] extract service from OrderEntryCellAppearanceUtils and use this class as its implementation for idea-ui +public class ProjectStructureDialogCellAppearanceUtils { + + private ProjectStructureDialogCellAppearanceUtils() { + } + + public static CellAppearance forOrderEntry(OrderEntry orderEntry, StructureConfigurableContext context, boolean selected) { + if (orderEntry instanceof LibraryOrderEntry) { + final Library library = ((LibraryOrderEntry)orderEntry).getLibrary(); + if (orderEntry.isValid()) { + return forLibrary(library, context); + } + } + return OrderEntryCellAppearanceUtils.forOrderEntry(orderEntry, selected); + } + + public static CellAppearance forLibrary(Library library, StructureConfigurableContext context) { + final Icon icon = LibraryPresentationManager.getInstance().getCustomIcon(library, context); + if (icon != null) { + final String name = library.getName(); + if (name != null) { + return SimpleTextCellAppearance.normal(name, icon); + } + } + return OrderEntryCellAppearanceUtils.forLibrary(library); + } + +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java index 4368359e1b1b..dd023a9a6d21 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java @@ -18,7 +18,6 @@ package com.intellij.openapi.roots.ui.configuration.classpath; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ex.ApplicationEx; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.StdModuleTypes; import com.intellij.openapi.project.Project; @@ -27,10 +26,7 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; -import com.intellij.openapi.roots.ui.configuration.LibraryTableModifiableModelProvider; -import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState; -import com.intellij.openapi.roots.ui.configuration.ModulesProvider; -import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; +import com.intellij.openapi.roots.ui.configuration.*; import com.intellij.openapi.roots.ui.configuration.dependencyAnalysis.AnalyzeDependenciesDialog; import com.intellij.openapi.roots.ui.configuration.libraryEditor.ChooseModulesDialog; import com.intellij.openapi.roots.ui.configuration.libraryEditor.EditExistingLibraryDialog; @@ -69,8 +65,6 @@ import java.util.List; import java.util.Set; public class ClasspathPanelImpl extends JPanel implements ClasspathPanel { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.classpath.ClasspathPanel"); - private final Table myEntryTable; private final ClasspathTableModel myModel; private final EventDispatcher myListeners = EventDispatcher.create(OrderPanelListener.class); @@ -90,7 +84,7 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel { myEntryTable.setShowVerticalLines(false); myEntryTable.setIntercellSpacing(new Dimension(0, 0)); - myEntryTable.setDefaultRenderer(ClasspathTableItem.class, new TableItemRenderer()); + myEntryTable.setDefaultRenderer(ClasspathTableItem.class, new TableItemRenderer(getStructureConfigurableContext())); myEntryTable.setDefaultRenderer(Boolean.class, new ExportFlagRenderer(myEntryTable.getDefaultRenderer(Boolean.class))); JComboBox scopeEditor = new JComboBox(new EnumComboBoxModel(DependencyScope.class)); @@ -117,7 +111,7 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel { } public String getElementText(Object element) { - return getCellAppearance((ClasspathTableItem)element, false).getText(); + return getCellAppearance((ClasspathTableItem)element, getStructureConfigurableContext(), false).getText(); } public void selectElement(Object element, String selectedText) { @@ -384,7 +378,7 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel { }; } else { - provider = ProjectStructureConfigurable.getInstance(myState.getProject()).getContext().createModifiableModelProvider(table.getTableLevel()); + provider = getStructureConfigurableContext().createModifiableModelProvider(table.getTableLevel()); } EditExistingLibraryDialog dialog = EditExistingLibraryDialog.createDialog(ClasspathPanelImpl.this, provider, library, myState.getProject()); dialog.addFileChooserContext(LangDataKeys.MODULE_CONTEXT, getRootModel().getModule()); @@ -457,11 +451,10 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel { private void initPopupActions() { if (myPopupActions == null) { - final StructureConfigurableContext context = ProjectStructureConfigurable.getInstance(myState.getProject()).getContext(); int actionIndex = 1; final List> actions = new ArrayList>(); actions.add(new AddSingleEntryModuleLibraryAction(this, actionIndex++)); - actions.add(new AddLibraryAction(this, actionIndex++, ProjectBundle.message("classpath.add.library.action"), context)); + actions.add(new AddLibraryAction(this, actionIndex++, ProjectBundle.message("classpath.add.library.action"), getStructureConfigurableContext())); actions.add(new AddItemPopupAction(this, actionIndex, ProjectBundle.message("classpath.add.module.dependency.action"), StdModuleTypes.JAVA.getNodeIcon(false)) { protected ClasspathTableItem createTableItem(final Module item) { @@ -482,6 +475,10 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel { } } + private StructureConfigurableContext getStructureConfigurableContext() { + return ProjectStructureConfigurable.getInstance(myState.getProject()).getContext(); + } + private void enableModelUpdate() { myInsideChange--; @@ -596,24 +593,31 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel { } - private static CellAppearance getCellAppearance(final ClasspathTableItem item, final boolean selected) { + private static CellAppearance getCellAppearance(final ClasspathTableItem item, + StructureConfigurableContext context, + final boolean selected) { if (item instanceof InvalidJdkItem) { return OrderEntryCellAppearanceUtils.forJdk(null, false, selected); } else { - return OrderEntryCellAppearanceUtils.forOrderEntry(item.getEntry(), selected); + return ProjectStructureDialogCellAppearanceUtils.forOrderEntry(item.getEntry(), context, selected); } } private static class TableItemRenderer extends ColoredTableCellRenderer { private final Border NO_FOCUS_BORDER = BorderFactory.createEmptyBorder(1, 1, 1, 1); + private StructureConfigurableContext myContext; + + public TableItemRenderer(StructureConfigurableContext context) { + myContext = context; + } protected void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { setPaintFocusBorder(false); setFocusBorderAroundIcon(true); setBorder(NO_FOCUS_BORDER); if (value instanceof ClasspathTableItem) { - getCellAppearance((ClasspathTableItem)value, selected).customize(this); + getCellAppearance((ClasspathTableItem)value, myContext, selected).customize(this); } } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ProjectStructureChooseLibrariesDialog.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ProjectStructureChooseLibrariesDialog.java index 5079e2769091..7f40e3ccd0a5 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ProjectStructureChooseLibrariesDialog.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ProjectStructureChooseLibrariesDialog.java @@ -20,6 +20,7 @@ import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.ui.configuration.libraries.LibraryPresentationManager; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesModifiableModel; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.util.Condition; @@ -99,15 +100,19 @@ public class ProjectStructureChooseLibrariesDialog extends ChooseLibrariesFromTa protected LibrariesTreeNodeBase createLibraryDescriptor(NodeDescriptor parentDescriptor, Library library) { final String libraryName = getLibraryName(library); - return new LibraryEditorDescriptor(getProject(), parentDescriptor, library, libraryName); + return new LibraryEditorDescriptor(getProject(), parentDescriptor, library, libraryName, myContext); } private static class LibraryEditorDescriptor extends LibrariesTreeNodeBase { protected LibraryEditorDescriptor(final Project project, final NodeDescriptor parentDescriptor, final Library element, - String libraryName) { + String libraryName, StructureConfigurableContext context) { super(project, parentDescriptor, element); final PresentationData templatePresentation = getTemplatePresentation(); - templatePresentation.setIcons(Icons.LIBRARY_ICON); + Icon icon = LibraryPresentationManager.getInstance().getCustomIcon(element, context); + if (icon == null) { + icon = Icons.LIBRARY_ICON; + } + templatePresentation.setIcons(icon); templatePresentation.addText(libraryName, SimpleTextAttributes.REGULAR_ATTRIBUTES); } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/LibraryPresentationManager.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/LibraryPresentationManager.java new file mode 100644 index 000000000000..e0a97bf4e544 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/LibraryPresentationManager.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.libraries; + +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.List; + +/** + * @author nik + */ +public abstract class LibraryPresentationManager { + public static LibraryPresentationManager getInstance() { + return ServiceManager.getService(LibraryPresentationManager.class); + } + + @Nullable + public abstract Icon getCustomIcon(@NotNull Library library, @Nullable StructureConfigurableContext context); + + @NotNull + public abstract List getCustomIcons(@NotNull Library library, @Nullable StructureConfigurableContext context); + + @NotNull + public abstract List getDescriptions(@NotNull Library library, StructureConfigurableContext context); + + @NotNull + public abstract List getDescriptions(@NotNull VirtualFile[] classRoots); +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/LibraryPresentationManagerImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/LibraryPresentationManagerImpl.java new file mode 100644 index 000000000000..645a18aba97a --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/LibraryPresentationManagerImpl.java @@ -0,0 +1,117 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.libraries; + +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.*; +import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesModifiableModel; +import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.SmartList; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author nik + */ +public class LibraryPresentationManagerImpl extends LibraryPresentationManager { + private Map, LibraryPresentationProvider> myPresentationProviders; + + private

LibraryPresentationProvider

getPresentationProvider(LibraryKind

kind) { + if (myPresentationProviders == null) { + final Map, LibraryPresentationProvider> providers = new HashMap, LibraryPresentationProvider>(); + for (LibraryPresentationProvider provider : LibraryPresentationProvider.EP_NAME.getExtensions()) { + providers.put(provider.getKind(), provider); + } + myPresentationProviders = providers; + } + //noinspection unchecked + return (LibraryPresentationProvider

)myPresentationProviders.get(kind); + } + + @Override + public Icon getCustomIcon(@NotNull Library library, StructureConfigurableContext context) { + final List icons = getCustomIcons(library, context); + if (icons.size() == 1) { + return icons.get(0); + } + return null; + } + + @NotNull + @Override + public List getCustomIcons(@NotNull Library library, StructureConfigurableContext context) { + final VirtualFile[] files = getLibraryFiles(library, context); + final List icons = new SmartList(); + LibraryDetectionManager.getInstance().processProperties(Arrays.asList(files), new LibraryDetectionManager.LibraryPropertiesProcessor() { + @Override + public

boolean processProperties(@NotNull LibraryKind

kind, @NotNull P properties) { + final LibraryPresentationProvider

provider = getPresentationProvider(kind); + if (provider != null) { + ContainerUtil.addIfNotNull(icons, provider.getIcon()); + } + return true; + } + }); + return icons; + } + + private static VirtualFile[] getLibraryFiles(Library library, StructureConfigurableContext context) { + if (context != null) { + final LibraryTable table = library.getTable(); + if (table != null) { + final LibraryTable.ModifiableModel modifiableModel = context.getModifiableLibraryTable(table); + if (modifiableModel instanceof LibrariesModifiableModel) { + final LibrariesModifiableModel librariesModel = (LibrariesModifiableModel)modifiableModel; + if (librariesModel.hasLibraryEditor(library)) { + return librariesModel.getLibraryEditor(library).getFiles(OrderRootType.CLASSES); + } + } + } + } + return library.getFiles(OrderRootType.CLASSES); + } + + @NotNull + @Override + public List getDescriptions(@NotNull Library library, StructureConfigurableContext context) { + final VirtualFile[] files = getLibraryFiles(library, context); + return getDescriptions(files); + } + + @NotNull + @Override + public List getDescriptions(@NotNull VirtualFile[] classRoots) { + final SmartList result = new SmartList(); + LibraryDetectionManager.getInstance().processProperties(Arrays.asList(classRoots), new LibraryDetectionManager.LibraryPropertiesProcessor() { + @Override + public

boolean processProperties(@NotNull LibraryKind

kind, @NotNull P properties) { + final LibraryPresentationProvider

provider = getPresentationProvider(kind); + if (provider != null) { + ContainerUtil.addIfNotNull(result, provider.getDescription(properties)); + } + return true; + } + }); + return result; + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/LibraryPresentationProvider.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/LibraryPresentationProvider.java new file mode 100644 index 000000000000..8b902e93a3b7 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/LibraryPresentationProvider.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.libraries; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.roots.libraries.LibraryKind; +import com.intellij.openapi.roots.libraries.LibraryProperties; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** + * @author nik + */ +public abstract class LibraryPresentationProvider

{ + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.library.presentationProvider"); + private final LibraryKind

myKind; + + protected LibraryPresentationProvider(LibraryKind

kind) { + myKind = kind; + } + + public final LibraryKind

getKind() { + return myKind; + } + + @Nullable + public abstract Icon getIcon(); + + @Nullable + public String getDescription(@NotNull P properties) { + return null; + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java index 9e42015fdbd6..5d9ac32c6f1a 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java @@ -36,8 +36,10 @@ import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.libraries.LibraryUtil; import com.intellij.openapi.roots.ui.configuration.ModuleEditor; import com.intellij.openapi.roots.ui.configuration.PathUIUtils; +import com.intellij.openapi.roots.ui.configuration.libraries.LibraryPresentationManager; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesModifiableModel; import com.intellij.openapi.roots.ui.configuration.projectRoot.ModuleStructureConfigurable; +import com.intellij.openapi.ui.ex.MultiLineLabel; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.ListPopup; import com.intellij.openapi.ui.popup.PopupStep; @@ -90,6 +92,7 @@ public class LibraryRootsComponent implements Disposable { private JPanel myTreePanel; private JButton myAttachAnnotationsButton; private JButton myAttachMoreButton; + private MultiLineLabel myPropertiesLabel; private Tree myTree; private LibraryTableTreeBuilder myTreeBuilder; private static final Icon INVALID_ITEM_ICON = IconLoader.getIcon("/nodes/ppInvalid.png"); @@ -101,10 +104,21 @@ public class LibraryRootsComponent implements Disposable { private final Map myFileChooserUserData = new HashMap(); private final LibraryEditor myLibraryEditor; - private LibraryRootsComponent(Project project, - LibraryEditor libraryEditor){ + private LibraryRootsComponent(Project project, LibraryEditor libraryEditor) { myProject = project; myLibraryEditor = libraryEditor; + updateProperties(); + } + + private void updateProperties() { + StringBuilder text = new StringBuilder(); + for (String description : LibraryPresentationManager.getInstance().getDescriptions(myLibraryEditor.getFiles(OrderRootType.CLASSES))) { + if (text.length() > 0) { + text.append("\n"); + } + text.append(description); + } + myPropertiesLabel.setText(text.toString()); } public static LibraryRootsComponent createComponent(final @Nullable Project project, @NotNull LibraryEditor libraryEditor) { @@ -337,6 +351,7 @@ public class LibraryRootsComponent implements Disposable { } } }); + updateProperties(); myTreeBuilder.updateFromRoot(); } return filesToAttach; @@ -491,6 +506,7 @@ public class LibraryRootsComponent implements Disposable { } protected void librariesChanged(boolean putFocusIntoTree) { + updateProperties(); myTreeBuilder.updateFromRoot(); if (putFocusIntoTree) { myTree.requestFocus(); 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 472db8b275a4..77842d8111db 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 @@ -119,7 +119,7 @@ public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurabl private void createLibrariesNode(final StructureLibraryTableModifiableModelProvider modelProvider) { final Library[] libraries = modelProvider.getModifiableModel().getLibraries(); for (Library library : libraries) { - myRoot.add(new MyNode(new LibraryConfigurable(modelProvider, library, myProject, TREE_UPDATER))); + myRoot.add(new MyNode(new LibraryConfigurable(modelProvider, library, myContext, TREE_UPDATER))); } TreeUtil.sort(myRoot, new Comparator() { public int compare(final Object o1, final Object o2) { @@ -147,7 +147,7 @@ public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurabl if (table != null) { final String level = table.getTableLevel(); final LibraryConfigurable configurable = - new LibraryConfigurable(myContext.createModifiableModelProvider(level), library, myProject, TREE_UPDATER); + new LibraryConfigurable(myContext.createModifiableModelProvider(level), library, myContext, TREE_UPDATER); final MyNode node = new MyNode(configurable); addNode(node, myRoot); myContext.getDaemonAnalyzer().queueUpdate(new LibraryProjectStructureElement(myContext, library)); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibraryConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibraryConfigurable.java index 17bd71e6d928..341aefb9dd88 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibraryConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibraryConfigurable.java @@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.ui.configuration.libraries.LibraryPresentationManager; import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryRootsComponent; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.LibraryProjectStructureElement; @@ -41,19 +42,20 @@ public class LibraryConfigurable extends ProjectStructureElementConfigurable, List>> myCache = new HashMap, List>>(); + + @Override + public boolean processProperties(@NotNull List files, @NotNull LibraryPropertiesProcessor processor) { + for (Pair pair : getOrComputeKinds(files)) { + //noinspection unchecked + if (!processor.processProperties(pair.getFirst(), pair.getSecond())) { + return false; + } + } + return true; + } + + private List> getOrComputeKinds(List files) { + List> result = myCache.get(files); + if (result == null) { + result = computeKinds(files); + myCache.put(files, result); + } + return result; + } + + private static List> computeKinds(List files) { + final SmartList> result = new SmartList>(); + for (LibraryDetector detector : LibraryDetector.EP_NAME.getExtensions()) { + final LibraryProperties properties = detector.detect(files); + if (properties != null) { + result.add(Pair.create(detector.getKind(), properties)); + } + } + return result; + } +} diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/DummyLibraryProperties.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/DummyLibraryProperties.java new file mode 100644 index 000000000000..a3a798835b06 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/DummyLibraryProperties.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.libraries; + +/** +* @author nik +*/ +public class DummyLibraryProperties extends LibraryProperties { + public static final DummyLibraryProperties INSTANCE = new DummyLibraryProperties(); + + @Override + public Object getState() { + return null; + } + + @Override + public void loadState(Object state) { + } +} diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryDetectionManager.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryDetectionManager.java new file mode 100644 index 000000000000..78a6473b40f7 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryDetectionManager.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.libraries; + +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author nik + */ +public abstract class LibraryDetectionManager { + public static LibraryDetectionManager getInstance() { + return ServiceManager.getService(LibraryDetectionManager.class); + } + + public abstract boolean processProperties(@NotNull List files, @NotNull LibraryPropertiesProcessor processor); + + public interface LibraryPropertiesProcessor { +

boolean processProperties(@NotNull LibraryKind

kind, @NotNull P properties); + } +} diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryDetector.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryDetector.java new file mode 100644 index 000000000000..d92eb26e4b4f --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryDetector.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.libraries; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * @author nik + */ +public abstract class LibraryDetector

{ + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.library.detector"); + private final LibraryKind

myKind; + + protected LibraryDetector(LibraryKind

kind) { + myKind = kind; + } + + public final LibraryKind

getKind() { + return myKind; + } + + @Nullable + public abstract P detect(@NotNull List classesRoots); +} diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryKind.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryKind.java new file mode 100644 index 000000000000..2ec7ea66f589 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryKind.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.libraries; + +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class LibraryKind

{ + private String myKindId; + + public LibraryKind(@NotNull @NonNls String kindId) { + myKindId = kindId; + } + + public String getKindId() { + return myKindId; + } + + @Override + public String toString() { + return "LibraryKind:" + myKindId; + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsData.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryProperties.java similarity index 68% rename from java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsData.java rename to platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryProperties.java index 6b7bebf62e13..cf81ca8facc6 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsData.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryProperties.java @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.roots.ui.configuration.libraryEditor; +package com.intellij.openapi.roots.libraries; + +import com.intellij.openapi.components.PersistentStateComponent; /** * @author nik */ -public class LibraryRootsData { - +public abstract class LibraryProperties implements PersistentStateComponent { + public static final LibraryProperties DUMMY_PROPERTIES = new DummyLibraryProperties(); } diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 5d58a0045261..390944d9dc96 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -276,6 +276,8 @@ + + + + diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 3c227f3cad34..ee0a133c13a5 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -90,6 +90,8 @@ + + @@ -457,6 +459,8 @@ +