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.event.ActionEvent;
022: import java.io.File;
023: import java.io.FileInputStream;
024: import java.io.InputStream;
025: import java.util.HashSet;
026: import java.util.Set;
027:
028: import javax.swing.JFileChooser;
029: import javax.swing.JTree;
030: import javax.swing.tree.TreePath;
031:
032: import org.apache.jmeter.exceptions.IllegalUserActionException;
033: import org.apache.jmeter.gui.GuiPackage;
034: import org.apache.jmeter.gui.tree.JMeterTreeNode;
035: import org.apache.jmeter.gui.util.FileDialoger;
036: import org.apache.jmeter.gui.util.MenuFactory;
037: import org.apache.jmeter.save.SaveService;
038: import org.apache.jmeter.services.FileServer;
039: import org.apache.jmeter.testelement.TestElement;
040: import org.apache.jmeter.testelement.TestPlan;
041: import org.apache.jmeter.testelement.WorkBench;
042: import org.apache.jmeter.util.JMeterUtils;
043: import org.apache.jorphan.collections.HashTree;
044: import org.apache.jorphan.logging.LoggingManager;
045: import org.apache.jorphan.util.JOrphanUtils;
046: import org.apache.log.Logger;
047:
048: import com.thoughtworks.xstream.converters.ConversionException;
049:
050: /**
051: * Handles the Open (load a new file) and Merge commands.
052: *
053: */
054: public class Load implements Command {
055: private static final Logger log = LoggingManager
056: .getLoggerForClass();
057:
058: private static final boolean expandTree = JMeterUtils
059: .getPropDefault("onload.expandtree", true); //$NON-NLS-1$
060:
061: private static Set commands = new HashSet();
062: static {
063: commands.add(ActionNames.OPEN);
064: commands.add(ActionNames.MERGE);
065: }
066:
067: public Load() {
068: super ();
069: }
070:
071: public Set getActionNames() {
072: return commands;
073: }
074:
075: public void doAction(ActionEvent e) {
076: JFileChooser chooser = FileDialoger
077: .promptToOpenFile(new String[] { ".jmx" }); //$NON-NLS-1$
078: if (chooser == null) {
079: return;
080: }
081: File selectedFile = chooser.getSelectedFile();
082: if (selectedFile != null) {
083: boolean merging = e.getActionCommand().equals(
084: ActionNames.MERGE);
085: // We must ask the user if it is ok to close current project
086: if (!merging) {
087: if (!Close.performAction(e))
088: return;
089: }
090: loadProjectFile(e, selectedFile, merging);
091: }
092: }
093:
094: static void loadProjectFile(ActionEvent e, File f, boolean merging) {
095: GuiPackage guiPackage = GuiPackage.getInstance();
096: InputStream reader = null;
097: try {
098: if (f != null) {
099: boolean isTestPlan = false;
100:
101: if (merging) {
102: log.info("Merging file: " + f);
103: } else {
104: log.info("Loading file: " + f);
105: FileServer.getFileServer().setBasedir(
106: f.getAbsolutePath());
107: }
108: reader = new FileInputStream(f);
109: HashTree tree = SaveService.loadTree(reader);
110: isTestPlan = insertLoadedTree(e.getID(), tree, merging);
111:
112: // don't change name if merging
113: if (!merging && isTestPlan) {
114: guiPackage.setTestPlanFile(f.getAbsolutePath());
115: }
116: }
117: } catch (NoClassDefFoundError ex) // Allow for missing optional jars
118: {
119: log.warn("Missing jar file", ex);
120: String msg = ex.getMessage();
121: if (msg == null) {
122: msg = "Missing jar file - see log for details";
123: }
124: JMeterUtils.reportErrorToUser(msg);
125: } catch (ConversionException ex) {
126: log.warn("Could not convert file " + ex);
127: JMeterUtils.reportErrorToUser(SaveService.CEtoString(ex));
128: } catch (Exception ex) {
129: log.warn("Unexpected error", ex);
130: String msg = ex.getMessage();
131: if (msg == null) {
132: msg = "Unexpected error - see log for details";
133: }
134: JMeterUtils.reportErrorToUser(msg);
135: } finally {
136: JOrphanUtils.closeQuietly(reader);
137: guiPackage.updateCurrentGui();
138: guiPackage.getMainFrame().repaint();
139: }
140: }
141:
142: /**
143: * Returns a boolean indicating whether the loaded tree was a full test plan
144: */
145: public static boolean insertLoadedTree(int id, HashTree tree,
146: boolean merging) throws Exception,
147: IllegalUserActionException {
148: // convertTree(tree);
149: if (tree == null) {
150: throw new Exception("Error in TestPlan - see log file");
151: }
152: boolean isTestPlan = tree.getArray()[0] instanceof TestPlan;
153:
154: // If we are loading a new test plan, initialize the tree with the testplan node we are loading
155: GuiPackage guiInstance = GuiPackage.getInstance();
156: if (isTestPlan && !merging) {
157: guiInstance.getTreeModel().clearTestPlan(
158: (TestElement) tree.getArray()[0]);
159: }
160:
161: if (merging) { // Check if target of merge is reasonable
162: TestElement te = (TestElement) tree.getArray()[0];
163: if (!(te instanceof WorkBench || te instanceof TestPlan)) {// These are handled specially by addToTree
164: boolean ok = MenuFactory.canAddTo(guiInstance
165: .getCurrentNode(), te);
166: if (!ok) {
167: String name = te.getName();
168: String className = te.getClass().getName();
169: className = className.substring(className
170: .lastIndexOf(".") + 1);
171: throw new IllegalUserActionException("Can't merge "
172: + name + " (" + className + ") here");
173: }
174: }
175: }
176: HashTree newTree = guiInstance.addSubTree(tree);
177: guiInstance.updateCurrentGui();
178: guiInstance.getMainFrame().getTree().setSelectionPath(
179: new TreePath(((JMeterTreeNode) newTree.getArray()[0])
180: .getPath()));
181: tree = guiInstance.getCurrentSubTree();
182: // Send different event wether we are merging a test plan into another test plan,
183: // or loading a testplan from scratch
184: ActionEvent actionEvent = null;
185: if (!merging) {
186: actionEvent = new ActionEvent(tree.get(tree.getArray()[tree
187: .size() - 1]), id, ActionNames.SUB_TREE_LOADED);
188: } else {
189: actionEvent = new ActionEvent(tree.get(tree.getArray()[tree
190: .size() - 1]), id, ActionNames.SUB_TREE_MERGED);
191: }
192:
193: ActionRouter.getInstance().actionPerformed(actionEvent);
194: if (expandTree && !merging) { // don't automatically expand when merging
195: JTree jTree = guiInstance.getMainFrame().getTree();
196: for (int i = 0; i < jTree.getRowCount(); i++) {
197: jTree.expandRow(i);
198: }
199: }
200:
201: return isTestPlan;
202: }
203:
204: public static boolean insertLoadedTree(int id, HashTree tree)
205: throws Exception, IllegalUserActionException {
206: return insertLoadedTree(id, tree, false);
207: }
208: }
|