Author: mattsicker
Date: Tue May 27 13:57:31 2014
New Revision: 1597790
URL: http://svn.apache.org/r1597790
Log:
Switch from a registry-based strategy to a meta-annotation-based strategy for
associating visitors to annotations.
- More easily extensible as there is no registry or special file to maintain.
- Still maintains OSGi compatibility with correct ClassLoader usage.
- Updated PluginVisitor(Builder|s) accordingly to use new algorithm.
Added:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginVisitorStrategy.java
(with props)
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginVisitors.java
- copied, changed from r1597667,
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginVisitorRegistry.java
Removed:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginVisitorRegistry.java
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttribute.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginConfiguration.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginElement.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/SensitivePluginAttribute.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/package-info.java
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttribute.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttribute.java?rev=1597790&r1=1597789&r2=1597790&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttribute.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttribute.java
Tue May 27 13:57:31 2014
@@ -32,6 +32,7 @@ import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
+@PluginVisitorStrategy("org.apache.logging.log4j.core.config.plugins.visitors.PluginAttributeVisitor")
public @interface PluginAttribute {
// TODO: could we allow a blank value and infer the attribute name through
reflection?
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginConfiguration.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginConfiguration.java?rev=1597790&r1=1597789&r2=1597790&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginConfiguration.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginConfiguration.java
Tue May 27 13:57:31 2014
@@ -29,5 +29,6 @@ import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
+@PluginVisitorStrategy("org.apache.logging.log4j.core.config.plugins.visitors.PluginConfigurationVisitor")
public @interface PluginConfiguration {
}
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginElement.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginElement.java?rev=1597790&r1=1597789&r2=1597790&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginElement.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginElement.java
Tue May 27 13:57:31 2014
@@ -28,6 +28,7 @@ import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
+@PluginVisitorStrategy("org.apache.logging.log4j.core.config.plugins.visitors.PluginElementVisitor")
public @interface PluginElement {
/**
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java?rev=1597790&r1=1597789&r2=1597790&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java
Tue May 27 13:57:31 2014
@@ -28,5 +28,6 @@ import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
+@PluginVisitorStrategy("org.apache.logging.log4j.core.config.plugins.visitors.PluginNodeVisitor")
public @interface PluginNode {
}
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java?rev=1597790&r1=1597789&r2=1597790&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java
Tue May 27 13:57:31 2014
@@ -31,6 +31,7 @@ import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
+@PluginVisitorStrategy("org.apache.logging.log4j.core.config.plugins.visitors.PluginValueVisitor")
public @interface PluginValue {
String value();
Added:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginVisitorStrategy.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginVisitorStrategy.java?rev=1597790&view=auto
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginVisitorStrategy.java
(added)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginVisitorStrategy.java
Tue May 27 13:57:31 2014
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.logging.log4j.core.config.plugins;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Meta-annotation to denote the class name to use that implements
+ * {@link org.apache.logging.log4j.core.config.plugins.visitors.PluginVisitor}
for the annotated annotation.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface PluginVisitorStrategy {
+
+ /**
+ * The class name to use that implements {@link
org.apache.logging.log4j.core.config.plugins.visitors.PluginVisitor}
+ * for the given annotation.
+ */
+ String value();
+}
Propchange:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginVisitorStrategy.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/SensitivePluginAttribute.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/SensitivePluginAttribute.java?rev=1597790&r1=1597789&r2=1597790&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/SensitivePluginAttribute.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/SensitivePluginAttribute.java
Tue May 27 13:57:31 2014
@@ -34,6 +34,7 @@ import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
+@PluginVisitorStrategy("org.apache.logging.log4j.core.config.plugins.visitors.SensitivePluginAttributeVisitor")
public @interface SensitivePluginAttribute {
String value();
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java?rev=1597790&r1=1597789&r2=1597790&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
Tue May 27 13:57:31 2014
@@ -34,7 +34,7 @@ import org.apache.logging.log4j.core.con
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.config.plugins.visitors.PluginVisitor;
-import
org.apache.logging.log4j.core.config.plugins.visitors.PluginVisitorRegistry;
+import org.apache.logging.log4j.core.config.plugins.visitors.PluginVisitors;
import org.apache.logging.log4j.core.util.Assert;
import org.apache.logging.log4j.core.util.Builder;
import org.apache.logging.log4j.status.StatusLogger;
@@ -164,7 +164,7 @@ public class PluginBuilder<T> implements
continue; // already processed
}
final PluginVisitor<? extends Annotation> visitor =
- PluginVisitorRegistry.findVisitor(a.annotationType());
+ PluginVisitors.findVisitor(a.annotationType());
if (visitor != null) {
final Object value = visitor.setAliases(aliases)
.setAnnotation(a)
@@ -200,7 +200,7 @@ public class PluginBuilder<T> implements
if (a instanceof PluginAliases) {
continue; // already processed
}
- final PluginVisitor<? extends Annotation> visitor =
PluginVisitorRegistry.findVisitor(
+ final PluginVisitor<? extends Annotation> visitor =
PluginVisitors.findVisitor(
a.annotationType());
if (visitor != null) {
args[i] = visitor.setAliases(aliases)
Copied:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginVisitors.java
(from r1597667,
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginVisitorRegistry.java)
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginVisitors.java?p2=logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginVisitors.java&p1=logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginVisitorRegistry.java&r1=1597667&r2=1597790&rev=1597790&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginVisitorRegistry.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginVisitors.java
Tue May 27 13:57:31 2014
@@ -18,58 +18,24 @@
package org.apache.logging.log4j.core.config.plugins.visitors;
import java.lang.annotation.Annotation;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
-import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
-import org.apache.logging.log4j.core.config.plugins.PluginElement;
-import org.apache.logging.log4j.core.config.plugins.PluginNode;
-import org.apache.logging.log4j.core.config.plugins.PluginValue;
-import org.apache.logging.log4j.core.config.plugins.SensitivePluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginVisitorStrategy;
import org.apache.logging.log4j.status.StatusLogger;
/**
- * Registry for associating Plugin annotations with PluginVisitor
implementations.
+ * Utility class to locate an appropriate PluginVisitor implementation for an
annotation.
*/
-public final class PluginVisitorRegistry {
+public final class PluginVisitors {
private static final Logger LOGGER = StatusLogger.getLogger();
- // map of annotation classes to their corresponding PluginVisitor classes
- // generics are fun!
- private static final Map<Class<? extends Annotation>, Class<? extends
PluginVisitor<? extends Annotation>>> REGISTRY;
-
- static {
- // register the default PluginVisitor classes
- // TODO: this could probably be combined with the usual plugin
architecture instead
- REGISTRY = new ConcurrentHashMap<Class<? extends Annotation>, Class<?
extends PluginVisitor<? extends Annotation>>>();
- registerVisitor(PluginAttribute.class, PluginAttributeVisitor.class);
- registerVisitor(SensitivePluginAttribute.class,
SensitivePluginAttributeVisitor.class);
- registerVisitor(PluginConfiguration.class,
PluginConfigurationVisitor.class);
- registerVisitor(PluginNode.class, PluginNodeVisitor.class);
- registerVisitor(PluginValue.class, PluginValueVisitor.class);
- registerVisitor(PluginElement.class, PluginElementVisitor.class);
- }
-
- private PluginVisitorRegistry() {
- }
-
- /**
- * Registers a PluginVisitor class associated to a specific annotation.
- *
- * @param annotation the Plugin annotation to associate with.
- * @param helper the PluginVisitor class to use for the annotation.
- * @param <A> the Plugin annotation type.
- */
- public static <A extends Annotation> void registerVisitor(final Class<A>
annotation,
- final Class<?
extends PluginVisitor<A>> helper) {
- REGISTRY.put(annotation, helper);
+ private PluginVisitors() {
}
/**
- * Creates a PluginVisitor instance for the given annotation class. This
instance must be further populated with
+ * Creates a PluginVisitor instance for the given annotation class using
metadata provided by the annotation's
+ * {@link PluginVisitorStrategy} annotation. This instance must be further
populated with
* data to be useful. Such data is passed through both the setters and the
visit method.
*
* @param annotation the Plugin annotation class to find a PluginVisitor
for.
@@ -78,14 +44,21 @@ public final class PluginVisitorRegistry
*/
@SuppressWarnings("unchecked") // we're keeping track of types, thanks
public static <A extends Annotation> PluginVisitor<A> findVisitor(final
Class<A> annotation) {
+ final PluginVisitorStrategy strategy =
annotation.getAnnotation(PluginVisitorStrategy.class);
+ if (strategy == null) {
+ LOGGER.debug("No PluginVisitorStrategy found on annotation [{}].
Ignoring.", annotation);
+ return null;
+ }
+ final String visitorClassName = strategy.value();
try {
- final Class<PluginVisitor<A>> clazz = (Class<PluginVisitor<A>>)
REGISTRY.get(annotation);
- if (clazz == null) {
- return null;
- }
- return clazz.newInstance();
+ // if a PluginVisitor is in a different JAR than log4j-core, it
can be safely assumed that the
+ // corresponding annotation is in the same JAR as the
PluginVisitor implementation. thus, we use that
+ // ClassLoader instead of any default one
+ final Class<? extends PluginVisitor<A>> visitorClass =
+ (Class<? extends PluginVisitor<A>>)
annotation.getClassLoader().loadClass(visitorClassName);
+ return visitorClass.newInstance();
} catch (final Exception e) {
- LOGGER.debug("No PluginVisitor found for annotation: {}.",
annotation);
+ LOGGER.error("Error loading PluginVisitor [{}] for annotation
[{}].", visitorClassName, annotation, e);
return null;
}
}
Modified:
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/package-info.java
URL:
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/package-info.java?rev=1597790&r1=1597789&r2=1597790&view=diff
==============================================================================
---
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/package-info.java
(original)
+++
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/package-info.java
Tue May 27 13:57:31 2014
@@ -17,5 +17,8 @@
/**
* Visitor classes for extracting values from a Configuration or Node
corresponding to a plugin annotation.
+ * Visitor implementations must implement {@link
org.apache.logging.log4j.core.config.plugins.visitors.PluginVisitor},
+ * and the corresponding annotation must be annotated with
+ * {@link org.apache.logging.log4j.core.config.plugins.PluginVisitorStrategy}.
*/
package org.apache.logging.log4j.core.config.plugins.visitors;
\ No newline at end of file