You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2022/10/16 06:33:41 UTC
[logging-log4j2] 02/04: Add PluginEntry.Builder to simplify code generation
This is an automated email from the ASF dual-hosted git repository.
mattsicker pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit c5d55239bba6c9e209d079d71bd3f5c96927fb3e
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Sat Oct 15 15:50:40 2022 -0500
Add PluginEntry.Builder to simplify code generation
This updates PluginProcessor to use the builder class while removing the implemented interfaces property from PluginEntry.
Signed-off-by: Matt Sicker <ma...@apache.org>
---
.../log4j/plugin/processor/PluginProcessor.java | 65 +++++-----------------
.../logging/log4j/plugins/di/DefaultInjector.java | 40 ++++++-------
.../logging/log4j/plugins/model/PluginEntry.java | 48 ++--------------
.../logging/log4j/plugins/model/PluginType.java | 18 +-----
4 files changed, 40 insertions(+), 131 deletions(-)
diff --git a/log4j-plugin-processor/src/main/java/org/apache/logging/log4j/plugin/processor/PluginProcessor.java b/log4j-plugin-processor/src/main/java/org/apache/logging/log4j/plugin/processor/PluginProcessor.java
index c991ce8f45..87eb4197b7 100644
--- a/log4j-plugin-processor/src/main/java/org/apache/logging/log4j/plugin/processor/PluginProcessor.java
+++ b/log4j-plugin-processor/src/main/java/org/apache/logging/log4j/plugin/processor/PluginProcessor.java
@@ -34,16 +34,10 @@ import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.Modifier;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.ElementKindVisitor9;
import javax.lang.model.util.Elements;
import javax.lang.model.util.SimpleElementVisitor8;
-import javax.lang.model.util.SimpleTypeVisitor9;
-import javax.lang.model.util.Types;
import javax.tools.Diagnostic.Kind;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
@@ -55,7 +49,6 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -170,33 +163,27 @@ public class PluginProcessor extends AbstractProcessor {
writer.println("");
writer.println("public class Log4jPlugins extends PluginService {");
writer.println("");
- writer.println(" private static final PluginEntry[] ENTRIES = new PluginEntry[] {");
- StringBuilder sb = new StringBuilder();
+ writer.println(" private static final PluginEntry[] ENTRIES = new PluginEntry[] {");
int max = list.size() - 1;
for (int i = 0; i < list.size(); ++i) {
PluginEntryMirror mirror = list.get(i);
final PluginEntry entry = mirror.entry;
- sb.append(" ").append("new PluginEntry(\"");
- sb.append(entry.getKey()).append("\", \"");
- sb.append(entry.getClassName()).append("\", \"");
- sb.append(entry.getName()).append("\", \"");
- final String elementName = entry.getElementType();
- if (elementName != null) {
- sb.append(elementName);
+ writer.println(" PluginEntry.builder()");
+ writer.println(String.format(" .setKey(\"%s\")", entry.getKey()));
+ writer.println(String.format(" .setClassName(\"%s\")", entry.getClassName()));
+ writer.println(String.format(" .setName(\"%s\")", entry.getName()));
+ writer.println(String.format(" .setNamespace(\"%s\")", entry.getNamespace()));
+ final String elementType = entry.getElementType();
+ if (Strings.isNotEmpty(elementType)) {
+ writer.println(String.format(" .setElementType(\"%s\")", elementType));
}
- sb.append("\", ");
- sb.append(entry.isPrintable()).append(", ");
- sb.append(entry.isDeferChildren()).append(", \"");
- sb.append(entry.getNamespace()).append("\"");
- for (final Name implementedInterface : getImplementedInterfaces(mirror.element.asType())) {
- sb.append(", ").append(implementedInterface).append(".class");
+ if (entry.isPrintable()) {
+ writer.println(" .setPrintable(true)");
}
- sb.append(')');
- if (i < max) {
- sb.append(",");
+ if (entry.isDeferChildren()) {
+ writer.println(" .setDeferChildren(true)");
}
- writer.println(sb);
- sb.setLength(0);
+ writer.println(" .get()" + (i < max ? "," : Strings.EMPTY));
}
writer.println(" };");
writer.println(" @Override");
@@ -274,30 +261,6 @@ public class PluginProcessor extends AbstractProcessor {
}
}
- private Set<Name> getImplementedInterfaces(final TypeMirror base) {
- final Set<Name> implementedInterfaces = new LinkedHashSet<>();
- final Types types = processingEnv.getTypeUtils();
- base.accept(new SimpleTypeVisitor9<Void, Void>() {
- @Override
- public Void visitDeclared(final DeclaredType t, final Void unused) {
- for (final TypeMirror directSupertype : types.directSupertypes(t)) {
- directSupertype.accept(this, null);
- }
- t.asElement().accept(new ElementKindVisitor9<Void, Void>() {
- @Override
- public Void visitTypeAsInterface(final TypeElement e, final Void unused) {
- if (e.getModifiers().contains(Modifier.PUBLIC)) {
- implementedInterfaces.add(e.getQualifiedName());
- }
- return null;
- }
- }, null);
- return null;
- }
- }, null);
- return implementedInterfaces;
- }
-
private String commonPrefix(String str1, String str2) {
int minLength = Math.min(str1.length(), str2.length());
for (int i = 0; i < minLength; i++) {
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/DefaultInjector.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/DefaultInjector.java
index e930f33ded..c61f10df99 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/DefaultInjector.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/di/DefaultInjector.java
@@ -319,10 +319,8 @@ class DefaultInjector implements Injector {
}
final PluginNamespace namespace = getInstance(PluginRegistry.class).getNamespace(itemKey.getNamespace(), getPluginPackages());
final Type type = itemKey.getType();
- final Class<T> rawType = itemKey.getRawType();
return namespace.stream()
- .filter(pluginType -> rawType.isInterface() && pluginType.getImplementedInterfaces().contains(rawType) ||
- TypeUtil.isAssignable(type, pluginType.getPluginClass()))
+ .filter(pluginType -> TypeUtil.isAssignable(type, pluginType.getPluginClass()))
.sorted(Comparator.comparing(PluginType::getPluginClass, OrderedComparator.INSTANCE))
.map(TypeUtil::cast);
}
@@ -574,22 +572,7 @@ class DefaultInjector implements Injector {
.allMatch(condition -> condition.matches(key, rawType))) {
return null;
}
- final Executable factory = Stream.of(rawType.getDeclaredMethods())
- .filter(method -> Modifier.isStatic(method.getModifiers()) &&
- AnnotationUtil.isMetaAnnotationPresent(method, FactoryType.class))
- .min(Comparator.comparingInt(Method::getParameterCount).thenComparing(Method::getReturnType, (c1, c2) -> {
- if (c1.equals(c2)) {
- return 0;
- } else if (Supplier.class.isAssignableFrom(c1)) {
- return -1;
- } else if (Supplier.class.isAssignableFrom(c2)) {
- return 1;
- } else {
- return c1.getName().compareTo(c2.getName());
- }
- }))
- .map(Executable.class::cast)
- .orElseGet(() -> getInjectableConstructor(key, Set.of()));
+ final Executable factory = getInjectablePluginFactory(rawType);
final List<InjectionPoint<?>> points = InjectionPoint.fromExecutable(factory);
if (!factory.canAccess(null)) {
accessor.makeAccessible(factory);
@@ -783,6 +766,25 @@ class DefaultInjector implements Injector {
return newChain;
}
+ private static Executable getInjectablePluginFactory(final Class<?> pluginClass) {
+ return Stream.of(pluginClass.getDeclaredMethods())
+ .filter(method -> Modifier.isStatic(method.getModifiers()) &&
+ AnnotationUtil.isMetaAnnotationPresent(method, FactoryType.class))
+ .min(Comparator.comparingInt(Method::getParameterCount).thenComparing(Method::getReturnType, (c1, c2) -> {
+ if (c1.equals(c2)) {
+ return 0;
+ } else if (Supplier.class.isAssignableFrom(c1)) {
+ return -1;
+ } else if (Supplier.class.isAssignableFrom(c2)) {
+ return 1;
+ } else {
+ return c1.getName().compareTo(c2.getName());
+ }
+ }))
+ .map(Executable.class::cast)
+ .orElseGet(() -> getInjectableConstructor(Key.forClass(pluginClass), Set.of()));
+ }
+
private static <T> Constructor<T> getInjectableConstructor(final Key<T> key, final Set<Key<?>> chain) {
final Class<T> rawType = key.getRawType();
final List<Constructor<?>> injectConstructors = Stream.of(rawType.getDeclaredConstructors())
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/model/PluginEntry.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/model/PluginEntry.java
index f9e240e745..fb507b4dbc 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/model/PluginEntry.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/model/PluginEntry.java
@@ -17,6 +17,8 @@
package org.apache.logging.log4j.plugins.model;
+import org.apache.logging.log4j.util.Strings;
+
import java.util.function.Supplier;
/**
@@ -30,32 +32,6 @@ public class PluginEntry {
private final boolean printable;
private final boolean deferChildren;
private final String namespace;
- private final Class<?>[] interfaces;
-
- public PluginEntry(
- String key, String className, String name, String elementType, boolean printable, boolean deferChildren, String namespace) {
- this.key = key;
- this.className = className;
- this.name = name;
- this.elementType = elementType;
- this.printable = printable;
- this.deferChildren = deferChildren;
- this.namespace = namespace;
- this.interfaces = null;
- }
-
- public PluginEntry(
- final String key, final String className, final String name, final String elementType, final boolean printable,
- final boolean deferChildren, final String namespace, final Class<?>... interfaces) {
- this.key = key;
- this.className = className;
- this.name = name;
- this.elementType = elementType;
- this.printable = printable;
- this.deferChildren = deferChildren;
- this.namespace = namespace;
- this.interfaces = interfaces;
- }
private PluginEntry(final Builder builder) {
key = builder.getKey();
@@ -65,8 +41,6 @@ public class PluginEntry {
printable = builder.isPrintable();
deferChildren = builder.isDeferChildren();
namespace = builder.getNamespace();
- final Class<?>[] classes = builder.getInterfaces();
- interfaces = classes != null ? classes.clone() : null;
}
public String getKey() {
@@ -97,10 +71,6 @@ public class PluginEntry {
return namespace;
}
- public Class<?>[] getInterfaces() {
- return interfaces;
- }
-
@Override
public String toString() {
return "PluginEntry [key=" + key + ", className=" + className + ", name=" + name + ", printable=" + printable
@@ -115,11 +85,10 @@ public class PluginEntry {
private String key;
private String className;
private String name;
- private String elementType;
+ private String elementType = Strings.EMPTY;
private boolean printable;
private boolean deferChildren;
- private String namespace;
- private Class<?>[] interfaces;
+ private String namespace = Strings.EMPTY;
public String getKey() {
return key;
@@ -184,15 +153,6 @@ public class PluginEntry {
return this;
}
- public Class<?>[] getInterfaces() {
- return interfaces;
- }
-
- public Builder setInterfaces(final Class<?>... interfaces) {
- this.interfaces = interfaces;
- return this;
- }
-
@Override
public PluginEntry get() {
return new PluginEntry(this);
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/model/PluginType.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/model/PluginType.java
index 0c8bbcd7cd..028d56ee77 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/model/PluginType.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/model/PluginType.java
@@ -19,7 +19,6 @@ package org.apache.logging.log4j.plugins.model;
import org.apache.logging.log4j.plugins.util.TypeUtil;
import org.apache.logging.log4j.util.LazyValue;
-import java.util.Set;
import java.util.function.Supplier;
/**
@@ -32,7 +31,6 @@ public class PluginType<T> {
private final PluginEntry pluginEntry;
private final Supplier<Class<T>> pluginClass;
- private final Supplier<Set<Class<?>>> implementedInterfaces;
/**
* Constructor.
@@ -44,8 +42,6 @@ public class PluginType<T> {
final PluginEntry pluginEntry, final Class<T> pluginClass) {
this.pluginEntry = pluginEntry;
this.pluginClass = () -> pluginClass;
- final var interfaces = Set.of(pluginClass.getInterfaces());
- this.implementedInterfaces = () -> interfaces;
}
/**
@@ -55,7 +51,7 @@ public class PluginType<T> {
*/
public PluginType(final PluginEntry pluginEntry, final ClassLoader classLoader) {
this.pluginEntry = pluginEntry;
- final LazyValue<Class<T>> classProvider = LazyValue.from(() -> {
+ this.pluginClass = LazyValue.from(() -> {
try {
return TypeUtil.cast(classLoader.loadClass(pluginEntry.getClassName()));
} catch (final ClassNotFoundException e) {
@@ -63,14 +59,6 @@ public class PluginType<T> {
" located for element " + pluginEntry.getName(), e);
}
});
- this.pluginClass = classProvider;
- final Class<?>[] interfaces = pluginEntry.getInterfaces();
- if (interfaces != null) {
- final var implementedInterfaces = Set.of(interfaces);
- this.implementedInterfaces = () -> implementedInterfaces;
- } else {
- this.implementedInterfaces = classProvider.map(clazz -> Set.of(clazz.getInterfaces()));
- }
}
public PluginEntry getPluginEntry() {
@@ -81,10 +69,6 @@ public class PluginType<T> {
return pluginClass.get();
}
- public Set<Class<?>> getImplementedInterfaces() {
- return implementedInterfaces.get();
- }
-
public String getElementType() {
return pluginEntry.getElementType();
}