org.shaf.core.util.ClassUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.shaf.core.util.ClassUtils.java

Source

/**
 * Copyright 2014-2015 SHAF-WORK
 * 
 * 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 org.shaf.core.util;

import java.io.Closeable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.shaf.core.process.Process;
import org.shaf.core.process.ProcessVariable;
import org.shaf.core.process.type.comp.CompositeProcess;
import org.shaf.core.process.type.dist.DistributedProcess;
import org.shaf.core.process.type.local.LocalProcess;

/**
 * The class utilities.
 * 
 * @author Mykola Galushka
 */
public class ClassUtils {

    /**
     * Tests if the specified class represents a primitive type.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents a primitive type and
     *         {@code false} otherwise.
     */
    public static final boolean isPrimitiveType(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return cls == byte.class || cls == short.class || cls == int.class || cls == long.class
                || cls == float.class || cls == double.class || cls == boolean.class;
    }

    /**
     * Tests if the specified object is a primitive type.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is a primitive type and {@code false}
     *         otherwise.
     */
    public static final boolean isPrimitiveType(final Object obj) {
        return isPrimitiveType(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the specified class represents a wrapper type.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents a wrapper type and
     *         {@code false} otherwise.
     */
    public static final boolean isWrapperType(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return cls == Byte.class || cls == Short.class || cls == Integer.class || cls == Long.class
                || cls == Float.class || cls == Double.class || cls == Boolean.class;
    }

    /**
     * Tests if the specified object is a wrapper type.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is a wrapper type and {@code false}
     *         otherwise.
     */
    public static final boolean isWrapperType(final Object obj) {
        return isWrapperType(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the specified class represents a {@code boolean} type.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents a {@code boolean} type and
     *         {@code false} otherwise.
     */
    public static final boolean isBoolean(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return cls == boolean.class || cls == Boolean.class;
    }

    /**
     * Tests if the specified object is {@code boolean}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@code boolean} and {@code false}
     *         otherwise.
     */
    public static final boolean isBoolean(final Object obj) {
        return isBoolean(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the specified class represents a {@code byte} type.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents a {@code byte} type and
     *         {@code false} otherwise.
     */
    public static final boolean isByte(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return cls == byte.class || cls == Byte.class;
    }

    /**
     * Tests if the specified object is {@code byte}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@code byte} and {@code false}
     *         otherwise.
     */
    public static final boolean isByte(final Object obj) {
        return isByte(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the specified class represents a {@code short} type.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents a {@code short} type and
     *         {@code false} otherwise.
     */
    public static final boolean isShort(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return cls == short.class || cls == Short.class;
    }

    /**
     * Tests if the specified object is {@code short}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@code short} and {@code false}
     *         otherwise.
     */
    public static final boolean isShort(final Object obj) {
        return isShort(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the specified class represents a {@code integer} type.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents a {@code integer} type and
     *         {@code false} otherwise.
     */
    public static final boolean isInteger(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return cls == int.class || cls == Integer.class;
    }

    /**
     * Tests if the specified object is {@code integer}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@code integer} and {@code false}
     *         otherwise.
     */
    public static final boolean isInteger(final Object obj) {
        return isInteger(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the specified class represents a {@code long} type.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents a {@code long} type and
     *         {@code false} otherwise.
     */
    public static final boolean isLong(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return cls == long.class || cls == Long.class;
    }

    /**
     * Tests if the specified object is {@code long}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@code long} and {@code false}
     *         otherwise.
     */
    public static final boolean isLong(final Object obj) {
        return isLong(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the specified class represents a {@code float} type.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents a {@code float} type and
     *         {@code false} otherwise.
     */
    public static final boolean isFloat(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return cls == float.class || cls == Float.class;
    }

    /**
     * Tests if the specified object is {@code float}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@code float} and {@code false}
     *         otherwise.
     */
    public static final boolean isFloat(final Object obj) {
        return isFloat(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the specified class represents a {@code double} type.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents a {@code double} type and
     *         {@code false} otherwise.
     */
    public static final boolean isDouble(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return cls == double.class || cls == Double.class;
    }

    /**
     * Tests if the specified object is {@code double}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@code double} and {@code false}
     *         otherwise.
     */
    public static final boolean isDouble(final Object obj) {
        return isDouble(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the specified class represents a number.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents a number and {@code false}
     *         otherwise.
     */
    public static final boolean isNumber(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return isByte(cls) || isShort(cls) || isInteger(cls) || isLong(cls) || isFloat(cls) || isDouble(cls);
    }

    /**
     * Tests if the specified object is a number.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is a number and {@code false}
     *         otherwise.
     */
    public static final boolean isNumber(final Object obj) {
        return isNumber(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the specified class represents a {@code String} type.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents a {@code String} type and
     *         {@code false} otherwise.
     */
    public static final boolean isString(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return cls == String.class;
    }

    /**
     * Tests if the specified object is {@code String}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@code String} and {@code false}
     *         otherwise.
     */
    public static final boolean isString(final Object obj) {
        return isString(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the specified class represents an {@code Enum} type.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents an {@code Enum} type and
     *         {@code false} otherwise.
     */
    public static final boolean isEnum(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return cls.isEnum();
    }

    /**
     * Tests if the specified object is an {@code Enum}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is an {@code Enum} and {@code false}
     *         otherwise.
     */
    public static final boolean isEnum(final Object obj) {
        return isEnum(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the specified class represents an {@code Array} type.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents an {@code Array} type and
     *         {@code false} otherwise.
     */
    public static final boolean isArray(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return cls.isArray();
    }

    /**
     * Tests if the specified object is an {@code Array}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is an {@code Array} and {@code false}
     *         otherwise.
     */
    public static final boolean isArray(final Object obj) {
        return isArray(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the specified class represents an {@code ProcessVariable}
     * type.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class represents an
     *         {@code ProcessVariable} type and {@code false} otherwise.
     */
    public static final boolean isProcessVariable(final Class<?> cls) {
        if (cls == null) {
            throw new IllegalArgumentException("Undefined class.");
        }

        return cls == ProcessVariable.class;
    }

    /**
     * Tests if the specified object is an {@code ProcessVariable}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is an {@code ProcessVariable} and
     *         {@code false} otherwise.
     */
    public static final boolean isProcessVariable(final Object obj) {
        return isProcessVariable(obj == null ? null : obj.getClass());
    }

    /**
     * Tests if the child class inherits the specified parent class.
     * 
     * @param child
     *            the class to test.
     * @param parent
     *            the inheriting class.
     * @return {@code true} if the child class inherits the specified parent
     *         class and {@code false} otherwise.
     */
    @SuppressWarnings("unchecked")
    public static final boolean inherits(final Class<?> child, final Class<?> parent) {
        if (child == null) {
            throw new IllegalArgumentException("Undefined child class.");
        }

        if (parent == null) {
            throw new IllegalArgumentException("Undefined parent class.");
        }

        Set<Class<?>> parents = new HashSet<>();
        parents.addAll(org.apache.commons.lang.ClassUtils.getAllInterfaces(child));
        parents.addAll(org.apache.commons.lang.ClassUtils.getAllSuperclasses(child));

        return parents.contains(parent);
    }

    /**
     * Tests if the object type inherits the specified parent class.
     * 
     * @param obj
     *            the object to test.
     * @param parent
     *            the inheriting class.
     * @return {@code true} if the object type inherits the specified parent and
     *         {@code false} otherwise.
     */
    public static final boolean inherits(final Object obj, final Class<?> parent) {
        return inherits(obj == null ? null : obj.getClass(), parent);
    }

    /**
     * Tests if the specified class implements the {@link Comparable} interface.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class implements the {@link Comparable}
     *         interface and {@code false} otherwise.
     */
    public static final boolean isComparable(final Class<?> cls) {
        return inherits(cls, Comparable.class);

    }

    /**
     * Tests if the specified object is {@link Comparable}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@link Comparable} interface and
     *         {@code false} otherwise.
     */
    public static final boolean isComparable(final Object obj) {
        return inherits(obj, Comparable.class);
    }

    /**
     * Tests if the specified class implements the {@link LocalProcess}
     * interface.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class implements the {@link LocalProcess}
     *         interface and {@code false} otherwise.
     */
    public static final boolean isLocalProcess(final Class<?> cls) {
        return inherits(cls, LocalProcess.class);
    }

    /**
     * Tests if the specified object is {@link LocalProcess}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@link LocalProcess} interface and
     *         {@code false} otherwise.
     */
    public static final boolean isLocalProcess(final Object obj) {
        return inherits(obj, LocalProcess.class);
    }

    /**
     * Tests if the specified class implements the {@link DistributedProcess}
     * interface.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class implements the
     *         {@link DistributedProcess} interface and {@code false} otherwise.
     */
    public static final boolean isDistributedProcess(final Class<?> cls) {
        return inherits(cls, DistributedProcess.class);
    }

    /**
     * Tests if the specified object is {@link DistributedProcess}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@link DistributedProcess}
     *         interface and {@code false} otherwise.
     */
    public static final boolean isDistributedProcess(final Object obj) {
        return inherits(obj, DistributedProcess.class);
    }

    /**
     * Tests if the specified class implements the {@link CompositeProcess}
     * interface.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class implements the {@link CompositeProcess}
     *         interface and {@code false} otherwise.
     */
    public static final boolean isCompositeProcess(final Class<?> cls) {
        return inherits(cls, CompositeProcess.class);
    }

    /**
     * Tests if the specified object is {@link CompositeProcess}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@link CompositeProcess} interface
     *         and {@code false} otherwise.
     */
    public static final boolean isCompositeProcess(final Object obj) {
        return inherits(obj, CompositeProcess.class);
    }

    /**
     * Tests if the specified class implements the {@link Process} interface.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class implements the {@link Process}
     *         interface and {@code false} otherwise.
     */
    public static final boolean isProcess(final Class<?> cls) {
        return isLocalProcess(cls) || isDistributedProcess(cls) || isCompositeProcess(cls);
    }

    /**
     * Tests if the specified object is {@link Process}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@link Process} interface and
     *         {@code false} otherwise.
     */
    public static final boolean isProcess(final Object obj) {
        return isLocalProcess(obj) || isDistributedProcess(obj) || isCompositeProcess(obj);
    }

    /**
     * Tests if the specified class implements the {@link Closeable} interface.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class implements the {@link Closeable}
     *         interface and {@code false} otherwise.
     */
    public static final boolean isCloseable(final Class<?> cls) {
        return inherits(cls, Closeable.class);

    }

    /**
     * Tests if the specified object is {@link Closeable}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@link Closeable} interface and
     *         {@code false} otherwise.
     */
    public static final boolean isCloseable(final Object obj) {
        return inherits(obj, Closeable.class);
    }

    /**
     * Tests if the specified class implements the {@link Iterable} interface.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class implements the {@link Iterable}
     *         interface and {@code false} otherwise.
     */
    public static final boolean isIterable(final Class<?> cls) {
        return inherits(cls, Iterable.class);

    }

    /**
     * Tests if the specified object is {@link Iterable}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is {@link Iterable} interface and
     *         {@code false} otherwise.
     */
    public static final boolean isIterable(final Object obj) {
        return inherits(obj, Iterable.class);
    }

    /**
     * Tests if the specified class implements the {@link Collection} interface.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class implements the {@link Collection}
     *         interface and {@code false} otherwise.
     */
    public static final boolean isCollection(final Class<?> cls) {
        return inherits(cls, Collection.class);

    }

    /**
     * Tests if the specified object is a {@link Collection}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is a {@link Collection} interface and
     *         {@code false} otherwise.
     */
    public static final boolean isCollection(final Object obj) {
        return inherits(obj, Collection.class);
    }

    /**
     * Tests if the specified class implements the {@link Map} interface.
     * 
     * @param cls
     *            the class to test.
     * @return {@code true} if the class implements the {@link Map} interface
     *         and {@code false} otherwise.
     */
    public static final boolean isMap(final Class<?> cls) {
        return inherits(cls, Map.class);

    }

    /**
     * Tests if the specified object is a {@link Map}.
     * 
     * @param obj
     *            the object to test.
     * @return {@code true} if the object is a {@link Map} interface and
     *         {@code false} otherwise.
     */
    public static final boolean isMap(final Object obj) {
        return inherits(obj, Map.class);
    }

    /**
     * Returns all fields declared in the specified class (including inherited).
     * 
     * @param cls
     *            the class which fields need to be returned.
     * @return the declared fields.
     */
    public static Field[] getClassFields(Class<?> cls) {
        List<Field> fields = new ArrayList<Field>();
        for (Class<?> c = cls; c != null; c = c.getSuperclass()) {
            fields.addAll(Arrays.asList(c.getDeclaredFields()));
        }
        return fields.toArray(new Field[fields.size()]);
    }

    /**
     * Returns a filed by its name from the specified class (including
     * inherited).
     * 
     * @param cls
     *            the class which field needs to be returned.
     * @param name
     *            the field name.
     * @return the found filed or {@code null} if such field not found.
     */
    public static Field getClassField(Class<?> cls, String name) {
        for (Field field : getClassFields(cls)) {
            if (field.getName().equals(name)) {
                return field;
            }
        }
        return null;
    }
}