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 }