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 7f40e3ccd0a5..4af2475d5b4a 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 @@ -25,7 +25,6 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesModifiab import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.util.Condition; import com.intellij.ui.SimpleTextAttributes; -import com.intellij.util.Icons; import com.intellij.util.ui.classpath.ChooseLibrariesFromTablesDialog; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -108,10 +107,7 @@ public class ProjectStructureChooseLibrariesDialog extends ChooseLibrariesFromTa String libraryName, StructureConfigurableContext context) { super(project, parentDescriptor, element); final PresentationData templatePresentation = getTemplatePresentation(); - Icon icon = LibraryPresentationManager.getInstance().getCustomIcon(element, context); - if (icon == null) { - icon = Icons.LIBRARY_ICON; - } + Icon icon = LibraryPresentationManager.getInstance().getNamedLibraryIcon(element, context); templatePresentation.setIcons(icon); templatePresentation.addText(libraryName, SimpleTextAttributes.REGULAR_ATTRIBUTES); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/AddExistingCustomLibraryAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/AddExistingCustomLibraryAction.java new file mode 100644 index 000000000000..e87e18facf94 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/AddExistingCustomLibraryAction.java @@ -0,0 +1,53 @@ +/* + * 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.actionSystem.AnActionEvent; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.ui.configuration.projectRoot.ModuleStructureConfigurable; +import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; + +import javax.swing.*; + +/** + * @author nik + */ +public class AddExistingCustomLibraryAction extends DumbAwareAction { + private Library myLibrary; + private StructureConfigurableContext myContext; + private ModuleStructureConfigurable myModuleStructureConfigurable; + private Module myModule; + + public AddExistingCustomLibraryAction(Library library, Icon icon, StructureConfigurableContext context, + ModuleStructureConfigurable moduleStructureConfigurable, Module module) { + super(library.getName(), null, icon); + myLibrary = library; + myContext = context; + myModuleStructureConfigurable = moduleStructureConfigurable; + myModule = module; + } + + @Override + public void actionPerformed(AnActionEvent e) { + final ModifiableRootModel rootModel = myContext.getModulesConfigurator().getOrCreateModuleEditor(myModule).getModifiableRootModelProxy(); + final LibraryOrderEntry orderEntry = rootModel.addLibraryEntry(myLibrary); + myModuleStructureConfigurable.selectOrderEntry(myModule, orderEntry); + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/CreateCustomLibraryAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/CreateCustomLibraryAction.java new file mode 100644 index 000000000000..deb556a705b2 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/CreateCustomLibraryAction.java @@ -0,0 +1,109 @@ +/* + * 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.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryKind; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.CreateNewLibraryDialog; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor; +import com.intellij.openapi.roots.ui.configuration.projectRoot.ModuleStructureConfigurable; +import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; +import com.intellij.openapi.util.Disposer; + +import javax.swing.*; +import java.util.*; + +/** + * @author nik + */ +public class CreateCustomLibraryAction extends DumbAwareAction { + private final CustomLibraryCreator myCreator; + private StructureConfigurableContext myContext; + private ModuleStructureConfigurable myModuleStructureConfigurable; + private Module myModule; + + public CreateCustomLibraryAction(final String name, CustomLibraryCreator creator, + StructureConfigurableContext context, + ModuleStructureConfigurable moduleStructureConfigurable, Module module) { + super(name, null, creator.getIcon()); + myCreator = creator; + myContext = context; + myModuleStructureConfigurable = moduleStructureConfigurable; + myModule = module; + } + + @Override + public void actionPerformed(AnActionEvent e) { + final CustomLibraryCreator.NewLibraryConfiguration libraryConfiguration = myCreator.createNewLibrary(myModuleStructureConfigurable.getTree()); + if (libraryConfiguration == null) { + return; + } + + final NewLibraryEditor libraryEditor = new NewLibraryEditor(); + libraryEditor.setName(libraryConfiguration.getDefaultLibraryName()); + libraryConfiguration.addRoots(libraryEditor); + LibraryTablesRegistrar registrar = LibraryTablesRegistrar.getInstance(); + final Project project = myContext.getProject(); + final List tables = Arrays.asList(registrar.getLibraryTable(project), registrar.getLibraryTable()); + final CreateNewLibraryDialog dialog = new CreateNewLibraryDialog(myModuleStructureConfigurable.getTree(), project, libraryEditor, tables, 0); + dialog.show(); + if (dialog.isOK()) { + final Library library = dialog.createLibrary(myContext.getModifiableLibraryTable(dialog.getSelectedTable())); + Disposer.dispose(libraryEditor); + final ModifiableRootModel rootModel = myContext.getModulesConfigurator().getOrCreateModuleEditor(myModule).getModifiableRootModelProxy(); + final LibraryOrderEntry orderEntry = rootModel.addLibraryEntry(library); + myModuleStructureConfigurable.selectOrderEntry(myModule, orderEntry); + } + else { + Disposer.dispose(libraryEditor); + } + } + + public static List getActions(StructureConfigurableContext context, ModuleStructureConfigurable moduleStructureConfigurable) { + final Module module = moduleStructureConfigurable.getSelectedModule(); + if (module == null) return Collections.emptyList(); + + final List actions = new ArrayList(); + for (CustomLibraryCreator creator : CustomLibraryCreator.EP_NAME.getExtensions()) { + final HashSet> kinds = new HashSet>(creator.getSuitableKinds()); + List suitableLibraries = LibraryPresentationManager.getInstance().getLibraries(kinds, context.getProject(), context); + if (suitableLibraries.isEmpty()) { + actions.add(new CreateCustomLibraryAction(creator.getDisplayName(), creator, context, moduleStructureConfigurable, module)); + } + else { + final DefaultActionGroup group = new DefaultActionGroup(creator.getDisplayName(), true); + group.getTemplatePresentation().setIcon(creator.getIcon()); + group.add(new CreateCustomLibraryAction("New...", creator, context, moduleStructureConfigurable, module)); + for (Library library : suitableLibraries) { + Icon icon = LibraryPresentationManager.getInstance().getNamedLibraryIcon(library, context); + group.add(new AddExistingCustomLibraryAction(library, icon, context, moduleStructureConfigurable, module)); + } + actions.add(group); + } + } + return actions; + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/CustomLibraryCreator.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/CustomLibraryCreator.java new file mode 100644 index 000000000000..c3f983710f78 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/CustomLibraryCreator.java @@ -0,0 +1,60 @@ +/* + * 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.ui.configuration.libraryEditor.LibraryEditor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.Collections; +import java.util.List; + +/** + * @author nik + */ +public abstract class CustomLibraryCreator { + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.library.creator"); + + public abstract String getDisplayName(); + + @Nullable + public abstract Icon getIcon(); + + @NotNull + public List> getSuitableKinds() { + return Collections.emptyList(); + } + + @Nullable + public abstract NewLibraryConfiguration createNewLibrary(JComponent parentComponent); + + public static abstract class NewLibraryConfiguration { + private String myDefaultLibraryName; + + protected NewLibraryConfiguration(String defaultLibraryName) { + myDefaultLibraryName = defaultLibraryName; + } + + public String getDefaultLibraryName() { + return myDefaultLibraryName; + } + + public abstract void addRoots(@NotNull LibraryEditor editor); + } +} 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 index e0a97bf4e544..63327060c309 100644 --- 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 @@ -16,7 +16,9 @@ package com.intellij.openapi.roots.ui.configuration.libraries; import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryKind; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; @@ -24,6 +26,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.List; +import java.util.Set; /** * @author nik @@ -33,6 +36,9 @@ public abstract class LibraryPresentationManager { return ServiceManager.getService(LibraryPresentationManager.class); } + @NotNull + public abstract Icon getNamedLibraryIcon(@NotNull Library library, @Nullable StructureConfigurableContext context); + @Nullable public abstract Icon getCustomIcon(@NotNull Library library, @Nullable StructureConfigurableContext context); @@ -44,4 +50,6 @@ public abstract class LibraryPresentationManager { @NotNull public abstract List getDescriptions(@NotNull VirtualFile[] classRoots); + + public abstract List getLibraries(@NotNull Set> kinds, @NotNull Project project, @Nullable StructureConfigurableContext context); } 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 index 645a18aba97a..c25f6c1be04d 100644 --- 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 @@ -15,20 +15,20 @@ */ package com.intellij.openapi.roots.ui.configuration.libraries; +import com.intellij.openapi.project.Project; 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.Icons; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * @author nik @@ -48,6 +48,13 @@ public class LibraryPresentationManagerImpl extends LibraryPresentationManager { return (LibraryPresentationProvider

)myPresentationProviders.get(kind); } + @NotNull + @Override + public Icon getNamedLibraryIcon(@NotNull Library library, @Nullable StructureConfigurableContext context) { + final Icon icon = getCustomIcon(library, context); + return icon != null ? icon : Icons.LIBRARY_ICON; + } + @Override public Icon getCustomIcon(@NotNull Library library, StructureConfigurableContext context) { final List icons = getCustomIcons(library, context); @@ -67,7 +74,7 @@ public class LibraryPresentationManagerImpl extends LibraryPresentationManager { public

boolean processProperties(@NotNull LibraryKind

kind, @NotNull P properties) { final LibraryPresentationProvider

provider = getPresentationProvider(kind); if (provider != null) { - ContainerUtil.addIfNotNull(icons, provider.getIcon()); + ContainerUtil.addIfNotNull(icons, provider.getIcon(properties)); } return true; } @@ -75,6 +82,19 @@ public class LibraryPresentationManagerImpl extends LibraryPresentationManager { return icons; } + public static List> getLibraryKinds(@NotNull Library library, StructureConfigurableContext context) { + final List> result = new SmartList>(); + final VirtualFile[] files = getLibraryFiles(library, context); + LibraryDetectionManager.getInstance().processProperties(Arrays.asList(files), new LibraryDetectionManager.LibraryPropertiesProcessor() { + @Override + public

boolean processProperties(@NotNull LibraryKind

kind, @NotNull P properties) { + result.add(kind); + return true; + } + }); + return result; + } + private static VirtualFile[] getLibraryFiles(Library library, StructureConfigurableContext context) { if (context != null) { final LibraryTable table = library.getTable(); @@ -114,4 +134,28 @@ public class LibraryPresentationManagerImpl extends LibraryPresentationManager { }); return result; } + + @Override + public List getLibraries(@NotNull Set> kinds, @NotNull Project project, @Nullable StructureConfigurableContext context) { + List libraries = new ArrayList(); + if (context != null) { + Collections.addAll(libraries, context.getProjectLibrariesProvider().getModifiableModel().getLibraries()); + Collections.addAll(libraries, context.getGlobalLibrariesProvider().getModifiableModel().getLibraries()); + } + else { + final LibraryTablesRegistrar registrar = LibraryTablesRegistrar.getInstance(); + Collections.addAll(libraries, registrar.getLibraryTable(project).getLibraries()); + Collections.addAll(libraries, registrar.getLibraryTable().getLibraries()); + } + + final Iterator iterator = libraries.iterator(); + while (iterator.hasNext()) { + Library library = iterator.next(); + final List> libraryKinds = getLibraryKinds(library, context); + if (!ContainerUtil.intersects(libraryKinds, kinds)) { + iterator.remove(); + } + } + return libraries; + } } 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 index 8b902e93a3b7..99014a0d3853 100644 --- 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 @@ -39,7 +39,7 @@ public abstract class LibraryPresentationProvider

{ } @Nullable - public abstract Icon getIcon(); + public abstract Icon getIcon(P properties); @Nullable public String getDescription(@NotNull P properties) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryDialog.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryDialog.java index 905aec396ec7..e5ea042ccdec 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryDialog.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryDialog.java @@ -46,7 +46,7 @@ public class CreateNewLibraryDialog extends LibraryEditorDialogBase { return new CreateNewLibraryDialog(parent, project, libraryEditor, libraryTables, selectedTable); } - private CreateNewLibraryDialog(@NotNull JComponent parent, @Nullable Project project, @NotNull NewLibraryEditor libraryEditor, + public CreateNewLibraryDialog(@NotNull JComponent parent, @Nullable Project project, @NotNull NewLibraryEditor libraryEditor, @NotNull List libraryTables, int selectedTable) { super(parent, LibraryRootsComponent.createComponent(project, libraryEditor)); myLibraryEditor = libraryEditor; diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ExistingLibraryEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ExistingLibraryEditor.java index 1ff9373bd0ca..f89f0870bc0f 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ExistingLibraryEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ExistingLibraryEditor.java @@ -92,6 +92,11 @@ public class ExistingLibraryEditor implements LibraryEditor { getModel().addJarDirectory(file, recursive); } + @Override + public void addJarDirectory(String url, boolean recursive) { + getModel().addJarDirectory(url, recursive); + } + @Override public void removeRoot(String url, OrderRootType rootType) { while (getModel().removeRoot(url, rootType)) ; diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java index c36a3df721a4..153fdf935559 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java @@ -37,6 +37,8 @@ public interface LibraryEditor extends Disposable { void addJarDirectory(VirtualFile file, boolean recursive); + void addJarDirectory(String url, boolean recursive); + void removeRoot(String url, OrderRootType rootType); boolean hasChanges(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java index 52631a30159f..acb9da74b5dc 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java @@ -74,8 +74,13 @@ public class NewLibraryEditor implements LibraryEditor { @Override public void addJarDirectory(VirtualFile file, boolean recursive) { - myRoots.get(OrderRootType.CLASSES).add(file); - myJarDirectories.put(file.getUrl(), recursive); + addJarDirectory(file.getUrl(), recursive); + } + + @Override + public void addJarDirectory(final String url, boolean recursive) { + myRoots.get(OrderRootType.CLASSES).add(url); + myJarDirectories.put(url, recursive); } @Override 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 341aefb9dd88..4dd82591bf30 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 @@ -26,7 +26,6 @@ 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; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement; -import com.intellij.openapi.util.IconLoader; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -37,8 +36,6 @@ import javax.swing.*; * Date: 02-Jun-2006 */ public class LibraryConfigurable extends ProjectStructureElementConfigurable { - private static final Icon ICON = IconLoader.getIcon("/modules/library.png"); - private LibraryRootsComponent myLibraryEditor; private final Library myLibrary; private final StructureLibraryTableModifiableModelProvider myModel; @@ -134,11 +131,7 @@ public class LibraryConfigurable extends ProjectStructureElementConfigurable 0) { result.add(new Separator(ProjectBundle.message("add.group.facet.separator"))); + ContainerUtil.addAll(result, facets); } - ContainerUtil.addAll(result, facets); + final List libraryActions = CreateCustomLibraryAction.getActions(myContext, ModuleStructureConfigurable.this); + if (!libraryActions.isEmpty()) { + result.add(new Separator("Library")); + result.addAll(libraryActions); + } return result.toArray(new AnAction[result.size()]); } 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 index 2ec7ea66f589..6377dd3fda99 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryKind.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/LibraryKind.java @@ -36,4 +36,8 @@ public class LibraryKind

{ public String toString() { return "LibraryKind:" + myKindId; } + + public static

LibraryKind

create(@NotNull @NonNls String kindId) { + return new LibraryKind

(kindId); + } } diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 570a443a43d7..ca5971cd336b 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -102,6 +102,10 @@ + + + + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/AbstractGroovyLibraryManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/AbstractGroovyLibraryManager.java index b5de7d6b72e0..c68c2f4bb85f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/AbstractGroovyLibraryManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/AbstractGroovyLibraryManager.java @@ -15,21 +15,24 @@ */ package org.jetbrains.plugins.groovy.config; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable; 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.libraries.LibraryUtil; -import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; -import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectLibrariesConfigurable; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor; import com.intellij.openapi.roots.ui.configuration.projectRoot.GlobalLibrariesConfigurable; +import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesModifiableModel; -import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable; +import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectLibrariesConfigurable; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.CollectionFactory; import com.intellij.util.containers.ContainerUtil; @@ -48,13 +51,11 @@ public abstract class AbstractGroovyLibraryManager extends LibraryManager { public static final ExtensionPointName EP_NAME = ExtensionPointName.create("org.intellij.groovy.libraryManager"); @NotNull - private static String generatePointerName(String version, final String libPrefix, final LibrariesContainer container, - final Set usedLibraryNames) { - String originalName = libPrefix + version; - String newName = originalName; + private static String generatePointerName(final String defaultName, final Set usedLibraryNames) { + String newName = defaultName; int index = 1; while (usedLibraryNames.contains(newName)) { - newName = originalName + " (" + index + ")"; + newName = defaultName + " (" + index + ")"; index++; } return newName; @@ -64,10 +65,18 @@ public abstract class AbstractGroovyLibraryManager extends LibraryManager { return getIcon(); } - protected abstract void fillLibrary(final String path, final Library.ModifiableModel model); + private void fillLibrary(String path, Library.ModifiableModel model) { + NewLibraryEditor editor = new NewLibraryEditor(); + editor.setName(model.getName()); + fillLibrary(path, editor); + editor.apply(model); + Disposer.dispose(editor); + } + + protected abstract void fillLibrary(String path, LibraryEditor libraryEditor); @Nullable - public final Library createSDKLibrary(final String path, + private Library createSDKLibrary(final String path, final String name, final Project project, final boolean inModuleSettings, @@ -126,7 +135,7 @@ public abstract class AbstractGroovyLibraryManager extends LibraryManager { if (addVersion && !AbstractConfigUtils.UNDEFINED_VERSION.equals(newVersion)) { final Project project = container.getProject(); - final String name = generatePointerName(newVersion, getLibraryPrefix() + "-", container, usedLibraryNames); + final String name = generatePointerName(getLibraryPrefix() + "-" + newVersion, usedLibraryNames); final CreateLibraryDialog dialog = new CreateLibraryDialog(project, "Create " + libraryKind + " library", "Create Project " + libraryKind + " library '" + name + "'", "Create Global " + libraryKind + " library '" + name + "'"); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryCreator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryCreator.java new file mode 100644 index 000000000000..8dd7682cf7f6 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryCreator.java @@ -0,0 +1,74 @@ +/* + * 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 org.jetbrains.plugins.groovy.config; + +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.roots.libraries.LibraryKind; +import com.intellij.openapi.roots.ui.configuration.libraries.CustomLibraryCreator; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.GroovyIcons; +import org.jetbrains.plugins.groovy.config.ui.GroovyFacetEditor; + +import javax.swing.*; +import java.util.Collections; +import java.util.List; + +/** + * @author nik + */ +public class GroovyLibraryCreator extends CustomLibraryCreator { + @Override + public String getDisplayName() { + return "Groovy"; + } + + @Override + public Icon getIcon() { + return GroovyIcons.GROOVY_ICON_16x16; + } + + @NotNull + @Override + public List> getSuitableKinds() { + return Collections.singletonList(GroovyLibraryDetector.GROOVY_KIND); + } + + @Override + public NewLibraryConfiguration createNewLibrary(JComponent parentComponent) { + final VirtualFile[] files = FileChooser.chooseFiles(parentComponent, FileChooserDescriptorFactory.createSingleFolderDescriptor()); + if (files.length != 1) return null; + + final VirtualFile dir = files[0]; + final AbstractGroovyLibraryManager manager = GroovyFacetEditor.findManager(dir); + if (manager == null) return null; + + final String path = dir.getPath(); + final String sdkVersion = manager.getSDKVersion(path); + if (AbstractConfigUtils.UNDEFINED_VERSION.equals(sdkVersion)) { + return null; + } + + return new NewLibraryConfiguration(manager.getLibraryPrefix() + "-" + sdkVersion) { + @Override + public void addRoots(@NotNull LibraryEditor editor) { + manager.fillLibrary(path, editor); + } + }; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryDetector.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryDetector.java new file mode 100644 index 000000000000..f36d448a2c58 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryDetector.java @@ -0,0 +1,44 @@ +/* + * 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 org.jetbrains.plugins.groovy.config; + +import com.intellij.openapi.roots.libraries.LibraryDetector; +import com.intellij.openapi.roots.libraries.LibraryKind; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author nik + */ +public class GroovyLibraryDetector extends LibraryDetector { + public static final LibraryKind GROOVY_KIND = LibraryKind.create("groovy"); + + public GroovyLibraryDetector() { + super(GROOVY_KIND); + } + + @Override + public GroovyLibraryProperties detect(@NotNull List classesRoots) { + final VirtualFile[] libraryFiles = classesRoots.toArray(new VirtualFile[classesRoots.size()]); + final LibraryManager manager = LibraryManager.findManagerFor(AbstractGroovyLibraryManager.EP_NAME.getExtensions(), libraryFiles); + if (manager != null) { + return new GroovyLibraryProperties(manager); + } + return null; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryManager.java index f4a52ddac0fa..048465413d82 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryManager.java @@ -16,8 +16,7 @@ package org.jetbrains.plugins.groovy.config; import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.Nls; @@ -55,10 +54,10 @@ public class GroovyLibraryManager extends AbstractGroovyLibraryManager { } @Override - protected void fillLibrary(String path, Library.ModifiableModel model) { + protected void fillLibrary(String path, LibraryEditor libraryEditor) { File srcRoot = new File(path + "/src/main"); if (srcRoot.exists()) { - model.addRoot(VfsUtil.getUrlForLibraryRoot(srcRoot), OrderRootType.SOURCES); + libraryEditor.addRoot(VfsUtil.getUrlForLibraryRoot(srcRoot), OrderRootType.SOURCES); } File[] jars; @@ -71,7 +70,7 @@ public class GroovyLibraryManager extends AbstractGroovyLibraryManager { if (jars != null) { for (File file : jars) { if (file.getName().endsWith(".jar")) { - model.addRoot(VfsUtil.getUrlForLibraryRoot(file), OrderRootType.CLASSES); + libraryEditor.addRoot(VfsUtil.getUrlForLibraryRoot(file), OrderRootType.CLASSES); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryPresentationProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryPresentationProvider.java new file mode 100644 index 000000000000..0633031a4a1b --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryPresentationProvider.java @@ -0,0 +1,34 @@ +/* + * 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 org.jetbrains.plugins.groovy.config; + +import com.intellij.openapi.roots.ui.configuration.libraries.LibraryPresentationProvider; + +import javax.swing.*; + +/** + * @author nik + */ +public class GroovyLibraryPresentationProvider extends LibraryPresentationProvider { + public GroovyLibraryPresentationProvider() { + super(GroovyLibraryDetector.GROOVY_KIND); + } + + @Override + public Icon getIcon(GroovyLibraryProperties properties) { + return properties.getManager().getIcon(); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryProperties.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryProperties.java new file mode 100644 index 000000000000..0bf1976c6927 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/GroovyLibraryProperties.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 org.jetbrains.plugins.groovy.config; + +import com.intellij.openapi.roots.libraries.LibraryProperties; + +/** + * @author nik + */ +public class GroovyLibraryProperties extends LibraryProperties { + private LibraryManager myManager; + + public GroovyLibraryProperties(LibraryManager manager) { + myManager = manager; + } + + public LibraryManager getManager() { + return myManager; + } + + @Override + public GroovyLibraryProperties getState() { + return null; + } + + @Override + public void loadState(GroovyLibraryProperties state) { + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/LibraryManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/LibraryManager.java index ea93f41a5e1c..ba7ee6a3c1a8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/LibraryManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/LibraryManager.java @@ -40,8 +40,13 @@ public abstract class LibraryManager { } } + return findManagerFor(managers, container.getLibraryFiles(library, OrderRootType.CLASSES)); + } + + @Nullable + public static LibraryManager findManagerFor(LibraryManager[] managers, final VirtualFile[] libraryFiles) { for (final LibraryManager manager : managers) { - if (manager.managesLibrary(container.getLibraryFiles(library, OrderRootType.CLASSES))) { + if (manager.managesLibrary(libraryFiles)) { return manager; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ui/GroovyFacetEditor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ui/GroovyFacetEditor.java index 2a76341b8ca5..7acdb5043e85 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ui/GroovyFacetEditor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ui/GroovyFacetEditor.java @@ -211,7 +211,7 @@ public class GroovyFacetEditor { } @Nullable - private static AbstractGroovyLibraryManager findManager(VirtualFile dir) { + public static AbstractGroovyLibraryManager findManager(VirtualFile dir) { if (GroovyUtils.getFilesInDirectoryByPattern(dir.getPath() + "/lib", "groovy.*\\.jar").length == 0) { return null; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantLibraryManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantLibraryManager.java index c799ef2de862..ff529b738279 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantLibraryManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantLibraryManager.java @@ -17,8 +17,7 @@ package org.jetbrains.plugins.groovy.gant; import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.Nls; @@ -70,10 +69,10 @@ public class GantLibraryManager extends AbstractGroovyLibraryManager { } @Override - protected void fillLibrary(String path, Library.ModifiableModel model) { + protected void fillLibrary(String path, LibraryEditor libraryEditor) { File srcRoot = new File(path + "/src/main"); if (srcRoot.exists()) { - model.addRoot(VfsUtil.getUrlForLibraryRoot(srcRoot), OrderRootType.SOURCES); + libraryEditor.addRoot(VfsUtil.getUrlForLibraryRoot(srcRoot), OrderRootType.SOURCES); } // Add Gant jars @@ -82,7 +81,7 @@ public class GantLibraryManager extends AbstractGroovyLibraryManager { if (jars != null) { for (File file : jars) { if (file.getName().endsWith(".jar")) { - model.addRoot(VfsUtil.getUrlForLibraryRoot(file), OrderRootType.CLASSES); + libraryEditor.addRoot(VfsUtil.getUrlForLibraryRoot(file), OrderRootType.CLASSES); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppLibraryManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppLibraryManager.java index 9ec8cedce74e..309818205d36 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppLibraryManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gpp/GppLibraryManager.java @@ -2,6 +2,7 @@ package org.jetbrains.plugins.groovy.gpp; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -24,32 +25,32 @@ import java.util.regex.Pattern; public class GppLibraryManager extends AbstractGroovyLibraryManager { private static final Pattern GROOVYPP_JAR = Pattern.compile("groovypp-([\\d\\.]+)\\.jar"); private static final Pattern GROOVYPP_ALL_JAR = Pattern.compile("groovypp-all-([\\d\\.]+)\\.jar"); - + @Override - protected void fillLibrary(String path, Library.ModifiableModel model) { + protected void fillLibrary(String path, LibraryEditor libraryEditor) { File lib = new File(path + "/lib"); if (lib.exists()) { - model.addJarDirectory(VfsUtil.getUrlForLibraryRoot(lib), false); + libraryEditor.addJarDirectory(VfsUtil.getUrlForLibraryRoot(lib), false); } File srcRoot = new File(path + "/src"); - addSources(model, srcRoot.exists() ? srcRoot : new File(path)); + addSources(libraryEditor, srcRoot.exists() ? srcRoot : new File(path)); } - private static void addSources(Library.ModifiableModel model, File srcRoot) { + private static void addSources(LibraryEditor libraryEditor, File srcRoot) { File compilerSrc = new File(srcRoot, "Compiler/src"); if (compilerSrc.exists()) { - model.addRoot(VfsUtil.getUrlForLibraryRoot(compilerSrc), OrderRootType.SOURCES); + libraryEditor.addRoot(VfsUtil.getUrlForLibraryRoot(compilerSrc), OrderRootType.SOURCES); } File stdLibSrc = new File(srcRoot, "StdLib/src"); if (stdLibSrc.exists()) { - model.addRoot(VfsUtil.getUrlForLibraryRoot(stdLibSrc), OrderRootType.SOURCES); + libraryEditor.addRoot(VfsUtil.getUrlForLibraryRoot(stdLibSrc), OrderRootType.SOURCES); } File mainSrc = new File(srcRoot, "main"); if (mainSrc.exists()) { - model.addRoot(VfsUtil.getUrlForLibraryRoot(mainSrc), OrderRootType.SOURCES); + libraryEditor.addRoot(VfsUtil.getUrlForLibraryRoot(mainSrc), OrderRootType.SOURCES); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleLibraryManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleLibraryManager.java index fe6823296bc2..5498da8a816f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleLibraryManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleLibraryManager.java @@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.OrderEnumerator; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.vfs.LocalFileSystem; @@ -156,13 +157,13 @@ public class GradleLibraryManager extends AbstractGroovyLibraryManager { } @Override - protected void fillLibrary(String path, Library.ModifiableModel model) { + protected void fillLibrary(String path, LibraryEditor libraryEditor) { File lib = new File(path + "/lib"); File[] jars = lib.exists() ? lib.listFiles() : new File[0]; if (jars != null) { for (File file : jars) { if (file.getName().endsWith(".jar")) { - model.addRoot(VfsUtil.getUrlForLibraryRoot(file), OrderRootType.CLASSES); + libraryEditor.addRoot(VfsUtil.getUrlForLibraryRoot(file), OrderRootType.CLASSES); } } } diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index ee0a133c13a5..0eea9414eed9 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -91,6 +91,7 @@ beanClass="com.intellij.openapi.extensions.KeyedFactoryEPBean"/> +