static void logPlugins() { List<String> loadedBundled = new ArrayList<String>(); List<String> disabled = new ArrayList<String>(); List<String> loadedCustom = new ArrayList<String>(); for (IdeaPluginDescriptor descriptor : ourPlugins) { final String version = descriptor.getVersion(); String s = descriptor.getName() + (version != null ? " (" + version + ")" : ""); if (descriptor.isEnabled()) { if (descriptor.isBundled() || SPECIAL_IDEA_PLUGIN.equals(descriptor.getName())) loadedBundled.add(s); else loadedCustom.add(s); } else { disabled.add(s); } } Collections.sort(loadedBundled); Collections.sort(loadedCustom); Collections.sort(disabled); getLogger().info("Loaded bundled plugins: " + StringUtil.join(loadedBundled, ", ")); if (!loadedCustom.isEmpty()) { getLogger().info("Loaded custom plugins: " + StringUtil.join(loadedCustom, ", ")); } if (!disabled.isEmpty()) { getLogger().info("Disabled plugins: " + StringUtil.join(disabled, ", ")); } }
private void queueNotificationAction(final Runnable action) { if (myAvailabilityNotificationsActive) { action.run(); } else { mySuspendedListenerActions.add(action); } }
public static void loadDescriptors( String pluginsPath, List<IdeaPluginDescriptorImpl> result, @Nullable StartupProgress progress, int pluginsCount) { final File pluginsHome = new File(pluginsPath); final File[] files = pluginsHome.listFiles(); if (files != null) { int i = result.size(); for (File file : files) { final IdeaPluginDescriptorImpl descriptor = loadDescriptor(file, PLUGIN_XML); if (descriptor == null) continue; if (progress != null) { progress.showProgress( descriptor.getName(), PLUGINS_PROGRESS_MAX_VALUE * ((float) ++i / pluginsCount)); } int oldIndex = result.indexOf(descriptor); if (oldIndex >= 0) { final IdeaPluginDescriptorImpl oldDescriptor = result.get(oldIndex); if (StringUtil.compareVersionNumbers(oldDescriptor.getVersion(), descriptor.getVersion()) < 0) { result.set(oldIndex, descriptor); } } else { result.add(descriptor); } } } }
static void loadDescriptorsFromClassPath( @NotNull List<IdeaPluginDescriptorImpl> result, @Nullable StartupProgress progress) { Collection<URL> urls = getClassLoaderUrls(); String platformPrefix = System.getProperty(PlatformUtilsCore.PLATFORM_PREFIX_KEY); int i = 0; for (URL url : urls) { i++; if ("file".equals(url.getProtocol())) { File file = new File(decodeUrl(url.getFile())); IdeaPluginDescriptorImpl platformPluginDescriptor = null; if (platformPrefix != null) { platformPluginDescriptor = loadDescriptor(file, platformPrefix + "Plugin.xml"); if (platformPluginDescriptor != null && !result.contains(platformPluginDescriptor)) { platformPluginDescriptor.setUseCoreClassLoader(true); result.add(platformPluginDescriptor); } } IdeaPluginDescriptorImpl pluginDescriptor = loadDescriptor(file, PLUGIN_XML); if (platformPrefix != null && pluginDescriptor != null && pluginDescriptor.getName().equals(SPECIAL_IDEA_PLUGIN)) { continue; } if (pluginDescriptor != null && !result.contains(pluginDescriptor)) { if (platformPluginDescriptor != null) { // if we found a regular plugin.xml in the same .jar/root as a platform-prefixed // descriptor, use the core loader for it too pluginDescriptor.setUseCoreClassLoader(true); } result.add(pluginDescriptor); if (progress != null) { progress.showProgress( "Plugin loaded: " + pluginDescriptor.getName(), PLUGINS_PROGRESS_MAX_VALUE * ((float) i / urls.size())); } } } } }
static void loadDescriptorsFromProperty(final List<IdeaPluginDescriptorImpl> result) { final String pathProperty = System.getProperty(PROPERTY_PLUGIN_PATH); if (pathProperty == null) return; for (StringTokenizer t = new StringTokenizer(pathProperty, File.pathSeparator); t.hasMoreTokens(); ) { String s = t.nextToken(); final IdeaPluginDescriptorImpl ideaPluginDescriptor = loadDescriptor(new File(s), PLUGIN_XML); if (ideaPluginDescriptor != null) { result.add(ideaPluginDescriptor); } } }
@Nullable static ClassLoader createPluginClassLoader( @NotNull File[] classPath, @NotNull ClassLoader[] parentLoaders, @NotNull IdeaPluginDescriptor pluginDescriptor) { if (pluginDescriptor.getUseIdeaClassLoader()) { try { final ClassLoader loader = PluginManagerCore.class.getClassLoader(); final Method addUrlMethod = getAddUrlMethod(loader); for (File aClassPath : classPath) { final File file = aClassPath.getCanonicalFile(); addUrlMethod.invoke(loader, file.toURI().toURL()); } return loader; } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } PluginId pluginId = pluginDescriptor.getPluginId(); File pluginRoot = pluginDescriptor.getPath(); // if (classPath.length == 0) return null; if (isUnitTestMode()) return null; try { final List<URL> urls = new ArrayList<URL>(classPath.length); for (File aClassPath : classPath) { final File file = aClassPath .getCanonicalFile(); // it is critical not to have "." and ".." in classpath // elements urls.add(file.toURI().toURL()); } return new PluginClassLoader( urls, parentLoaders, pluginId, pluginDescriptor.getVersion(), pluginRoot); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; }
static ClassLoader[] getParentLoaders( Map<PluginId, ? extends IdeaPluginDescriptor> idToDescriptorMap, PluginId[] pluginIds) { if (isUnitTestMode()) return new ClassLoader[0]; final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(); for (final PluginId id : pluginIds) { IdeaPluginDescriptor pluginDescriptor = idToDescriptorMap.get(id); if (pluginDescriptor == null) { continue; // Might be an optional dependency } final ClassLoader loader = pluginDescriptor.getPluginClassLoader(); if (loader == null) { getLogger().error("Plugin class loader should be initialized for plugin " + id); } classLoaders.add(loader); } return classLoaders.toArray(new ClassLoader[classLoaders.size()]); }
static void initializePlugins(@Nullable StartupProgress progress) { configureExtensions(); final IdeaPluginDescriptorImpl[] pluginDescriptors = loadDescriptors(progress); final Class callerClass = ReflectionUtil.findCallerClass(1); assert callerClass != null; final ClassLoader parentLoader = callerClass.getClassLoader(); final List<IdeaPluginDescriptorImpl> result = new ArrayList<IdeaPluginDescriptorImpl>(); final HashMap<String, String> disabledPluginNames = new HashMap<String, String>(); for (IdeaPluginDescriptorImpl descriptor : pluginDescriptors) { if (descriptor.getPluginId().getIdString().equals(CORE_PLUGIN_ID)) { final List<String> modules = descriptor.getModules(); if (modules != null) { ourAvailableModules.addAll(modules); } } if (!shouldSkipPlugin(descriptor, pluginDescriptors)) { result.add(descriptor); } else { descriptor.setEnabled(false); disabledPluginNames.put(descriptor.getPluginId().getIdString(), descriptor.getName()); initClassLoader(parentLoader, descriptor); } } prepareLoadingPluginsErrorMessage(filterBadPlugins(result, disabledPluginNames)); final Map<PluginId, IdeaPluginDescriptorImpl> idToDescriptorMap = new HashMap<PluginId, IdeaPluginDescriptorImpl>(); for (final IdeaPluginDescriptorImpl descriptor : result) { idToDescriptorMap.put(descriptor.getPluginId(), descriptor); } final IdeaPluginDescriptor corePluginDescriptor = idToDescriptorMap.get(PluginId.getId(CORE_PLUGIN_ID)); assert corePluginDescriptor != null : CORE_PLUGIN_ID + " not found; platform prefix is " + System.getProperty(PlatformUtilsCore.PLATFORM_PREFIX_KEY); for (IdeaPluginDescriptorImpl descriptor : result) { if (descriptor != corePluginDescriptor) { descriptor.insertDependency(corePluginDescriptor); } } mergeOptionalConfigs(idToDescriptorMap); // sort descriptors according to plugin dependencies Collections.sort(result, getPluginDescriptorComparator(idToDescriptorMap)); for (int i = 0; i < result.size(); i++) { ourId2Index.put(result.get(i).getPluginId(), i); } int i = 0; for (final IdeaPluginDescriptorImpl pluginDescriptor : result) { if (pluginDescriptor.getPluginId().getIdString().equals(CORE_PLUGIN_ID) || pluginDescriptor.isUseCoreClassLoader()) { pluginDescriptor.setLoader(parentLoader); } else { final List<File> classPath = pluginDescriptor.getClassPath(); final PluginId[] dependentPluginIds = pluginDescriptor.getDependentPluginIds(); final ClassLoader[] parentLoaders = getParentLoaders(idToDescriptorMap, dependentPluginIds); final ClassLoader pluginClassLoader = createPluginClassLoader( classPath.toArray(new File[classPath.size()]), parentLoaders.length > 0 ? parentLoaders : new ClassLoader[] {parentLoader}, pluginDescriptor); pluginDescriptor.setLoader(pluginClassLoader); } if (progress != null) { progress.showProgress( "", PLUGINS_PROGRESS_MAX_VALUE + (i++ / (float) result.size()) * 0.35f); } } registerExtensionPointsAndExtensions(Extensions.getRootArea(), result); Extensions.getRootArea() .getExtensionPoint(Extensions.AREA_LISTENER_EXTENSION_POINT) .registerExtension( new AreaListener() { @Override public void areaCreated( @NotNull String areaClass, @NotNull AreaInstance areaInstance) { registerExtensionPointsAndExtensions(Extensions.getArea(areaInstance), result); } @Override public void areaDisposing( @NotNull String areaClass, @NotNull AreaInstance areaInstance) {} }); ourPlugins = pluginDescriptors; }