001 /* 002 * Created on Nov 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.beanproperty; 017 018 import static org.fest.reflect.beanproperty.PropertyType.newPropertyType; 019 import static org.fest.reflect.beanproperty.PropertyTypeRef.newPropertyTypeRef; 020 import static org.fest.util.Strings.isEmpty; 021 022 import org.fest.reflect.reference.TypeRef; 023 024 025 /** 026 * Understands the name of a property to access using Bean Introspection. 027 * <p> 028 * The following is an example of proper usage of this class: 029 * <pre> 030 * // Retrieves the value of the property "name" 031 * 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 Invoker#get() get}(); 032 * 033 * // Sets the value of the property "name" to "Yoda" 034 * {@link org.fest.reflect.core.Reflection#property(String) property}("name").{@link PropertyName#ofType(Class) ofType}(String.class).{@link PropertyType#in(Object) in}(person).{@link Invoker#set(Object) set}("Yoda"); 035 * 036 * // Retrieves the value of the property "powers" 037 * List<String> powers = {@link org.fest.reflect.core.Reflection#property(String) property}("powers").{@link #ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link PropertyTypeRef#in(Object) in}(jedi).{@link Invoker#get() get}(); 038 * 039 * // Sets the value of the property "powers" 040 * List<String> powers = new ArrayList<String>(); 041 * powers.add("heal"); 042 * {@link org.fest.reflect.core.Reflection#property(String) property}("powers").{@link #ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link PropertyTypeRef#in(Object) in}(jedi).{@link Invoker#set(Object) set}(powers); 043 * </pre> 044 * </p> 045 * 046 * @author Alex Ruiz 047 * 048 * @since 1.2 049 */ 050 public final class PropertyName { 051 052 /** 053 * Creates a new <code>{@link PropertyName}</code>: the starting point of the fluent interface for accessing 054 * properties using Bean Introspection. 055 * @param name the name of the property to access using Bean Introspection. 056 * @return the created <code>PropertyName</code>. 057 * @throws NullPointerException if the given name is <code>null</code>. 058 * @throws IllegalArgumentException if the given name is empty. 059 */ 060 public static PropertyName startPropertyAccess(String name) { 061 validateIsNotNullOrEmpty(name); 062 return new PropertyName(name); 063 } 064 065 private static void validateIsNotNullOrEmpty(String name) { 066 if (name == null) 067 throw new NullPointerException("The name of the property to access should not be null"); 068 if (isEmpty(name)) 069 throw new IllegalArgumentException("The name of the property to access should not be empty"); 070 } 071 072 private final String name; 073 074 private PropertyName(String name) { 075 this.name = name; 076 } 077 078 /** 079 * Sets the type of the property to access. 080 * @param <T> the generic type of the property type. 081 * @param type the type of the property to access. 082 * @return a recipient for the property type. 083 * @throws NullPointerException if the given type is <code>null</code>. 084 */ 085 public <T> PropertyType<T> ofType(Class<T> type) { 086 return newPropertyType(name, type); 087 } 088 089 /** 090 * Sets the type reference of the property to access. This method reduces casting when the type of the property to 091 * access uses generics. 092 * <p> 093 * For example: 094 * <pre> 095 * List<String> powers = {@link org.fest.reflect.core.Reflection#property(String) property}("powers").{@link #ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link PropertyTypeRef#in(Object) in}(jedi).{@link Invoker#get() get}(); 096 * </pre> 097 * </p> 098 * @param <T> the generic type of the property type. 099 * @param type the type of the property to access. 100 * @return a recipient for the property type. 101 * @throws NullPointerException if the given type reference is <code>null</code>. 102 */ 103 public <T> PropertyTypeRef<T> ofType(TypeRef<T> type) { 104 return newPropertyTypeRef(name, type); 105 } 106 }