001: /*
002: * SwingML Copyright (C) 2002 SwingML Team
003: *
004: * This library is free software; you can redistribute it and/or modify it under
005: * the terms of the GNU Lesser General Public License as published by the Free
006: * Software Foundation; either version 2 of the License, or (at your option) any
007: * later version.
008: *
009: * This library is distributed in the hope that it will be useful, but WITHOUT
010: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011: * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012: * details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with this library; if not, write to the Free Software Foundation, Inc.,
016: * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: *
018: * Authors:
019: * Ezequiel Cuellar <ecuellar@crosslogic.com>
020: * Robert Morris<robertj@morris.net>
021: *
022: */
023:
024: package org.swingml.event;
025:
026: import java.awt.*;
027: import java.lang.reflect.*;
028: import java.util.*;
029: import java.util.List;
030:
031: import javax.swing.*;
032:
033: import org.swingml.*;
034: import org.swingml.model.*;
035: import org.swingml.system.*;
036: import org.swingml.treetablebrowser.ext.*;
037:
038: public class EventHandler {
039:
040: protected class EventHandlerTools extends EventUtil {
041:
042: public SwingMLRenderer getRenderer(Component aComponent) {
043: return super .getRenderer(aComponent);
044: }
045: }
046:
047: private static EventHandler instance = null;
048:
049: public static EventHandler getInstance() {
050: if (instance == null) {
051: instance = new EventHandler();
052: }
053: return instance;
054: }
055:
056: public void execute(Method aMethod, ActionModel anAction,
057: Component anActionTarget, String anEventOwnerName,
058: ListenerModel aListener, Class[] aClassTypesArray) {
059: try {
060: String theValuesString = anAction.getValues();
061: String theTypesString = anAction.getTypes();
062: if (!theTypesString.equals("")) {
063: Constructor theArgumentTypeConstructor = null;
064: Object[] theArgumentValue = new Object[1];
065: Class theStringClassArray[] = { String.class };
066: StringTokenizer theArgumentValues = new StringTokenizer(
067: theValuesString, ",");
068:
069: Object[] theArgumentsArray = null;
070: int theArgumentsCount = theArgumentValues.countTokens();
071: if (theArgumentsCount > 0) {
072: theArgumentsArray = new Object[theArgumentValues
073: .countTokens()];
074: for (int i = 0; i < aClassTypesArray.length; i++) {
075: theArgumentTypeConstructor = aClassTypesArray[i]
076: .getConstructor(theStringClassArray);
077: theArgumentValue[0] = theArgumentValues
078: .nextToken();
079: theArgumentsArray[i] = theArgumentTypeConstructor
080: .newInstance(theArgumentValue);
081: }
082: } else {
083: theArgumentsArray = new Object[1];
084: theArgumentsArray[0] = null;
085: }
086: try {
087: aMethod.invoke(anActionTarget, theArgumentsArray);
088: } catch (InvocationTargetException ite) {
089: ite.printStackTrace();
090: }
091: } else {
092: try {
093: aMethod.invoke(anActionTarget, null);
094: } catch (InvocationTargetException ite) {
095: ite.printStackTrace();
096: }
097: }
098: } catch (NoSuchMethodException e) {
099: SwingMLLogger
100: .getInstance()
101: .log(ILogCapable.ERROR,
102: "NoSuchMethodException in method EventHandler.invoke();");
103: SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
104: } catch (InstantiationException e) {
105: SwingMLLogger
106: .getInstance()
107: .log(ILogCapable.ERROR,
108: "InstanttiationException in method EventHandler.invoke();");
109: SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
110: } catch (IllegalAccessException e) {
111: SwingMLLogger
112: .getInstance()
113: .log(ILogCapable.ERROR,
114: "IllegalAccessException in method EventHandler.invoke();");
115: SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
116: } catch (InvocationTargetException e) {
117: SwingMLLogger
118: .getInstance()
119: .log(ILogCapable.ERROR,
120: "The requested operation could not be performed due to a bad syntax error.");
121: SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
122: } catch (IllegalArgumentException e) {
123: SwingMLLogger.getInstance().log(
124: ILogCapable.ERROR,
125: "Syntax Error: The VALUES and TYPES specified for the method "
126: + anAction.getMethod()
127: + " in the action for the listener "
128: + aListener.getEvent() + " in the element "
129: + anEventOwnerName + " are incorrect.");
130: SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
131: }
132: }
133:
134: public Component findActionTarget(Container aRootContainer,
135: String anActionTargetName) {
136:
137: Component theActionTarget = null;
138: if (aRootContainer != null) {
139: Component[] theComponents = aRootContainer.getComponents();
140: if (aRootContainer.getName() != null
141: && aRootContainer.getName().equals(
142: anActionTargetName)) {
143: theActionTarget = aRootContainer;
144: } else {
145: for (int i = 0; i < theComponents.length; i++) {
146: theActionTarget = theComponents[i];
147: if (theActionTarget.getName() != null
148: && theActionTarget.getName().equals(
149: anActionTargetName)) {
150: break;
151: }
152: theActionTarget = this .findActionTarget(
153: (Container) theActionTarget,
154: anActionTargetName);
155: if (theActionTarget != null) {
156: break;
157: }
158: }
159: }
160: }
161: return theActionTarget;
162: }
163:
164: public List findEventListeners(SwingMLModel anEventOwnerModel,
165: String anEventName) {
166: List result = new ArrayList();
167: Iterator theListeners = anEventOwnerModel.getListeners()
168: .iterator();
169: while (theListeners.hasNext()) {
170: ListenerModel aListener = (ListenerModel) theListeners
171: .next();
172: if (aListener.getEvent().equalsIgnoreCase(anEventName)) { // TODO - this should be case sensitive
173: result.add(aListener);
174: }
175: }
176: return result;
177: }
178:
179: public void handleEvent(SwingMLModel anEventOwnerModel,
180: String anEventName, JComponent anEventOwner) {
181: List listeners = findEventListeners(anEventOwnerModel,
182: anEventName);
183: if (listeners != null) {
184: ThreadedEventHandler eventHandler = ThreadedEventHandler
185: .getInstance();
186: ListenerModel listener;
187: Iterator schmiterator = listeners.iterator();
188: while (schmiterator.hasNext()) {
189: listener = (ListenerModel) schmiterator.next();
190: SwingMLEvent event = new SwingMLEvent(listener,
191: anEventOwnerModel, anEventName, anEventOwner);
192:
193: if (listener.isSynchronous()) {
194: // execute the event right now and wait for it to end.
195: eventHandler.executeEvent(event);
196: } else {
197: // queue the event to execute later.
198: eventHandler.queueEvent(event);
199: }
200: }
201: }
202: }
203:
204: public void handleExternalEvent(
205: ExternalActionModel anExternalAction,
206: JComponent anEventOwner, SwingMLModel anEventOwnerModel,
207: ListenerModel anEventListener) {
208: Component theActionTarget = this
209: .findActionTarget(anEventOwner.getTopLevelAncestor(),
210: anExternalAction.getComponent());
211: if (theActionTarget != null
212: && anExternalAction.getExternalClass() != null) {
213: try {
214: SwingMLRenderer theRenderer = new EventHandlerTools()
215: .getRenderer(anEventOwner);
216: InvokableEventHandler theInvokableEventHandler = null;
217: if (anExternalAction.getExternalFactoryClass() == null) {
218: theInvokableEventHandler = ExternalEventManager
219: .loadInvokableEvent(theRenderer,
220: anExternalAction.getExternalClass()
221: .getName(), null);
222: } else {
223: theInvokableEventHandler = ExternalEventManager
224: .loadInvokableEvent(theRenderer,
225: anExternalAction.getExternalClass()
226: .getName(),
227: anExternalAction
228: .getExternalFactoryClass()
229: .getName());
230: }
231: theInvokableEventHandler.initialize(theActionTarget,
232: anExternalAction.getParams().toArray());
233:
234: // Check for ITreeTableBrowserCellUpdateEventHandler
235: if (theInvokableEventHandler instanceof ITreeTableBrowserCellUpdateEventHandler) {
236: ITreeTableBrowserCellUpdateEventHandler cellUpdateEventHandler = (ITreeTableBrowserCellUpdateEventHandler) theInvokableEventHandler;
237: if (anEventOwnerModel instanceof TreeTableBrowserCellUpdateModel) {
238: cellUpdateEventHandler
239: .initialize((TreeTableBrowserCellUpdateModel) anEventOwnerModel);
240: } else {
241: cellUpdateEventHandler.initialize(null);
242: }
243: }
244:
245: theInvokableEventHandler.invoke();
246: theInvokableEventHandler.destroy();
247: } catch (Exception e) {
248: SwingMLLogger
249: .getInstance()
250: .log(
251: ILogCapable.ERROR,
252: "Syntax Error: Failed to instantiate: ["
253: + anExternalAction
254: .getExternalClass()
255: .getName()
256: + "]. Check your CLASSPATH and make sure the referenced class is accessible.");
257: SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
258: }
259: } else {
260: SwingMLLogger
261: .getInstance()
262: .log(
263: ILogCapable.ERROR,
264: "Syntax Error: The component "
265: + anExternalAction.getComponent()
266: + " in the action for the listener "
267: + anEventListener.getEvent()
268: + " in the element "
269: + anEventOwnerModel.getName()
270: + " wasn't found. Verify the value of COMPONENT.");
271: }
272: }
273:
274: public void handleControllerActionEvent(
275: ControllerActionModel aControllerActionModel,
276: JComponent anEventOwner, SwingMLModel anEventOwnerModel,
277: ListenerModel anEventListener) {
278:
279: Component theActionTarget = this .findActionTarget(anEventOwner
280: .getTopLevelAncestor(), aControllerActionModel
281: .getComponent());
282: if (theActionTarget == null) {
283: throw new RuntimeException("Target Component "
284: + aControllerActionModel.getComponent()
285: + " is not found...");
286:
287: }
288:
289: ControllerActionEventHandler handler = new ControllerActionEventHandler();
290:
291: handler.initialize(theActionTarget, aControllerActionModel
292: .getParams().toArray(), aControllerActionModel);
293: handler.invoke();
294:
295: }
296:
297: public void processAction(ActionModel anAction,
298: Component anActionTarget, String anEventOwnerName,
299: ListenerModel anEventListener) {
300: try {
301: Method theMethod = null;
302: Class[] theClassTypesArray = null;
303: Class[] thePrimitivesArray = null;
304: String theArgumentTypeToken = null;
305: String theArgumentTypesString = anAction.getTypes();
306: String theMethodName = anAction.getMethod();
307: Class theActionTargetClass = anActionTarget.getClass();
308: if (theArgumentTypesString != null) {
309: StringTokenizer theArgumentTypeTokens = new StringTokenizer(
310: theArgumentTypesString, ",");
311: theClassTypesArray = new Class[theArgumentTypeTokens
312: .countTokens()];
313: thePrimitivesArray = new Class[theArgumentTypeTokens
314: .countTokens()];
315: int theArgumentTypeIndex = 0;
316: while (theArgumentTypeTokens.hasMoreTokens()) {
317: theArgumentTypeToken = theArgumentTypeTokens
318: .nextToken().trim();
319: this .resolveArgumentType(theArgumentTypeIndex,
320: theArgumentTypeToken, theClassTypesArray,
321: thePrimitivesArray);
322: theArgumentTypeIndex++;
323: }
324: theMethod = theActionTargetClass.getMethod(
325: theMethodName, thePrimitivesArray);
326: } else {
327: theMethod = theActionTargetClass.getMethod(
328: theMethodName, null);
329: }
330: if (theMethod != null) {
331: this .execute(theMethod, anAction, anActionTarget,
332: anEventOwnerName, anEventListener,
333: theClassTypesArray);
334: }
335: } catch (NoSuchMethodException e) {
336: SwingMLLogger
337: .getInstance()
338: .log(
339: ILogCapable.ERROR,
340: "Syntax error:The method "
341: + anAction.getMethod()
342: + " for the action in the listener "
343: + anEventListener.getEvent()
344: + " in the element "
345: + anEventOwnerName
346: + " wasn't found. Verify the value of METHOD and TYPES.");
347: SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
348: } catch (ClassNotFoundException e) {
349: SwingMLLogger.getInstance().log(
350: ILogCapable.ERROR,
351: "Syntax error:An incorrect value in TYPES has been specified for the method "
352: + anAction.getMethod()
353: + " in the action for the listener "
354: + anEventListener.getEvent()
355: + " in the element " + anEventOwnerName
356: + ".");
357: SwingMLLogger.getInstance().log(ILogCapable.ERROR, e);
358: }
359: }
360:
361: public void resolveArgumentType(int anArgumentTypeIndex,
362: String anArgumentTypeToken, Class[] aClassTypesArray,
363: Class[] aPrimitivesArray) throws ClassNotFoundException {
364: if (anArgumentTypeToken.equals(Constants.PRIMITIVE_INTEGER)) {
365: aClassTypesArray[anArgumentTypeIndex] = Class
366: .forName(Constants.INTEGER_WRAPPER);
367: aPrimitivesArray[anArgumentTypeIndex] = Integer.TYPE;
368: } else if (anArgumentTypeToken.equals(Constants.INTEGER)) {
369: aClassTypesArray[anArgumentTypeIndex] = Class
370: .forName(Constants.INTEGER_WRAPPER);
371: aPrimitivesArray[anArgumentTypeIndex] = Class
372: .forName(Constants.INTEGER_WRAPPER);
373: } else if (anArgumentTypeToken
374: .equals(Constants.PRIMITIVE_BOOLEAN)) {
375: aClassTypesArray[anArgumentTypeIndex] = Class
376: .forName(Constants.BOOLEAN_WRAPPER);
377: aPrimitivesArray[anArgumentTypeIndex] = Boolean.TYPE;
378: } else if (anArgumentTypeToken.equals(Constants.BOOLEAN)) {
379: aClassTypesArray[anArgumentTypeIndex] = Class
380: .forName(Constants.BOOLEAN_WRAPPER);
381: aPrimitivesArray[anArgumentTypeIndex] = Class
382: .forName(Constants.BOOLEAN_WRAPPER);
383: } else if (anArgumentTypeToken.equals(Constants.PRIMITIVE_BYTE)) {
384: aClassTypesArray[anArgumentTypeIndex] = Class
385: .forName(Constants.BYTE_WRAPPER);
386: aPrimitivesArray[anArgumentTypeIndex] = Byte.TYPE;
387: } else if (anArgumentTypeToken.equals(Constants.BYTE)) {
388: aClassTypesArray[anArgumentTypeIndex] = Class
389: .forName(Constants.BYTE_WRAPPER);
390: aPrimitivesArray[anArgumentTypeIndex] = Class
391: .forName(Constants.BYTE_WRAPPER);
392: } else if (anArgumentTypeToken
393: .equals(Constants.PRIMITIVE_FLOAT)) {
394: aClassTypesArray[anArgumentTypeIndex] = Class
395: .forName(Constants.FLOAT_WRAPPER);
396: aPrimitivesArray[anArgumentTypeIndex] = Float.TYPE;
397: } else if (anArgumentTypeToken.equals(Constants.FLOAT)) {
398: aClassTypesArray[anArgumentTypeIndex] = Class
399: .forName(Constants.FLOAT_WRAPPER);
400: aPrimitivesArray[anArgumentTypeIndex] = Class
401: .forName(Constants.FLOAT_WRAPPER);
402: } else if (anArgumentTypeToken.equals(Constants.PRIMITIVE_CHAR)) {
403: aClassTypesArray[anArgumentTypeIndex] = Class
404: .forName(Constants.CHAR_WRAPPER);
405: aPrimitivesArray[anArgumentTypeIndex] = Character.TYPE;
406: } else if (anArgumentTypeToken.equals(Constants.CHAR)) {
407: aClassTypesArray[anArgumentTypeIndex] = Class
408: .forName(Constants.CHAR_WRAPPER);
409: aPrimitivesArray[anArgumentTypeIndex] = Class
410: .forName(Constants.CHAR_WRAPPER);
411: } else if (anArgumentTypeToken
412: .equals(Constants.PRIMITIVE_SHORT)) {
413: aClassTypesArray[anArgumentTypeIndex] = Class
414: .forName(Constants.SHORT_WRAPPER);
415: aPrimitivesArray[anArgumentTypeIndex] = Short.TYPE;
416: } else if (anArgumentTypeToken.equals(Constants.SHORT)) {
417: aClassTypesArray[anArgumentTypeIndex] = Class
418: .forName(Constants.SHORT_WRAPPER);
419: aPrimitivesArray[anArgumentTypeIndex] = Class
420: .forName(Constants.SHORT_WRAPPER);
421: } else if (anArgumentTypeToken.equals(Constants.PRIMITIVE_LONG)) {
422: aClassTypesArray[anArgumentTypeIndex] = Class
423: .forName(Constants.LONG_WRAPPER);
424: aPrimitivesArray[anArgumentTypeIndex] = Long.TYPE;
425: } else if (anArgumentTypeToken.equals(Constants.LONG)) {
426: aClassTypesArray[anArgumentTypeIndex] = Class
427: .forName(Constants.LONG_WRAPPER);
428: aPrimitivesArray[anArgumentTypeIndex] = Class
429: .forName(Constants.LONG_WRAPPER);
430: } else if (anArgumentTypeToken
431: .equals(Constants.PRIMITIVE_DOUBLE)) {
432: aClassTypesArray[anArgumentTypeIndex] = Class
433: .forName(Constants.DOUBLE_WRAPPER);
434: aPrimitivesArray[anArgumentTypeIndex] = Double.TYPE;
435: } else if (anArgumentTypeToken.equals(Constants.DOUBLE)) {
436: aClassTypesArray[anArgumentTypeIndex] = Class
437: .forName(Constants.DOUBLE_WRAPPER);
438: aPrimitivesArray[anArgumentTypeIndex] = Class
439: .forName(Constants.DOUBLE_WRAPPER);
440: } else if (anArgumentTypeToken.equals(Constants.STRING)) {
441: aClassTypesArray[anArgumentTypeIndex] = Class
442: .forName(Constants.STRING_WRAPPER);
443: aPrimitivesArray[anArgumentTypeIndex] = Class
444: .forName(Constants.STRING_WRAPPER);
445: } else {
446: aClassTypesArray[anArgumentTypeIndex] = Class
447: .forName(anArgumentTypeToken);
448: aPrimitivesArray[anArgumentTypeIndex] = Class
449: .forName(anArgumentTypeToken);
450: }
451: }
452: }
|