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 }