1 package org.apache.commons.beanutils2;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.util.Map;
23
24 /**
25 * Provides access to properties and methods of a bean.
26 *
27 * @param <B> the type of the bean this BeanAcessor is associated with.
28 */
29 public interface BeanAccessor<B>
30 {
31
32 // get
33
34 /**
35 * Gets the value of the property with name {@code propertyName} from the bean wrapped by this BeanAccessor. The
36 * value will be wrapped in a {@code BeanAccessor} to enable fluent calls.
37 *
38 * @param propertyName the name of the property to get the value from. Must not be {@code null}!
39 * @return a {@code BeanAccessor} wrapping the properties value.
40 */
41 BeanAccessor<?> get( String propertyName );
42
43 /**
44 * Selects the indexed property with name {@code propertyName} from the bean wrapped by this {@code BeanAccessor}. A
45 * {@link IndexedPropertyGetterAccessor} will be returned for specifying the index to return the value of.
46 *
47 * @param propertyName the name of the indexed property to select. Must not be {@code null}!
48 * @return a {@link IndexedPropertyGetterAccessor} for specifying the index to return the value of.
49 */
50 IndexedPropertyGetterAccessor<?> getIndexed( String propertyName );
51
52 /**
53 * Selects the mapped property with name {@code propertyName} from the bean wrapped by this {@code BeanAccessor}. A
54 * {@link MappedPropertyGetterAccessor} will be returned for specifying the key to return the value of.
55 *
56 * @param propertyName the name of the mapped property to select. Must not be {@code null}!
57 * @return a {@link MappedPropertyGetterAccessor} for specifying the key to return the value of.
58 */
59 MappedPropertyGetterAccessor getMapped( String propertyName );
60
61 /**
62 * Gets the bean wrapped by this {@code BeanAccessor}.
63 *
64 * @return the bean.
65 */
66 B get();
67
68 /**
69 * Tries to cast the bean wrapped by this {@code BeanAccessor} an returns the result.
70 *
71 * @param <V> the type to cast the wrapped bean to.
72 * @return the wrapped bean, casted to type {@code V}.
73 */
74 <V> V cast();
75
76 // set
77
78 /**
79 * Selects the property with name {@code propertyName} for setting a new value. A {@link BeanPropertySetter} will be
80 * returned for specifying the new value.
81 *
82 * @param propertyName the name of the property to select for setting a new value. Must not be {@code null}.
83 * @return a {@link BeanPropertySetter} for setting a new value.
84 */
85 BeanPropertySetter<B> set( String propertyName );
86
87 /**
88 * Selects the indexed property with name {@code propertyName} for setting a new value. A
89 * {@link IndexedPropertySetterAccessor} will be returned for specifying the index to set a new value to.
90 *
91 * @param propertyName the name of the indexed property to select for setting a new value. Must not be {@code null}.
92 * @return a {@link IndexedPropertySetterAccessor} for setting a new value.
93 */
94 IndexedPropertySetterAccessor<B> setIndexed( String propertyName );
95
96 /**
97 * Selects the mapped property with name {@code propertyName} for setting a new value. A
98 * {@link MappedPropertySetterAccessor} will be returned for specifying the key to set a new value to.
99 *
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 }