public void registerExtensionPoint(final ExtensionPointImpl extensionPoint) { final String name = extensionPoint.getName(); myExtensionPoints.put(name, extensionPoint); notifyEPRegistered(extensionPoint); if (DEBUG_REGISTRATION) { myEPTraces.put(name, new Throwable("Original registration for " + name)); } }
public void registerExtension( final PluginDescriptor pluginDescriptor, final Element extensionElement) { final PluginId pluginId = pluginDescriptor.getPluginId(); String epName = extractEPName(extensionElement); ExtensionComponentAdapter adapter; final PicoContainer container = getPluginContainer(pluginId.getIdString()); final ExtensionPoint extensionPoint = getExtensionPoint(epName); if (extensionPoint.getKind() == ExtensionPoint.Kind.INTERFACE) { String implClass = extensionElement.getAttributeValue("implementation"); if (implClass == null) { throw new RuntimeException( "'implementation' attribute not specified for '" + epName + "' extension in '" + pluginId.getIdString() + "' plugin"); } adapter = new ExtensionComponentAdapter( implClass, extensionElement, container, pluginDescriptor, shouldDeserializeInstance(extensionElement)); } else { adapter = new ExtensionComponentAdapter( extensionPoint.getClassName(), extensionElement, container, pluginDescriptor, true); } myExtensionElement2extension.put(extensionElement, adapter); internalGetPluginContainer().registerComponent(adapter); getExtensionPoint(epName).registerExtensionAdapter(adapter); }
static boolean shouldSkipPlugin( final IdeaPluginDescriptor descriptor, IdeaPluginDescriptor[] loaded) { final String idString = descriptor.getPluginId().getIdString(); if (idString.equals(CORE_PLUGIN_ID)) { return false; } //noinspection HardCodedStringLiteral final String pluginId = System.getProperty("idea.load.plugins.id"); if (pluginId == null) { if (descriptor instanceof IdeaPluginDescriptorImpl && !descriptor.isEnabled()) return true; if (!shouldLoadPlugins()) return true; } final List<String> pluginIds = pluginId == null ? null : StringUtil.split(pluginId, ","); final boolean checkModuleDependencies = !ourAvailableModules.isEmpty() && !ourAvailableModules.contains("com.intellij.modules.all"); if (checkModuleDependencies && !hasModuleDependencies(descriptor)) { return true; } boolean shouldLoad; //noinspection HardCodedStringLiteral final String loadPluginCategory = System.getProperty("idea.load.plugins.category"); if (loadPluginCategory != null) { shouldLoad = loadPluginCategory.equals(descriptor.getCategory()); } else { if (pluginIds != null) { shouldLoad = pluginIds.contains(idString); if (!shouldLoad) { Map<PluginId, IdeaPluginDescriptor> map = new HashMap<PluginId, IdeaPluginDescriptor>(); for (final IdeaPluginDescriptor pluginDescriptor : loaded) { map.put(pluginDescriptor.getPluginId(), pluginDescriptor); } addModulesAsDependents(map); final IdeaPluginDescriptor descriptorFromProperty = map.get(PluginId.getId(pluginId)); shouldLoad = descriptorFromProperty != null && isDependent( descriptorFromProperty, descriptor.getPluginId(), map, checkModuleDependencies); } } else { shouldLoad = !getDisabledPlugins().contains(idString); } if (shouldLoad && descriptor instanceof IdeaPluginDescriptorImpl) { if (isIncompatible(descriptor)) return true; } } return !shouldLoad; }
static { ourDefaultEPs.put( EPAvailabilityListenerExtension.EXTENSION_POINT_NAME, EPAvailabilityListenerExtension.class.getName()); }
@Nullable static String filterBadPlugins( List<? extends IdeaPluginDescriptor> result, final Map<String, String> disabledPluginNames) { final Map<PluginId, IdeaPluginDescriptor> idToDescriptorMap = new HashMap<PluginId, IdeaPluginDescriptor>(); final StringBuffer message = new StringBuffer(); boolean pluginsWithoutIdFound = false; for (Iterator<? extends IdeaPluginDescriptor> it = result.iterator(); it.hasNext(); ) { final IdeaPluginDescriptor descriptor = it.next(); final PluginId id = descriptor.getPluginId(); if (id == null) { pluginsWithoutIdFound = true; } if (idToDescriptorMap.containsKey(id)) { message.append("<br>"); message.append(IdeBundle.message("message.duplicate.plugin.id")); message.append(id); it.remove(); } else if (descriptor.isEnabled()) { idToDescriptorMap.put(id, descriptor); } } addModulesAsDependents(idToDescriptorMap); final List<String> disabledPluginIds = new ArrayList<String>(); final LinkedHashSet<String> faultyDescriptors = new LinkedHashSet<String>(); for (final Iterator<? extends IdeaPluginDescriptor> it = result.iterator(); it.hasNext(); ) { final IdeaPluginDescriptor pluginDescriptor = it.next(); checkDependants( pluginDescriptor, new Function<PluginId, IdeaPluginDescriptor>() { @Override public IdeaPluginDescriptor fun(final PluginId pluginId) { return idToDescriptorMap.get(pluginId); } }, new Condition<PluginId>() { @Override public boolean value(final PluginId pluginId) { if (!idToDescriptorMap.containsKey(pluginId)) { pluginDescriptor.setEnabled(false); if (!pluginId.getIdString().startsWith(MODULE_DEPENDENCY_PREFIX)) { faultyDescriptors.add(pluginId.getIdString()); disabledPluginIds.add(pluginDescriptor.getPluginId().getIdString()); message.append("<br>"); final String name = pluginDescriptor.getName(); final IdeaPluginDescriptor descriptor = idToDescriptorMap.get(pluginId); String pluginName; if (descriptor == null) { pluginName = pluginId.getIdString(); if (disabledPluginNames.containsKey(pluginName)) { pluginName = disabledPluginNames.get(pluginName); } } else { pluginName = descriptor.getName(); } message.append( getDisabledPlugins().contains(pluginId.getIdString()) ? IdeBundle.message("error.required.plugin.disabled", name, pluginName) : IdeBundle.message( "error.required.plugin.not.installed", name, pluginName)); } it.remove(); return false; } return true; } }); } if (!disabledPluginIds.isEmpty()) { myPlugins2Disable = disabledPluginIds; myPlugins2Enable = faultyDescriptors; message.append("<br>"); message.append("<br>").append("<a href=\"" + DISABLE + "\">Disable "); if (disabledPluginIds.size() == 1) { final PluginId pluginId2Disable = PluginId.getId(disabledPluginIds.iterator().next()); message.append( idToDescriptorMap.containsKey(pluginId2Disable) ? idToDescriptorMap.get(pluginId2Disable).getName() : pluginId2Disable.getIdString()); } else { message.append("not loaded plugins"); } message.append("</a>"); boolean possibleToEnable = true; for (String descriptor : faultyDescriptors) { if (disabledPluginNames.get(descriptor) == null) { possibleToEnable = false; break; } } if (possibleToEnable) { message .append("<br>") .append("<a href=\"" + ENABLE + "\">Enable ") .append( faultyDescriptors.size() == 1 ? disabledPluginNames.get(faultyDescriptors.iterator().next()) : " all necessary plugins") .append("</a>"); } message.append("<br>").append("<a href=\"" + EDIT + "\">Open plugin manager</a>"); } if (pluginsWithoutIdFound) { message.append("<br>"); message.append(IdeBundle.message("error.plugins.without.id.found")); } if (message.length() > 0) { message.insert(0, IdeBundle.message("error.problems.found.loading.plugins")); return message.toString(); } return null; }
@SuppressWarnings({"HardCodedStringLiteral"}) @Nullable public static IdeaPluginDescriptorImpl loadDescriptor( final File file, @NonNls final String fileName) { IdeaPluginDescriptorImpl descriptor = null; if (file.isDirectory()) { descriptor = loadDescriptorFromDir(file, fileName); if (descriptor == null) { File libDir = new File(file, "lib"); if (!libDir.isDirectory()) { return null; } final File[] files = libDir.listFiles(); if (files == null || files.length == 0) { return null; } Arrays.sort( files, new Comparator<File>() { @Override public int compare(File o1, File o2) { if (o2.getName().startsWith(file.getName())) return Integer.MAX_VALUE; if (o1.getName().startsWith(file.getName())) return -Integer.MAX_VALUE; if (o2.getName().startsWith("resources")) return -Integer.MAX_VALUE; if (o1.getName().startsWith("resources")) return Integer.MAX_VALUE; return 0; } }); for (final File f : files) { if (FileUtil.isJarOrZip(f)) { descriptor = loadDescriptorFromJar(f, fileName); if (descriptor != null) { descriptor.setPath(file); break; } // getLogger().warn("Cannot load descriptor from " + f.getName() + ""); } else if (f.isDirectory()) { IdeaPluginDescriptorImpl descriptor1 = loadDescriptorFromDir(f, fileName); if (descriptor1 != null) { if (descriptor != null) { getLogger() .info("Cannot load " + file + " because two or more plugin.xml's detected"); return null; } descriptor = descriptor1; descriptor.setPath(file); } } } } } else if (StringUtil.endsWithIgnoreCase(file.getName(), ".jar") && file.exists()) { descriptor = loadDescriptorFromJar(file, fileName); } if (descriptor != null && !descriptor.getOptionalConfigs().isEmpty()) { final Map<PluginId, IdeaPluginDescriptorImpl> descriptors = new HashMap<PluginId, IdeaPluginDescriptorImpl>(descriptor.getOptionalConfigs().size()); for (Map.Entry<PluginId, String> entry : descriptor.getOptionalConfigs().entrySet()) { String optionalDescriptorName = entry.getValue(); assert !Comparing.equal(fileName, optionalDescriptorName) : "recursive dependency: " + fileName; IdeaPluginDescriptorImpl optionalDescriptor = loadDescriptor(file, optionalDescriptorName); if (optionalDescriptor == null && !FileUtil.isJarOrZip(file)) { for (URL url : getClassLoaderUrls()) { if ("file".equals(url.getProtocol())) { optionalDescriptor = loadDescriptor(new File(decodeUrl(url.getFile())), optionalDescriptorName); if (optionalDescriptor != null) { break; } } } } if (optionalDescriptor != null) { descriptors.put(entry.getKey(), optionalDescriptor); } else { getLogger().info("Cannot find optional descriptor " + optionalDescriptorName); } } descriptor.setOptionalDescriptors(descriptors); } return descriptor; }
private static void addModulesAsDependents(Map<PluginId, ? super IdeaPluginDescriptorImpl> map) { for (String module : ourAvailableModules) { // fake plugin descriptors to satisfy dependencies map.put(PluginId.getId(module), new IdeaPluginDescriptorImpl()); } }
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; }