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

play.classloading.ApplicationClasses Maven / Gradle / Ivy

There is a newer version: 2.6.3
Show newest version
package play.classloading;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BinaryOperator;

import static java.util.Collections.emptyList;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;
import static org.apache.commons.lang3.StringUtils.replace;

public class ApplicationClasses {
    /**
     * Cache of all compiled classes
     */
    private Map classes;
    private Map allClassesByNormalizedName;
    private final Map, Object> assignableClasses = new HashMap<>(100);

    private Map classes() {
        if (classes == null) {
            List> applicationClasses = new JavaClassesScanner().allClassesInProject();
            classes = toMapIgnoringDuplicates(applicationClasses);
        }
        return classes;
    }

    private Map allClassesByNormalizedName() {
        if (allClassesByNormalizedName == null) {
            allClassesByNormalizedName = unmodifiableMap(normalizeByName(classes()));
        }
        return allClassesByNormalizedName;
    }

    private Map toMapIgnoringDuplicates(List> applicationClasses) {
        BinaryOperator ignoreDuplicates = (old, _new) -> old;
        return applicationClasses.stream().collect(toMap(cl -> cl.getName(), cl -> cl, ignoreDuplicates));
    }

    private Map normalizeByName(Map applicationClasses) {
        Map byNormalizedName = new HashMap<>(applicationClasses.size());
        for (Class clazz : applicationClasses.values()) {
            byNormalizedName.put(clazz.getName().toLowerCase(), clazz);
            if (clazz.getName().contains("$")) {
                byNormalizedName.put(replace(clazz.getName().toLowerCase(), "$", "."), clazz);
            }
        }
        return byNormalizedName;
    }

    public  List> getAssignableClasses(Class aClass) {
        if (aClass == null) {
            return emptyList();
        }

        List> result = (List>) assignableClasses.get(aClass);
        if (result == null) {
            result = findAssignableClasses(aClass);
            assignableClasses.put(aClass, result);
        }
        return result;
    }

    private  List> findAssignableClasses(Class clazz) {
        return unmodifiableList(classes().values().stream()
          .filter(applicationClass -> isSubclass(applicationClass, clazz))
          .map(applicationClass -> (Class) applicationClass)
          .collect(toList()));
    }

    private boolean isSubclass(Class subClass, Class superClass) {
        return superClass.isAssignableFrom(subClass) && !subClass.equals(superClass);
    }

    public Class getClassIgnoreCase(String name) {
        String nameLowerCased = name.toLowerCase();
        return allClassesByNormalizedName().get(nameLowerCased);
    }

    /**
     * Retrieve all application classes with a specific annotation.
     *
     * @param clazz
     *            The annotation class.
     * @return A list of application classes.
     */
    public List getAnnotatedClasses(Class clazz) {
        return classes().values().stream().filter(applicationClass ->
          applicationClass != null && applicationClass.isAnnotationPresent(clazz))
          .collect(toList());
    }

    @Override
    public String toString() {
        return String.format("%s classes", classes().size());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy