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+
26+package java.beans;
27+
28+import java.lang.ref.Reference;
29+import 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+
41+public 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