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