Skip to content

Commit

Permalink
Support any interface as an ExtensionPoint (#350)
Browse files Browse the repository at this point in the history
  • Loading branch information
decebals committed Nov 15, 2019
1 parent 6d442e9 commit 45eeec8
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,23 @@
public class ExtensionAnnotationProcessor extends AbstractProcessor {

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>> oldExtensions = new HashMap<>(); // the key is the extension point

private ExtensionStorage storage;
private boolean ignoreExtensionPoint;

@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);

info("%s init", ExtensionAnnotationProcessor.class.getName());
info("Options %s", processingEnv.getOptions());

initStorage();
initIgnoreExtensionPoint();
}

@Override
Expand All @@ -81,6 +85,7 @@ public Set<String> getSupportedAnnotationTypes() {
public Set<String> getSupportedOptions() {
Set<String> options = new HashSet<>();
options.add(STORAGE_CLASS_NAME);
options.add(IGNORE_EXTENSION_POINT);

return options;
}
Expand Down Expand Up @@ -186,11 +191,11 @@ private List<TypeElement> findExtensionPoints(TypeElement extensionElement) {
// detect extension points automatically, if they are not explicitly configured (default behaviour)
else {
// 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());
if (isExtensionPoint) {
TypeElement extensionPointElement = (TypeElement) ((DeclaredType) item).asElement();
extensionPointElements.add(extensionPointElement);
extensionPointElements.add(getElement(item));
}
}

Expand All @@ -199,8 +204,18 @@ private List<TypeElement> findExtensionPoints(TypeElement extensionElement) {
if (superclass.getKind() != TypeKind.NONE) {
boolean isExtensionPoint = processingEnv.getTypeUtils().isSubtype(superclass, getExtensionPointType());
if (isExtensionPoint) {
TypeElement extensionPointElement = (TypeElement) ((DeclaredType) superclass).asElement();
extensionPointElements.add(extensionPointElement);
extensionPointElements.add(getElement(superclass));
}
}

// 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);
}
}
}
Expand Down Expand Up @@ -242,6 +257,12 @@ private void initStorage() {
}
}

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) {
// check if @Extension is put on class and not on method or constructor
if (!(element instanceof TypeElement)) {
Expand All @@ -250,7 +271,7 @@ private void processExtensionElement(Element element) {
}

// 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);
return;
}
Expand All @@ -270,4 +291,8 @@ private void processExtensionElement(Element element) {
}
}

private TypeElement getElement(TypeMirror typeMirror) {
return (TypeElement) ((DeclaredType) typeMirror).asElement();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public void getSupportedAnnotationTypes() {
public void getSupportedOptions() {
ExtensionAnnotationProcessor instance = new ExtensionAnnotationProcessor();
Set<String> result = instance.getSupportedOptions();
assertEquals(1, result.size());
assertEquals(2, result.size());
}

@Test
Expand Down

0 comments on commit 45eeec8

Please sign in to comment.