001package org.apache.commons.beanutils2; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.util.Map; 023 024/** 025 * Provides access to properties and methods of a bean. 026 * 027 * @param <B> the type of the bean this BeanAcessor is associated with. 028 */ 029public interface BeanAccessor<B> 030{ 031 032 // get 033 034 /** 035 * Gets the value of the property with name {@code propertyName} from the bean wrapped by this BeanAccessor. The 036 * value will be wrapped in a {@code BeanAccessor} to enable fluent calls. 037 * 038 * @param propertyName the name of the property to get the value from. Must not be {@code null}! 039 * @return a {@code BeanAccessor} wrapping the properties value. 040 */ 041 BeanAccessor<?> get( String propertyName ); 042 043 /** 044 * Selects the indexed property with name {@code propertyName} from the bean wrapped by this {@code BeanAccessor}. A 045 * {@link IndexedPropertyGetterAccessor} will be returned for specifying the index to return the value of. 046 * 047 * @param propertyName the name of the indexed property to select. Must not be {@code null}! 048 * @return a {@link IndexedPropertyGetterAccessor} for specifying the index to return the value of. 049 */ 050 IndexedPropertyGetterAccessor<?> getIndexed( String propertyName ); 051 052 /** 053 * Selects the mapped property with name {@code propertyName} from the bean wrapped by this {@code BeanAccessor}. A 054 * {@link MappedPropertyGetterAccessor} will be returned for specifying the key to return the value of. 055 * 056 * @param propertyName the name of the mapped property to select. Must not be {@code null}! 057 * @return a {@link MappedPropertyGetterAccessor} for specifying the key to return the value of. 058 */ 059 MappedPropertyGetterAccessor getMapped( String propertyName ); 060 061 /** 062 * Gets the bean wrapped by this {@code BeanAccessor}. 063 * 064 * @return the bean. 065 */ 066 B get(); 067 068 /** 069 * Tries to cast the bean wrapped by this {@code BeanAccessor} an returns the result. 070 * 071 * @param <V> the type to cast the wrapped bean to. 072 * @return the wrapped bean, casted to type {@code V}. 073 */ 074 <V> V cast(); 075 076 // set 077 078 /** 079 * Selects the property with name {@code propertyName} for setting a new value. A {@link BeanPropertySetter} will be 080 * returned for specifying the new value. 081 * 082 * @param propertyName the name of the property to select for setting a new value. Must not be {@code null}. 083 * @return a {@link BeanPropertySetter} for setting a new value. 084 */ 085 BeanPropertySetter<B> set( String propertyName ); 086 087 /** 088 * Selects the indexed property with name {@code propertyName} for setting a new value. A 089 * {@link IndexedPropertySetterAccessor} will be returned for specifying the index to set a new value to. 090 * 091 * @param propertyName the name of the indexed property to select for setting a new value. Must not be {@code null}. 092 * @return a {@link IndexedPropertySetterAccessor} for setting a new value. 093 */ 094 IndexedPropertySetterAccessor<B> setIndexed( String propertyName ); 095 096 /** 097 * Selects the mapped property with name {@code propertyName} for setting a new value. A 098 * {@link MappedPropertySetterAccessor} will be returned for specifying the key to set a new value to. 099 * 100 * @param propertyName the name of the mapped property to select for setting a new value. Must not be {@code null}. 101 * @return a {@link MappedPropertySetterAccessor} for setting a new value. 102 */ 103 MappedPropertySetterAccessor<B> setMapped( String propertyName ); 104 105 // clone 106 107 /** 108 * Clones a bean based on the available property getters and setters, even if the bean class itself does not 109 * implement Cloneable. 110 * <p> 111 * <strong>Note:</strong> this method creates a <strong>shallow</strong> clone. In other words, any objects referred 112 * to by the bean are shared with the clone rather than being cloned in turn. 113 * 114 * @return the cloned bean 115 */ 116 B cloneBean(); 117 118 /** 119 * Copies property values from the bean wrapped by this {@code BeanAccessor} to {@code target} for all cases where 120 * the property names are the same. For each property, a conversion is attempted as necessary. 121 * <p> 122 * <strong>Note</strong> that this method is intended to perform a "shallow copy" of the properties and so complex 123 * properties (for example, nested ones) will not be copied. 124 * <p> 125 * <strong>TODO</strong> should we implement something like the following? 126 * <p> 127 * If you know that no type conversions are required, the <code>copyProperties()</code> method in 128 * {@link PropertyUtils} will execute faster than this method. 129 * <p> 130 * <strong>FIXME</strong> - Indexed and mapped properties that do not have getter and setter methods for the 131 * underlying array or Map are not copied by this method. 132 * 133 * @param <T> the type of the bean to copy properties to. 134 * @param target the target to copy properties to from the wrapped bean 135 */ 136 <T extends B> void copyPropertiesTo( T target ); 137 138 // description 139 140 /** 141 * Return the entire set of properties for which the specified bean provides a read method. This map contains the 142 * property names as keys and the property values as values, for all properties the bean provides a read method for 143 * (i.e. where the getReadMethod() returns non-null). 144 * <p> 145 * This map can be fed back to a call to <code>BeanAccessor.populate()</code> to reconstitute the same set of 146 * properties, modulo differences for read-only and write-only properties, but only if there are no indexed 147 * properties. 148 * <p> 149 * <strong>Warning:</strong> if any of the bean property implementations contain (directly or indirectly) a call to 150 * this method then a stack overflow may result. For example: <code><pre> 151 * class MyBean 152 * { 153 * public Map<String, Object> getParameterMap() 154 * { 155 * on( this ).describe; 156 * } 157 * } 158 * </pre></code> will result in an infinite regression when <code>getParametersMap</code> is called. It is 159 * recommended that such methods are given alternative names (for example, <code>parametersMap</code>). 160 * 161 * @return Map that contains the property names as keys and property values as values. 162 */ 163 Map<String, Object> describe(); 164 165 /** 166 * Populate {@code properties} to the bean wrapped by this {@code BeanAccessor}. The map of properties passed to 167 * this method has to specify names of properties to set and corresponding values as key-value-pairs. 168 * 169 * @param properties Map keyed by property name, with the corresponding value to be set. 170 * Must not be {@code null}. 171 */ 172 void populate( Map<String, Object> properties ); 173 174 // methods invocation 175 176 /** 177 * Invokes the method with name {@code methodName}. An {@link ArgumentsAccessor} will be returned to specify the 178 * parameters for the method invocation. 179 * 180 * @param methodName the name of the method to invoke. Must not be {@code null}! 181 * @return an {@link ArgumentsAccessor} to specify arguments for the method invocation. 182 */ 183 ArgumentsAccessor invoke( String methodName ); 184 185 /** 186 * Invokes the method with name {@code methodName} and the exact arguments. An {@link ArgumentsAccessor} will be 187 * returned to specify the parameters for the method invocation. 188 * 189 * @param methodName the name of the method to invoke. Must not be {@code null}! 190 * @return a {@link ArgumentsAccessor} to specify any arguments 191 */ 192 ArgumentsAccessor invokeExact( String methodName ); 193 194}