Browse Source

Refactoring to make PluginDescriptor more usable (#180)

tags/release-2.1.0
Josiah Haswell 6 years ago
parent
commit
5b192003f4

+ 211
- 0
pf4j/src/main/java/org/pf4j/DefaultPluginDescriptor.java View File

@@ -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;
}

}

+ 3
- 3
pf4j/src/main/java/org/pf4j/ManifestPluginDescriptorFinder.java View File

@@ -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();
}

}

+ 10
- 144
pf4j/src/main/java/org/pf4j/PluginDescriptor.java View File

@@ -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();
}

+ 3
- 3
pf4j/src/main/java/org/pf4j/PropertiesPluginDescriptorFinder.java View File

@@ -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();
}

}

+ 2
- 2
pf4j/src/test/java/org/pf4j/DefaultPluginManagerTest.java View File

@@ -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");

+ 10
- 10
pf4j/src/test/java/org/pf4j/DependencyResolverTest.java View File

@@ -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");


+ 82
- 0
pf4j/src/test/java/org/pf4j/processor/ServiceProviderExtensionStorageTest.java View File

@@ -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")));
}

}

Loading…
Cancel
Save