History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/beans/decoder/PropertyElementHandler.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/beans/decoder/PropertyElementHandler.java+287−0
@@ -0,0 +1,287 @@
1/*
2 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package com.sun.beans.decoder;
26
27import com.sun.beans.finder.MethodFinder;
28
29import java.beans.IndexedPropertyDescriptor;
30import java.beans.IntrospectionException;
31import java.beans.Introspector;
32import java.beans.PropertyDescriptor;
33
34import java.lang.reflect.Array;
35import java.lang.reflect.InvocationTargetException;
36import java.lang.reflect.Method;
37
38/**
39 * This class is intended to handle <property> element.
40 * This element simplifies access to the properties.
41 * If the {@code index} attribute is specified
42 * this element uses additional {@code int} parameter.
43 * If the {@code name} attribute is not specified
44 * this element uses method "get" as getter
45 * and method "set" as setter.
46 * This element defines getter if it contains no argument.
47 * It returns the value of the property in this case.
48 * For example:<pre>
49 * &lt;property name="object" index="10"/&gt;</pre>
50 * is shortcut to<pre>
51 * &lt;method name="getObject"&gt;
52 * &lt;int&gt;10&lt;/int&gt;
53 * &lt;/method&gt;</pre>
54 * which is equivalent to {@code getObject(10)} in Java code.
55 * This element defines setter if it contains one argument.
56 * It does not return the value of the property in this case.
57 * For example:<pre>
58 * &lt;property&gt;&lt;int&gt;0&lt;/int&gt;&lt;/property&gt;</pre>
59 * is shortcut to<pre>
60 * &lt;method name="set"&gt;
61 * &lt;int&gt;0&lt;/int&gt;
62 * &lt;/method&gt;</pre>
63 * which is equivalent to {@code set(0)} in Java code.
64 * <p>The following atributes are supported:
65 * <dl>
66 * <dt>name
67 * <dd>the property name
68 * <dt>index
69 * <dd>the property index
70 * <dt>id
71 * <dd>the identifier of the variable that is intended to store the result
72 * </dl>
73 *
74 * @since 1.7
75 *
76 * @author Sergey A. Malenkov
77 */
78final class PropertyElementHandler extends AccessorElementHandler {
79 static final String GETTER = "get"; // NON-NLS: the getter prefix
80 static final String SETTER = "set"; // NON-NLS: the setter prefix
81
82 private Integer index;
83
84 /**
85 * Parses attributes of the element.
86 * The following atributes are supported:
87 * <dl>
88 * <dt>name
89 * <dd>the property name
90 * <dt>index
91 * <dd>the property index
92 * <dt>id
93 * <dd>the identifier of the variable that is intended to store the result
94 * </dl>
95 *
96 * @param name the attribute name
97 * @param value the attribute value
98 */
99 @Override
100 public void addAttribute(String name, String value) {
101 if (name.equals("index")) { // NON-NLS: the attribute name
102 this.index = Integer.valueOf(value);
103 } else {
104 super.addAttribute(name, value);
105 }
106 }
107
108 /**
109 * Tests whether the value of this element can be used
110 * as an argument of the element that contained in this one.
111 *
112 * @return {@code true} if the value of this element should be used
113 * as an argument of the element that contained in this one,
114 * {@code false} otherwise
115 */
116 @Override
117 protected boolean isArgument() {
118 return false; // non-static accessor cannot be used an argument
119 }
120
121 /**
122 * Returns the value of the property with specified {@code name}.
123 *
124 * @param name the name of the property
125 * @return the value of the specified property
126 */
127 @Override
128 protected Object getValue(String name) {
129 try {
130 return getPropertyValue(getContextBean(), name, this.index);
131 }
132 catch (Exception exception) {
133 getOwner().handleException(exception);
134 }
135 return null;
136 }
137
138 /**
139 * Sets the new value for the property with specified {@code name}.
140 *
141 * @param name the name of the property
142 * @param value the new value for the specified property
143 */
144 @Override
145 protected void setValue(String name, Object value) {
146 try {
147 setPropertyValue(getContextBean(), name, this.index, value);
148 }
149 catch (Exception exception) {
150 getOwner().handleException(exception);
151 }
152 }
153
154 /**
155 * Performs the search of the getter for the property
156 * with specified {@code name} in specified class
157 * and returns value of the property.
158 *
159 * @param bean the context bean that contains property
160 * @param name the name of the property
161 * @param index the index of the indexed property
162 * @return the value of the property
163 * @throws IllegalAccessException if the property is not accesible
164 * @throws IntrospectionException if the bean introspection is failed
165 * @throws InvocationTargetException if the getter cannot be invoked
166 * @throws NoSuchMethodException if the getter is not found
167 */
168 private static Object getPropertyValue(Object bean, String name, Integer index) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException {
169 Class<?> type = bean.getClass();
170 if (index == null) {
171 return findGetter(type, name).invoke(bean);
172 } else if (type.isArray() && (name == null)) {
173 return Array.get(bean, index);
174 } else {
175 return findGetter(type, name, int.class).invoke(bean, index);
176 }
177 }
178
179 /**
180 * Performs the search of the setter for the property
181 * with specified {@code name} in specified class
182 * and updates value of the property.
183 *
184 * @param bean the context bean that contains property
185 * @param name the name of the property
186 * @param index the index of the indexed property
187 * @param value the new value for the property
188 * @throws IllegalAccessException if the property is not accesible
189 * @throws IntrospectionException if the bean introspection is failed
190 * @throws InvocationTargetException if the setter cannot be invoked
191 * @throws NoSuchMethodException if the setter is not found
192 */
193 private static void setPropertyValue(Object bean, String name, Integer index, Object value) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException {
194 Class<?> type = bean.getClass();
195 Class<?> param = (value != null)
196 ? value.getClass()
197 : null;
198
199 if (index == null) {
200 findSetter(type, name, param).invoke(bean, value);
201 } else if (type.isArray() && (name == null)) {
202 Array.set(bean, index, value);
203 } else {
204 findSetter(type, name, int.class, param).invoke(bean, index, value);
205 }
206 }
207
208 /**
209 * Performs the search of the getter for the property
210 * with specified {@code name} in specified class.
211 *
212 * @param type the class that contains method
213 * @param name the name of the property
214 * @param args the method arguments
215 * @return method object that represents found getter
216 * @throws IntrospectionException if the bean introspection is failed
217 * @throws NoSuchMethodException if method is not found
218 */
219 private static Method findGetter(Class<?> type, String name, Class<?>...args) throws IntrospectionException, NoSuchMethodException {
220 if (name == null) {
221 return MethodFinder.findInstanceMethod(type, GETTER, args);
222 }
223 PropertyDescriptor pd = getProperty(type, name);
224 if (args.length == 0) {
225 Method method = pd.getReadMethod();
226 if (method != null) {
227 return method;
228 }
229 } else if (pd instanceof IndexedPropertyDescriptor) {
230 IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
231 Method method = ipd.getIndexedReadMethod();
232 if (method != null) {
233 return method;
234 }
235 }
236 throw new IntrospectionException("Could not find getter for the " + name + " property");
237 }
238
239 /**
240 * Performs the search of the setter for the property
241 * with specified {@code name} in specified class.
242 *
243 * @param type the class that contains method
244 * @param name the name of the property
245 * @param args the method arguments
246 * @return method object that represents found setter
247 * @throws IntrospectionException if the bean introspection is failed
248 * @throws NoSuchMethodException if method is not found
249 */
250 private static Method findSetter(Class<?> type, String name, Class<?>...args) throws IntrospectionException, NoSuchMethodException {
251 if (name == null) {
252 return MethodFinder.findInstanceMethod(type, SETTER, args);
253 }
254 PropertyDescriptor pd = getProperty(type, name);
255 if (args.length == 1) {
256 Method method = pd.getWriteMethod();
257 if (method != null) {
258 return method;
259 }
260 } else if (pd instanceof IndexedPropertyDescriptor) {
261 IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
262 Method method = ipd.getIndexedWriteMethod();
263 if (method != null) {
264 return method;
265 }
266 }
267 throw new IntrospectionException("Could not find setter for the " + name + " property");
268 }
269
270 /**
271 * Performs the search of the descriptor for the property
272 * with specified {@code name} in specified class.
273 *
274 * @param type the class to introspect
275 * @param name the property name
276 * @return descriptor for the named property
277 * @throws IntrospectionException if property descriptor is not found
278 */
279 private static PropertyDescriptor getProperty(Class<?> type, String name) throws IntrospectionException {
280 for (PropertyDescriptor pd : Introspector.getBeanInfo(type).getPropertyDescriptors()) {
281 if (name.equals(pd.getName())) {
282 return pd;
283 }
284 }
285 throw new IntrospectionException("Could not find the " + name + " property descriptor");
286 }
287}