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

at.molindo.utils.reflect.ClassUtils Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
/**
 * Copyright 2010 Molindo GmbH
 *
 * 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 at.molindo.utils.reflect;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;

import at.molindo.thirdparty.org.springframework.core.GenericTypeResolver;
import at.molindo.utils.collections.ArrayUtils;
import at.molindo.utils.collections.IteratorUtils;

public class ClassUtils {
	private ClassUtils() {
	}

	/**
	 * @param type
	 * @param genericCls
	 * @return first actual type arguments of gernicCls in type hierarchy of cls
	 */
	public static Class getTypeArgument(Class cls, Class genericCls) {
		return ArrayUtils.first(getTypeArguments(cls, genericCls));
	}

	/**
	 * @param type
	 * @param genericCls
	 * @return actual type arguments of gernicCls in type hierarchy of cls
	 */
	public static Class[] getTypeArguments(Class cls, Class genericCls) {
		return GenericTypeResolver.resolveTypeArguments(cls, genericCls);
	}

	public static Class toClass(Class declaringCls, Type type) {
		return GenericTypeResolver.extractClass(declaringCls, type);
	}

	/**
	 * @return true if cls is assignable to at least
	 *         one class in classes
	 */
	public static boolean isAssignable(Class cls, Set> classes) {
		if (cls == null || classes.isEmpty()) {
			return false;
		}
		for (Class c : classes) {
			if (c.isAssignableFrom(cls)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @return true if cls is assignable to all
	 *         classes
	 */
	public static boolean isAssignableToAll(Class cls, Set> classes) {
		if (cls == null) {
			return false;
		}
		for (Class c : classes) {
			if (!c.isAssignableFrom(cls)) {
				return false;
			}
		}
		return true;
	}

	public static Class forName(String classname) throws ClassNotFoundException {
		return forName(classname, false, null, null);
	}

	public static Class forName(String classname, boolean init) throws ClassNotFoundException {
		return forName(classname, init, null, null);
	}

	public static Class forName(String classname, boolean init, Thread thread) throws ClassNotFoundException {
		return forName(classname, init, thread, null);
	}

	public static Class forName(String classname, boolean init, Class fallback) throws ClassNotFoundException {
		return forName(classname, init, null, fallback);
	}

	/**
	 * @param
	 * @param classname
	 *            fully qualified name of the desired class
	 * @param init
	 *            whether the class must be initialized
	 * @param thread
	 *            thread to use for context classloader or null for
	 *            current thread
	 * @param fallback
	 *            {@link ClassLoader} providing class if no context classloader
	 *            or null for this class
	 * @return class object representing the desired class
	 * @throws ClassNotFoundException
	 *             if the class cannot be located by the specified class loader
	 * 
	 * @see Thread#currentThread()
	 * @see Thread#getContextClassLoader()
	 * @see Class#getClassLoader()
	 * @see Class#forName(String, boolean, ClassLoader)
	 */
	public static Class forName(String classname, boolean init, Thread thread, Class fallback)
			throws ClassNotFoundException {

		return Class.forName(classname, init, getClassLoader(thread, fallback));
	}

	public static ClassLoader getClassLoader() {
		return getClassLoader(null, null);
	}

	public static ClassLoader getClassLoader(Class fallback) {
		return getClassLoader(null, fallback);
	}

	public static ClassLoader getClassLoader(Thread thread) {
		return getClassLoader(thread, null);
	}

	/**
	 * @param thread
	 *            {@link Thread} to use for
	 *            {@link Thread#getContextClassLoader() context ClassLoader} or
	 *            null for {@link Thread#currentThread() current
	 *            thread}
	 * @param fallback
	 *            {@link ClassLoader} providing class if no context classloader
	 *            or null for this class
	 * @return never null
	 */
	public static ClassLoader getClassLoader(Thread thread, Class fallback) {
		if (thread == null) {
			thread = Thread.currentThread();
		}
		ClassLoader loader = thread.getContextClassLoader();

		if (loader == null) {
			loader = (fallback != null ? fallback : ClassUtils.class).getClassLoader();
		}

		if (loader == null) {
			ClassLoader.getSystemClassLoader();
		}

		return loader;
	}

	/**
	 * @see #getPackageResourcePath(Class, String)
	 * @see ClassLoader#getResource(String)
	 */
	public static URL getClasspathResource(Class scope, String resource) {
		return getClassLoader(scope).getResource(getPackageResourcePath(scope, resource));
	}

	/**
	 * @see #getPackageResourcePath(Class, String)
	 * @see ClassLoader#getResourceAsStream(String)
	 */
	public static InputStream getClasspathResourceAsStream(Class scope, String resource) {
		return getClassLoader(scope).getResourceAsStream(getPackageResourcePath(scope, resource));
	}

	/**
	 * @see #getPackageResourcePath(Class, String)
	 * @see ClassLoader#getResources(String)
	 */
	public static Enumeration getClasspathResources(Class scope, String resource) throws IOException {
		return getClassLoader(scope).getResources(getPackageResourcePath(scope, resource));
	}

	/**
	 * @return the full classpath for the resource in the same package as scope
	 */
	public static String getPackageResourcePath(Class scope, String resource) {
		return scope.getPackage().getName().replace('.', '/') + '/' + resource;
	}

	/**
	 * @return an {@link Iterator} over the {@link Class} hierarchy
	 * 
	 * @see Class#getSuperclass()
	 */
	public static Iterator> hierarchy(Class cls) {
		if (cls == null) {
			return IteratorUtils.empty();
		}

		class ClassHierarchyIterator implements Iterator> {

			private Class _next;

			private ClassHierarchyIterator(Class cls) {
				if (cls == null) {
					throw new NullPointerException("cls");
				}
				_next = cls;
			}

			@Override
			public boolean hasNext() {
				return _next != null;
			}

			@Override
			public Class next() {
				if (!hasNext()) {
					throw new NoSuchElementException();
				}

				Class next = _next;
				_next = _next.getSuperclass();
				return next;
			}

			@Override
			public void remove() {
				throw new UnsupportedOperationException("read-only");
			}
		}

		return new ClassHierarchyIterator(cls);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy