projectConfigurable and applicationConfigurable extension points reworked
authornik <Nikolay.Chashnikov@jetbrains.com>
Tue, 31 Aug 2010 13:46:15 +0000 (17:46 +0400)
committernik <Nikolay.Chashnikov@jetbrains.com>
Tue, 31 Aug 2010 13:58:24 +0000 (17:58 +0400)
31 files changed:
java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java
java/idea-ui/src/com/intellij/ide/actions/TemplateProjectStructureAction.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectJdksConfigurable.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FacetStructureConfigurable.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/GlobalLibrariesConfigurable.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/JdkListConfigurable.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ProjectLibrariesConfigurable.java
platform/extensions/src/com/intellij/openapi/extensions/AbstractExtensionPointBean.java
platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ErrorsConfigurable.java
platform/platform-api/src/com/intellij/openapi/options/Configurable.java
platform/platform-api/src/com/intellij/openapi/options/ConfigurableProvider.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/ide/MacOSApplicationProvider.java
platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsAction.java
platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java
platform/platform-impl/src/com/intellij/ide/actions/TemplateProjectPropertiesAction.java
platform/platform-impl/src/com/intellij/ide/ui/search/SearchUtil.java
platform/platform-impl/src/com/intellij/openapi/options/ConfigurableEP.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/openapi/options/ex/IdeConfigurablesGroup.java
platform/platform-impl/src/com/intellij/openapi/options/ex/ProjectConfigurablesGroup.java
platform/platform-resources/src/META-INF/LangExtensions.xml
platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
platform/platform-resources/src/META-INF/xdebugger.xml
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java [new file with mode: 0644]
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerSettingsPanelProvider.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerSettingsPanelProviderImpl.java
resources/src/META-INF/IdeaPlugin.xml

index 6f4e0fa08cc7def04d20b4f785209ad314307811..777105f840bacfbc0544c9b3c7a1c7a85791fcb4 100644 (file)
@@ -32,6 +32,6 @@ public class ShowStructureSettingsAction extends AnAction implements DumbAware {
       project = ProjectManager.getInstance().getDefaultProject();
     }
 
-    ShowSettingsUtil.getInstance().editProjectConfigurable(project, ProjectStructureConfigurable.class, OptionsEditorDialog.DIMENSION_KEY);
+    ShowSettingsUtil.getInstance().editConfigurable(project, OptionsEditorDialog.DIMENSION_KEY, ProjectStructureConfigurable.getInstance(project));
   }
 }
\ No newline at end of file
index 8386a91d80370ece19aa92fb3267373ffad30aa1..0255cb005ee72ad45d64cc6e9c0c4b83c84159a6 100644 (file)
@@ -27,6 +27,6 @@ import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
 public class TemplateProjectStructureAction extends AnAction implements DumbAware {
   public void actionPerformed(final AnActionEvent e) {
     Project defaultProject = ProjectManagerEx.getInstanceEx().getDefaultProject();
-    ShowSettingsUtil.getInstance().editProjectConfigurable(defaultProject, ProjectStructureConfigurable.class, OptionsEditorDialog.DIMENSION_KEY);
+    ShowSettingsUtil.getInstance().editConfigurable(defaultProject, OptionsEditorDialog.DIMENSION_KEY, ProjectStructureConfigurable.getInstance(defaultProject));
   }
 }
\ No newline at end of file
index 3edad868db794b3e534b10edcb45f127ddd72d70..01c93a435756ee435d33bf2ab581c52a0ab4fd92 100644 (file)
@@ -25,7 +25,6 @@ package com.intellij.openapi.roots.ui.configuration;
 import com.intellij.ide.util.PropertiesComponent;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
-import com.intellij.openapi.options.Configurable;
 import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectBundle;
@@ -54,7 +53,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Set;
 
