001 /* 002 * Created on Oct 31, 2006 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 005 * 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 is distributed on 010 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 011 * specific language governing permissions and limitations under the License. 012 * 013 * Copyright @2006-2009 the original author or authors. 014 */ 015 package org.fest.reflect.core; 016 017 import static org.fest.reflect.beanproperty.PropertyName.startPropertyAccess; 018 import static org.fest.reflect.constructor.TargetType.startConstructorAccess; 019 import static org.fest.reflect.field.FieldName.beginFieldAccess; 020 import static org.fest.reflect.field.StaticFieldName.beginStaticFieldAccess; 021 import static org.fest.reflect.innerclass.StaticInnerClassName.startStaticInnerClassAccess; 022 import static org.fest.reflect.method.MethodName.startMethodAccess; 023 import static org.fest.reflect.method.StaticMethodName.startStaticMethodAccess; 024 import static org.fest.reflect.type.Type.newType; 025 026 import org.fest.reflect.beanproperty.PropertyName; 027 import org.fest.reflect.beanproperty.PropertyType; 028 import org.fest.reflect.constructor.TargetType; 029 import org.fest.reflect.field.*; 030 import org.fest.reflect.innerclass.StaticInnerClassName; 031 import org.fest.reflect.method.*; 032 import org.fest.reflect.method.Invoker; 033 import org.fest.reflect.reference.TypeRef; 034 import org.fest.reflect.type.Type; 035 036 /** 037 * Understands the entry point for the classes in this package. 038 * The following is an example of proper usage of the classes in this package: 039 * <pre> 040 * // Loads the class 'org.republic.Jedi' 041 * Class<?> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#load() load}(); 042 * 043 * // Loads the class 'org.republic.Jedi' as 'org.republic.Person' (Jedi extends Person) 044 * Class<Person> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#loadAs(Class) loadAs}(Person.class); 045 * 046 * // Loads the class 'org.republic.Jedi' using a custom class loader 047 * 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}(); 048 * 049 * // Gets the inner class 'Master' in the declaring class 'Jedi': 050 * Class<?> masterClass = {@link org.fest.reflect.core.Reflection#staticInnerClass(String) staticInnerClass}("Master").{@link org.fest.reflect.innerclass.StaticInnerClassName#in(Class) in}(Jedi.class).{@link org.fest.reflect.innerclass.Invoker#get() get}(); 051 * 052 * // Equivalent to call 'new Person()' 053 * Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link TargetType#in in}(Person.class).{@link org.fest.reflect.constructor.Invoker#newInstance(Object...) newInstance}(); 054 * 055 * // Equivalent to call 'new Person("Yoda")' 056 * Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link TargetType#withParameterTypes(Class...) withParameterTypes}(String.class).{@link org.fest.reflect.constructor.ParameterTypes#in(Class) in}(Person.class).{@link org.fest.reflect.constructor.Invoker#newInstance(Object...) newInstance}("Yoda"); 057 * 058 * // Retrieves the value of the field "name" 059 * String name = {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link org.fest.reflect.field.FieldName#ofType(Class) ofType}(String.class).{@link org.fest.reflect.field.FieldType#in(Object) in}(person).{@link org.fest.reflect.field.Invoker#get() get}(); 060 * 061 * // Sets the value of the field "name" to "Yoda" 062 * {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link org.fest.reflect.field.FieldName#ofType(Class) ofType}(String.class).{@link org.fest.reflect.field.FieldType#in(Object) in}(person).{@link org.fest.reflect.field.Invoker#set(Object) set}("Yoda"); 063 * 064 * // Retrieves the value of the field "powers" 065 * List<String> powers = {@link org.fest.reflect.core.Reflection#field(String) field}("powers").{@link FieldName#ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link FieldTypeRef#in(Object) in}(jedi).{@link org.fest.reflect.field.Invoker#get() get}(); 066 * 067 * // Equivalent to call 'person.setName("Luke")' 068 * {@link org.fest.reflect.core.Reflection#method(String) method}("setName").{@link org.fest.reflect.method.MethodName#withParameterTypes(Class...) withParameterTypes}(String.class) 069 * .{@link org.fest.reflect.method.MethodParameterTypes#in(Object) in}(person) 070 * .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}("Luke"); 071 * 072 * // Equivalent to call 'jedi.getPowers()' 073 * List<String> powers = {@link org.fest.reflect.core.Reflection#method(String) method}("getPowers").{@link MethodName#withReturnType(TypeRef) withReturnType}(new {@link TypeRef TypeRef}<List<String>>() {}) 074 * .{@link MethodReturnTypeRef#in(Object) in}(person) 075 * .{@link Invoker#invoke(Object...) invoke}(); 076 * 077 * // Retrieves the value of the static field "count" in Person.class 078 * int count = {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("count").{@link StaticFieldName#ofType(Class) ofType}(int.class).{@link StaticFieldType#in(Class) in}(Person.class).{@link org.fest.reflect.field.Invoker#get() get}(); 079 * 080 * // Sets the value of the static field "count" to 3 in Person.class 081 * {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("count").{@link StaticFieldName#ofType(Class) ofType}(int.class).{@link StaticFieldType#in(Class) in}(Person.class).{@link org.fest.reflect.field.Invoker#set(Object) set}(3); 082 * 083 * // Retrieves the value of the static field "commonPowers" in Jedi.class 084 * List<String> commmonPowers = {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("commonPowers").{@link StaticFieldName#ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link StaticFieldTypeRef#in(Class) in}(Jedi.class).{@link org.fest.reflect.field.Invoker#get() get}(); 085 * 086 * // Equivalent to call 'person.concentrate()' 087 * {@link org.fest.reflect.core.Reflection#method(String) method}("concentrate").{@link org.fest.reflect.method.MethodName#in(Object) in}(person).{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}(); 088 * 089 * // Equivalent to call 'person.getName()' 090 * String name = {@link org.fest.reflect.core.Reflection#method(String) method}("getName").{@link org.fest.reflect.method.MethodName#withReturnType(Class) withReturnType}(String.class) 091 * .{@link org.fest.reflect.method.MethodReturnType#in(Object) in}(person) 092 * .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}(); 093 * 094 * // Equivalent to call 'Jedi.setCommonPower("Jump")' 095 * {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("setCommonPower").{@link org.fest.reflect.method.StaticMethodName#withParameterTypes(Class...) withParameterTypes}(String.class) 096 * .{@link org.fest.reflect.method.StaticMethodParameterTypes#in(Class) in}(Jedi.class) 097 * .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}("Jump"); 098 * 099 * // Equivalent to call 'Jedi.addPadawan()' 100 * {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("addPadawan").{@link org.fest.reflect.method.StaticMethodName#in(Class) in}(Jedi.class).{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}(); 101 * 102 * // Equivalent to call 'Jedi.commonPowerCount()' 103 * String name = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("commonPowerCount").{@link org.fest.reflect.method.StaticMethodName#withReturnType(Class) withReturnType}(String.class) 104 * .{@link org.fest.reflect.method.StaticMethodReturnType#in(Class) in}(Jedi.class) 105 * .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}(); 106 * 107 * // Equivalent to call 'Jedi.getCommonPowers()' 108 * List<String> powers = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("getCommonPowers").{@link StaticMethodName#withReturnType(TypeRef) withReturnType}(new {@link TypeRef TypeRef}<List<String>>() {}) 109 * .{@link StaticMethodReturnTypeRef#in(Class) in}(Jedi.class) 110 * .{@link Invoker#invoke(Object...) invoke}(); 111 * 112 * // Retrieves the value of the property "name" 113 * String name = {@link org.fest.reflect.core.Reflection#property(String) property}("name").{@link PropertyName#ofType(Class) ofType}(String.class).{@link PropertyType#in(Object) in}(person).{@link org.fest.reflect.beanproperty.Invoker#get() get}(); 114 * 115 * // Sets the value of the property "name" to "Yoda" 116 * {@link org.fest.reflect.core.Reflection#property(String) property}("name").{@link PropertyName#ofType(Class) ofType}(String.class).{@link PropertyType#in(Object) in}(person).{@link org.fest.reflect.beanproperty.Invoker#set(Object) set}("Yoda"); 117 * </pre> 118 * </p> 119 * 120 * @author Alex Ruiz 121 * @author Yvonne Wang 122 */ 123 public final class Reflection { 124 125 /** 126 * Starting point of the fluent interface for loading a class dynamically. 127 * @param name the name of the class to load. 128 * @return the starting point of the method chain. 129 * @throws NullPointerException if the given name is <code>null</code>. 130 * @throws IllegalArgumentException if the given name is empty. 131 * @since 1.1 132 */ 133 public static Type type(String name) { return newType(name); } 134 135 /** 136 * Starting point of the fluent interface for accessing static inner class via reflection. 137 * @param name the name of the static inner class to access. 138 * @return the starting point of the method chain. 139 * @throws NullPointerException if the given name is <code>null</code>. 140 * @throws IllegalArgumentException if the given name is empty. 141 * @since 1.1 142 */ 143 public static StaticInnerClassName staticInnerClass(String name) { return startStaticInnerClassAccess(name); } 144 145 /** 146 * Starting point of the fluent interface for accessing fields via reflection. 147 * @param name the name of the field to access. 148 * @return the starting point of the method chain. 149 * @throws NullPointerException if the given name is <code>null</code>. 150 * @throws IllegalArgumentException if the given name is empty. 151 */ 152 public static FieldName field(String name) { return beginFieldAccess(name); } 153 154 /** 155 * Starting point of the fluent interface for accessing static fields via reflection. 156 * @param name the name of the static field to access. 157 * @return the starting point of the method chain. 158 * @throws NullPointerException if the given name is <code>null</code>. 159 * @throws IllegalArgumentException if the given name is empty. 160 */ 161 public static StaticFieldName staticField(String name) { return beginStaticFieldAccess(name); } 162 163 /** 164 * Starting point of the fluent interface for invoking methods via reflection. 165 * @param name the name of the method to invoke. 166 * @return the starting point of the method chain. 167 * @throws NullPointerException if the given name is <code>null</code>. 168 * @throws IllegalArgumentException if the given name is empty. 169 */ 170 public static MethodName method(String name) { return startMethodAccess(name); } 171 172 /** 173 * Starting point of the fluent interface for invoking static methods via reflection. 174 * @param name the name of the static method to invoke. 175 * @return the starting point of the static method chain. 176 * @throws NullPointerException if the given name is <code>null</code>. 177 * @throws IllegalArgumentException if the given name is empty. 178 */ 179 public static StaticMethodName staticMethod(String name) { return startStaticMethodAccess(name); } 180 181 /** 182 * Starting point of the fluent interface for invoking constructors via reflection. 183 * @return the starting point of the method chain. 184 */ 185 public static TargetType constructor() { return startConstructorAccess(); } 186 187 /** 188 * Starting point of the fluent interface for accessing properties via Bean Instrospection. 189 * @param name the name of the property to access. 190 * @return the starting point of the method chain. 191 * @throws NullPointerException if the given name is <code>null</code>. 192 * @throws IllegalArgumentException if the given name is empty. 193 * @since 1.2 194 */ 195 public static PropertyName property(String name) { return startPropertyAccess(name); } 196 197 private Reflection() {} 198 }