001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.jmeter.gui.action;
020:
021: import java.awt.HeadlessException;
022: import java.awt.event.ActionEvent;
023: import java.awt.event.ActionListener;
024: import java.lang.reflect.Modifier;
025: import java.util.HashMap;
026: import java.util.HashSet;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Map;
030: import java.util.Set;
031:
032: import javax.swing.SwingUtilities;
033:
034: import org.apache.jmeter.exceptions.IllegalUserActionException;
035: import org.apache.jmeter.gui.GuiPackage;
036: import org.apache.jmeter.util.JMeterUtils;
037: import org.apache.jorphan.logging.LoggingManager;
038: import org.apache.jorphan.reflect.ClassFinder;
039: import org.apache.jorphan.util.JMeterError;
040: import org.apache.log.Logger;
041:
042: public final class ActionRouter implements ActionListener {
043: private Map commands = new HashMap();
044:
045: private static ActionRouter router;
046:
047: private static final Logger log = LoggingManager
048: .getLoggerForClass();
049:
050: private Map preActionListeners = new HashMap();
051:
052: private Map postActionListeners = new HashMap();
053:
054: private ActionRouter() {
055: }
056:
057: public void actionPerformed(final ActionEvent e) {
058: SwingUtilities.invokeLater(new Runnable() {
059: public void run() {
060: performAction(e);
061: }
062:
063: });
064: }
065:
066: private void performAction(final ActionEvent e) {
067: String actionCommand = e.getActionCommand();
068: try {
069: try {
070: GuiPackage.getInstance().updateCurrentGui();
071: } catch (Exception err) {
072: log.error("performAction(" + actionCommand
073: + ") updateCurrentGui() on" + e.toString()
074: + " caused", err);
075: JMeterUtils
076: .reportErrorToUser("Problem updating GUI - see log file for details");
077: }
078: Set commandObjects = (Set) commands.get(actionCommand);
079: Iterator iter = commandObjects.iterator();
080: while (iter.hasNext()) {
081: try {
082: Command c = (Command) iter.next();
083: preActionPerformed(c.getClass(), e);
084: c.doAction(e);
085: postActionPerformed(c.getClass(), e);
086: } catch (IllegalUserActionException err) {
087: JMeterUtils.reportErrorToUser(err.toString());
088: } catch (Exception err) {
089: log.error("", err);
090: }
091: }
092: } catch (NullPointerException er) {
093: log.error("performAction(" + actionCommand + ") "
094: + e.toString() + " caused", er);
095: JMeterUtils.reportErrorToUser("Sorry, this feature ("
096: + actionCommand + ") not yet implemented");
097: }
098: }
099:
100: /**
101: * To execute an action immediately in the current thread.
102: *
103: * @param e
104: * the action to execute
105: */
106: public void doActionNow(ActionEvent e) {
107: performAction(e);
108: }
109:
110: public Set getAction(String actionName) {
111: Set set = new HashSet();
112: Set commandObjects = (Set) commands.get(actionName);
113: Iterator iter = commandObjects.iterator();
114: while (iter.hasNext()) {
115: try {
116: set.add(iter.next());
117: } catch (Exception err) {
118: log.error("", err);
119: }
120: }
121: return set;
122: }
123:
124: public Command getAction(String actionName, Class actionClass) {
125: Set commandObjects = (Set) commands.get(actionName);
126: Iterator iter = commandObjects.iterator();
127: while (iter.hasNext()) {
128: try {
129: Command com = (Command) iter.next();
130: if (com.getClass().equals(actionClass)) {
131: return com;
132: }
133: } catch (Exception err) {
134: log.error("", err);
135: }
136: }
137: return null;
138: }
139:
140: public Command getAction(String actionName, String className) {
141: Set commandObjects = (Set) commands.get(actionName);
142: Iterator iter = commandObjects.iterator();
143: while (iter.hasNext()) {
144: try {
145: Command com = (Command) iter.next();
146: if (com.getClass().getName().equals(className)) {
147: return com;
148: }
149: } catch (Exception err) {
150: log.error("", err);
151: }
152: }
153: return null;
154: }
155:
156: /**
157: * Allows an ActionListener to receive notification of a command being
158: * executed prior to the actual execution of the command.
159: *
160: * @param action
161: * the Class of the command for which the listener will
162: * notifications for. Class must extend
163: * org.apache.jmeter.gui.action.Command.
164: * @param listener
165: * the ActionListener to receive the notifications
166: */
167: public void addPreActionListener(Class action,
168: ActionListener listener) {
169: if (action != null) {
170: HashSet set = (HashSet) preActionListeners.get(action
171: .getName());
172: if (set == null) {
173: set = new HashSet();
174: }
175: set.add(listener);
176: preActionListeners.put(action.getName(), set);
177: }
178: }
179:
180: /**
181: * Allows an ActionListener to be removed from receiving notifications of a
182: * command being executed prior to the actual execution of the command.
183: *
184: * @param action
185: * the Class of the command for which the listener will
186: * notifications for. Class must extend
187: * org.apache.jmeter.gui.action.Command.
188: * @param listener
189: * the ActionListener to receive the notifications
190: */
191: public void removePreActionListener(Class action,
192: ActionListener listener) {
193: if (action != null) {
194: HashSet set = (HashSet) preActionListeners.get(action
195: .getName());
196: if (set != null) {
197: set.remove(listener);
198: preActionListeners.put(action.getName(), set);
199: }
200: }
201: }
202:
203: /**
204: * Allows an ActionListener to receive notification of a command being
205: * executed after the command has executed.
206: *
207: * @param action
208: * the Class of the command for which the listener will
209: * notifications for. Class must extend
210: * org.apache.jmeter.gui.action.Command.
211: * @param listener
212: */
213: public void addPostActionListener(Class action,
214: ActionListener listener) {
215: if (action != null) {
216: HashSet set = (HashSet) postActionListeners.get(action
217: .getName());
218: if (set == null) {
219: set = new HashSet();
220: }
221: set.add(listener);
222: postActionListeners.put(action.getName(), set);
223: }
224: }
225:
226: /**
227: * Allows an ActionListener to be removed from receiving notifications of a
228: * command being executed after the command has executed.
229: *
230: * @param action
231: * the Class of the command for which the listener will
232: * notifications for. Class must extend
233: * org.apache.jmeter.gui.action.Command.
234: * @param listener
235: */
236: public void removePostActionListener(Class action,
237: ActionListener listener) {
238: if (action != null) {
239: HashSet set = (HashSet) postActionListeners.get(action
240: .getName());
241: if (set != null) {
242: set.remove(listener);
243: postActionListeners.put(action.getName(), set);
244: }
245: }
246: }
247:
248: protected void preActionPerformed(Class action, ActionEvent e) {
249: if (action != null) {
250: HashSet listenerSet = (HashSet) preActionListeners
251: .get(action.getName());
252: if (listenerSet != null && listenerSet.size() > 0) {
253: Object[] listeners = listenerSet.toArray();
254: for (int i = 0; i < listeners.length; i++) {
255: ((ActionListener) listeners[i]).actionPerformed(e);
256: }
257: }
258: }
259: }
260:
261: protected void postActionPerformed(Class action, ActionEvent e) {
262: if (action != null) {
263: HashSet listenerSet = (HashSet) postActionListeners
264: .get(action.getName());
265: if (listenerSet != null && listenerSet.size() > 0) {
266: Object[] listeners = listenerSet.toArray();
267: for (int i = 0; i < listeners.length; i++) {
268: ((ActionListener) listeners[i]).actionPerformed(e);
269: }
270: }
271: }
272: }
273:
274: private void populateCommandMap() {
275: List listClasses;
276: Command command;
277: Iterator iterClasses;
278: Class commandClass;
279: try {
280: listClasses = ClassFinder.findClassesThatExtend(JMeterUtils
281: .getSearchPaths(), new Class[] { Class
282: .forName("org.apache.jmeter.gui.action.Command") });
283: commands = new HashMap(listClasses.size());
284: if (listClasses.size() == 0) {
285: log
286: .fatalError("!!!!!Uh-oh, didn't find any action handlers!!!!!");
287: throw new JMeterError(
288: "No action handlers found - check JMeterHome and libraries");
289: }
290: iterClasses = listClasses.iterator();
291: while (iterClasses.hasNext()) {
292: String strClassName = (String) iterClasses.next();
293: if (strClassName.startsWith("org.apache.jmeter.gui")) {
294: commandClass = Class.forName(strClassName);
295: if (!Modifier.isAbstract(commandClass
296: .getModifiers())) {
297: command = (Command) commandClass.newInstance();
298: Iterator iter = command.getActionNames()
299: .iterator();
300: while (iter.hasNext()) {
301: String commandName = (String) iter.next();
302: Set commandObjects = (Set) commands
303: .get(commandName);
304: if (commandObjects == null) {
305: commandObjects = new HashSet();
306: commands.put(commandName,
307: commandObjects);
308: }
309: commandObjects.add(command);
310: }
311: }
312: }
313: }
314: } catch (HeadlessException e) {
315: log.warn(e.toString());
316: } catch (JMeterError e) {
317: throw e;
318: } catch (Exception e) {
319: log.error("exception finding action handlers", e);
320: }
321: }
322:
323: /**
324: * Gets the Instance attribute of the ActionRouter class
325: *
326: * @return The Instance value
327: */
328: public static ActionRouter getInstance() {
329: if (router == null) {
330: router = new ActionRouter();
331: router.populateCommandMap();
332: }
333: return router;
334: }
335: }
|