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

Unified · Split

java/pkg/java/beans/EventSetDescriptor.java+536−0
@@ -0,0 +1,536 @@
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+import java.lang.reflect.Modifier;
31+
32+/**
33+ * An EventSetDescriptor describes a group of events that a given Java
34+ * bean fires.
35+ * <P>
36+ * The given group of events are all delivered as method calls on a single
37+ * event listener interface, and an event listener object can be registered
38+ * via a call on a registration method supplied by the event source.
39+ */
40+public class EventSetDescriptor extends FeatureDescriptor {
41+
42+ private MethodDescriptor[] listenerMethodDescriptors;
43+ private MethodDescriptor addMethodDescriptor;
44+ private MethodDescriptor removeMethodDescriptor;
45+ private MethodDescriptor getMethodDescriptor;
46+
47+ private Reference<Method[]> listenerMethodsRef;
48+ private Reference<Class> listenerTypeRef;
49+
50+ private boolean unicast;
51+ private boolean inDefaultEventSet = true;
52+
53+ /**
54+ * Creates an <TT>EventSetDescriptor</TT> assuming that you are
55+ * following the most simple standard design pattern where a named
56+ * event &quot;fred&quot; is (1) delivered as a call on the single method of
57+ * interface FredListener, (2) has a single argument of type FredEvent,
58+ * and (3) where the FredListener may be registered with a call on an
59+ * addFredListener method of the source component and removed with a
60+ * call on a removeFredListener method.
61+ *
62+ * @param sourceClass The class firing the event.
63+ * @param eventSetName The programmatic name of the event. E.g. &quot;fred&quot;.
64+ * Note that this should normally start with a lower-case character.
65+ * @param listenerType The target interface that events
66+ * will get delivered to.
67+ * @param listenerMethodName The method that will get called when the event gets
68+ * delivered to its target listener interface.
69+ * @exception IntrospectionException if an exception occurs during
70+ * introspection.
71+ */
72+ public EventSetDescriptor(Class<?> sourceClass, String eventSetName,
73+ Class<?> listenerType, String listenerMethodName)
74+ throws IntrospectionException {
75+ this(sourceClass, eventSetName, listenerType,
76+ new String[] { listenerMethodName },
77+ Introspector.ADD_PREFIX + getListenerClassName(listenerType),
78+ Introspector.REMOVE_PREFIX + getListenerClassName(listenerType),
79+ Introspector.GET_PREFIX + getListenerClassName(listenerType) + "s");
80+
81+ String eventName = NameGenerator.capitalize(eventSetName) + "Event";
82+ Method[] listenerMethods = getListenerMethods();
83+ if (listenerMethods.length > 0) {
84+ Class[] args = getParameterTypes(getClass0(), listenerMethods[0]);
85+ // Check for EventSet compliance. Special case for vetoableChange. See 4529996
86+ if (!"vetoableChange".equals(eventSetName) && !args[0].getName().endsWith(eventName)) {
87+ throw new IntrospectionException("Method \"" + listenerMethodName +
88+ "\" should have argument \"" +
89+ eventName + "\"");
90+ }
91+ }
92+ }
93+
94+ private static String getListenerClassName(Class cls) {
95+ String className = cls.getName();
96+ return className.substring(className.lastIndexOf('.') + 1);
97+ }
98+
99+ /**
100+ * Creates an <TT>EventSetDescriptor</TT> from scratch using
101+ * string names.
102+ *
103+ * @param sourceClass The class firing the event.
104+ * @param eventSetName The programmatic name of the event set.
105+ * Note that this should normally start with a lower-case character.
106+ * @param listenerType The Class of the target interface that events
107+ * will get delivered to.
108+ * @param listenerMethodNames The names of the methods that will get called
109+ * when the event gets delivered to its target listener interface.
110+ * @param addListenerMethodName The name of the method on the event source
111+ * that can be used to register an event listener object.
112+ * @param removeListenerMethodName The name of the method on the event source
113+ * that can be used to de-register an event listener object.
114+ * @exception IntrospectionException if an exception occurs during
115+ * introspection.
116+ */
117+ public EventSetDescriptor(Class<?> sourceClass,
118+ String eventSetName,
119+ Class<?> listenerType,
120+ String listenerMethodNames[],
121+ String addListenerMethodName,
122+ String removeListenerMethodName)
123+ throws IntrospectionException {
124+ this(sourceClass, eventSetName, listenerType,
125+ listenerMethodNames, addListenerMethodName,
126+ removeListenerMethodName, null);
127+ }
128+
129+ /**
130+ * This constructor creates an EventSetDescriptor from scratch using
131+ * string names.
132+ *
133+ * @param sourceClass The class firing the event.
134+ * @param eventSetName The programmatic name of the event set.
135+ * Note that this should normally start with a lower-case character.
136+ * @param listenerType The Class of the target interface that events
137+ * will get delivered to.
138+ * @param listenerMethodNames The names of the methods that will get called
139+ * when the event gets delivered to its target listener interface.
140+ * @param addListenerMethodName The name of the method on the event source
141+ * that can be used to register an event listener object.
142+ * @param removeListenerMethodName The name of the method on the event source
143+ * that can be used to de-register an event listener object.
144+ * @param getListenerMethodName The method on the event source that
145+ * can be used to access the array of event listener objects.
146+ * @exception IntrospectionException if an exception occurs during
147+ * introspection.
148+ * @since 1.4
149+ */
150+ public EventSetDescriptor(Class<?> sourceClass,
151+ String eventSetName,
152+ Class<?> listenerType,
153+ String listenerMethodNames[],
154+ String addListenerMethodName,
155+ String removeListenerMethodName,
156+ String getListenerMethodName)
157+ throws IntrospectionException {
158+ if (sourceClass == null || eventSetName == null || listenerType == null) {
159+ throw new NullPointerException();
160+ }
161+ setName(eventSetName);
162+ setClass0(sourceClass);
163+ setListenerType(listenerType);
164+
165+ Method[] listenerMethods = new Method[listenerMethodNames.length];
166+ for (int i = 0; i < listenerMethodNames.length; i++) {
167+ // Check for null names
168+ if (listenerMethodNames[i] == null) {
169+ throw new NullPointerException();
170+ }
171+ listenerMethods[i] = getMethod(listenerType, listenerMethodNames[i], 1);
172+ }
173+ setListenerMethods(listenerMethods);
174+
175+ setAddListenerMethod(getMethod(sourceClass, addListenerMethodName, 1));
176+ setRemoveListenerMethod(getMethod(sourceClass, removeListenerMethodName, 1));
177+
178+ // Be more forgiving of not finding the getListener method.
179+ Method method = Introspector.findMethod(sourceClass, getListenerMethodName, 0);
180+ if (method != null) {
181+ setGetListenerMethod(method);
182+ }
183+ }
184+
185+ private static Method getMethod(Class cls, String name, int args)
186+ throws IntrospectionException {
187+ if (name == null) {
188+ return null;
189+ }
190+ Method method = Introspector.findMethod(cls, name, args);
191+ if ((method == null) || Modifier.isStatic(method.getModifiers())) {
192+ throw new IntrospectionException("Method not found: " + name +
193+ " on class " + cls.getName());
194+ }
195+ return method;
196+ }
197+
198+ /**
199+ * Creates an <TT>EventSetDescriptor</TT> from scratch using
200+ * <TT>java.lang.reflect.Method</TT> and <TT>java.lang.Class</TT> objects.
201+ *
202+ * @param eventSetName The programmatic name of the event set.
203+ * @param listenerType The Class for the listener interface.
204+ * @param listenerMethods An array of Method objects describing each
205+ * of the event handling methods in the target listener.
206+ * @param addListenerMethod The method on the event source
207+ * that can be used to register an event listener object.
208+ * @param removeListenerMethod The method on the event source
209+ * that can be used to de-register an event listener object.
210+ * @exception IntrospectionException if an exception occurs during
211+ * introspection.
212+ */
213+ public EventSetDescriptor(String eventSetName,
214+ Class<?> listenerType,
215+ Method listenerMethods[],
216+ Method addListenerMethod,
217+ Method removeListenerMethod)
218+ throws IntrospectionException {
219+ this(eventSetName, listenerType, listenerMethods,
220+ addListenerMethod, removeListenerMethod, null);
221+ }
222+
223+ /**
224+ * This constructor creates an EventSetDescriptor from scratch using
225+ * java.lang.reflect.Method and java.lang.Class objects.
226+ *
227+ * @param eventSetName The programmatic name of the event set.
228+ * @param listenerType The Class for the listener interface.
229+ * @param listenerMethods An array of Method objects describing each
230+ * of the event handling methods in the target listener.
231+ * @param addListenerMethod The method on the event source
232+ * that can be used to register an event listener object.
233+ * @param removeListenerMethod The method on the event source
234+ * that can be used to de-register an event listener object.
235+ * @param getListenerMethod The method on the event source
236+ * that can be used to access the array of event listener objects.
237+ * @exception IntrospectionException if an exception occurs during
238+ * introspection.
239+ * @since 1.4
240+ */
241+ public EventSetDescriptor(String eventSetName,
242+ Class<?> listenerType,
243+ Method listenerMethods[],
244+ Method addListenerMethod,
245+ Method removeListenerMethod,
246+ Method getListenerMethod)
247+ throws IntrospectionException {
248+ setName(eventSetName);
249+ setListenerMethods(listenerMethods);
250+ setAddListenerMethod(addListenerMethod);
251+ setRemoveListenerMethod( removeListenerMethod);
252+ setGetListenerMethod(getListenerMethod);
253+ setListenerType(listenerType);
254+ }
255+
256+ /**
257+ * Creates an <TT>EventSetDescriptor</TT> from scratch using
258+ * <TT>java.lang.reflect.MethodDescriptor</TT> and <TT>java.lang.Class</TT>
259+ * objects.
260+ *
261+ * @param eventSetName The programmatic name of the event set.
262+ * @param listenerType The Class for the listener interface.
263+ * @param listenerMethodDescriptors An array of MethodDescriptor objects
264+ * describing each of the event handling methods in the
265+ * target listener.
266+ * @param addListenerMethod The method on the event source
267+ * that can be used to register an event listener object.
268+ * @param removeListenerMethod The method on the event source
269+ * that can be used to de-register an event listener object.
270+ * @exception IntrospectionException if an exception occurs during
271+ * introspection.
272+ */
273+ public EventSetDescriptor(String eventSetName,
274+ Class<?> listenerType,
275+ MethodDescriptor listenerMethodDescriptors[],
276+ Method addListenerMethod,
277+ Method removeListenerMethod)
278+ throws IntrospectionException {
279+ setName(eventSetName);
280+ this.listenerMethodDescriptors = listenerMethodDescriptors;
281+ setAddListenerMethod(addListenerMethod);
282+ setRemoveListenerMethod(removeListenerMethod);
283+ setListenerType(listenerType);
284+ }
285+
286+ /**
287+ * Gets the <TT>Class</TT> object for the target interface.
288+ *
289+ * @return The Class object for the target interface that will
290+ * get invoked when the event is fired.
291+ */
292+ public Class<?> getListenerType() {
293+ return (this.listenerTypeRef != null)
294+ ? this.listenerTypeRef.get()
295+ : null;
296+ }
297+
298+ private void setListenerType(Class cls) {
299+ this.listenerTypeRef = getWeakReference(cls);
300+ }
301+
302+ /**
303+ * Gets the methods of the target listener interface.
304+ *
305+ * @return An array of <TT>Method</TT> objects for the target methods
306+ * within the target listener interface that will get called when
307+ * events are fired.
308+ */
309+ public synchronized Method[] getListenerMethods() {
310+ Method[] methods = getListenerMethods0();
311+ if (methods == null) {
312+ if (listenerMethodDescriptors != null) {
313+ methods = new Method[listenerMethodDescriptors.length];
314+ for (int i = 0; i < methods.length; i++) {
315+ methods[i] = listenerMethodDescriptors[i].getMethod();
316+ }
317+ }
318+ setListenerMethods(methods);
319+ }
320+ return methods;
321+ }
322+
323+ private void setListenerMethods(Method[] methods) {
324+ if (methods == null) {
325+ return;
326+ }
327+ if (listenerMethodDescriptors == null) {
328+ listenerMethodDescriptors = new MethodDescriptor[methods.length];
329+ for (int i = 0; i < methods.length; i++) {
330+ listenerMethodDescriptors[i] = new MethodDescriptor(methods[i]);
331+ }
332+ }
333+ this.listenerMethodsRef = getSoftReference(methods);
334+ }
335+
336+ private Method[] getListenerMethods0() {
337+ return (this.listenerMethodsRef != null)
338+ ? this.listenerMethodsRef.get()
339+ : null;
340+ }
341+
342+ /**
343+ * Gets the <code>MethodDescriptor</code>s of the target listener interface.
344+ *
345+ * @return An array of <code>MethodDescriptor</code> objects for the target methods
346+ * within the target listener interface that will get called when
347+ * events are fired.
348+ */
349+ public synchronized MethodDescriptor[] getListenerMethodDescriptors() {
350+ return listenerMethodDescriptors;
351+ }
352+
353+ /**
354+ * Gets the method used to add event listeners.
355+ *
356+ * @return The method used to register a listener at the event source.
357+ */
358+ public synchronized Method getAddListenerMethod() {
359+ return getMethod(this.addMethodDescriptor);
360+ }
361+
362+ private synchronized void setAddListenerMethod(Method method) {
363+ if (method == null) {
364+ return;
365+ }
366+ if (getClass0() == null) {
367+ setClass0(method.getDeclaringClass());
368+ }
369+ addMethodDescriptor = new MethodDescriptor(method);
370+ setTransient(method.getAnnotation(Transient.class));
371+ }
372+
373+ /**
374+ * Gets the method used to remove event listeners.
375+ *
376+ * @return The method used to remove a listener at the event source.
377+ */
378+ public synchronized Method getRemoveListenerMethod() {
379+ return getMethod(this.removeMethodDescriptor);
380+ }
381+
382+ private synchronized void setRemoveListenerMethod(Method method) {
383+ if (method == null) {
384+ return;
385+ }
386+ if (getClass0() == null) {
387+ setClass0(method.getDeclaringClass());
388+ }
389+ removeMethodDescriptor = new MethodDescriptor(method);
390+ setTransient(method.getAnnotation(Transient.class));
391+ }
392+
393+ /**
394+ * Gets the method used to access the registered event listeners.
395+ *
396+ * @return The method used to access the array of listeners at the event
397+ * source or null if it doesn't exist.
398+ * @since 1.4
399+ */
400+ public synchronized Method getGetListenerMethod() {
401+ return getMethod(this.getMethodDescriptor);
402+ }
403+
404+ private synchronized void setGetListenerMethod(Method method) {
405+ if (method == null) {
406+ return;
407+ }
408+ if (getClass0() == null) {
409+ setClass0(method.getDeclaringClass());
410+ }
411+ getMethodDescriptor = new MethodDescriptor(method);
412+ setTransient(method.getAnnotation(Transient.class));
413+ }
414+
415+ /**
416+ * Mark an event set as unicast (or not).
417+ *
418+ * @param unicast True if the event set is unicast.
419+ */
420+ public void setUnicast(boolean unicast) {
421+ this.unicast = unicast;
422+ }
423+
424+ /**
425+ * Normally event sources are multicast. However there are some
426+ * exceptions that are strictly unicast.
427+ *
428+ * @return <TT>true</TT> if the event set is unicast.
429+ * Defaults to <TT>false</TT>.
430+ */
431+ public boolean isUnicast() {
432+ return unicast;
433+ }
434+
435+ /**
436+ * Marks an event set as being in the &quot;default&quot; set (or not).
437+ * By default this is <TT>true</TT>.
438+ *
439+ * @param inDefaultEventSet <code>true</code> if the event set is in
440+ * the &quot;default&quot; set,
441+ * <code>false</code> if not
442+ */
443+ public void setInDefaultEventSet(boolean inDefaultEventSet) {
444+ this.inDefaultEventSet = inDefaultEventSet;
445+ }
446+
447+ /**
448+ * Reports if an event set is in the &quot;default&quot; set.
449+ *
450+ * @return <TT>true</TT> if the event set is in
451+ * the &quot;default&quot; set. Defaults to <TT>true</TT>.
452+ */
453+ public boolean isInDefaultEventSet() {
454+ return inDefaultEventSet;
455+ }
456+
457+ /*
458+ * Package-private constructor
459+ * Merge two event set descriptors. Where they conflict, give the
460+ * second argument (y) priority over the first argument (x).
461+ *
462+ * @param x The first (lower priority) EventSetDescriptor
463+ * @param y The second (higher priority) EventSetDescriptor
464+ */
465+ EventSetDescriptor(EventSetDescriptor x, EventSetDescriptor y) {
466+ super(x,y);
467+ listenerMethodDescriptors = x.listenerMethodDescriptors;
468+ if (y.listenerMethodDescriptors != null) {
469+ listenerMethodDescriptors = y.listenerMethodDescriptors;
470+ }
471+
472+ listenerTypeRef = x.listenerTypeRef;
473+ if (y.listenerTypeRef != null) {
474+ listenerTypeRef = y.listenerTypeRef;
475+ }
476+
477+ addMethodDescriptor = x.addMethodDescriptor;
478+ if (y.addMethodDescriptor != null) {
479+ addMethodDescriptor = y.addMethodDescriptor;
480+ }
481+
482+ removeMethodDescriptor = x.removeMethodDescriptor;
483+ if (y.removeMethodDescriptor != null) {
484+ removeMethodDescriptor = y.removeMethodDescriptor;
485+ }
486+
487+ getMethodDescriptor = x.getMethodDescriptor;
488+ if (y.getMethodDescriptor != null) {
489+ getMethodDescriptor = y.getMethodDescriptor;
490+ }
491+
492+ unicast = y.unicast;
493+ if (!x.inDefaultEventSet || !y.inDefaultEventSet) {
494+ inDefaultEventSet = false;
495+ }
496+ }
497+
498+ /*
499+ * Package-private dup constructor
500+ * This must isolate the new object from any changes to the old object.
501+ */
502+ EventSetDescriptor(EventSetDescriptor old) {
503+ super(old);
504+ if (old.listenerMethodDescriptors != null) {
505+ int len = old.listenerMethodDescriptors.length;
506+ listenerMethodDescriptors = new MethodDescriptor[len];
507+ for (int i = 0; i < len; i++) {
508+ listenerMethodDescriptors[i] = new MethodDescriptor(
509+ old.listenerMethodDescriptors[i]);
510+ }
511+ }
512+ listenerTypeRef = old.listenerTypeRef;
513+
514+ addMethodDescriptor = old.addMethodDescriptor;
515+ removeMethodDescriptor = old.removeMethodDescriptor;
516+ getMethodDescriptor = old.getMethodDescriptor;
517+
518+ unicast = old.unicast;
519+ inDefaultEventSet = old.inDefaultEventSet;
520+ }
521+
522+ void appendTo(StringBuilder sb) {
523+ appendTo(sb, "unicast", this.unicast);
524+ appendTo(sb, "inDefaultEventSet", this.inDefaultEventSet);
525+ appendTo(sb, "listenerType", this.listenerTypeRef);
526+ appendTo(sb, "getListenerMethod", getMethod(this.getMethodDescriptor));
527+ appendTo(sb, "addListenerMethod", getMethod(this.addMethodDescriptor));
528+ appendTo(sb, "removeListenerMethod", getMethod(this.removeMethodDescriptor));
529+ }
530+
531+ private static Method getMethod(MethodDescriptor descriptor) {
532+ return (descriptor != null)
533+ ? descriptor.getMethod()
534+ : null;
535+ }
536+}