protected final void init(@Nullable ProgressIndicator indicator, @Nullable Runnable componentsRegistered) { List<ComponentConfig> componentConfigs = getComponentConfigs(); for (ComponentConfig config : componentConfigs) { registerComponents(config); } myComponentConfigCount = componentConfigs.size(); if (componentsRegistered != null) { componentsRegistered.run(); } if (indicator != null) { indicator.setIndeterminate(false); } createComponents(indicator); myComponentsCreated = true; }
@NotNull private List<ComponentConfig> getComponentConfigs() { ArrayList<ComponentConfig> componentConfigs = new ArrayList<ComponentConfig>(); boolean isDefaultProject = this instanceof Project && ((Project)this).isDefault(); boolean headless = ApplicationManager.getApplication().isHeadlessEnvironment(); for (IdeaPluginDescriptor plugin : PluginManagerCore.getPlugins()) { if (PluginManagerCore.shouldSkipPlugin(plugin)) { continue; } ComponentConfig[] configs = getMyComponentConfigsFromDescriptor(plugin); componentConfigs.ensureCapacity(componentConfigs.size() + configs.length); for (ComponentConfig config : configs) { if ((!isDefaultProject || config.isLoadForDefaultProject()) && isComponentSuitable(config.options) && config.prepareClasses(headless)) { config.pluginDescriptor = plugin; componentConfigs.add(config); } } } return componentConfigs; }
private void registerComponents(@NotNull ComponentConfig config) { ClassLoader loader = config.getClassLoader(); try { final Class<?> interfaceClass = Class.forName(config.getInterfaceClass(), true, loader); final Class<?> implementationClass = Comparing.equal(config.getInterfaceClass(), config.getImplementationClass()) ? interfaceClass : StringUtil.isEmpty(config.getImplementationClass()) ? null : Class.forName(config.getImplementationClass(), true, loader); MutablePicoContainer picoContainer = getPicoContainer(); if (config.options != null && Boolean.parseBoolean(config.options.get("overrides"))) { ComponentAdapter oldAdapter = picoContainer.getComponentAdapterOfType(interfaceClass); if (oldAdapter == null) { throw new RuntimeException(config + " does not override anything"); } picoContainer.unregisterComponent(oldAdapter.getComponentKey()); } // implementationClass == null means we want to unregister this component if (implementationClass != null) { picoContainer.registerComponent(new ComponentConfigComponentAdapter(interfaceClass, implementationClass, config.getPluginId(), config.options != null && Boolean.parseBoolean(config.options.get("workspace")))); } } catch (Throwable t) { handleInitComponentError(t, null, config.getPluginId()); } }
public static void handleComponentError(Throwable t, String componentClassName, ComponentConfig config) { if (t instanceof StartupAbortedException) { throw (StartupAbortedException)t; } PluginId pluginId = config != null ? config.getPluginId() : getPluginByClassName(componentClassName); if (pluginId != null && !CORE_PLUGIN_ID.equals(pluginId.getIdString())) { getLogger().warn(t); disablePlugin(pluginId.getIdString()); String message = "Plugin '" + pluginId.getIdString() + "' failed to initialize and will be disabled\n" + "(reason: " + t.getMessage() + ")\n\n" + ApplicationNamesInfo.getInstance().getFullProductName() + " will be restarted."; Main.showMessage("Plugin Error", message, false); throw new StartupAbortedException(t).exitCode(Main.PLUGIN_ERROR).logError(false); } else { throw new StartupAbortedException("Fatal error initializing '" + componentClassName + "'", t); } }
private static ComponentConfig[] mergeComponents(ComponentConfig[] first, ComponentConfig[] second) { if (first == null) { return second; } if (second == null) { return first; } return ArrayUtil.mergeArrays(first, second); }
@Override protected void handleInitComponentError(Throwable t, String componentClassName, ComponentConfig config) { if (!myHandlingInitComponentError) { myHandlingInitComponentError = true; try { PluginManager.handleComponentError(t, componentClassName, config); } finally { myHandlingInitComponentError = false; } } }
public void loadComponentsConfiguration(final ComponentConfig[] components, final PluginDescriptor descriptor, final boolean defaultProject) { if (components == null) return; loadConfiguration(components, defaultProject, descriptor); }
@Override protected void handleInitComponentError(@Nonnull Throwable ex, @Nullable String componentClassName, @Nullable ComponentConfig config) { if (!myHandlingInitComponentError) { myHandlingInitComponentError = true; try { PluginManager.handleComponentError(ex, componentClassName, config); } finally { myHandlingInitComponentError = false; } } }
public static void handleComponentError(@Nonnull Throwable t, @Nullable String componentClassName, @Nullable ComponentConfig config) { if (t instanceof StartupAbortedException) { throw (StartupAbortedException)t; } PluginId pluginId = null; if (config != null) { pluginId = config.getPluginId(); } if (pluginId == null || CORE_PLUGIN.equals(pluginId)) { pluginId = componentClassName == null ? null : getPluginByClassName(componentClassName); } if (pluginId == null || CORE_PLUGIN.equals(pluginId)) { if (t instanceof PicoPluginExtensionInitializationException) { pluginId = ((PicoPluginExtensionInitializationException)t).getPluginId(); } } if (pluginId != null && !isSystemPlugin(pluginId)) { getLogger().warn(t); if(!ApplicationProperties.isInSandbox()) { disablePlugin(pluginId.getIdString()); } StringWriter message = new StringWriter(); message.append("Plugin '").append(pluginId.getIdString()).append("' failed to initialize and will be disabled. "); message.append(" Please restart ").append(ApplicationNamesInfo.getInstance().getFullProductName()).append('.'); message.append("\n\n"); t.printStackTrace(new PrintWriter(message)); Main.showMessage("Plugin Error", message.toString(), false); throw new StartupAbortedException(t).exitCode(Main.PLUGIN_ERROR).logError(false); } else { throw new StartupAbortedException("Fatal error initializing '" + componentClassName + "'", t); } }
@NotNull ComponentConfig[] getAppComponents();
@NotNull ComponentConfig[] getProjectComponents();
@NotNull ComponentConfig[] getModuleComponents();
@NotNull @Override public ComponentConfig[] getMyComponentConfigsFromDescriptor(@NotNull IdeaPluginDescriptor plugin) { return plugin.getAppComponents(); }
@NotNull public ComponentConfig[] getComponentConfigurations() { return new ComponentConfig[0]; }
@Nullable public Object getComponent(final ComponentConfig componentConfig) { return null; }
public ComponentConfig getConfig(Class componentImplementation) { throw new UnsupportedOperationException("Method getConfig not implemented in " + getClass()); }
@NotNull public ComponentConfig[] getAppComponents() { throw new IllegalStateException(); }
@NotNull public ComponentConfig[] getProjectComponents() { throw new IllegalStateException(); }
@NotNull public ComponentConfig[] getModuleComponents() { throw new IllegalStateException(); }
@NotNull public ComponentConfig[] getMyComponentConfigsFromDescriptor(@NotNull IdeaPluginDescriptor plugin) { return plugin.getAppComponents(); }
@Override @NotNull public ComponentConfig[] getAppComponents() { return myAppComponents; }
@Override @NotNull public ComponentConfig[] getProjectComponents() { return myProjectComponents; }
@Override @NotNull public ComponentConfig[] getModuleComponents() { return myModuleComponents; }
private void loadConfiguration(final ComponentConfig[] configs, final boolean defaultProject, final PluginDescriptor descriptor) { for (ComponentConfig config : configs) { loadSingleConfig(defaultProject, config, descriptor); } }
private void loadSingleConfig(final boolean defaultProject, final ComponentConfig config, final PluginDescriptor descriptor) { if (defaultProject && !config.isLoadForDefaultProject()) return; if (!myComponentManager.isComponentSuitable(config.options)) return; myComponentManager.registerComponent(config, descriptor); }