You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2018/02/14 15:15:23 UTC
[isis] 07/13: ISIS-1816 refactoring Annotations + implement
hierarchy search
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 0645ecde12e94d416bf858387eeca960cb0bc60a
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Jan 15 11:15:35 2018 +0100
ISIS-1816 refactoring Annotations + implement hierarchy search
---
.../isis/core/metamodel/facets/Annotations.java | 103 ++++++++++++++++-----
1 file changed, 80 insertions(+), 23 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java
index 5a4a45e..3d24c77 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java
@@ -26,13 +26,13 @@ import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.validation.constraints.Pattern;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import com.google.common.collect.Lists;
-
import org.apache.isis.applib.annotation.Collection;
import org.apache.isis.applib.annotation.CollectionLayout;
import org.apache.isis.applib.annotation.MemberOrder;
@@ -43,6 +43,8 @@ import org.apache.isis.core.commons.lang.ThrowableExtensions;
import org.apache.isis.core.metamodel.exceptions.MetaModelException;
import org.apache.isis.core.metamodel.methodutils.MethodScope;
+import com.google.common.collect.Lists;
+
public final class Annotations {
private Annotations() {}
@@ -352,48 +354,103 @@ public final class Annotations {
/**
* Searches for all no-arg methods or fields with a specified title, returning an
- * {@link Evaluator} object that wraps either. Will search up hierarchy also.
+ * {@link Evaluator} object that wraps either. Will search up hierarchy also,
+ * including implemented interfaces.
*/
public static <T extends Annotation> List<Evaluator<T>> getEvaluators(
final Class<?> cls,
final Class<T> annotationClass) {
- List<Evaluator<T>> evaluators = Lists.newArrayList();
- appendEvaluators(cls, annotationClass, evaluators);
+ final List<Evaluator<T>> evaluators = Lists.newArrayList();
+ visitEvaluators(cls, annotationClass, evaluators::add);
+
+ // search implemented interfaces
+ final Class<?>[] interfaces = cls.getInterfaces();
+ for (final Class<?> iface : interfaces) {
+ visitEvaluators(iface, annotationClass, evaluators::add);
+ }
+
return evaluators;
}
+
+ /**
+ * Starting from the current class {@code cls}, we search down the inheritance
+ * hierarchy (super class, super super class, ...), until we find
+ * the first class that has at least a field or no-arg method with {@code annotationClass} annotation.
+ * <br/>
+ * In this hierarchy traversal, implemented interfaces are not processed.
+ * @param cls
+ * @param annotationClass
+ * @return list of {@link Evaluator} that wraps each annotated member found on the class where
+ * the search stopped, null otherwise
+ *
+ * @since 2.0.0
+ */
+ public static <T extends Annotation> List<Evaluator<T>> findFirstInHierarchyHaving(
+ final Class<?> cls,
+ final Class<T> annotationClass) {
+
+ final List<Evaluator<T>> evaluators = Lists.newArrayList();
+ visitEvaluatorsWhile(cls, annotationClass, __->evaluators.isEmpty(), evaluators::add);
+
+ return evaluators;
+ }
- private static <T extends Annotation> void appendEvaluators(
+ private static <T extends Annotation> void visitEvaluators(
+ final Class<?> cls,
+ final Class<T> annotationClass,
+ final Consumer<Evaluator<T>> visitor) {
+ visitEvaluatorsWhile(cls, annotationClass, __->true, visitor);
+ }
+
+ private static <T extends Annotation> void visitEvaluatorsWhile(
final Class<?> cls,
final Class<T> annotationClass,
- final List<Evaluator<T>> evaluators) {
+ Predicate<Class<?>> filter,
+ final Consumer<Evaluator<T>> visitor) {
+
+ if(!filter.test(cls))
+ return; // stop visitation
+
+ collectMethodEvaluators(cls, annotationClass, visitor);
+ collectFieldEvaluators(cls, annotationClass, visitor);
+
+ // search super-classes
+ final Class<?> superclass = cls.getSuperclass();
+ if (superclass != null) {
+ visitEvaluatorsWhile(superclass, annotationClass, filter, visitor);
+ }
- for (Method method : cls.getDeclaredMethods()) {
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private static <T extends Annotation> void collectMethodEvaluators(
+ final Class<?> cls,
+ final Class<T> annotationClass,
+ final Consumer<Evaluator<T>> action) {
+
+ for (Method method : cls.getDeclaredMethods()) {
if(MethodScope.OBJECT.matchesScopeOf(method) &&
method.getParameterTypes().length == 0) {
final Annotation annotation = method.getAnnotation(annotationClass);
if(annotation != null) {
- evaluators.add(new MethodEvaluator(method, annotation));
+ action.accept(new MethodEvaluator(method, annotation));
}
}
}
- for (final Field field: cls.getDeclaredFields()) {
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private static <T extends Annotation> void collectFieldEvaluators(
+ final Class<?> cls,
+ final Class<T> annotationClass,
+ final Consumer<Evaluator<T>> action) {
+
+ for (final Field field: cls.getDeclaredFields()) {
final Annotation annotation = field.getAnnotation(annotationClass);
if(annotation != null) {
- evaluators.add(new FieldEvaluator(field, annotation));
+ action.accept(new FieldEvaluator(field, annotation));
}
}
-
- // search superclasses
- final Class<?> superclass = cls.getSuperclass();
- if (superclass != null) {
- appendEvaluators(superclass, annotationClass, evaluators);
- }
-
- // search implemented interfaces
- final Class<?>[] interfaces = cls.getInterfaces();
- for (final Class<?> iface : interfaces) {
- appendEvaluators(iface, annotationClass, evaluators);
- }
}
public static abstract class Evaluator<T extends Annotation> {
--
To stop receiving notification emails like this one, please contact
danhaywood@apache.org.