public static IdeaPluginDescriptorImpl[] loadDescriptors(@Nullable StartupProgress progress) { if (ClassUtilCore.isLoadingOfExternalPluginsDisabled()) { return IdeaPluginDescriptorImpl.EMPTY_ARRAY; } final List<IdeaPluginDescriptorImpl> result = new ArrayList<IdeaPluginDescriptorImpl>(); int pluginsCount = countPlugins(PathManager.getPluginsPath()) + countPlugins(PathManager.getPreInstalledPluginsPath()); loadDescriptors(PathManager.getPluginsPath(), result, progress, pluginsCount); Application application = ApplicationManager.getApplication(); boolean fromSources = false; if (application == null || !application.isUnitTestMode()) { int size = result.size(); loadDescriptors(PathManager.getPreInstalledPluginsPath(), result, progress, pluginsCount); fromSources = size == result.size(); } loadDescriptorsFromProperty(result); loadDescriptorsFromClassPath(result, fromSources ? progress : null); IdeaPluginDescriptorImpl[] pluginDescriptors = result.toArray(new IdeaPluginDescriptorImpl[result.size()]); try { Arrays.sort(pluginDescriptors, new PluginDescriptorComparator(pluginDescriptors)); } catch (Exception e) { prepareLoadingPluginsErrorMessage( IdeBundle.message("error.plugins.were.not.loaded", e.getMessage())); getLogger().info(e); return findCorePlugin(pluginDescriptors); } return pluginDescriptors; }
private static boolean checkDependants( final IdeaPluginDescriptor pluginDescriptor, final Function<PluginId, IdeaPluginDescriptor> pluginId2Descriptor, final Condition<PluginId> check, final Set<PluginId> processed) { processed.add(pluginDescriptor.getPluginId()); final PluginId[] dependentPluginIds = pluginDescriptor.getDependentPluginIds(); final Set<PluginId> optionalDependencies = new HashSet<PluginId>(Arrays.asList(pluginDescriptor.getOptionalDependentPluginIds())); for (final PluginId dependentPluginId : dependentPluginIds) { if (processed.contains(dependentPluginId)) continue; // TODO[yole] should this condition be a parameter? if (isModuleDependency(dependentPluginId) && (ourAvailableModules.isEmpty() || ourAvailableModules.contains(dependentPluginId.getIdString()))) { continue; } if (!optionalDependencies.contains(dependentPluginId)) { if (!check.value(dependentPluginId)) { return false; } final IdeaPluginDescriptor dependantPluginDescriptor = pluginId2Descriptor.fun(dependentPluginId); if (dependantPluginDescriptor != null && !checkDependants(dependantPluginDescriptor, pluginId2Descriptor, check, processed)) { return false; } } } return true; }
static Collection<URL> getClassLoaderUrls() { final ClassLoader classLoader = PluginManagerCore.class.getClassLoader(); final Class<? extends ClassLoader> aClass = classLoader.getClass(); try { @SuppressWarnings("unchecked") List<URL> urls = (List<URL>) aClass.getMethod("getUrls").invoke(classLoader); return urls; } catch (IllegalAccessException ignored) { } catch (InvocationTargetException ignored) { } catch (NoSuchMethodException ignored) { } if (classLoader instanceof URLClassLoader) { return Arrays.asList(((URLClassLoader) classLoader).getURLs()); } return Collections.emptyList(); }
@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; }