001 /*
002 * Created on Jan 23, 2009
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 *
014 * Copyright @2009 the original author or authors.
015 */
016 package org.fest.reflect.type;
017
018 import org.fest.reflect.exception.ReflectionError;
019
020 import static org.fest.reflect.type.TypeLoader.newLoader;
021 import static org.fest.util.Strings.isEmpty;
022
023 /**
024 * Understands loading a class dynamically.
025 * <p>
026 * The following is an example of proper usage of this class:
027 * <pre>
028 * // Loads the class 'org.republic.Jedi'
029 * Class<?> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#load() load}();
030 *
031 * // Loads the class 'org.republic.Jedi' as 'org.republic.Person' (Jedi extends Person)
032 * Class<Person> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#loadAs(Class) loadAs}(Person.class);
033 *
034 * // Loads the class 'org.republic.Jedi' using a custom class loader
035 * Class<?> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#withClassLoader(ClassLoader) withClassLoader}(myClassLoader).{@link org.fest.reflect.type.TypeLoader#load() load}();
036 * </pre>
037 * </p>
038 *
039 * @author Alex Ruiz
040 *
041 * @since 1.1
042 */
043 public final class Type {
044
045 /**
046 * Creates a new <code>{@link Type}</code>: the starting point of the fluent interface for loading classes
047 * dynamically.
048 * @param name the name of the class to load.
049 * @return the created <code>Type</code>.
050 * @throws NullPointerException if the given name is <code>null</code>.
051 * @throws IllegalArgumentException if the given name is empty.
052 */
053 public static Type newType(String name) {
054 if (name == null)
055 throw new NullPointerException("The name of the class to load should not be null");
056 if (isEmpty(name))
057 throw new IllegalArgumentException("The name of the class to load should not be empty");
058 return new Type(name);
059 }
060
061 private final String name;
062
063 private Type(String name) {
064 this.name = name;
065 }
066
067 /**
068 * Loads the class with the name specified in this type, using this class' <code>ClassLoader</code>.
069 * @return the loaded class.
070 * @throws ReflectionError wrapping any error that occurred during class loading.
071 */
072 public Class<?> load() {
073 return newLoader(name, thisClassLoader()).load();
074 }
075
076 /**
077 * Loads the class with the name specified in this type, as the given type, using this class'
078 * <code>ClassLoader</code>.
079 * <p>
080 * The following example shows how to use this method. Let's assume that we have the class <code>Jedi</code> that
081 * extends the class <code>Person</code>:
082 * <pre>
083 * Class<Person> type = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#loadAs(Class) loadAs}(Person.class);
084 * </pre>
085 * </p>
086 * @param type the given type.
087 * @param <T> the generic type of the type.
088 * @return the loaded class.
089 * @throws NullPointerException if the given type is <code>null</code>.
090 * @throws ReflectionError wrapping any error that occurred during class loading.
091 */
092 public <T> Class<? extends T> loadAs(Class<T> type) {
093 return newLoader(name, thisClassLoader()).loadAs(type);
094 }
095
096 private ClassLoader thisClassLoader() { return getClass().getClassLoader(); }
097
098 /**
099 * Specifies the <code>{@link ClassLoader}</code> to use to load the class.
100 * <p>
101 * Example:
102 * <pre>
103 * Class<?> type = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#withClassLoader(ClassLoader) withClassLoader}(myClassLoader).{@link TypeLoader#load() load}();
104 * </pre>
105 * </p>
106 * @param classLoader the given <code>ClassLoader</code>.
107 * @return an object responsible of loading a class with the given <code>ClassLoader</code>.
108 * @throws NullPointerException if the given <code>ClassLoader</code> is <code>null</code>.
109 */
110 public TypeLoader withClassLoader(ClassLoader classLoader) {
111 return newLoader(name, classLoader);
112 }
113 }