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.util;
020:
021: import java.awt.event.KeyEvent;
022: import java.util.Collection;
023: import java.util.Collections;
024: import java.util.HashMap;
025: import java.util.HashSet;
026: import java.util.Iterator;
027: import java.util.LinkedList;
028: import java.util.List;
029: import java.util.Map;
030: import java.util.Set;
031:
032: import javax.swing.JMenu;
033: import javax.swing.JMenuItem;
034: import javax.swing.JPopupMenu;
035: import javax.swing.KeyStroke;
036: import javax.swing.MenuElement;
037:
038: import org.apache.jmeter.gui.JMeterGUIComponent;
039: import org.apache.jmeter.gui.ReportGuiPackage;
040: import org.apache.jmeter.gui.action.ActionNames;
041: import org.apache.jmeter.report.gui.action.ReportActionRouter;
042: import org.apache.jmeter.testbeans.TestBean;
043: import org.apache.jmeter.testbeans.gui.TestBeanGUI;
044: import org.apache.jmeter.util.JMeterUtils;
045: import org.apache.jmeter.visualizers.Printable;
046: import org.apache.jorphan.logging.LoggingManager;
047: import org.apache.jorphan.reflect.ClassFinder;
048: import org.apache.jorphan.util.JOrphanUtils;
049: import org.apache.log.Logger;
050:
051: /**
052: * @author Peter Lin
053: * @version $Revision: 535162 $ updated on $Date: 2007-05-04 11:53:59 +0100 (Fri, 04 May 2007) $
054: */
055: public final class ReportMenuFactory {
056: transient private static Logger log = LoggingManager
057: .getLoggerForClass();
058:
059: public final static String TIMERS = "menu_timer";
060:
061: public final static String CONTROLLERS = "menu_logic_controller";
062:
063: public final static String CONFIG_ELEMENTS = "menu_config_element";
064:
065: public final static String POST_PROCESSORS = "menu_post_processors";
066:
067: public final static String PRE_PROCESSORS = "menu_pre_processors";
068:
069: public final static String NON_TEST_ELEMENTS = "menu_non_test_elements";
070:
071: public final static String LISTENERS = "menu_listener";
072:
073: public final static String REPORT_PAGE = "menu_report_page";
074:
075: public final static String TABLES = "menu_tables";
076:
077: private static Map menuMap = new HashMap();
078:
079: private static Set elementsToSkip = new HashSet();
080:
081: // MENU_ADD_xxx - controls which items are in the ADD menu
082: // MENU_PARENT_xxx - controls which items are in the Insert Parent menu
083: private static final String[] MENU_ADD_CONTROLLER = new String[] {
084: ReportMenuFactory.CONTROLLERS,
085: ReportMenuFactory.CONFIG_ELEMENTS,
086: ReportMenuFactory.TIMERS, ReportMenuFactory.LISTENERS,
087: ReportMenuFactory.PRE_PROCESSORS,
088: ReportMenuFactory.POST_PROCESSORS };
089:
090: private static final String[] MENU_PARENT_CONTROLLER = new String[] { ReportMenuFactory.CONTROLLERS };
091:
092: // private static final String[] MENU_ADD_REPORT_PAGE = new String[] { ReportMenuFactory.CONFIG_ELEMENTS,
093: // ReportMenuFactory.PRE_PROCESSORS, ReportMenuFactory.POST_PROCESSORS,
094: // ReportMenuFactory.TABLES };
095: //
096: // private static final String[] MENU_ADD_TABLES = new String[] { ReportMenuFactory.TABLES };
097: //
098: // private static final String[] MENU_PARENT_SAMPLER = new String[] { ReportMenuFactory.CONTROLLERS };
099:
100: private static List controllers, configElements, listeners,
101: nonTestElements, postProcessors, preProcessors, reportPage,
102: tables;
103:
104: // private static JMenu timerMenu;
105: // private static JMenu controllerMenu;
106: // private static JMenu generativeControllerMenu;
107: // private static JMenu listenerMenu;
108: // private static JMenu assertionMenu;
109: // private static JMenu configMenu;
110: // private static JMenu insertControllerMenu;
111: // private static JMenu postProcessorMenu;
112: // private static JMenu preProcessorMenu;
113:
114: static {
115: try {
116: String[] classesToSkip = JOrphanUtils.split(JMeterUtils
117: .getPropDefault("not_in_menu", ""), ",");
118: for (int i = 0; i < classesToSkip.length; i++) {
119: elementsToSkip.add(classesToSkip[i].trim());
120: }
121:
122: initializeMenus();
123: } catch (Throwable e) {
124: log.error("", e);
125: }
126: }
127:
128: /**
129: * Private constructor to prevent instantiation.
130: */
131: private ReportMenuFactory() {
132: }
133:
134: public static String doNothing() {
135: return "doing nothing";
136: }
137:
138: public static void addEditMenu(JPopupMenu menu, boolean removable) {
139: addSeparator(menu);
140: if (removable) {
141: menu.add(makeMenuItem(JMeterUtils.getResString("remove"),
142: "Remove", "remove", KeyStroke.getKeyStroke(
143: KeyEvent.VK_DELETE, 0)));
144: }
145: menu.add(makeMenuItem(JMeterUtils.getResString("cut"), "Cut",
146: "Cut", KeyStroke.getKeyStroke(KeyEvent.VK_X,
147: KeyEvent.CTRL_MASK)));
148: menu.add(makeMenuItem(JMeterUtils.getResString("copy"), "Copy",
149: "Copy", KeyStroke.getKeyStroke(KeyEvent.VK_C,
150: KeyEvent.CTRL_MASK)));
151: menu.add(makeMenuItem(JMeterUtils.getResString("paste"),
152: "Paste", "Paste", KeyStroke.getKeyStroke(KeyEvent.VK_V,
153: KeyEvent.CTRL_MASK)));
154: menu.add(makeMenuItem(JMeterUtils.getResString("paste_insert"),
155: "Paste Insert", "Paste Insert"));
156: }
157:
158: public static void addFileMenu(JPopupMenu menu) {
159: addSeparator(menu);
160: menu.add(makeMenuItem(JMeterUtils.getResString("open"), "Open",
161: "open"));
162: menu.add(makeMenuItem(JMeterUtils.getResString("save_as"),
163: "Save As", "save_as"));
164: JMenuItem savePicture = makeMenuItem(JMeterUtils
165: .getResString("save_as_image"), "Save Image",
166: "save_graphics", KeyStroke.getKeyStroke(KeyEvent.VK_G,
167: KeyEvent.CTRL_MASK));
168: menu.add(savePicture);
169: if (!(ReportGuiPackage.getInstance().getCurrentGui() instanceof Printable)) {
170: savePicture.setEnabled(false);
171: }
172: JMenuItem disabled = makeMenuItem(JMeterUtils
173: .getResString("disable"), "Disable", "disable");
174: JMenuItem enabled = makeMenuItem(JMeterUtils
175: .getResString("enable"), "Enable", "enable");
176: boolean isEnabled = ReportGuiPackage.getInstance()
177: .getTreeListener().getCurrentNode().isEnabled();
178: if (isEnabled) {
179: disabled.setEnabled(true);
180: enabled.setEnabled(false);
181: } else {
182: disabled.setEnabled(false);
183: enabled.setEnabled(true);
184: }
185: menu.add(enabled);
186: menu.add(disabled);
187: addSeparator(menu);
188: menu.add(makeMenuItem(JMeterUtils.getResString("help"), "Help",
189: "help"));
190: }
191:
192: public static JMenu makeMenus(String[] categories, String label,
193: String actionCommand) {
194: JMenu addMenu = new JMenu(label);
195: for (int i = 0; i < categories.length; i++) {
196: addMenu.add(makeMenu(categories[i], actionCommand));
197: }
198: return addMenu;
199: }
200:
201: public static JPopupMenu getDefaultControllerMenu() {
202: JPopupMenu pop = new JPopupMenu();
203: pop.add(MenuFactory.makeMenus(MENU_ADD_CONTROLLER, JMeterUtils
204: .getResString("add"),// $NON-NLS-1$
205: ActionNames.ADD));
206: pop.add(makeMenus(MENU_PARENT_CONTROLLER, JMeterUtils
207: .getResString("insert_parent"),// $NON-NLS-1$
208: ActionNames.ADD_PARENT));
209: MenuFactory.addEditMenu(pop, true);
210: MenuFactory.addFileMenu(pop);
211: return pop;
212: }
213:
214: public static JPopupMenu getDefaultConfigElementMenu() {
215: JPopupMenu pop = new JPopupMenu();
216: MenuFactory.addEditMenu(pop, true);
217: MenuFactory.addFileMenu(pop);
218: return pop;
219: }
220:
221: public static JPopupMenu getDefaultVisualizerMenu() {
222: JPopupMenu pop = new JPopupMenu();
223: MenuFactory.addEditMenu(pop, true);
224: MenuFactory.addFileMenu(pop);
225: return pop;
226: }
227:
228: public static JPopupMenu getDefaultTimerMenu() {
229: JPopupMenu pop = new JPopupMenu();
230: MenuFactory.addEditMenu(pop, true);
231: MenuFactory.addFileMenu(pop);
232: return pop;
233: }
234:
235: public static JPopupMenu getDefaultAssertionMenu() {
236: JPopupMenu pop = new JPopupMenu();
237: MenuFactory.addEditMenu(pop, true);
238: MenuFactory.addFileMenu(pop);
239: return pop;
240: }
241:
242: public static JPopupMenu getDefaultExtractorMenu() {
243: JPopupMenu pop = new JPopupMenu();
244: MenuFactory.addEditMenu(pop, true);
245: MenuFactory.addFileMenu(pop);
246: return pop;
247: }
248:
249: public static JMenu makeMenu(String category, String actionCommand) {
250: return makeMenu((Collection) menuMap.get(category),
251: actionCommand, JMeterUtils.getResString(category));
252: }
253:
254: public static JMenu makeMenu(Collection menuInfo,
255: String actionCommand, String menuName) {
256: Iterator iter = menuInfo.iterator();
257: JMenu menu = new JMenu(menuName);
258: while (iter.hasNext()) {
259: MenuInfo info = (MenuInfo) iter.next();
260: menu.add(makeMenuItem(info.label, info.className,
261: actionCommand));
262: }
263: return menu;
264: }
265:
266: public static void setEnabled(JMenu menu) {
267: if (menu.getSubElements().length == 0) {
268: menu.setEnabled(false);
269: }
270: }
271:
272: public static JMenuItem makeMenuItem(String label, String name,
273: String actionCommand) {
274: JMenuItem newMenuChoice = new JMenuItem(label);
275: newMenuChoice.setName(name);
276: newMenuChoice.addActionListener(ReportActionRouter
277: .getInstance());
278: if (actionCommand != null) {
279: newMenuChoice.setActionCommand(actionCommand);
280: }
281:
282: return newMenuChoice;
283: }
284:
285: public static JMenuItem makeMenuItem(String label, String name,
286: String actionCommand, KeyStroke accel) {
287: JMenuItem item = makeMenuItem(label, name, actionCommand);
288: item.setAccelerator(accel);
289: return item;
290: }
291:
292: private static void initializeMenus() {
293: try {
294: List guiClasses = ClassFinder.findClassesThatExtend(
295: JMeterUtils.getSearchPaths(), new Class[] {
296: JMeterGUIComponent.class, TestBean.class });
297: controllers = new LinkedList();
298: configElements = new LinkedList();
299: listeners = new LinkedList();
300: postProcessors = new LinkedList();
301: preProcessors = new LinkedList();
302: tables = new LinkedList();
303: reportPage = new LinkedList();
304: nonTestElements = new LinkedList();
305: menuMap.put(CONFIG_ELEMENTS, configElements);
306: menuMap.put(CONTROLLERS, controllers);
307: menuMap.put(LISTENERS, listeners);
308: menuMap.put(NON_TEST_ELEMENTS, nonTestElements);
309: menuMap.put(POST_PROCESSORS, postProcessors);
310: menuMap.put(PRE_PROCESSORS, preProcessors);
311: menuMap.put(REPORT_PAGE, reportPage);
312: menuMap.put(TABLES, tables);
313: Collections.sort(guiClasses);
314: Iterator iter = guiClasses.iterator();
315: while (iter.hasNext()) {
316: String name = (String) iter.next();
317:
318: /*
319: * JMeterTreeNode and TestBeanGUI are special GUI classes, and
320: * aren't intended to be added to menus
321: *
322: * TODO: find a better way of checking this
323: */
324: if (name.endsWith("JMeterTreeNode")
325: || name.endsWith("TestBeanGUI")) {
326: continue;// Don't try to instantiate these
327: }
328:
329: JMeterGUIComponent item;
330: try {
331: Class c = Class.forName(name);
332: if (TestBean.class.isAssignableFrom(c)) {
333: item = new TestBeanGUI(c);
334: } else {
335: item = (JMeterGUIComponent) c.newInstance();
336: }
337: } catch (NoClassDefFoundError e) {
338: log.warn("Missing jar? Could not create " + name
339: + ". " + e);
340: continue;
341: } catch (Throwable e) {
342: log.warn("Could not instantiate " + name, e);
343: continue;
344: }
345: if (elementsToSkip.contains(name)
346: || elementsToSkip.contains(item
347: .getStaticLabel())) {
348: log.info("Skipping " + name);
349: continue;
350: } else {
351: elementsToSkip.add(name);
352: }
353: Collection categories = item.getMenuCategories();
354: if (categories == null) {
355: log.debug(name + " participates in no menus.");
356: continue;
357: }
358:
359: if (categories.contains(POST_PROCESSORS)) {
360: postProcessors.add(new MenuInfo(item
361: .getStaticLabel(), name));
362: }
363:
364: if (categories.contains(PRE_PROCESSORS)) {
365: preProcessors.add(new MenuInfo(item
366: .getStaticLabel(), name));
367: }
368:
369: if (categories.contains(CONTROLLERS)) {
370: controllers.add(new MenuInfo(item.getStaticLabel(),
371: name));
372: }
373:
374: if (categories.contains(NON_TEST_ELEMENTS)) {
375: nonTestElements.add(new MenuInfo(item
376: .getStaticLabel(), name));
377: }
378:
379: if (categories.contains(LISTENERS)) {
380: listeners.add(new MenuInfo(item.getStaticLabel(),
381: name));
382: }
383:
384: if (categories.contains(CONFIG_ELEMENTS)) {
385: configElements.add(new MenuInfo(item
386: .getStaticLabel(), name));
387: }
388:
389: if (categories.contains(TABLES)) {
390: tables
391: .add(new MenuInfo(item.getStaticLabel(),
392: name));
393: }
394:
395: if (categories.contains(REPORT_PAGE)) {
396: reportPage.add(new MenuInfo(item.getStaticLabel(),
397: name));
398: }
399: }
400: } catch (Exception e) {
401: log.error("", e);
402: }
403: }
404:
405: private static void addSeparator(JPopupMenu menu) {
406: MenuElement[] elements = menu.getSubElements();
407: if ((elements.length > 0)
408: && !(elements[elements.length - 1] instanceof JPopupMenu.Separator)) {
409: menu.addSeparator();
410: }
411: }
412: }
|