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+ */
25+package com.sun.beans.decoder;
26+
27+import com.sun.beans.finder.MethodFinder;
28+
29+import java.beans.IndexedPropertyDescriptor;
30+import java.beans.IntrospectionException;
31+import java.beans.Introspector;
32+import java.beans.PropertyDescriptor;
33+
34+import java.lang.reflect.Array;
35+import java.lang.reflect.InvocationTargetException;
36+import 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+ */
78+final 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+}