You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ManifestPluginDescriptorFinder.java 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * Copyright (C) 2012-present the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.pf4j;
  17. import org.pf4j.util.FileUtils;
  18. import org.pf4j.util.StringUtils;
  19. import org.slf4j.Logger;
  20. import org.slf4j.LoggerFactory;
  21. import java.io.IOException;
  22. import java.io.InputStream;
  23. import java.nio.file.Files;
  24. import java.nio.file.Path;
  25. import java.util.jar.Attributes;
  26. import java.util.jar.JarFile;
  27. import java.util.jar.Manifest;
  28. import java.util.zip.ZipEntry;
  29. import java.util.zip.ZipFile;
  30. /**
  31. * Read the plugin descriptor from the manifest file.
  32. *
  33. * @author Decebal Suiu
  34. */
  35. public class ManifestPluginDescriptorFinder implements PluginDescriptorFinder {
  36. private static final Logger log = LoggerFactory.getLogger(ManifestPluginDescriptorFinder.class);
  37. public static final String PLUGIN_ID = "Plugin-Id";
  38. public static final String PLUGIN_DESCRIPTION = "Plugin-Description";
  39. public static final String PLUGIN_CLASS = "Plugin-Class";
  40. public static final String PLUGIN_VERSION = "Plugin-Version";
  41. public static final String PLUGIN_PROVIDER = "Plugin-Provider";
  42. public static final String PLUGIN_DEPENDENCIES = "Plugin-Dependencies";
  43. public static final String PLUGIN_REQUIRES = "Plugin-Requires";
  44. public static final String PLUGIN_LICENSE = "Plugin-License";
  45. @Override
  46. public boolean isApplicable(Path pluginPath) {
  47. return Files.exists(pluginPath) && (Files.isDirectory(pluginPath) || FileUtils.isZipOrJarFile(pluginPath));
  48. }
  49. @Override
  50. public PluginDescriptor find(Path pluginPath) {
  51. Manifest manifest = readManifest(pluginPath);
  52. return createPluginDescriptor(manifest);
  53. }
  54. protected Manifest readManifest(Path pluginPath) {
  55. if (FileUtils.isJarFile(pluginPath)) {
  56. return readManifestFromJar(pluginPath);
  57. }
  58. if (FileUtils.isZipFile(pluginPath)) {
  59. return readManifestFromZip(pluginPath);
  60. }
  61. return readManifestFromDirectory(pluginPath);
  62. }
  63. protected PluginDescriptor createPluginDescriptor(Manifest manifest) {
  64. DefaultPluginDescriptor pluginDescriptor = createPluginDescriptorInstance();
  65. // TODO validate !!!
  66. Attributes attributes = manifest.getMainAttributes();
  67. String id = attributes.getValue(PLUGIN_ID);
  68. pluginDescriptor.setPluginId(id);
  69. String description = attributes.getValue(PLUGIN_DESCRIPTION);
  70. if (StringUtils.isNullOrEmpty(description)) {
  71. pluginDescriptor.setPluginDescription("");
  72. } else {
  73. pluginDescriptor.setPluginDescription(description);
  74. }
  75. String clazz = attributes.getValue(PLUGIN_CLASS);
  76. if (StringUtils.isNotNullOrEmpty(clazz)) {
  77. pluginDescriptor.setPluginClass(clazz);
  78. }
  79. String version = attributes.getValue(PLUGIN_VERSION);
  80. if (StringUtils.isNotNullOrEmpty(version)) {
  81. pluginDescriptor.setPluginVersion(version);
  82. }
  83. String provider = attributes.getValue(PLUGIN_PROVIDER);
  84. pluginDescriptor.setProvider(provider);
  85. String dependencies = attributes.getValue(PLUGIN_DEPENDENCIES);
  86. pluginDescriptor.setDependencies(dependencies);
  87. String requires = attributes.getValue(PLUGIN_REQUIRES);
  88. if (StringUtils.isNotNullOrEmpty(requires)) {
  89. pluginDescriptor.setRequires(requires);
  90. }
  91. pluginDescriptor.setLicense(attributes.getValue(PLUGIN_LICENSE));
  92. return pluginDescriptor;
  93. }
  94. protected DefaultPluginDescriptor createPluginDescriptorInstance() {
  95. return new DefaultPluginDescriptor();
  96. }
  97. protected Manifest readManifestFromJar(Path jarPath) {
  98. try (JarFile jar = new JarFile(jarPath.toFile())) {
  99. return jar.getManifest();
  100. } catch (IOException e) {
  101. throw new PluginRuntimeException(e, "Cannot read manifest from {}", jarPath);
  102. }
  103. }
  104. protected Manifest readManifestFromZip(Path zipPath) {
  105. try (ZipFile zip = new ZipFile(zipPath.toFile())) {
  106. ZipEntry manifestEntry = zip.getEntry("classes/META-INF/MANIFEST.MF");
  107. try (InputStream manifestInput = zip.getInputStream(manifestEntry)) {
  108. return new Manifest(manifestInput);
  109. }
  110. } catch (IOException e) {
  111. throw new PluginRuntimeException(e, "Cannot read manifest from {}", zipPath);
  112. }
  113. }
  114. protected Manifest readManifestFromDirectory(Path pluginPath) {
  115. // legacy (the path is something like "classes/META-INF/MANIFEST.MF")
  116. Path manifestPath = FileUtils.findFile(pluginPath,"MANIFEST.MF");
  117. if (manifestPath == null) {
  118. throw new PluginRuntimeException("Cannot find the manifest path");
  119. }
  120. log.debug("Lookup plugin descriptor in '{}'", manifestPath);
  121. if (Files.notExists(manifestPath)) {
  122. throw new PluginRuntimeException("Cannot find '{}' path", manifestPath);
  123. }
  124. try (InputStream input = Files.newInputStream(manifestPath)) {
  125. return new Manifest(input);
  126. } catch (IOException e) {
  127. throw new PluginRuntimeException(e, "Cannot read manifest from {}", pluginPath);
  128. }
  129. }
  130. }