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

com.squeakysand.commons.lang.ClassMetaInfo Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2010-2012 Craig S. Dickson (http://craigsdickson.com)
 *
 * Licensed 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 com.squeakysand.commons.lang;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Utility class that provides useful methods for interacting with {@link java.lang.Class} objects.
 */
public class ClassMetaInfo {

    private static final Logger LOG = LoggerFactory.getLogger(ClassMetaInfo.class);

    private Class klass;

    public ClassMetaInfo(Class klass) {
        if (klass == null) {
            throw new IllegalArgumentException("klass cannot be null");
        }
        this.klass = klass;
    }

    /**
     * Interrogates a {@link java.lang.Class} object and returns a list of all of the types it is assignable to. For
     * example, if class X extends class Y and class X also implements interface Z, then the result would
     * include the class objects representing Y and Z as well as the {@link java.lang.Object} class object.
     *
     * @return  a list sorted by super classTypes first, followed by implemented interfaceTypes 2nd.
     */
    public Set> getAssignableToTypes() {
        Set> result = new HashSet>();
        result.addAll(getSuperClasses());
        result.addAll(getImplementedInterfaces());
        if (LOG.isDebugEnabled()) {
            LOG.debug("assignableToTypes for {} are {}", ToStringHelper.toString(klass), ToStringHelper.toString(result));
        }
        return result;
    }

    /**
     * Interrogates a {@link java.lang.Class} object and returns a list of all of the interfaceTypes implemented by the
     * class, including those inherited from super classTypes.
     *
     * @return  a list of {@link java.lang.Class} objects sorted in closest ancestor first order.
     */
    public Set> getImplementedInterfaces() {
        Set> result = new HashSet>();
        List> classTypes = new ArrayList>();
        classTypes.add(klass);
        classTypes.addAll(getSuperClasses());
        for (Class classType : classTypes) {
            Class[] interfaceTypes = classType.getInterfaces();
            for (Class interfaceType : interfaceTypes) {
                result.add(interfaceType);
                ClassMetaInfo interfaceMetaInfo = new ClassMetaInfo(interfaceType);
                Set> superInterfaces = interfaceMetaInfo.getImplementedInterfaces();
                for (Class superInterface : superInterfaces) {
                    result.add(superInterface);
                }
            }
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug("interfaces for {} are {}", ToStringHelper.toString(klass), ToStringHelper.toString(result));
        }
        return result;
    }

    public List getMethods() {
        return getMethods(null);
    }

    public List getMethods(int... modifiers) {
        List result = new ArrayList();
        Method[] allMethods = klass.getDeclaredMethods();
        for (Method method : allMethods) {
            MethodMetaInfo methodInfo = new MethodMetaInfo(method);
            if (methodInfo.hasModifiers(modifiers)) {
                result.add(method);
            }
        }
        return result;
    }

    public List getStaticMethods() {
        return getMethods(Modifier.STATIC);
    }

    /**
     * Interrogates a {@link java.lang.Class} object and returns a list of all of its super classTypes.
     *
     * @return  a list of {@link java.lang.Class} objects sorted in closest ancestor first order.
     */
    public Set> getSuperClasses() {
        Set> superClasses = new HashSet>();
        Class superClass = klass.getSuperclass();
        while (superClass != null) {
            superClasses.add(superClass);
            superClass = superClass.getSuperclass();
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug("super classes for {} are {}", ToStringHelper.toString(klass), ToStringHelper.toString(superClasses));
        }
        return superClasses;
    }

    public List> getClassHierarchy() {
        List> result = new ArrayList>();
        Class currentClass = klass;
        while (currentClass != null) {
            result.add(0, currentClass);
            currentClass = currentClass.getSuperclass();
        }
        return result;
    }

    public boolean isPublic() {
        return hasModifiers(Modifier.PUBLIC);
    }

    public boolean hasModifiers(int... modifiers) {
        int klassModifiers = klass.getModifiers();
        boolean result = true;
        if (modifiers != null) {
            for (int modifier : modifiers) {
                switch (modifier) {
                    case Modifier.ABSTRACT:
                        if (!Modifier.isAbstract(modifier)) {
                            result = false;
                        }
                        break;
                    case Modifier.FINAL:
                        if (!Modifier.isFinal(modifier)) {
                            result = false;
                        }
                        break;
                    case Modifier.NATIVE:
                        if (!Modifier.isNative(modifier)) {
                            result = false;
                        }
                        break;
                    case Modifier.PRIVATE:
                        if (!Modifier.isPrivate(modifier)) {
                            result = false;
                        }
                        break;
                    case Modifier.PROTECTED:
                        if (!Modifier.isProtected(modifier)) {
                            result = false;
                        }
                        break;
                    case Modifier.PUBLIC:
                        if (!Modifier.isPublic(klassModifiers)) {
                            result = false;
                        }
                        break;
                    case Modifier.STATIC:
                        if (!Modifier.isStatic(klassModifiers)) {
                            result = false;
                        }
                        break;
                    case Modifier.STRICT:
                        if (!Modifier.isStrict(klassModifiers)) {
                            result = false;
                        }
                        break;
                    case Modifier.SYNCHRONIZED:
                        if (!Modifier.isSynchronized(klassModifiers)) {
                            result = false;
                        }
                        break;
                    default:
                        throw new IllegalArgumentException("illegal class modifier found: " + modifier);

                }
            }
        }
        return result;
    }

    public Object asString() {
        return ToStringHelper.toString(klass);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy