All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fiolino.common.analyzing.ClassWalker Maven / Gradle / Ivy

Go to download

General structure to easily create dynamic logic via MethodHandles and others.

There is a newer version: 1.0.10
Show newest version
package org.fiolino.common.analyzing;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
 * Analyzes classes to find annotated elements (fields or methods).
 */
public class ClassWalker {

    private final List> visitors = new ArrayList<>();

    public static final class ClassVisitor {
        private final Predicate> classTest;
        private final List> fieldActions = new ArrayList<>();
        private final List> methodActions = new ArrayList<>();

        private ClassVisitor(Predicate> classTest) {
            this.classTest = classTest;
        }

        private ClassVisitor() {
            this(c -> true);
        }

        private boolean startClass(Class type) {
            return classTest.test(type);
        }

        private void visitField(Field f) {
            for (Consumer c : fieldActions) {
                c.accept(f);
            }
        }

        private void visitMethod(Method m) {
            for (Consumer c : methodActions) {
                c.accept(m);
            }
        }

        public ClassVisitor onField(Consumer action) {
            fieldActions.add(action);
            return this;
        }

        public ClassVisitor onMethod(Consumer action) {
            methodActions.add(action);
            return this;
        }
    }

    private ClassVisitor addVisitor(ClassVisitor visitor) {
        visitors.add(visitor);
        return visitor;
    }

    public ClassVisitor forClasses(Predicate> classTest) {
        return addVisitor(new ClassVisitor(classTest));
    }

    public ClassVisitor onField(Consumer action) {
        return addVisitor(new ClassVisitor()).onField(action);
    }

    public ClassVisitor onMethod(Consumer action) {
        return addVisitor(new ClassVisitor()).onMethod(action);
    }

    public void analyze(Class model) throws E {
        for (ClassVisitor v : visitors) {
            if (v.startClass(model)) {
                analyzeUsing(model, v);
            }
        }
    }

    private void analyzeUsing(Class modelClass, ClassVisitor visitor) throws E {
        Class supertype = modelClass.getSuperclass();
        if (supertype != null && supertype != Object.class) {
            analyzeUsing(supertype, visitor);
        }

        for (Field f : modelClass.getDeclaredFields()) {
            visitor.visitField(f);
        }
        for (Method m : modelClass.getDeclaredMethods()) {
            visitor.visitMethod(m);
        }
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + " with " +
                visitors.size() + " visitors.";
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy