com.squeakysand.commons.lang.ClassMetaInfo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of squeakysand-commons Show documentation
Show all versions of squeakysand-commons Show documentation
Classes, interfaces and enums that assist with everyday Java development tasks.
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