@@ -0,0 +1,211 @@ | |||
/* | |||
* Copyright 2012 Decebal Suiu | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
* You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
package org.pf4j; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.List; | |||
/** | |||
* A plugin descriptor contains information about a plug-in obtained | |||
* from the manifest (META-INF) file. | |||
* | |||
* @author Decebal Suiu | |||
*/ | |||
public class DefaultPluginDescriptor implements PluginDescriptor { | |||
private String pluginId; | |||
private String pluginDescription; | |||
private String pluginClass; | |||
private String version; | |||
private String requires = "*"; // SemVer format | |||
private String provider; | |||
private List<PluginDependency> dependencies; | |||
private String license; | |||
public DefaultPluginDescriptor() { | |||
dependencies = new ArrayList<>(); | |||
} | |||
/** | |||
* @param pluginId | |||
* @param pluginDescription | |||
* @param pluginClass | |||
* @param version | |||
* @param requires | |||
* @param provider | |||
* @param license | |||
*/ | |||
public DefaultPluginDescriptor(String pluginId, String pluginDescription, String pluginClass, String version, String requires, String provider, String license) { | |||
this(); | |||
this.pluginId = pluginId; | |||
this.pluginDescription = pluginDescription; | |||
this.pluginClass = pluginClass; | |||
this.version = version; | |||
this.requires = requires; | |||
this.provider = provider; | |||
this.license = license; | |||
} | |||
public void addDependency(PluginDependency dependency) { | |||
this.dependencies.add(dependency); | |||
} | |||
/** | |||
* Returns the unique identifier of this plugin. | |||
*/ | |||
@Override | |||
public String getPluginId() { | |||
return pluginId; | |||
} | |||
/** | |||
* Returns the description of this plugin. | |||
*/ | |||
@Override | |||
public String getPluginDescription() { | |||
return pluginDescription; | |||
} | |||
/** | |||
* Returns the name of the class that implements Plugin interface. | |||
*/ | |||
@Override | |||
public String getPluginClass() { | |||
return pluginClass; | |||
} | |||
/** | |||
* Returns the version of this plugin. | |||
*/ | |||
@Override | |||
public String getVersion() { | |||
return version; | |||
} | |||
/** | |||
* Returns string version of requires | |||
* | |||
* @return String with requires expression on SemVer format | |||
*/ | |||
@Override | |||
public String getRequires() { | |||
return requires; | |||
} | |||
/** | |||
* Returns the provider name of this plugin. | |||
*/ | |||
@Override | |||
public String getProvider() { | |||
return provider; | |||
} | |||
/** | |||
* Returns the legal license of this plugin, e.g. "Apache-2.0", "MIT" etc | |||
*/ | |||
@Override | |||
public String getLicense() { | |||
return license; | |||
} | |||
/** | |||
* Returns all dependencies declared by this plugin. | |||
* Returns an empty array if this plugin does not declare any require. | |||
*/ | |||
@Override | |||
public List<PluginDependency> getDependencies() { | |||
return dependencies; | |||
} | |||
@Override | |||
public String toString() { | |||
return "PluginDescriptor [pluginId=" + pluginId + ", pluginClass=" | |||
+ pluginClass + ", version=" + version + ", provider=" | |||
+ provider + ", dependencies=" + dependencies + ", description=" | |||
+ pluginDescription + ", requires=" + requires + ", license=" | |||
+ license + "]"; | |||
} | |||
protected DefaultPluginDescriptor setPluginId(String pluginId) { | |||
this.pluginId = pluginId; | |||
return this; | |||
} | |||
protected PluginDescriptor setPluginDescription(String pluginDescription) { | |||
this.pluginDescription = pluginDescription; | |||
return this; | |||
} | |||
protected PluginDescriptor setPluginClass(String pluginClassName) { | |||
this.pluginClass = pluginClassName; | |||
return this; | |||
} | |||
protected DefaultPluginDescriptor setPluginVersion(String version) { | |||
this.version = version; | |||
return this; | |||
} | |||
protected PluginDescriptor setProvider(String provider) { | |||
this.provider = provider; | |||
return this; | |||
} | |||
protected PluginDescriptor setRequires(String requires) { | |||
this.requires = requires; | |||
return this; | |||
} | |||
protected PluginDescriptor setDependencies(String dependencies) { | |||
if (dependencies != null) { | |||
dependencies = dependencies.trim(); | |||
if (dependencies.isEmpty()) { | |||
this.dependencies = Collections.emptyList(); | |||
} else { | |||
this.dependencies = new ArrayList<>(); | |||
String[] tokens = dependencies.split(","); | |||
for (String dependency : tokens) { | |||
dependency = dependency.trim(); | |||
if (!dependency.isEmpty()) { | |||
this.dependencies.add(new PluginDependency(dependency)); | |||
} | |||
} | |||
if (this.dependencies.isEmpty()) { | |||
this.dependencies = Collections.emptyList(); | |||
} | |||
} | |||
} else { | |||
this.dependencies = Collections.emptyList(); | |||
} | |||
return this; | |||
} | |||
public PluginDescriptor setLicense(String license) { | |||
this.license = license; | |||
return this; | |||
} | |||
} |
@@ -88,7 +88,7 @@ public class ManifestPluginDescriptorFinder implements PluginDescriptorFinder { | |||
} | |||
protected PluginDescriptor createPluginDescriptor(Manifest manifest) { | |||
PluginDescriptor pluginDescriptor = createPluginDescriptorInstance(); | |||
DefaultPluginDescriptor pluginDescriptor = createPluginDescriptorInstance(); | |||
// TODO validate !!! | |||
Attributes attributes = manifest.getMainAttributes(); | |||
@@ -125,8 +125,8 @@ public class ManifestPluginDescriptorFinder implements PluginDescriptorFinder { | |||
return pluginDescriptor; | |||
} | |||
protected PluginDescriptor createPluginDescriptorInstance() { | |||
return new PluginDescriptor(); | |||
protected DefaultPluginDescriptor createPluginDescriptorInstance() { | |||
return new DefaultPluginDescriptor(); | |||
} | |||
} |
@@ -1,5 +1,5 @@ | |||
/* | |||
* Copyright 2012 Decebal Suiu | |||
* Copyright 2015 Decebal Suiu | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
@@ -15,8 +15,6 @@ | |||
*/ | |||
package org.pf4j; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.List; | |||
/** | |||
@@ -25,153 +23,21 @@ import java.util.List; | |||
* | |||
* @author Decebal Suiu | |||
*/ | |||
public class PluginDescriptor { | |||
public interface PluginDescriptor { | |||
private String pluginId; | |||
private String pluginDescription; | |||
private String pluginClass; | |||
private String version; | |||
private String requires = "*"; // SemVer format | |||
private String provider; | |||
private List<PluginDependency> dependencies; | |||
private String license; | |||
String getPluginId(); | |||
public PluginDescriptor() { | |||
dependencies = new ArrayList<>(); | |||
} | |||
String getPluginDescription(); | |||
/** | |||
* Returns the unique identifier of this plugin. | |||
*/ | |||
public String getPluginId() { | |||
return pluginId; | |||
} | |||
String getPluginClass(); | |||
/** | |||
* Returns the description of this plugin. | |||
*/ | |||
public String getPluginDescription() { | |||
return pluginDescription; | |||
} | |||
String getVersion(); | |||
/** | |||
* Returns the name of the class that implements Plugin interface. | |||
*/ | |||
public String getPluginClass() { | |||
return pluginClass; | |||
} | |||
String getRequires(); | |||
/** | |||
* Returns the version of this plugin. | |||
*/ | |||
public String getVersion() { | |||
return version; | |||
} | |||
String getProvider(); | |||
/** | |||
* Returns string version of requires | |||
* @return String with requires expression on SemVer format | |||
*/ | |||
public String getRequires() { | |||
return requires; | |||
} | |||
/** | |||
* Returns the provider name of this plugin. | |||
*/ | |||
public String getProvider() { | |||
return provider; | |||
} | |||
/** | |||
* Returns the legal license of this plugin, e.g. "Apache-2.0", "MIT" etc | |||
*/ | |||
public String getLicense() { | |||
return license; | |||
} | |||
/** | |||
* Returns all dependencies declared by this plugin. | |||
* Returns an empty array if this plugin does not declare any require. | |||
*/ | |||
public List<PluginDependency> getDependencies() { | |||
return dependencies; | |||
} | |||
@Override | |||
public String toString() { | |||
return "PluginDescriptor [pluginId=" + pluginId + ", pluginClass=" | |||
+ pluginClass + ", version=" + version + ", provider=" | |||
+ provider + ", dependencies=" + dependencies + ", description=" | |||
+ pluginDescription + ", requires=" + requires + ", license=" | |||
+ license + "]"; | |||
} | |||
PluginDescriptor setPluginId(String pluginId) { | |||
this.pluginId = pluginId; | |||
return this; | |||
} | |||
PluginDescriptor setPluginDescription(String pluginDescription) { | |||
this.pluginDescription = pluginDescription; | |||
return this; | |||
} | |||
PluginDescriptor setPluginClass(String pluginClassName) { | |||
this.pluginClass = pluginClassName; | |||
return this; | |||
} | |||
PluginDescriptor setPluginVersion(String version) { | |||
this.version = version; | |||
return this; | |||
} | |||
PluginDescriptor setProvider(String provider) { | |||
this.provider = provider; | |||
return this; | |||
} | |||
PluginDescriptor setRequires(String requires) { | |||
this.requires = requires; | |||
return this; | |||
} | |||
PluginDescriptor setDependencies(String dependencies) { | |||
if (dependencies != null) { | |||
dependencies = dependencies.trim(); | |||
if (dependencies.isEmpty()) { | |||
this.dependencies = Collections.emptyList(); | |||
} else { | |||
this.dependencies = new ArrayList<>(); | |||
String[] tokens = dependencies.split(","); | |||
for (String dependency : tokens) { | |||
dependency = dependency.trim(); | |||
if (!dependency.isEmpty()) { | |||
this.dependencies.add(new PluginDependency(dependency)); | |||
} | |||
} | |||
if (this.dependencies.isEmpty()) { | |||
this.dependencies = Collections.emptyList(); | |||
} | |||
} | |||
} else { | |||
this.dependencies = Collections.emptyList(); | |||
} | |||
return this; | |||
} | |||
public PluginDescriptor setLicense(String license) { | |||
this.license = license; | |||
return this; | |||
} | |||
String getLicense(); | |||
List<PluginDependency> getDependencies(); | |||
} |
@@ -95,7 +95,7 @@ public class PropertiesPluginDescriptorFinder implements PluginDescriptorFinder | |||
} | |||
protected PluginDescriptor createPluginDescriptor(Properties properties) { | |||
PluginDescriptor pluginDescriptor = createPluginDescriptorInstance(); | |||
DefaultPluginDescriptor pluginDescriptor = createPluginDescriptorInstance(); | |||
// TODO validate !!! | |||
String id = properties.getProperty("plugin.id"); | |||
@@ -132,8 +132,8 @@ public class PropertiesPluginDescriptorFinder implements PluginDescriptorFinder | |||
return pluginDescriptor; | |||
} | |||
protected PluginDescriptor createPluginDescriptorInstance() { | |||
return new PluginDescriptor(); | |||
protected DefaultPluginDescriptor createPluginDescriptorInstance() { | |||
return new DefaultPluginDescriptor(); | |||
} | |||
} |
@@ -27,13 +27,13 @@ import static org.junit.Assert.assertTrue; | |||
public class DefaultPluginManagerTest { | |||
private PluginDescriptor pd1 = null; | |||
private DefaultPluginDescriptor pd1 = null; | |||
private DefaultPluginManager pluginManager = new DefaultPluginManager(); | |||
private PluginWrapper pw1; | |||
@Before | |||
public void init() throws IOException { | |||
pd1 = new PluginDescriptor(); | |||
pd1 = new DefaultPluginDescriptor(); | |||
pd1.setPluginId("myPlugin"); | |||
pd1.setPluginVersion("1.2.3"); | |||
pd1.setPluginClass("foo"); |
@@ -40,11 +40,11 @@ public class DependencyResolverTest { | |||
@Test | |||
public void sortedPlugins() { | |||
// create incomplete plugin descriptor (ignore some attributes) | |||
PluginDescriptor pd1 = new PluginDescriptor() | |||
PluginDescriptor pd1 = new DefaultPluginDescriptor() | |||
.setPluginId("p1") | |||
.setDependencies("p2"); | |||
PluginDescriptor pd2 = new PluginDescriptor() | |||
PluginDescriptor pd2 = new DefaultPluginDescriptor() | |||
.setPluginId("p2") | |||
.setPluginVersion("0.0.0"); // needed in "checkDependencyVersion" method | |||
@@ -60,7 +60,7 @@ public class DependencyResolverTest { | |||
@Test | |||
public void notFoundDependencies() throws Exception { | |||
PluginDescriptor pd1 = new PluginDescriptor() | |||
PluginDescriptor pd1 = new DefaultPluginDescriptor() | |||
.setPluginId("p1") | |||
.setDependencies("p2, p3"); | |||
@@ -75,17 +75,17 @@ public class DependencyResolverTest { | |||
@Test | |||
public void cyclicDependencies() { | |||
PluginDescriptor pd1 = new PluginDescriptor() | |||
PluginDescriptor pd1 = new DefaultPluginDescriptor() | |||
.setPluginId("p1") | |||
.setPluginVersion("0.0.0") | |||
.setDependencies("p2"); | |||
PluginDescriptor pd2 = new PluginDescriptor() | |||
PluginDescriptor pd2 = new DefaultPluginDescriptor() | |||
.setPluginId("p2") | |||
.setPluginVersion("0.0.0") | |||
.setDependencies("p3"); | |||
PluginDescriptor pd3 = new PluginDescriptor() | |||
PluginDescriptor pd3 = new DefaultPluginDescriptor() | |||
.setPluginId("p3") | |||
.setPluginVersion("0.0.0") | |||
.setDependencies("p1"); | |||
@@ -102,12 +102,12 @@ public class DependencyResolverTest { | |||
@Test | |||
public void wrongDependencyVersion() { | |||
PluginDescriptor pd1 = new PluginDescriptor() | |||
PluginDescriptor pd1 = new DefaultPluginDescriptor() | |||
.setPluginId("p1") | |||
// .setDependencies("p2@2.0.0"); // simple version | |||
.setDependencies("p2@>=1.5.0 & <1.6.0"); // range version | |||
PluginDescriptor pd2 = new PluginDescriptor() | |||
PluginDescriptor pd2 = new DefaultPluginDescriptor() | |||
.setPluginId("p2") | |||
.setPluginVersion("1.4.0"); | |||
@@ -122,11 +122,11 @@ public class DependencyResolverTest { | |||
@Test | |||
public void goodDependencyVersion() { | |||
PluginDescriptor pd1 = new PluginDescriptor() | |||
PluginDescriptor pd1 = new DefaultPluginDescriptor() | |||
.setPluginId("p1") | |||
.setDependencies("p2@2.0.0"); | |||
PluginDescriptor pd2 = new PluginDescriptor() | |||
PluginDescriptor pd2 = new DefaultPluginDescriptor() | |||
.setPluginId("p2") | |||
.setPluginVersion("2.0.0"); | |||
@@ -0,0 +1,82 @@ | |||
/* | |||
* Copyright 2015 Decebal Suiu | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
* You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
package org.pf4j.processor; | |||
import org.junit.Test; | |||
import javax.annotation.processing.Filer; | |||
import javax.tools.FileObject; | |||
import javax.tools.StandardLocation; | |||
import java.io.IOException; | |||
import java.io.StringReader; | |||
import java.util.*; | |||
import static org.hamcrest.core.Is.is; | |||
import static org.junit.Assert.*; | |||
import static org.mockito.BDDMockito.given; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Mockito.mock; | |||
/** | |||
* @author Josiah Haswell | |||
*/ | |||
public class ServiceProviderExtensionStorageTest { | |||
@Test | |||
public void ensureServiceProviderExtensionStorageReadWorks() throws IOException { | |||
final StringReader file = new StringReader("#hello\n World"); | |||
final Set<String> entries = new HashSet<>(); | |||
ServiceProviderExtensionStorage.read(file, entries); | |||
assertThat(entries.size(), is(1)); | |||
assertThat(entries.contains("World"), is(true)); | |||
} | |||
@Test | |||
public void ensureReadingExtensionsProducesCorrectListOfExtensions() { | |||
final StringReader file = new StringReader("#hello\n World"); | |||
final ExtensionAnnotationProcessor processor = mock(ExtensionAnnotationProcessor.class); | |||
final Map<String, Set<String>> extensions = new HashMap<>(); | |||
extensions.put("hello", Collections.singleton("world")); | |||
given(processor.getExtensions()).willReturn(extensions); | |||
ServiceProviderExtensionStorage extensionStorage = new ServiceProviderExtensionStorage(processor) { | |||
@Override | |||
protected Filer getFiler() { | |||
try { | |||
Filer filer = mock(Filer.class); | |||
FileObject fileObject = mock(FileObject.class); | |||
given(fileObject.openReader(true)).willReturn(file); | |||
given(filer.getResource( | |||
any(StandardLocation.class), | |||
any(String.class), | |||
any(String.class) | |||
)).willReturn(fileObject); | |||
return filer; | |||
} catch(IOException ex) { | |||
throw new IllegalStateException("Shouldn't have gotten here"); | |||
} | |||
} | |||
}; | |||
Map<String, Set<String>> read = extensionStorage.read(); | |||
assertThat(read.containsKey("hello"), is(true)); | |||
assertThat(read.get("hello"), is(Collections.singleton("World"))); | |||
} | |||
} |