Browse Source

Support any interface as an ExtensionPoint (#350)

pull/352/head
Decebal Suiu 5 years ago committed by GitHub
parent
commit
45eeec8a72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 37
      pf4j/src/main/java/org/pf4j/processor/ExtensionAnnotationProcessor.java
  2. 2
      pf4j/src/test/java/org/pf4j/ExtensionAnnotationProcessorTest.java

37
pf4j/src/main/java/org/pf4j/processor/ExtensionAnnotationProcessor.java

@ -52,19 +52,23 @@ import java.util.TreeSet;
public class ExtensionAnnotationProcessor extends AbstractProcessor { public class ExtensionAnnotationProcessor extends AbstractProcessor {
private static final String STORAGE_CLASS_NAME = "pf4j.storageClassName"; private static final String STORAGE_CLASS_NAME = "pf4j.storageClassName";
private static final String IGNORE_EXTENSION_POINT = "pf4j.ignoreExtensionPoint";
private Map<String, Set<String>> extensions = new HashMap<>(); // the key is the extension point private Map<String, Set<String>> extensions = new HashMap<>(); // the key is the extension point
private Map<String, Set<String>> oldExtensions = new HashMap<>(); // the key is the extension point private Map<String, Set<String>> oldExtensions = new HashMap<>(); // the key is the extension point
private ExtensionStorage storage; private ExtensionStorage storage;
private boolean ignoreExtensionPoint;
@Override @Override
public synchronized void init(ProcessingEnvironment processingEnv) { public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv); super.init(processingEnv);
info("%s init", ExtensionAnnotationProcessor.class.getName()); info("%s init", ExtensionAnnotationProcessor.class.getName());
info("Options %s", processingEnv.getOptions());
initStorage(); initStorage();
initIgnoreExtensionPoint();
} }
@Override @Override
@ -81,6 +85,7 @@ public class ExtensionAnnotationProcessor extends AbstractProcessor {
public Set<String> getSupportedOptions() { public Set<String> getSupportedOptions() {
Set<String> options = new HashSet<>(); Set<String> options = new HashSet<>();
options.add(STORAGE_CLASS_NAME); options.add(STORAGE_CLASS_NAME);
options.add(IGNORE_EXTENSION_POINT);
return options; return options;
} }
@ -186,11 +191,11 @@ public class ExtensionAnnotationProcessor extends AbstractProcessor {
// detect extension points automatically, if they are not explicitly configured (default behaviour) // detect extension points automatically, if they are not explicitly configured (default behaviour)
else { else {
// search in interfaces // search in interfaces
for (TypeMirror item : extensionElement.getInterfaces()) { List<? extends TypeMirror> interfaces = extensionElement.getInterfaces();
for (TypeMirror item : interfaces) {
boolean isExtensionPoint = processingEnv.getTypeUtils().isSubtype(item, getExtensionPointType()); boolean isExtensionPoint = processingEnv.getTypeUtils().isSubtype(item, getExtensionPointType());
if (isExtensionPoint) { if (isExtensionPoint) {
TypeElement extensionPointElement = (TypeElement) ((DeclaredType) item).asElement(); extensionPointElements.add(getElement(item));
extensionPointElements.add(extensionPointElement);
} }
} }
@ -199,8 +204,18 @@ public class ExtensionAnnotationProcessor extends AbstractProcessor {
if (superclass.getKind() != TypeKind.NONE) { if (superclass.getKind() != TypeKind.NONE) {
boolean isExtensionPoint = processingEnv.getTypeUtils().isSubtype(superclass, getExtensionPointType()); boolean isExtensionPoint = processingEnv.getTypeUtils().isSubtype(superclass, getExtensionPointType());
if (isExtensionPoint) { if (isExtensionPoint) {
TypeElement extensionPointElement = (TypeElement) ((DeclaredType) superclass).asElement(); extensionPointElements.add(getElement(superclass));
extensionPointElements.add(extensionPointElement); }
}
// pickup the first interface
if (extensionPointElements.isEmpty() && ignoreExtensionPoint) {
if (interfaces.isEmpty()) {
error(extensionElement, "%s is not an extension (it doesn't implement any interface)", extensionElement);
} else if (interfaces.size() == 1) {
extensionPointElements.add(getElement(interfaces.get(0)));
} else {
error(extensionElement, "%s is not an extension (it implements multiple interfaces)", extensionElement);
} }
} }
} }
@ -242,6 +257,12 @@ public class ExtensionAnnotationProcessor extends AbstractProcessor {
} }
} }
private void initIgnoreExtensionPoint() {
// search in processing options and system properties
ignoreExtensionPoint = getProcessingEnvironment().getOptions().containsKey(IGNORE_EXTENSION_POINT) ||
System.getProperty(IGNORE_EXTENSION_POINT) != null;
}
private void processExtensionElement(Element element) { private void processExtensionElement(Element element) {
// check if @Extension is put on class and not on method or constructor // check if @Extension is put on class and not on method or constructor
if (!(element instanceof TypeElement)) { if (!(element instanceof TypeElement)) {
@ -250,7 +271,7 @@ public class ExtensionAnnotationProcessor extends AbstractProcessor {
} }
// check if class extends/implements an extension point // check if class extends/implements an extension point
if (!isExtension(element.asType())) { if (!ignoreExtensionPoint && !isExtension(element.asType())) {
error(element, "%s is not an extension (it doesn't implement ExtensionPoint)", element); error(element, "%s is not an extension (it doesn't implement ExtensionPoint)", element);
return; return;
} }
@ -270,4 +291,8 @@ public class ExtensionAnnotationProcessor extends AbstractProcessor {
} }
} }
private TypeElement getElement(TypeMirror typeMirror) {
return (TypeElement) ((DeclaredType) typeMirror).asElement();
}
} }

2
pf4j/src/test/java/org/pf4j/ExtensionAnnotationProcessorTest.java

@ -115,7 +115,7 @@ public class ExtensionAnnotationProcessorTest {
public void getSupportedOptions() { public void getSupportedOptions() {
ExtensionAnnotationProcessor instance = new ExtensionAnnotationProcessor(); ExtensionAnnotationProcessor instance = new ExtensionAnnotationProcessor();
Set<String> result = instance.getSupportedOptions(); Set<String> result = instance.getSupportedOptions();
assertEquals(1, result.size()); assertEquals(2, result.size());
} }
@Test @Test

Loading…
Cancel
Save