Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/com/sun/beans/decoder/PropertyElementHandler.java
41171 views
1
/*
2
* Copyright (c) 2008, 2013, 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
import sun.reflect.misc.MethodUtil;
39
40
/**
41
* This class is intended to handle <property> element.
42
* This element simplifies access to the properties.
43
* If the {@code index} attribute is specified
44
* this element uses additional {@code int} parameter.
45
* If the {@code name} attribute is not specified
46
* this element uses method "get" as getter
47
* and method "set" as setter.
48
* This element defines getter if it contains no argument.
49
* It returns the value of the property in this case.
50
* For example:<pre>
51
* &lt;property name="object" index="10"/&gt;</pre>
52
* is shortcut to<pre>
53
* &lt;method name="getObject"&gt;
54
* &lt;int&gt;10&lt;/int&gt;
55
* &lt;/method&gt;</pre>
56
* which is equivalent to {@code getObject(10)} in Java code.
57
* This element defines setter if it contains one argument.
58
* It does not return the value of the property in this case.
59
* For example:<pre>
60
* &lt;property&gt;&lt;int&gt;0&lt;/int&gt;&lt;/property&gt;</pre>
61
* is shortcut to<pre>
62
* &lt;method name="set"&gt;
63
* &lt;int&gt;0&lt;/int&gt;
64
* &lt;/method&gt;</pre>
65
* which is equivalent to {@code set(0)} in Java code.
66
* <p>The following attributes are supported:
67
* <dl>
68
* <dt>name
69
* <dd>the property name
70
* <dt>index
71
* <dd>the property index
72
* <dt>id
73
* <dd>the identifier of the variable that is intended to store the result
74
* </dl>
75
*
76
* @since 1.7
77
*
78
* @author Sergey A. Malenkov
79
*/
80
final class PropertyElementHandler extends AccessorElementHandler {
81
static final String GETTER = "get"; // NON-NLS: the getter prefix
82
static final String SETTER = "set"; // NON-NLS: the setter prefix
83
84
private Integer index;
85
86
/**
87
* Parses attributes of the element.
88
* The following attributes are supported:
89
* <dl>
90
* <dt>name
91
* <dd>the property name
92
* <dt>index
93
* <dd>the property index
94
* <dt>id
95
* <dd>the identifier of the variable that is intended to store the result
96
* </dl>
97
*
98
* @param name the attribute name
99
* @param value the attribute value
100
*/
101
@Override
102
public void addAttribute(String name, String value) {
103
if (name.equals("index")) { // NON-NLS: the attribute name
104
this.index = Integer.valueOf(value);
105
} else {
106
super.addAttribute(name, value);
107
}
108
}
109
110
/**
111
* Tests whether the value of this element can be used
112
* as an argument of the element that contained in this one.
113
*
114
* @return {@code true} if the value of this element should be used
115
* as an argument of the element that contained in this one,
116
* {@code false} otherwise
117
*/
118
@Override
119
protected boolean isArgument() {
120
return false; // non-static accessor cannot be used an argument
121
}
122
123
/**
124
* Returns the value of the property with specified {@code name}.
125
*
126
* @param name the name of the property
127
* @return the value of the specified property
128
*/
129
@Override
130
protected Object getValue(String name) {
131
try {
132
return getPropertyValue(getContextBean(), name, this.index);
133
}
134
catch (Exception exception) {
135
getOwner().handleException(exception);
136
}
137
return null;
138
}
139
140
/**
141
* Sets the new value for the property with specified {@code name}.
142
*
143
* @param name the name of the property
144
* @param value the new value for the specified property
145
*/
146
@Override
147
protected void setValue(String name, Object value) {
148
try {
149
setPropertyValue(getContextBean(), name, this.index, value);
150
}
151
catch (Exception exception) {
152
getOwner().handleException(exception);
153
}
154
}
155
156
/**
157
* Performs the search of the getter for the property
158
* with specified {@code name} in specified class
159
* and returns value of the property.
160
*
161
* @param bean the context bean that contains property
162
* @param name the name of the property
163
* @param index the index of the indexed property
164
* @return the value of the property
165
* @throws IllegalAccessException if the property is not accesible
166
* @throws IntrospectionException if the bean introspection is failed
167
* @throws InvocationTargetException if the getter cannot be invoked
168
* @throws NoSuchMethodException if the getter is not found
169
*/
170
private static Object getPropertyValue(Object bean, String name, Integer index) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException {
171
Class<?> type = bean.getClass();
172
if (index == null) {
173
return MethodUtil.invoke(findGetter(type, name), bean, new Object[] {});
174
} else if (type.isArray() && (name == null)) {
175
return Array.get(bean, index);
176
} else {
177
return MethodUtil.invoke(findGetter(type, name, int.class), bean, new Object[] {index});
178
}
179
}
180
181
/**
182
* Performs the search of the setter for the property
183
* with specified {@code name} in specified class
184
* and updates value of the property.
185
*
186
* @param bean the context bean that contains property
187
* @param name the name of the property
188
* @param index the index of the indexed property
189
* @param value the new value for the property
190
* @throws IllegalAccessException if the property is not accesible
191
* @throws IntrospectionException if the bean introspection is failed
192
* @throws InvocationTargetException if the setter cannot be invoked
193
* @throws NoSuchMethodException if the setter is not found
194
*/
195
private static void setPropertyValue(Object bean, String name, Integer index, Object value) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException {
196
Class<?> type = bean.getClass();
197
Class<?> param = (value != null)
198
? value.getClass()
199
: null;
200
201
if (index == null) {
202
MethodUtil.invoke(findSetter(type, name, param), bean, new Object[] {value});
203
} else if (type.isArray() && (name == null)) {
204
Array.set(bean, index, value);
205
} else {
206
MethodUtil.invoke(findSetter(type, name, int.class, param), bean, new Object[] {index, value});
207
}
208
}
209
210
/**
211
* Performs the search of the getter for the property
212
* with specified {@code name} in specified class.
213
*
214
* @param type the class that contains method
215
* @param name the name of the property
216
* @param args the method arguments
217
* @return method object that represents found getter
218
* @throws IntrospectionException if the bean introspection is failed
219
* @throws NoSuchMethodException if method is not found
220
*/
221
private static Method findGetter(Class<?> type, String name, Class<?>...args) throws IntrospectionException, NoSuchMethodException {
222
if (name == null) {
223
return MethodFinder.findInstanceMethod(type, GETTER, args);
224
}
225
PropertyDescriptor pd = getProperty(type, name);
226
if (args.length == 0) {
227
Method method = pd.getReadMethod();
228
if (method != null) {
229
return method;
230
}
231
} else if (pd instanceof IndexedPropertyDescriptor) {
232
IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
233
Method method = ipd.getIndexedReadMethod();
234
if (method != null) {
235
return method;
236
}
237
}
238
throw new IntrospectionException("Could not find getter for the " + name + " property");
239
}
240
241
/**
242
* Performs the search of the setter for the property
243
* with specified {@code name} in specified class.
244
*
245
* @param type the class that contains method
246
* @param name the name of the property
247
* @param args the method arguments
248
* @return method object that represents found setter
249
* @throws IntrospectionException if the bean introspection is failed
250
* @throws NoSuchMethodException if method is not found
251
*/
252
private static Method findSetter(Class<?> type, String name, Class<?>...args) throws IntrospectionException, NoSuchMethodException {
253
if (name == null) {
254
return MethodFinder.findInstanceMethod(type, SETTER, args);
255
}
256
PropertyDescriptor pd = getProperty(type, name);
257
if (args.length == 1) {
258
Method method = pd.getWriteMethod();
259
if (method != null) {
260
return method;
261
}
262
} else if (pd instanceof IndexedPropertyDescriptor) {
263
IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
264
Method method = ipd.getIndexedWriteMethod();
265
if (method != null) {
266
return method;
267
}
268
}
269
throw new IntrospectionException("Could not find setter for the " + name + " property");
270
}
271
272
/**
273
* Performs the search of the descriptor for the property
274
* with specified {@code name} in specified class.
275
*
276
* @param type the class to introspect
277
* @param name the property name
278
* @return descriptor for the named property
279
* @throws IntrospectionException if property descriptor is not found
280
*/
281
private static PropertyDescriptor getProperty(Class<?> type, String name) throws IntrospectionException {
282
for (PropertyDescriptor pd : Introspector.getBeanInfo(type).getPropertyDescriptors()) {
283
if (name.equals(pd.getName())) {
284
return pd;
285
}
286
}
287
throw new IntrospectionException("Could not find the " + name + " property descriptor");
288
}
289
}
290
291