-public class ProjectJdksConfigurable extends MasterDetailsComponent implements Configurable.Assistant {
+public class ProjectJdksConfigurable extends MasterDetailsComponent {
 
   private final ProjectSdksModel myProjectJdksModel;
   private final Project myProject;
index 89b6c5db4681090251b3ed685e8717620e2bc640..7adcb4b39c34bd4f7adc74c77537dcc4a65af695 100644 (file)
@@ -18,6 +18,7 @@ package com.intellij.openapi.roots.ui.configuration;
 import com.intellij.facet.Facet;
 import com.intellij.ide.util.PropertiesComponent;
 import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.module.ModuleManager;
 import com.intellij.openapi.options.*;
@@ -470,7 +471,7 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se
   }
 
   public static ProjectStructureConfigurable getInstance(final Project project) {
-    return ShowSettingsUtil.getInstance().findProjectConfigurable(project, ProjectStructureConfigurable.class);
+    return ServiceManager.getService(project, ProjectStructureConfigurable.class);
   }
 
   public ProjectSdksModel getProjectJdksModel() {
index 778f2d2829ea62c51da49808833f0c22be223778..c533f91f00f74522139f67209ba98667de1a30ed 100644 (file)
@@ -23,7 +23,6 @@ import com.intellij.openapi.actionSystem.*;
 import com.intellij.openapi.keymap.Keymap;
 import com.intellij.openapi.keymap.KeymapManager;
 import com.intellij.openapi.module.Module;
-import com.intellij.openapi.options.Configurable;
 import com.intellij.openapi.options.SearchableConfigurable;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectBundle;
@@ -55,7 +54,7 @@ import java.awt.*;
 import java.util.*;
 import java.util.List;
 
-public abstract class BaseStructureConfigurable extends MasterDetailsComponent implements SearchableConfigurable, Disposable, Configurable.Assistant, Place.Navigator {
+public abstract class BaseStructureConfigurable extends MasterDetailsComponent implements SearchableConfigurable, Disposable, Place.Navigator {
 
   protected StructureConfigurableContext myContext;
 
index 625b217f64582f1e5d63bcd312cfafc9e9dfae8c..4e24082dfcecd5c3450dde675cd05c8e09cfbad9 100644 (file)
@@ -26,12 +26,12 @@ import com.intellij.facet.ui.FacetEditor;
 import com.intellij.facet.ui.MultipleFacetSettingsEditor;
 import com.intellij.ide.DataManager;
 import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.components.State;
 import com.intellij.openapi.components.Storage;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.module.ModuleManager;
 import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.options.ShowSettingsUtil;
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectBundle;
@@ -71,7 +71,7 @@ public class FacetStructureConfigurable extends BaseStructureConfigurable {
   }
 
   public static FacetStructureConfigurable getInstance(final @NotNull Project project) {
-    return ShowSettingsUtil.getInstance().findProjectConfigurable(project, FacetStructureConfigurable.class);
+    return ServiceManager.getService(project, FacetStructureConfigurable.class);
   }
 
   public static boolean isEnabled() {
index 0a0bde05b67e5c2450ae8d47fad820fb0175a3fd..7730b1eb78fca45ffd07d609a6aeb3e207fa0ec4 100644 (file)
@@ -15,9 +15,9 @@
  */
 package com.intellij.openapi.roots.ui.configuration.projectRoot;
 
+import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.components.State;
 import com.intellij.openapi.components.Storage;
-import com.intellij.openapi.options.ShowSettingsUtil;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectBundle;
 import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
@@ -60,7 +60,7 @@ public class GlobalLibrariesConfigurable extends BaseLibrariesConfigurable {
 
 
   public static GlobalLibrariesConfigurable getInstance(final Project project) {
-    return ShowSettingsUtil.getInstance().findProjectConfigurable(project, GlobalLibrariesConfigurable.class);
+    return ServiceManager.getService(project, GlobalLibrariesConfigurable.class);
   }
 
   public LibraryTableModifiableModelProvider getModelProvider(final boolean editable) {
index 5e50739e90812bc7fa20fb2bbd51b608101b9afa..cf8c4387e55fb4d91955559ec08f4fd71299f261 100644 (file)
@@ -18,10 +18,10 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.components.State;
 import com.intellij.openapi.components.Storage;
 import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.options.ShowSettingsUtil;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectBundle;
 import com.intellij.openapi.projectRoots.Sdk;
@@ -187,7 +187,7 @@ public class JdkListConfigurable extends BaseStructureConfigurable {
   }
 
   public static JdkListConfigurable getInstance(Project project) {
-    return ShowSettingsUtil.getInstance().findProjectConfigurable(project, JdkListConfigurable.class);
+    return ServiceManager.getService(project, JdkListConfigurable.class);
   }
 
   public AbstractAddGroup createAddAction() {
index 26a493cfb2e592f8138f75ddbf6260b8ac2b9f7c..424544067bfddb80731ba9444b90f9ca5ea24c0c 100644 (file)
@@ -29,11 +29,11 @@ import com.intellij.ide.util.projectWizard.NamePathComponent;
 import com.intellij.ide.util.projectWizard.ProjectWizardUtil;
 import com.intellij.openapi.actionSystem.*;
 import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.components.State;
 import com.intellij.openapi.components.Storage;
 import com.intellij.openapi.module.*;
 import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.options.ShowSettingsUtil;
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectBundle;
@@ -385,7 +385,7 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple
 
 
   public static ModuleStructureConfigurable getInstance(final Project project) {
-    return ShowSettingsUtil.getInstance().findProjectConfigurable(project, ModuleStructureConfigurable.class);
+    return ServiceManager.getService(project, ModuleStructureConfigurable.class);
   }
 
   public void setStartModuleWizard(final boolean show) {
index bf79437fdb854acdc29c8e5110153081ebdb6508..74ae6a3d778fd6876da446a270c8b38f8258def7 100644 (file)
@@ -15,9 +15,9 @@
  */
 package com.intellij.openapi.roots.ui.configuration.projectRoot;
 
+import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.components.State;
 import com.intellij.openapi.components.Storage;
-import com.intellij.openapi.options.ShowSettingsUtil;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectBundle;
 import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
@@ -68,7 +68,7 @@ public class ProjectLibrariesConfigurable extends BaseLibrariesConfigurable {
   }
 
   public static ProjectLibrariesConfigurable getInstance(final Project project) {
-    return ShowSettingsUtil.getInstance().findProjectConfigurable(project, ProjectLibrariesConfigurable.class);
+    return ServiceManager.getService(project, ProjectLibrariesConfigurable.class);
   }
 
   protected String getAddText() {
index 7264cdb556220ab0ea5f77e15ea94ca88b50d778..3ec9c294ac026936dbe5c33062b041d4947ad1a3 100644 (file)
@@ -59,7 +59,14 @@ public abstract class AbstractExtensionPointBean implements PluginAware {
 
   @NotNull
   public static <T> T instantiate(@NotNull final Class<T> aClass, @NotNull final PicoContainer container) {
-    return (T)new ConstructorInjectionComponentAdapter(aClass.getName(), aClass).getComponentInstance(container);
+    return instantiate(aClass, container, false);
+  }
+
+  @NotNull
+  public static <T> T instantiate(@NotNull final Class<T> aClass,
+                                  @NotNull final PicoContainer container,
+                                  final boolean allowNonPublicClasses) {
+    return (T)new ConstructorInjectionComponentAdapter(aClass.getName(), aClass, null, allowNonPublicClasses).getComponentInstance(container);
   }
 
 }
index f932bc423c868c32475a50edbca67b816354997e..27710d9329d4c9926d059846376f395b55cc2413 100644 (file)
@@ -16,8 +16,8 @@
 
 package com.intellij.profile.codeInspection.ui;
 
-import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ShowSettingsUtil;
 import com.intellij.openapi.project.Project;
 import org.jetbrains.annotations.Nullable;
 
@@ -38,19 +38,9 @@ public interface ErrorsConfigurable extends Configurable {
 
     @Nullable
     public static ErrorsConfigurable getInstance(Project project) {
-      ErrorsConfigurable profileConfigurable = findErrorsConfigurable(project.getExtensions(PROJECT_CONFIGURABLES));
+      ErrorsConfigurable profileConfigurable = ShowSettingsUtil.getInstance().findProjectConfigurable(project, ErrorsConfigurable.class);
       if (profileConfigurable != null) return profileConfigurable;
-      return findErrorsConfigurable(ApplicationManager.getApplication().getExtensions(APPLICATION_CONFIGURABLES));
-    }
-
-    @Nullable
-    private static ErrorsConfigurable findErrorsConfigurable(final Configurable[] extensions) {
-      for (Configurable configurable : extensions) {
-        if (ErrorsConfigurable.class.isAssignableFrom(configurable.getClass())) {
-          return (ErrorsConfigurable)configurable;
-        }
-      }
-      return null;
+      return ShowSettingsUtil.getInstance().findApplicationConfigurable(ErrorsConfigurable.class);
     }
   }
 }
index b9ec7b8d1f60c3b2da09bf91d695eefec200cb81..b10e334b2992bcb8f4c0a1fa51f7ec1ac70b2b87 100644 (file)
@@ -31,7 +31,13 @@ import javax.swing.*;
  * this interface are shown in the "Project Settings" group of that dialog.
  */
 public interface Configurable extends UnnamedConfigurable {
+  /**
+   * @deprecated
+   */
   ExtensionPointName<Configurable> PROJECT_CONFIGURABLES = ExtensionPointName.create("com.intellij.projectConfigurable");
+  /**
+   * @deprecated
+   */
   ExtensionPointName<Configurable> APPLICATION_CONFIGURABLES = ExtensionPointName.create("com.intellij.applicationConfigurable");
 
   /**
@@ -59,8 +65,10 @@ public interface Configurable extends UnnamedConfigurable {
   @Nullable
   @NonNls String getHelpTopic();
 
+  /**
+   * @deprecated
+   */
   interface Assistant extends Configurable {
-
   }
 
   interface Composite {
diff --git a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableProvider.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableProvider.java
new file mode 100644 (file)
index 0000000..67c1ebe
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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.options;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public abstract class ConfigurableProvider {
+
+  @Nullable
+  public abstract Configurable createConfigurable();
+
+}
index 7f1ebf0fe896d84a3c8194e84c7e7e6fec6e0a51..f84c59d4c0c4837d5b11c88f46c0475a5da80844 100644 (file)
@@ -74,7 +74,7 @@ public class MacOSApplicationProvider implements ApplicationComponent {
           }
 
           ConfigurableGroup[] group = new ConfigurableGroup[]{
-            new ProjectConfigurablesGroup(project, false),
+            new ProjectConfigurablesGroup(project),
             new IdeConfigurablesGroup()
           };
 
index b723323af571f049be39eac60f24f1f0d126355a..2f17c493787e8d10619ddd25680fa4b915c4fc97 100644 (file)
@@ -37,7 +37,7 @@ public class ShowSettingsAction extends AnAction implements DumbAware {
     }
 
     ConfigurableGroup[] group = new ConfigurableGroup[]{
-      new ProjectConfigurablesGroup(project, false),
+      new ProjectConfigurablesGroup(project),
       new IdeConfigurablesGroup()
     };
 
index f1feefdc86bcbb188888671781b7f513e7c3f251..a46e94136b28ac225c74f2c99aca8df3960611af 100644 (file)
@@ -79,7 +79,7 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
     if (project == null) {
       group = new ConfigurableGroup[] {new IdeConfigurablesGroup()};
     } else {
-      group = new ConfigurableGroup[] {new ProjectConfigurablesGroup(project, false), new IdeConfigurablesGroup()};
+      group = new ConfigurableGroup[] {new ProjectConfigurablesGroup(project), new IdeConfigurablesGroup()};
     }
 
     Project actualProject = project != null ? project  : ProjectManager.getInstance().getDefaultProject();
@@ -93,7 +93,7 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
 
   public void showSettingsDialog(@NotNull final Project project, final Configurable toSelect) {
     _showSettingsDialog(project, new ConfigurableGroup[]{
-      new ProjectConfigurablesGroup(project, false),
+      new ProjectConfigurablesGroup(project),
       new IdeConfigurablesGroup()
     }, toSelect);
   }
@@ -128,19 +128,11 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
   }
 
   public <T extends Configurable> T findApplicationConfigurable(final Class<T> confClass) {
-    return selectConfigurable(confClass, ApplicationManager.getApplication().getExtensions(Configurable.APPLICATION_CONFIGURABLES));
+    return ConfigurableExtensionPointUtil.findApplicationConfigurable(confClass);
   }
 
   public <T extends Configurable> T findProjectConfigurable(final Project project, final Class<T> confClass) {
-    return selectConfigurable(confClass, project.getExtensions(Configurable.PROJECT_CONFIGURABLES));
-  }
-
-  private static <T extends Configurable> T selectConfigurable(final Class<T> confClass, final Configurable... configurables) {
-    for (Configurable configurable : configurables) {
-      if (confClass.isAssignableFrom(configurable.getClass())) return (T)configurable;
-    }
-
-    throw new IllegalStateException("Can't find configurable of class " + confClass.getName());
+    return ConfigurableExtensionPointUtil.findProjectConfigurable(project, confClass);
   }
 
   public boolean editConfigurable(Project project, String dimensionServiceKey, Configurable configurable) {
index 26f97fb7a0727b444a13a1beefe783bf0f4c44a8..9d154a86e1633631af860fd1fdbb13c846d96823 100644 (file)
@@ -28,7 +28,7 @@ public class TemplateProjectPropertiesAction extends AnAction implements DumbAwa
   public void actionPerformed(AnActionEvent e) {
     Project defaultProject = ProjectManagerEx.getInstanceEx().getDefaultProject();
     ShowSettingsUtil.getInstance().showSettingsDialog(defaultProject, new ConfigurableGroup[]{
-      new ProjectConfigurablesGroup(defaultProject, false)
+      new ProjectConfigurablesGroup(defaultProject)
     });
   }
 }
index 9f4c225b4c8f7edee935bf5535815ba77f32849e..42a51d10b3a266a9bdcc32c78dee3dde5788e6aa 100644 (file)
@@ -63,7 +63,7 @@ public class SearchUtil {
   }
 
   public static void processProjectConfigurables(Project project, HashMap<SearchableConfigurable, TreeSet<OptionDescription>> options) {
-    processConfigurables(new ProjectConfigurablesGroup(project, false).getConfigurables(), options);
+    processConfigurables(new ProjectConfigurablesGroup(project).getConfigurables(), options);
     processConfigurables(new IdeConfigurablesGroup().getConfigurables(), options);
   }
 
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableEP.java b/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableEP.java
new file mode 100644 (file)
index 0000000..be9012d
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * 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.options;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.extensions.AbstractExtensionPointBean;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
+import com.intellij.openapi.util.NullableFactory;
+import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.picocontainer.PicoContainer;
+
+/**
+ * @author nik
+ */
+public class ConfigurableEP extends AbstractExtensionPointBean {
+  @Attribute("implementation")
+  public String implementationClass;
+  @Attribute("instance")
+  public String instanceClass;
+  @Attribute("provider")
+  public String providerClass;
+
+  private final AtomicNotNullLazyValue<NullableFactory<Configurable>> myFactory;
+  private final PicoContainer myPicoContainer;
+
+  public ConfigurableEP() {
+    this(ApplicationManager.getApplication().getPicoContainer());
+  }
+
+  public ConfigurableEP(Project project) {
+    this(project.getPicoContainer());
+  }
+
+  private ConfigurableEP(PicoContainer picoContainer) {
+    myPicoContainer = picoContainer;
+    myFactory = new AtomicNotNullLazyValue<NullableFactory<Configurable>>() {
+      @NotNull
+      @Override
+      protected NullableFactory<Configurable> compute() {
+        if (providerClass != null) {
+          return new InstanceFromProviderFactory();
+        }
+        else if (instanceClass != null) {
+          return new NewInstanceFactory();
+        }
+        else if (implementationClass != null) {
+          return new ImplementationFactory();
+        }
+        throw new RuntimeException();
+      }
+    };
+  }
+
+  @Nullable
+  public Configurable createConfigurable() {
+    return myFactory.getValue().create();
+  }
+
+  private class InstanceFromProviderFactory extends AtomicNotNullLazyValue<ConfigurableProvider> implements NullableFactory<Configurable> {
+    public Configurable create() {
+      return getValue().createConfigurable();
+    }
+
+    @NotNull
+    @Override
+    protected ConfigurableProvider compute() {
+      try {
+        return instantiate(providerClass, myPicoContainer);
+      }
+      catch (ClassNotFoundException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  private class NewInstanceFactory extends NotNullLazyValue<Class<? extends Configurable>> implements NullableFactory<Configurable> {
+    public Configurable create() {
+      return instantiate(getValue(), myPicoContainer);
+    }
+
+    @NotNull
+    @Override
+    protected Class<? extends Configurable> compute() {
+      try {
+        return findClass(instanceClass);
+      }
+      catch (ClassNotFoundException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  private class ImplementationFactory extends AtomicNotNullLazyValue<Configurable> implements NullableFactory<Configurable> {
+    @Override
+    public Configurable create() {
+      return compute();
+    }
+
+    @NotNull
+    @Override
+    protected Configurable compute() {
+      try {
+        final Class<Configurable> aClass = findClass(implementationClass);
+        return instantiate(aClass, myPicoContainer, true);
+      }
+      catch (ClassNotFoundException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java
new file mode 100644 (file)
index 0000000..18481d8
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * 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.options.ex;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurableEP;
+import com.intellij.openapi.options.OptionalConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class ConfigurableExtensionPointUtil {
+  public static final ExtensionPointName<ConfigurableEP> APPLICATION_CONFIGURABLES = ExtensionPointName.create("com.intellij.applicationConfigurable");
+  public static final ExtensionPointName<ConfigurableEP> PROJECT_CONFIGURABLES = ExtensionPointName.create("com.intellij.projectConfigurable");
+
+  private ConfigurableExtensionPointUtil() {
+  }
+
+
+  public static List<Configurable> buildConfigurablesList(final ConfigurableEP[] extensions, final Configurable[] components, ConfigurableFilter filter) {
+    List<Configurable> result = new ArrayList<Configurable>();
+    for (ConfigurableEP extension : extensions) {
+      ContainerUtil.addIfNotNull(extension.createConfigurable(), result);
+    }
+    ContainerUtil.addAll(result, components);
+
+    final Iterator<Configurable> iterator = result.iterator();
+    while (iterator.hasNext()) {
+      Configurable each = iterator.next();
+      if (each instanceof Configurable.Assistant
+          || each instanceof OptionalConfigurable && !((OptionalConfigurable) each).needDisplay()
+          || filter != null && !filter.isIncluded(each)) {
+        iterator.remove();
+      }
+    }
+
+    return result;
+  }
+
+  @NotNull
+  public static <T extends Configurable> T findProjectConfigurable(@NotNull Project project, @NotNull Class<T> configurableClass) {
+    return findConfigurable(project.getExtensions(PROJECT_CONFIGURABLES), configurableClass);
+  }
+
+  @NotNull
+  public static <T extends Configurable> T findApplicationConfigurable(@NotNull Class<T> configurableClass) {
+    return findConfigurable(APPLICATION_CONFIGURABLES.getExtensions(), configurableClass);
+  }
+
+  @NotNull
+  private static <T extends Configurable> T findConfigurable(ConfigurableEP[] extensions, Class<T> configurableClass) {
+    for (ConfigurableEP extension : extensions) {
+      if (extension.implementationClass != null) {
+        final Configurable configurable = extension.createConfigurable();
+        if (configurableClass.isInstance(configurable)) {
+          return configurableClass.cast(configurable);
+        }
+      }
+    }
+    throw new IllegalArgumentException("Cannot find singleton configurable of " + configurableClass);
+  }
+}
index 2cd7788f49923e976fb509d0f87b3749d3f49372..f099ad6794e99fce076da7628e8beae65faa96df 100644 (file)
@@ -17,10 +17,7 @@ package com.intellij.openapi.options.ex;
 
 import com.intellij.openapi.application.Application;
 import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.options.Configurable;
-import com.intellij.openapi.options.ConfigurableGroup;
-import com.intellij.openapi.options.OptionalConfigurable;
-import com.intellij.openapi.options.OptionsBundle;
+import com.intellij.openapi.options.*;
 
 import java.util.List;
 
@@ -32,6 +29,7 @@ import java.util.List;
  * To change this template use Options | File Templates.
  */
 public class IdeConfigurablesGroup implements ConfigurableGroup {
+
   public String getDisplayName() {
     return OptionsBundle.message("ide.settings.display.name");
   }
@@ -42,16 +40,10 @@ public class IdeConfigurablesGroup implements ConfigurableGroup {
 
   public Configurable[] getConfigurables() {
     final Application app = ApplicationManager.getApplication();
-    final Configurable[] extensions = app.getExtensions(Configurable.APPLICATION_CONFIGURABLES);
+    final ConfigurableEP[] extensions = app.getExtensions(ConfigurableExtensionPointUtil.APPLICATION_CONFIGURABLES);
     Configurable[] components = app.getComponents(Configurable.class);
 
-    List<Configurable> result = ProjectConfigurablesGroup.buildConfigurablesList(extensions, components, new ConfigurableFilter() {
-      public boolean isIncluded(final Configurable configurable) {
-        if (configurable instanceof Configurable.Assistant) return false;
-        if (configurable instanceof OptionalConfigurable && !((OptionalConfigurable) configurable).needDisplay()) return false;
-        return true;
-      }
-    });
+    List<Configurable> result = ConfigurableExtensionPointUtil.buildConfigurablesList(extensions, components, null);
 
     return result.toArray(new Configurable[result.size()]);
   }
index 8b898cf09c8f006bc120c95790ccfedba1f01f27..74ecce5af38a9e201e7d82282550e0b94c802631 100644 (file)
@@ -17,10 +17,7 @@ package com.intellij.openapi.options.ex;
 
 import com.intellij.openapi.options.*;
 import com.intellij.openapi.project.Project;
-import com.intellij.util.containers.ContainerUtil;
 
-import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -28,16 +25,9 @@ import java.util.List;
  */
 public class ProjectConfigurablesGroup implements ConfigurableGroup {
   private Project myProject;
-  private boolean myIncludeProjectStructure;
-  private static final String PROJECT_STRUCTURE_CLASS_FQ_NAME = "com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable";
 
   public ProjectConfigurablesGroup(Project project) {
-    this(project, true);
-  }
-
-  public ProjectConfigurablesGroup(Project project, boolean includeProjectStructure) {
     myProject = project;
-    myIncludeProjectStructure = includeProjectStructure;
   }
 
   public String getDisplayName() {
@@ -55,41 +45,18 @@ public class ProjectConfigurablesGroup implements ConfigurableGroup {
   }
 
   public Configurable[] getConfigurables() {
-    return getConfigurables(myProject, new ConfigurableFilter() {
+    final ConfigurableEP[] extensions = myProject.getExtensions(ConfigurableExtensionPointUtil.PROJECT_CONFIGURABLES);
+    Configurable[] components = myProject.getComponents(Configurable.class);
+    List<Configurable> result = ConfigurableExtensionPointUtil.buildConfigurablesList(extensions, components, new ConfigurableFilter() {
       public boolean isIncluded(final Configurable configurable) {
         if (isDefault() && configurable instanceof NonDefaultProjectConfigurable) return false;
-        if (configurable instanceof Configurable.Assistant) return false;
-        if (configurable instanceof OptionalConfigurable && !((OptionalConfigurable) configurable).needDisplay()) return false;
-        if (!myIncludeProjectStructure && PROJECT_STRUCTURE_CLASS_FQ_NAME.equals(configurable.getClass().getName())) return false;
         return true;
       }
     });
-  }
-
-  private static Configurable[] getConfigurables(Project project, final ConfigurableFilter filter) {
-    final Configurable[] extensions = project.getExtensions(Configurable.PROJECT_CONFIGURABLES);
-    Configurable[] components = project.getComponents(Configurable.class);
-    List<Configurable> result = buildConfigurablesList(extensions, components, filter);
 
     return result.toArray(new Configurable[result.size()]);
   }
 
-  static List<Configurable> buildConfigurablesList(final Configurable[] extensions, final Configurable[] components, ConfigurableFilter filter) {
-    List<Configurable> result = new ArrayList<Configurable>();
-    ContainerUtil.addAll(result, extensions);
-    ContainerUtil.addAll(result, components);
-
-    final Iterator<Configurable> iterator = result.iterator();
-    while (iterator.hasNext()) {
-      Configurable each = iterator.next();
-      if (!filter.isIncluded(each)) {
-        iterator.remove();
-      }
-    }
-
-    return result;
-  }
-
   public int hashCode() {
     return 0;
   }
@@ -97,6 +64,4 @@ public class ProjectConfigurablesGroup implements ConfigurableGroup {
   public boolean equals(Object object) {
     return object instanceof ProjectConfigurablesGroup && ((ProjectConfigurablesGroup)object).myProject == myProject;
   }
-
-
 }
index 21c5ea1853082f9ca4b16f6d1160097b0fb06c58..797029508bbd879eee3c643ff99c546b5be713a1 100644 (file)
   <applicationConfigurable implementation="com.intellij.ide.todo.configurable.TodoConfigurable"/>
 
   <!-- External Tools -->
-  <applicationConfigurable implementation="com.intellij.tools.ToolConfigurable"/>
+  <applicationConfigurable instance="com.intellij.tools.ToolConfigurable"/>
 
   <!-- Project Code Style -->
   <!--<projectConfigurable implementation="com.intellij.application.options.ProjectCodeStyleConfigurable" order="before vcs"/>-->
index 9a0c7693a1ec9f6d841395de435e0d82d9c9a765..5acd048014128bb8abfa22750ac3d0d26a8e6972 100644 (file)
@@ -9,11 +9,11 @@
                   interface="com.intellij.openapi.diagnostic.ErrorReportSubmitter"/>
 
   <extensionPoint name="projectConfigurable"
-                  interface="com.intellij.openapi.options.Configurable"
+                  beanClass="com.intellij.openapi.options.ConfigurableEP"
                   area="IDEA_PROJECT"/>
 
   <extensionPoint name="applicationConfigurable"
-                  interface="com.intellij.openapi.options.Configurable"/>
+                  beanClass="com.intellij.openapi.options.ConfigurableEP"/>
 
   <extensionPoint name="selectInTarget"
                   interface="com.intellij.ide.SelectInTarget"
index 51f12173bfef5370121385239ec417b165eb5b7c..b427b831d37d201928902e62ed3b9ab280ac418b 100644 (file)
@@ -34,7 +34,7 @@
     <projectService serviceInterface="com.intellij.xdebugger.impl.XDebuggerHistoryManager"
                     serviceImplementation="com.intellij.xdebugger.impl.XDebuggerHistoryManager"/>
 
-    <applicationConfigurable implementation="com.intellij.xdebugger.impl.settings.DebuggerConfigurable"/>
+    <applicationConfigurable provider="com.intellij.xdebugger.impl.settings.DebuggerConfigurableProvider"/>
 
     <xdebugger.debuggerSupport implementation="com.intellij.xdebugger.impl.XDebuggerSupport" order="first"/>
 
index f89c6e8cb9fc529eab1409dd964c462ee0580f51..8076728d8172c243392e9ce39c464949b1cf3711 100644 (file)
  */
 package com.intellij.xdebugger.impl.settings;
 
-import com.intellij.ide.DataManager;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.options.Configurable;
 import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.options.OptionalConfigurable;
 import com.intellij.openapi.options.SearchableConfigurable;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.project.ProjectManagerAdapter;
 import com.intellij.openapi.util.IconLoader;
 import com.intellij.xdebugger.XDebuggerBundle;
 import com.intellij.xdebugger.impl.DebuggerSupport;
 import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 
 /**
  * @author Eugene Belyaev & Eugene Zhuravlev
  */
-public class DebuggerConfigurable implements SearchableConfigurable.Parent, OptionalConfigurable {
+public class DebuggerConfigurable implements SearchableConfigurable.Parent {
+  public static final String DISPLAY_NAME = XDebuggerBundle.message("debugger.configurable.display.name");
   private Configurable myRootConfigurable;
   private Configurable[] myChildren;
-  private WeakReference<Project> myContextProject;
-
-  public static final String DISPLAY_NAME = XDebuggerBundle.message("debugger.configurable.display.name");
 
-  public DebuggerConfigurable(ProjectManager pm) {
-    pm.addProjectManagerListener(new ProjectManagerAdapter() {
-      public void projectClosed(final Project project) {
-        myChildren = null;
-        myRootConfigurable = null;
-      }
-    });
+  public DebuggerConfigurable(Configurable rootConfigurable, List<Configurable> children) {
+    myRootConfigurable = rootConfigurable;
+    myChildren = children.toArray(new Configurable[children.size()]);
   }
 
   public Icon getIcon() {
@@ -68,43 +53,6 @@ public class DebuggerConfigurable implements SearchableConfigurable.Parent, Opti
   }
 
   public Configurable[] getConfigurables() {
-    Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
-    if(project == null) {
-      project = ProjectManager.getInstance().getDefaultProject();
-    }
-
-    if (myContextProject == null || myContextProject.get() != project) {
-      // clear cached data built for the previous projects 
-      myChildren = null;
-      myRootConfigurable = null;
-      myContextProject = new WeakReference<Project>(project);
-    }
-
-    if (myChildren == null) {
-      final ArrayList<Configurable> configurables = new ArrayList<Configurable>();
-      final List<DebuggerSettingsPanelProvider> providers = new ArrayList<DebuggerSettingsPanelProvider>();
-      for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) {
-        providers.add(support.getSettingsPanelProvider());
-      }
-      Collections.sort(providers, new Comparator<DebuggerSettingsPanelProvider>() {
-        public int compare(final DebuggerSettingsPanelProvider o1, final DebuggerSettingsPanelProvider o2) {
-          return o2.getPriority() - o1.getPriority();
-        }
-      });
-      for (DebuggerSettingsPanelProvider provider : providers) {
-        configurables.addAll(provider.getConfigurables(project));
-        final Configurable rootConfigurable = provider.getRootConfigurable();
-        if (rootConfigurable != null) {
-          if (myRootConfigurable != null) {
-            configurables.add(rootConfigurable);
-          }
-          else {
-            myRootConfigurable = rootConfigurable;
-          }
-        }
-      }
-      myChildren = configurables.toArray(new Configurable[configurables.size()]);
-    }
     return myChildren;
   }
 
@@ -149,18 +97,9 @@ public class DebuggerConfigurable implements SearchableConfigurable.Parent, Opti
     }
   }
 
+  @NotNull
   @NonNls
   public String getId() {
     return "project.propDebugger";
   }
-
-  public boolean needDisplay() {
-    DebuggerSupport[] supports = DebuggerSupport.getDebuggerSupports();
-    for (DebuggerSupport support : supports) {
-      if (support.getSettingsPanelProvider().hasAnySettingsPanels()) {
-        return true;
-      }
-    }
-    return false;
-  }
 }
\ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java
new file mode 100644 (file)
index 0000000..2469d49
--- /dev/null
@@ -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 com.intellij.xdebugger.impl.settings;
+
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurableProvider;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.xdebugger.impl.DebuggerSupport;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class DebuggerConfigurableProvider extends ConfigurableProvider {
+  @Override
+  public Configurable createConfigurable() {
+    final List<DebuggerSettingsPanelProvider> providers = new ArrayList<DebuggerSettingsPanelProvider>();
+    final DebuggerSupport[] supports = DebuggerSupport.getDebuggerSupports();
+    for (DebuggerSupport support : supports) {
+      providers.add(support.getSettingsPanelProvider());
+    }
+
+    final ArrayList<Configurable> configurables = new ArrayList<Configurable>();
+    Collections.sort(providers, new Comparator<DebuggerSettingsPanelProvider>() {
+      public int compare(final DebuggerSettingsPanelProvider o1, final DebuggerSettingsPanelProvider o2) {
+        return o2.getPriority() - o1.getPriority();
+      }
+    });
+
+    Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
+    if(project == null) {
+      project = ProjectManager.getInstance().getDefaultProject();
+    }
+
+    Configurable rootConfigurable = null;
+    for (DebuggerSettingsPanelProvider provider : providers) {
+      configurables.addAll(provider.getConfigurables(project));
+      final Configurable aRootConfigurable = provider.getRootConfigurable();
+      if (aRootConfigurable != null) {
+        if (rootConfigurable != null) {
+          configurables.add(aRootConfigurable);
+        }
+        else {
+          rootConfigurable = aRootConfigurable;
+        }
+      }
+    }
+    if (configurables.isEmpty() && rootConfigurable == null) {
+      return null;
+    }
+
+    return new DebuggerConfigurable(rootConfigurable, configurables);
+  }
+}
index daf3849d463ab48b884d57bc0c23a160b03ce5f9..318f522857eb0b2e34562e5d609ef9c5cfd31af6 100644 (file)
@@ -37,8 +37,4 @@ public abstract class DebuggerSettingsPanelProvider {
   public Configurable getRootConfigurable() {
     return null;
   }
-
-  public boolean hasAnySettingsPanels() {
-    return true;
-  }
 }
index f1ce5fc7a02c8e001cedefd737da1718eb84ba9c..bb1a6793ff7a626f24927ef18078ac79b178cd0d 100644 (file)
@@ -38,8 +38,4 @@ public class XDebuggerSettingsPanelProviderImpl extends DebuggerSettingsPanelPro
     return list;
   }
 
-  @Override
-  public boolean hasAnySettingsPanels() {
-    return !XDebuggerSettingsManager.getInstance().getSettingsList().isEmpty();
-  }
 }
index ff9246ba591793161f12ef359e4e4d0bce165d26..8760ee1127762f722001d21ae1f146464a60fe15 100644 (file)
 
 
     <!-- Project Configurables -->
-    <projectConfigurable implementation="com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable" id="project"
-                         order="first"/>
-    <projectConfigurable implementation="com.intellij.openapi.roots.ui.configuration.projectRoot.ModuleStructureConfigurable"/>
-    <projectConfigurable implementation="com.intellij.openapi.roots.ui.configuration.projectRoot.FacetStructureConfigurable"/>
-    <projectConfigurable implementation="com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactsStructureConfigurable"/>
-    <projectConfigurable implementation="com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectLibrariesConfigurable"/>
-    <projectConfigurable implementation="com.intellij.openapi.roots.ui.configuration.projectRoot.GlobalLibrariesConfigurable"/>
-    <projectConfigurable implementation="com.intellij.openapi.roots.ui.configuration.projectRoot.JdkListConfigurable"/>
+    <projectService serviceImplementation="com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable"/>
+    <projectService serviceImplementation="com.intellij.openapi.roots.ui.configuration.projectRoot.ModuleStructureConfigurable"/>
+    <projectService serviceImplementation="com.intellij.openapi.roots.ui.configuration.projectRoot.FacetStructureConfigurable"/>
+    <projectService serviceImplementation="com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactsStructureConfigurable"/>
+    <projectService serviceImplementation="com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectLibrariesConfigurable"/>
+    <projectService serviceImplementation="com.intellij.openapi.roots.ui.configuration.projectRoot.GlobalLibrariesConfigurable"/>
+    <projectService serviceImplementation="com.intellij.openapi.roots.ui.configuration.projectRoot.JdkListConfigurable"/>
 
     <!-- Errors -->
     <!-- Show full error options configurable only in full IDEA - platform supports only default IDE profile for now -->
     <projectConfigurable implementation="com.intellij.profile.codeInspection.ui.ProjectInspectionToolsConfigurable"/>
 
-    <!--<projectConfigurable implementation="com.intellij.openapi.roots.ui.configuration.projectRoot.ModuleStructureConfigurable"/>-->
     <!-- Project Structure -->
     <projectConfigurable implementation="com.intellij.compiler.options.CompilerConfigurable" order="after project"/>
     <!-- Compiler -->