001 /* 002 * Created on Feb 22, 2011 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 @2011 the original author or authors. 014 */ 015 package org.fest.assertions.groups; 016 017 import static org.fest.assertions.util.ArrayWrapperList.wrap; 018 019 import java.util.Collection; 020 import java.util.List; 021 022 import org.fest.assertions.internal.PropertySupport; 023 import org.fest.util.IntrospectionError; 024 import org.fest.util.VisibleForTesting; 025 026 /** 027 * Extracts the values of a specified property from the elements of a given <code>{@link Collection}</code> or array. 028 * 029 * @author Yvonne Wang 030 * @author Mikhail Mazursky 031 * @author Joel Costigliola 032 */ 033 public class Properties<T> { 034 035 @VisibleForTesting 036 final String propertyName; 037 final Class<T> propertyType; 038 039 @VisibleForTesting 040 PropertySupport propertySupport = PropertySupport.instance(); 041 042 /** 043 * Creates a new <code>{@link Properties}</code>. 044 * @param propertyName the name of the property to be read from the elements of a {@code Collection}. It may be a 045 * nested property (e.g. "address.street.number"). 046 * @param propertyType the type of property to extract 047 * @throws NullPointerException if the given property name is {@code null}. 048 * @throws IllegalArgumentException if the given property name is empty. 049 * @return the created {@code Properties}. 050 */ 051 public static <T> Properties<T> extractProperty(String propertyName, Class<T> propertyType) { 052 checkIsNotNullOrEmpty(propertyName); 053 return new Properties<T>(propertyName, propertyType); 054 } 055 056 /** 057 * Creates a new <code>{@link Properties} with given propertyName and Object as property type.</code>. 058 * @param propertyName the name of the property to be read from the elements of a {@code Collection}. It may be a 059 * nested property (e.g. "address.street.number"). 060 * @throws NullPointerException if the given property name is {@code null}. 061 * @throws IllegalArgumentException if the given property name is empty. 062 * @return the created {@code Properties}. 063 */ 064 public static Properties<Object> extractProperty(String propertyName) { 065 return extractProperty(propertyName, Object.class); 066 } 067 068 private static void checkIsNotNullOrEmpty(String propertyName) { 069 if (propertyName == null) throw new NullPointerException("The name of the property to read should not be null"); 070 if (propertyName.length() == 0) 071 throw new IllegalArgumentException("The name of the property to read should not be empty"); 072 } 073 074 @VisibleForTesting 075 Properties(String propertyName, Class<T> propertyType) { 076 this.propertyName = propertyName; 077 this.propertyType = propertyType; 078 } 079 080 /** 081 * Extracts the values of the property (specified previously in <code>{@link #extractProperty(String)}</code>) from 082 * the elements of the given <code>{@link Collection}</code>. 083 * @param c the given {@code Collection}. 084 * @return the values of the previously specified property extracted from the given {@code Collection}. 085 * @throws IntrospectionError if an element in the given {@code Collection} does not have a property with a matching 086 * name. 087 */ 088 public List<T> from(Collection<?> c) { 089 return propertySupport.propertyValues(propertyName, propertyType, c); 090 } 091 092 /** 093 * Extracts the values of the property (specified previously in <code>{@link #extractProperty(String)}</code>) from 094 * the elements of the given array. 095 * @param array the given array. 096 * @return the values of the previously specified property extracted from the given array. 097 * @throws IntrospectionError if an element in the given array does not have a property with a matching name. 098 */ 099 public List<T> from(Object[] array) { 100 return propertySupport.propertyValues(propertyName, propertyType, wrap(array)); 101 } 102 }