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/java/beans/IndexedPropertyDescriptor.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/beans/IndexedPropertyDescriptor.java+523−0
@@ -0,0 +1,523 @@
1/*
2 * Copyright (c) 1996, 2010, 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
26package java.beans;
27
28import java.lang.ref.Reference;
29import java.lang.reflect.Method;
30
31/**
32 * An IndexedPropertyDescriptor describes a property that acts like an
33 * array and has an indexed read and/or indexed write method to access
34 * specific elements of the array.
35 * <p>
36 * An indexed property may also provide simple non-indexed read and write
37 * methods. If these are present, they read and write arrays of the type
38 * returned by the indexed read method.
39 */
40
41public class IndexedPropertyDescriptor extends PropertyDescriptor {
42
43 private Reference<Class> indexedPropertyTypeRef;
44 private Reference<Method> indexedReadMethodRef;
45 private Reference<Method> indexedWriteMethodRef;
46
47 private String indexedReadMethodName;
48 private String indexedWriteMethodName;
49
50 /**
51 * This constructor constructs an IndexedPropertyDescriptor for a property
52 * that follows the standard Java conventions by having getFoo and setFoo
53 * accessor methods, for both indexed access and array access.
54 * <p>
55 * Thus if the argument name is "fred", it will assume that there
56 * is an indexed reader method "getFred", a non-indexed (array) reader
57 * method also called "getFred", an indexed writer method "setFred",
58 * and finally a non-indexed writer method "setFred".
59 *
60 * @param propertyName The programmatic name of the property.
61 * @param beanClass The Class object for the target bean.
62 * @exception IntrospectionException if an exception occurs during
63 * introspection.
64 */
65 public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass)
66 throws IntrospectionException {
67 this(propertyName, beanClass,
68 Introspector.GET_PREFIX + NameGenerator.capitalize(propertyName),
69 Introspector.SET_PREFIX + NameGenerator.capitalize(propertyName),
70 Introspector.GET_PREFIX + NameGenerator.capitalize(propertyName),
71 Introspector.SET_PREFIX + NameGenerator.capitalize(propertyName));
72 }
73
74 /**
75 * This constructor takes the name of a simple property, and method
76 * names for reading and writing the property, both indexed
77 * and non-indexed.
78 *
79 * @param propertyName The programmatic name of the property.
80 * @param beanClass The Class object for the target bean.
81 * @param readMethodName The name of the method used for reading the property
82 * values as an array. May be null if the property is write-only
83 * or must be indexed.
84 * @param writeMethodName The name of the method used for writing the property
85 * values as an array. May be null if the property is read-only
86 * or must be indexed.
87 * @param indexedReadMethodName The name of the method used for reading
88 * an indexed property value.
89 * May be null if the property is write-only.
90 * @param indexedWriteMethodName The name of the method used for writing
91 * an indexed property value.
92 * May be null if the property is read-only.
93 * @exception IntrospectionException if an exception occurs during
94 * introspection.
95 */
96 public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass,
97 String readMethodName, String writeMethodName,
98 String indexedReadMethodName, String indexedWriteMethodName)
99 throws IntrospectionException {
100 super(propertyName, beanClass, readMethodName, writeMethodName);
101
102 this.indexedReadMethodName = indexedReadMethodName;
103 if (indexedReadMethodName != null && getIndexedReadMethod() == null) {
104 throw new IntrospectionException("Method not found: " + indexedReadMethodName);
105 }
106
107 this.indexedWriteMethodName = indexedWriteMethodName;
108 if (indexedWriteMethodName != null && getIndexedWriteMethod() == null) {
109 throw new IntrospectionException("Method not found: " + indexedWriteMethodName);
110 }
111 // Implemented only for type checking.
112 findIndexedPropertyType(getIndexedReadMethod(), getIndexedWriteMethod());
113 }
114
115 /**
116 * This constructor takes the name of a simple property, and Method
117 * objects for reading and writing the property.
118 *
119 * @param propertyName The programmatic name of the property.
120 * @param readMethod The method used for reading the property values as an array.
121 * May be null if the property is write-only or must be indexed.
122 * @param writeMethod The method used for writing the property values as an array.
123 * May be null if the property is read-only or must be indexed.
124 * @param indexedReadMethod The method used for reading an indexed property value.
125 * May be null if the property is write-only.
126 * @param indexedWriteMethod The method used for writing an indexed property value.
127 * May be null if the property is read-only.
128 * @exception IntrospectionException if an exception occurs during
129 * introspection.
130 */
131 public IndexedPropertyDescriptor(String propertyName, Method readMethod, Method writeMethod,
132 Method indexedReadMethod, Method indexedWriteMethod)
133 throws IntrospectionException {
134 super(propertyName, readMethod, writeMethod);
135
136 setIndexedReadMethod0(indexedReadMethod);
137 setIndexedWriteMethod0(indexedWriteMethod);
138
139 // Type checking
140 setIndexedPropertyType(findIndexedPropertyType(indexedReadMethod, indexedWriteMethod));
141 }
142
143 /**
144 * Creates <code>PropertyDescriptor</code> for the specified bean
145 * with the specified name and methods to read/write the property value.
146 *
147 * @param bean the type of the target bean
148 * @param base the base name of the property (the rest of the method name)
149 * @param read the method used for reading the property value
150 * @param write the method used for writing the property value
151 * @param readIndexed the method used for reading an indexed property value
152 * @param writeIndexed the method used for writing an indexed property value
153 * @exception IntrospectionException if an exception occurs during introspection
154 *
155 * @since 1.7
156 */
157 IndexedPropertyDescriptor(Class<?> bean, String base, Method read, Method write, Method readIndexed, Method writeIndexed) throws IntrospectionException {
158 super(bean, base, read, write);
159
160 setIndexedReadMethod0(readIndexed);
161 setIndexedWriteMethod0(writeIndexed);
162
163 // Type checking
164 setIndexedPropertyType(findIndexedPropertyType(readIndexed, writeIndexed));
165 }
166
167 /**
168 * Gets the method that should be used to read an indexed
169 * property value.
170 *
171 * @return The method that should be used to read an indexed
172 * property value.
173 * May return null if the property isn't indexed or is write-only.
174 */
175 public synchronized Method getIndexedReadMethod() {
176 Method indexedReadMethod = getIndexedReadMethod0();
177 if (indexedReadMethod == null) {
178 Class cls = getClass0();
179 if (cls == null ||
180 (indexedReadMethodName == null && indexedReadMethodRef == null)) {
181 // the Indexed readMethod was explicitly set to null.
182 return null;
183 }
184 if (indexedReadMethodName == null) {
185 Class type = getIndexedPropertyType0();
186 if (type == boolean.class || type == null) {
187 indexedReadMethodName = Introspector.IS_PREFIX + getBaseName();
188 } else {
189 indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
190 }
191 }
192
193 Class[] args = { int.class };
194 indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
195 if (indexedReadMethod == null) {
196 // no "is" method, so look for a "get" method.
197 indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
198 indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
199 }
200 setIndexedReadMethod0(indexedReadMethod);
201 }
202 return indexedReadMethod;
203 }
204
205 /**
206 * Sets the method that should be used to read an indexed property value.
207 *
208 * @param readMethod The new indexed read method.
209 */
210 public synchronized void setIndexedReadMethod(Method readMethod)
211 throws IntrospectionException {
212
213 // the indexed property type is set by the reader.
214 setIndexedPropertyType(findIndexedPropertyType(readMethod,
215 getIndexedWriteMethod0()));
216 setIndexedReadMethod0(readMethod);
217 }
218
219 private void setIndexedReadMethod0(Method readMethod) {
220 if (readMethod == null) {
221 indexedReadMethodName = null;
222 indexedReadMethodRef = null;
223 return;
224 }
225 setClass0(readMethod.getDeclaringClass());
226
227 indexedReadMethodName = readMethod.getName();
228 this.indexedReadMethodRef = getSoftReference(readMethod);
229 setTransient(readMethod.getAnnotation(Transient.class));
230 }
231
232
233 /**
234 * Gets the method that should be used to write an indexed property value.
235 *
236 * @return The method that should be used to write an indexed
237 * property value.
238 * May return null if the property isn't indexed or is read-only.
239 */
240 public synchronized Method getIndexedWriteMethod() {
241 Method indexedWriteMethod = getIndexedWriteMethod0();
242 if (indexedWriteMethod == null) {
243 Class cls = getClass0();
244 if (cls == null ||
245 (indexedWriteMethodName == null && indexedWriteMethodRef == null)) {
246 // the Indexed writeMethod was explicitly set to null.
247 return null;
248 }
249
250 // We need the indexed type to ensure that we get the correct method.
251 // Cannot use the getIndexedPropertyType method since that could
252 // result in an infinite loop.
253 Class type = getIndexedPropertyType0();
254 if (type == null) {
255 try {
256 type = findIndexedPropertyType(getIndexedReadMethod(), null);
257 setIndexedPropertyType(type);
258 } catch (IntrospectionException ex) {
259 // Set iprop type to be the classic type
260 Class propType = getPropertyType();
261 if (propType.isArray()) {
262 type = propType.getComponentType();
263 }
264 }
265 }
266
267 if (indexedWriteMethodName == null) {
268 indexedWriteMethodName = Introspector.SET_PREFIX + getBaseName();
269 }
270
271 Class[] args = (type == null) ? null : new Class[] { int.class, type };
272 indexedWriteMethod = Introspector.findMethod(cls, indexedWriteMethodName, 2, args);
273 if (indexedWriteMethod != null) {
274 if (!indexedWriteMethod.getReturnType().equals(void.class)) {
275 indexedWriteMethod = null;
276 }
277 }
278 setIndexedWriteMethod0(indexedWriteMethod);
279 }
280 return indexedWriteMethod;
281 }
282
283 /**
284 * Sets the method that should be used to write an indexed property value.
285 *
286 * @param writeMethod The new indexed write method.
287 */
288 public synchronized void setIndexedWriteMethod(Method writeMethod)
289 throws IntrospectionException {
290
291 // If the indexed property type has not been set, then set it.
292 Class type = findIndexedPropertyType(getIndexedReadMethod(),
293 writeMethod);
294 setIndexedPropertyType(type);
295 setIndexedWriteMethod0(writeMethod);
296 }
297
298 private void setIndexedWriteMethod0(Method writeMethod) {
299 if (writeMethod == null) {
300 indexedWriteMethodName = null;
301 indexedWriteMethodRef = null;
302 return;
303 }
304 setClass0(writeMethod.getDeclaringClass());
305
306 indexedWriteMethodName = writeMethod.getName();
307 this.indexedWriteMethodRef = getSoftReference(writeMethod);
308 setTransient(writeMethod.getAnnotation(Transient.class));
309 }
310
311 /**
312 * Returns the Java type info for the indexed property.
313 * Note that the {@code Class} object may describe
314 * primitive Java types such as {@code int}.
315 * This type is returned by the indexed read method
316 * or is used as the parameter type of the indexed write method.
317 *
318 * @return the {@code Class} object that represents the Java type info,
319 * or {@code null} if the type cannot be determined
320 */
321 public synchronized Class<?> getIndexedPropertyType() {
322 Class type = getIndexedPropertyType0();
323 if (type == null) {
324 try {
325 type = findIndexedPropertyType(getIndexedReadMethod(),
326 getIndexedWriteMethod());
327 setIndexedPropertyType(type);
328 } catch (IntrospectionException ex) {
329 // fall
330 }
331 }
332 return type;
333 }
334
335 // Private methods which set get/set the Reference objects
336
337 private void setIndexedPropertyType(Class type) {
338 this.indexedPropertyTypeRef = getWeakReference(type);
339 }
340
341 private Class getIndexedPropertyType0() {
342 return (this.indexedPropertyTypeRef != null)
343 ? this.indexedPropertyTypeRef.get()
344 : null;
345 }
346
347 private Method getIndexedReadMethod0() {
348 return (this.indexedReadMethodRef != null)
349 ? this.indexedReadMethodRef.get()
350 : null;
351 }
352
353 private Method getIndexedWriteMethod0() {
354 return (this.indexedWriteMethodRef != null)
355 ? this.indexedWriteMethodRef.get()
356 : null;
357 }
358
359 private Class findIndexedPropertyType(Method indexedReadMethod,
360 Method indexedWriteMethod)
361 throws IntrospectionException {
362 Class indexedPropertyType = null;
363
364 if (indexedReadMethod != null) {
365 Class params[] = getParameterTypes(getClass0(), indexedReadMethod);
366 if (params.length != 1) {
367 throw new IntrospectionException("bad indexed read method arg count");
368 }
369 if (params[0] != Integer.TYPE) {
370 throw new IntrospectionException("non int index to indexed read method");
371 }
372 indexedPropertyType = getReturnType(getClass0(), indexedReadMethod);
373 if (indexedPropertyType == Void.TYPE) {
374 throw new IntrospectionException("indexed read method returns void");
375 }
376 }
377 if (indexedWriteMethod != null) {
378 Class params[] = getParameterTypes(getClass0(), indexedWriteMethod);
379 if (params.length != 2) {
380 throw new IntrospectionException("bad indexed write method arg count");
381 }
382 if (params[0] != Integer.TYPE) {
383 throw new IntrospectionException("non int index to indexed write method");
384 }
385 if (indexedPropertyType != null && indexedPropertyType != params[1]) {
386 throw new IntrospectionException(
387 "type mismatch between indexed read and indexed write methods: "
388 + getName());
389 }
390 indexedPropertyType = params[1];
391 }
392 Class propertyType = getPropertyType();
393 if (propertyType != null && (!propertyType.isArray() ||
394 propertyType.getComponentType() != indexedPropertyType)) {
395 throw new IntrospectionException("type mismatch between indexed and non-indexed methods: "
396 + getName());
397 }
398 return indexedPropertyType;
399 }
400
401 /**
402 * Compares this <code>PropertyDescriptor</code> against the specified object.
403 * Returns true if the objects are the same. Two <code>PropertyDescriptor</code>s
404 * are the same if the read, write, property types, property editor and
405 * flags are equivalent.
406 *
407 * @since 1.4
408 */
409 public boolean equals(Object obj) {
410 // Note: This would be identical to PropertyDescriptor but they don't
411 // share the same fields.
412 if (this == obj) {
413 return true;
414 }
415
416 if (obj != null && obj instanceof IndexedPropertyDescriptor) {
417 IndexedPropertyDescriptor other = (IndexedPropertyDescriptor)obj;
418 Method otherIndexedReadMethod = other.getIndexedReadMethod();
419 Method otherIndexedWriteMethod = other.getIndexedWriteMethod();
420
421 if (!compareMethods(getIndexedReadMethod(), otherIndexedReadMethod)) {
422 return false;
423 }
424
425 if (!compareMethods(getIndexedWriteMethod(), otherIndexedWriteMethod)) {
426 return false;
427 }
428
429 if (getIndexedPropertyType() != other.getIndexedPropertyType()) {
430 return false;
431 }
432 return super.equals(obj);
433 }
434 return false;
435 }
436
437 /**
438 * Package-private constructor.
439 * Merge two property descriptors. Where they conflict, give the
440 * second argument (y) priority over the first argumnnt (x).
441 *
442 * @param x The first (lower priority) PropertyDescriptor
443 * @param y The second (higher priority) PropertyDescriptor
444 */
445
446 IndexedPropertyDescriptor(PropertyDescriptor x, PropertyDescriptor y) {
447 super(x,y);
448 if (x instanceof IndexedPropertyDescriptor) {
449 IndexedPropertyDescriptor ix = (IndexedPropertyDescriptor)x;
450 try {
451 Method xr = ix.getIndexedReadMethod();
452 if (xr != null) {
453 setIndexedReadMethod(xr);
454 }
455
456 Method xw = ix.getIndexedWriteMethod();
457 if (xw != null) {
458 setIndexedWriteMethod(xw);
459 }
460 } catch (IntrospectionException ex) {
461 // Should not happen
462 throw new AssertionError(ex);
463 }
464 }
465 if (y instanceof IndexedPropertyDescriptor) {
466 IndexedPropertyDescriptor iy = (IndexedPropertyDescriptor)y;
467 try {
468 Method yr = iy.getIndexedReadMethod();
469 if (yr != null && yr.getDeclaringClass() == getClass0()) {
470 setIndexedReadMethod(yr);
471 }
472
473 Method yw = iy.getIndexedWriteMethod();
474 if (yw != null && yw.getDeclaringClass() == getClass0()) {
475 setIndexedWriteMethod(yw);
476 }
477 } catch (IntrospectionException ex) {
478 // Should not happen
479 throw new AssertionError(ex);
480 }
481 }
482 }
483
484 /*
485 * Package-private dup constructor
486 * This must isolate the new object from any changes to the old object.
487 */
488 IndexedPropertyDescriptor(IndexedPropertyDescriptor old) {
489 super(old);
490 indexedReadMethodRef = old.indexedReadMethodRef;
491 indexedWriteMethodRef = old.indexedWriteMethodRef;
492 indexedPropertyTypeRef = old.indexedPropertyTypeRef;
493 indexedWriteMethodName = old.indexedWriteMethodName;
494 indexedReadMethodName = old.indexedReadMethodName;
495 }
496
497 /**
498 * Returns a hash code value for the object.
499 * See {@link java.lang.Object#hashCode} for a complete description.
500 *
501 * @return a hash code value for this object.
502 * @since 1.5
503 */
504 public int hashCode() {
505 int result = super.hashCode();
506
507 result = 37 * result + ((indexedWriteMethodName == null) ? 0 :
508 indexedWriteMethodName.hashCode());
509 result = 37 * result + ((indexedReadMethodName == null) ? 0 :
510 indexedReadMethodName.hashCode());
511 result = 37 * result + ((getIndexedPropertyType() == null) ? 0 :
512 getIndexedPropertyType().hashCode());
513
514 return result;
515 }
516
517 void appendTo(StringBuilder sb) {
518 super.appendTo(sb);
519 appendTo(sb, "indexedPropertyType", this.indexedPropertyTypeRef);
520 appendTo(sb, "indexedReadMethod", this.indexedReadMethodRef);
521 appendTo(sb, "indexedWriteMethod", this.indexedWriteMethodRef);
522 }
523}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t