Catalogs all of the plugins and their versions in the given paths.
| 42 | |
| 43 | /** Catalogs all of the plugins and their versions in the given paths. */ |
| 44 | class PluginCatalog { |
| 45 | /** A map from plugin name to a set of available versions. */ |
| 46 | private final SetMultimap<String, Version> availableVersions = HashMultimap.create(); |
| 47 | private final Table<String, Version, File> toFile = HashBasedTable.create(); |
| 48 | /** A version mapping policy. */ |
| 49 | private final ExplicitVersionPolicy versionPolicy; |
| 50 | /** A set containing plugins which are specific to platforms which we don't support. */ |
| 51 | private final Set<String> unsupportedPlatform = Sets.newHashSet(); |
| 52 | |
| 53 | private static final String MANIFEST_PATH = "META-INF/MANIFEST.MF"; |
| 54 | private static final String BUNDLE_NAME = "Bundle-SymbolicName"; |
| 55 | private static final String BUNDLE_VERSION = "Bundle-Version"; |
| 56 | private static final String ECLIPSE_PLATFORM_FILTER = "Eclipse-PlatformFilter"; |
| 57 | |
| 58 | /** |
| 59 | * Catalogs all of the plugins in the given roots. If a plugin |
| 60 | * exists with two versions, an exception is thrown, unless it is |
| 61 | * handled by the MultipleVersionPolicy. |
| 62 | */ |
| 63 | public PluginCatalog(ExplicitVersionPolicy versionPolicy, List<SwtPlatform> supported, List<File> roots) { |
| 64 | this.versionPolicy = Objects.requireNonNull(versionPolicy); |
| 65 | for (File root : roots) { |
| 66 | Preconditions.checkArgument(root.exists(), "Root '%s' does not exist.", root); |
| 67 | File pluginRoot = root; |
| 68 | File plugins = new File(root, "plugins"); |
| 69 | if (plugins.exists()) { |
| 70 | pluginRoot = plugins; |
| 71 | } |
| 72 | |
| 73 | List<File> files = FileMisc.list(pluginRoot); |
| 74 | Preconditions.checkArgument(files.size() > 0, "No plugins found in " + root); |
| 75 | // look for plugin.jar |
| 76 | files.stream().filter(file -> file.isFile() && file.getName().endsWith(".jar")) |
| 77 | .forEach(Errors.rethrow().wrap(file -> { |
| 78 | ZipMisc.read(file, MANIFEST_PATH, input -> addManifest(supported, new Manifest(input), file)); |
| 79 | })); |
| 80 | // look for folder-style plugins (especially org.eclipse.core.runtime.compatibility.registry) |
| 81 | files.stream().filter(file -> file.isDirectory()).forEach(Errors.rethrow().wrap(folder -> { |
| 82 | File manifestFile = new File(folder, MANIFEST_PATH); |
| 83 | if (manifestFile.exists()) { |
| 84 | try (FileInputStream input = new FileInputStream(new File(folder, MANIFEST_PATH))) { |
| 85 | addManifest(supported, new Manifest(input), folder); |
| 86 | } |
| 87 | } |
| 88 | })); |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | /** Adds a manifest to the catalog. */ |
| 93 | private void addManifest(List<SwtPlatform> supported, Manifest parsed, File plugin) { |
| 94 | // parse out the name (looking out for the ";singleton=true" names |
| 95 | String name = parsed.getMainAttributes().getValue(BUNDLE_NAME); |
| 96 | int splitIdx = name.indexOf(';'); |
| 97 | if (splitIdx > 0) { |
| 98 | name = name.substring(0, splitIdx); |
| 99 | } |
| 100 | |
| 101 | // parse out the platform filter (if any) |