KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > form > FormEvents


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.form;
21
22 import java.util.*;
23 import java.lang.reflect.Method JavaDoc;
24
25 /**
26  * Manages information about used component events and their handlers (in
27  * one form). Also maps handled events to methods of a "common event
28  * dispatching listener" (CEDL), which may be generated by the code generator
29  * (in certain modes).
30  *
31  * @author Tomas Pavek
32  */

33
34 public class FormEvents {
35
36     static final Event[] NO_EVENTS = {};
37
38     // CEDL: mapping listener type name to ListenerInfo
39
private Map usedListeners = new HashMap();
40
41     // CEDL: mapping listener method signature to list of Event
42
private Map usedMethods = new HashMap();
43
44     // event handlers: mapping event handler name to list of Event
45
private Map eventHandlers = new HashMap();
46
47     private FormModel formModel;
48
49     FormEvents(FormModel formModel) {
50         this.formModel = formModel;
51     }
52
53     // --------
54
// public interface - getters
55

56     public boolean hasEventsInCEDL() {
57         return !usedListeners.isEmpty();
58     }
59
60     public Class JavaDoc[] getCEDLTypes() {
61         Collection infoValues = usedListeners.values();
62         Class JavaDoc[] listenerTypes = new Class JavaDoc[infoValues.size()];
63         int i = 0;
64         Iterator it = infoValues.iterator();
65         while (it.hasNext())
66             listenerTypes[i++] = ((ListenerInfo)it.next()).listenerType;
67         
68         return listenerTypes;
69     }
70
71     public Event[] getEventsForCEDLMethod(Method JavaDoc listenerMethod) {
72         List eventList = (List) usedMethods.get(fullMethodName(listenerMethod));
73         if (eventList == null)
74             return NO_EVENTS;
75
76         Event[] eventArray = new Event[eventList.size()];
77         eventList.toArray(eventArray);
78         return eventArray;
79     }
80
81     public Event[] getEventsForHandler(String JavaDoc handlerName) {
82         List handlerEventList = (List) eventHandlers.get(handlerName);
83         Event[] events = new Event[handlerEventList.size()];
84         handlerEventList.toArray(events);
85         return events;
86     }
87
88     public Method JavaDoc getOriginalListenerMethod(String JavaDoc handlerName) {
89         List handlerEventList = (List) eventHandlers.get(handlerName);
90         return handlerEventList != null ?
91                ((Event)handlerEventList.get(0)).getListenerMethod() : null;
92     }
93
94     public String JavaDoc[] getAllEventHandlers() {
95         Set nameSet = eventHandlers.keySet();
96         String JavaDoc[] names = new String JavaDoc[nameSet.size()];
97         nameSet.toArray(names);
98         return names;
99     }
100
101     // --------
102
// public interface - adding/removing events
103

104     public void attachEvent(Event event, String JavaDoc handlerName, String JavaDoc handlerText)
105     {
106         boolean newHandler = false; // if new event handler has been created
107

108         if (handlerName == null && event.hasEventHandlers()) { // nothing to do
109
handlerName = (String JavaDoc) event.getEventHandlerList().get(0);
110             event = null;
111         }
112         else { // find/create handler, attach event to it
113
List handlerEventList;
114             if (handlerName != null) {
115                 handlerEventList = (List) eventHandlers.get(handlerName);
116                 if (handlerEventList != null) // handler already exists
117
checkCompatibility(event, (Event) handlerEventList.get(0));
118             }
119             else { // no name provided, find a free one
120
handlerEventList = null;
121                 handlerName = findFreeHandlerName(event,
122                                                   event.getComponent());
123             }
124
125             if (handlerEventList == null) { // create new handler
126
handlerEventList = new ArrayList(3);
127                 eventHandlers.put(handlerName, handlerEventList);
128                 newHandler = true;
129             }
130
131             if (!event.isInCEDL())
132                 registerEventInCEDL(event);
133
134             if (event.addEventHandler(handlerName))
135                 handlerEventList.add(event);
136             else // handler not added (event is already attached to it)
137
event = null;
138         }
139
140         formModel.fireEventHandlerAdded(event,
141                                         handlerName, handlerText, newHandler);
142     }
143
144     public void detachEvent(Event event, String JavaDoc handlerName) {
145         if (event.removeEventHandler(handlerName)) {
146             if (!event.hasEventHandlers())
147                 unregisterEventFromCEDL(event);
148
149             detachEventHandler(event, handlerName);
150         }
151     }
152
153     public void detachEvent(Event event) {
154         unregisterEventFromCEDL(event);
155         String JavaDoc[] handlerNames = event.getEventHandlers();
156         for (int i=0; i < handlerNames.length; i++) {
157             event.removeEventHandler(handlerNames[i]);
158             detachEventHandler(event, handlerNames[i]);
159         }
160     }
161
162     public void renameEventHandler(String JavaDoc oldHandlerName, String JavaDoc newHandlerName)
163     {
164         if (oldHandlerName == null || newHandlerName == null
165                 || oldHandlerName.equals(newHandlerName))
166             return;
167
168         List handlerEventList = (List) eventHandlers.get(oldHandlerName);
169         if (handlerEventList == null)
170             return; // oldHandlerName handler not found
171

172         if (eventHandlers.get(newHandlerName) == null) {
173             for (int j=0; j < handlerEventList.size(); j++) {
174                 Event event = (Event) handlerEventList.get(j);
175                 event.renameEventHandler(oldHandlerName, newHandlerName);
176             }
177             eventHandlers.remove(oldHandlerName);
178             eventHandlers.put(newHandlerName, handlerEventList);
179             formModel.fireEventHandlerRenamed(oldHandlerName, newHandlerName);
180         }
181         else {
182             IllegalArgumentException JavaDoc iae =
183                 new IllegalArgumentException JavaDoc("Cannot rename handler"); // NOI18N
184
org.openide.ErrorManager.getDefault().annotate(
185                 iae, FormUtils.getBundleString("MSG_CannotRename")); // NOI18N
186
throw iae;
187         }
188     }
189
190     public String JavaDoc findFreeHandlerName(Event event, RADComponent metacomp) {
191         String JavaDoc componentName = metacomp == formModel.getTopRADComponent() ?
192                                            "form" : metacomp.getName(); // NOI18N
193
String JavaDoc methodName = event.getListenerMethod().getName();
194
195         return findFreeHandlerName(componentName
196                                    + methodName.substring(0, 1).toUpperCase()
197                                    + methodName.substring(1));
198     }
199
200     public String JavaDoc findFreeHandlerName(String JavaDoc baseName) {
201         String JavaDoc name = baseName;
202         int n = 0;
203         while (eventHandlers.get(name) != null)
204             name = baseName + (++n);
205         return name;
206     }
207
208     // --------
209
// package private interface
210

211     static String JavaDoc getEventIdName(Method JavaDoc eventMethod) {
212         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(64);
213
214         buf.append("$"); // NOI18N
215
buf.append(eventMethod.getDeclaringClass().getName());
216         buf.append("."); // NOI18N
217
buf.append(eventMethod.getName());
218         buf.append("("); // NOI18N
219

220         Class JavaDoc[] parameterTypes = eventMethod.getParameterTypes();
221         for (int i=0; i < parameterTypes.length; i++) {
222             buf.append(parameterTypes[i].getName());
223             if (i+1 < parameterTypes.length)
224                 buf.append(", "); // NOI18N
225
}
226
227         buf.append(")"); // NOI18N
228
return buf.toString();
229     }
230
231     // --------
232
// private methods
233

234     private void registerEventInCEDL(Event event) {
235         // listener class must be an interface (required for CEDL)
236
Class JavaDoc listenerType = event.getEventSetDescriptor().getListenerType();
237         if (!listenerType.isInterface())
238             return;
239
240         // event method must have EventObject as parameter (required for CEDL)
241
Class JavaDoc[] parameters = event.getListenerMethod().getParameterTypes();
242         if (parameters.length == 0
243                 || !java.util.EventObject JavaDoc.class.isAssignableFrom(parameters[0]))
244             return;
245
246         if (!addEventToMethod(event))
247             return; // method signature already used
248

249         String JavaDoc listenerTypeName = listenerType.getName();
250         ListenerInfo lInfo = (ListenerInfo)
251                              usedListeners.get(listenerTypeName);
252         if (lInfo == null) {
253             lInfo = new ListenerInfo(listenerType);
254             usedListeners.put(listenerTypeName, lInfo);
255         }
256         else lInfo.listenerType = listenerType;
257         lInfo.useCount++;
258
259         event.setInCEDL(true);
260     }
261
262     private void unregisterEventFromCEDL(Event event) {
263         if (removeEventFromMethod(event)) {
264             String JavaDoc listenerTypeName = event.getEventSetDescriptor()
265                                                 .getListenerType().getName();
266             ListenerInfo lInfo = (ListenerInfo)
267                                  usedListeners.get(listenerTypeName);
268             if (lInfo != null && --lInfo.useCount == 0)
269                 usedListeners.remove(listenerTypeName);
270
271             event.setInCEDL(false);
272         }
273     }
274
275     private boolean addEventToMethod(Event event) {
276         String JavaDoc methodName = fullMethodName(event.getListenerMethod());
277         List eventList = (List) usedMethods.get(methodName);
278
279         if (eventList == null) {
280             eventList = new ArrayList();
281             eventList.add(event);
282             usedMethods.put(methodName, eventList);
283         }
284         else {
285             for (Iterator it=eventList.iterator(); it.hasNext(); ) {
286                 Event e = (Event) it.next();
287                 if (e.getComponent() == event.getComponent())
288                     return false; // same event, or another event of the same
289
// component with the same method signature
290
}
291             eventList.add(event);
292         }
293
294         return true;
295     }
296
297     private boolean removeEventFromMethod(Event event) {
298         boolean removed;
299         String JavaDoc methodName = fullMethodName(event.getListenerMethod());
300         List eventList = (List) usedMethods.get(methodName);
301
302         if (eventList != null) {
303             removed = eventList.remove(event);
304             if (eventList.size() == 0)
305                 usedMethods.remove(methodName);
306         }
307         else removed = false;
308
309         return removed;
310     }
311
312     private void detachEventHandler(Event event, String JavaDoc handlerName) {
313         List handlerEventList = (List) eventHandlers.get(handlerName);
314         handlerEventList.remove(event);
315         if (handlerEventList.size() == 0)
316             eventHandlers.remove(handlerName); // handler is not used anymore
317

318         formModel.fireEventHandlerRemoved(event,
319                                           handlerName,
320                                           handlerEventList.size() == 0);
321     }
322
323     private void checkCompatibility(Event event1, Event event2) {
324         Method JavaDoc m1 = event1.getListenerMethod();
325         Method JavaDoc m2 = event2.getListenerMethod();
326         Class JavaDoc[] params1 = m1.getParameterTypes();
327         Class JavaDoc[] params2 = m2.getParameterTypes();
328         boolean ok;
329
330         if (params1.length == params2.length) {
331             ok = true;
332             for (int i=0; i < params1.length; i++)
333                 if (!params1[i].getName().equals(params2[i].getName())) {
334                     ok = false;
335                     break;
336                 }
337             if (ok)
338                 ok = m1.getReturnType().equals(m2.getReturnType());
339         }
340         else ok = false;
341
342         if (!ok) {
343             IllegalArgumentException JavaDoc iae =
344                 new IllegalArgumentException JavaDoc("Incompatible event"); // NOI18N
345
org.openide.ErrorManager.getDefault().annotate(
346                 iae, FormUtils.getBundleString("MSG_CannotAttach")); // NOI18N
347
throw iae;
348         }
349     }
350
351     private static String JavaDoc fullMethodName(Method JavaDoc m) {
352         StringBuffer JavaDoc name = new StringBuffer JavaDoc();
353         name.append(m.getName());
354         name.append("("); // NOI18N
355

356         Class JavaDoc[] params = m.getParameterTypes();
357         for (int i=0; i < params.length; i++) {
358             name.append(params[i].getName());
359             if (i+1 < params.length)
360                 name.append(", "); // NOI18N
361
}
362
363         name.append(")"); // NOI18N
364
return name.toString();
365     }
366
367     // --------
368

369     private static class ListenerInfo {
370         Class JavaDoc listenerType;
371         int useCount;
372         ListenerInfo(Class JavaDoc listenerType) {
373             this.listenerType = listenerType;
374         }
375     }
376 }
377
Popular Tags