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.protocol.java.config.gui;
020:
021: import java.awt.BorderLayout;
022: import java.awt.event.ActionEvent;
023: import java.awt.event.ActionListener;
024: import java.util.List;
025: import java.util.Map;
026:
027: import javax.swing.JComboBox;
028: import javax.swing.JLabel;
029: import javax.swing.JPanel;
030:
031: import org.apache.jmeter.config.Argument;
032: import org.apache.jmeter.config.Arguments;
033: import org.apache.jmeter.config.gui.AbstractConfigGui;
034: import org.apache.jmeter.config.gui.ArgumentsPanel;
035: import org.apache.jmeter.gui.util.HorizontalPanel;
036: import org.apache.jmeter.protocol.java.config.JavaConfig;
037: import org.apache.jmeter.protocol.java.sampler.JavaSampler;
038: import org.apache.jmeter.protocol.java.sampler.JavaSamplerClient;
039: import org.apache.jmeter.testelement.TestElement;
040: import org.apache.jmeter.testelement.property.PropertyIterator;
041: import org.apache.jmeter.util.JMeterUtils;
042: import org.apache.jorphan.reflect.ClassFinder;
043: import org.apache.jorphan.logging.LoggingManager;
044: import org.apache.log.Logger;
045:
046: /**
047: * The <code>JavaConfigGui</code> class provides the user interface for the
048: * {@link JavaConfig} object.
049: *
050: */
051: public class JavaConfigGui extends AbstractConfigGui implements
052: ActionListener {
053: /** Logging */
054: private static final Logger log = LoggingManager
055: .getLoggerForClass();
056:
057: /** The name of the classnameCombo JComboBox */
058: private static final String CLASSNAMECOMBO = "classnamecombo";
059:
060: /** A combo box allowing the user to choose a test class. */
061: private JComboBox classnameCombo;
062:
063: /**
064: * Indicates whether or not the name of this component should be displayed
065: * as part of the GUI. If true, this is a standalone component. If false, it
066: * is embedded in some other component.
067: */
068: private boolean displayName = true;
069:
070: /** A panel allowing the user to set arguments for this test. */
071: private ArgumentsPanel argsPanel;
072:
073: /**
074: * Create a new JavaConfigGui as a standalone component.
075: */
076: public JavaConfigGui() {
077: this (true);
078: }
079:
080: /**
081: * Create a new JavaConfigGui as either a standalone or an embedded
082: * component.
083: *
084: * @param displayNameField
085: * tells whether the component name should be displayed with the
086: * GUI. If true, this is a standalone component. If false, this
087: * component is embedded in some other component.
088: */
089: public JavaConfigGui(boolean displayNameField) {
090: this .displayName = displayNameField;
091: init();
092: }
093:
094: public String getLabelResource() {
095: return "java_request_defaults"; // $NON-NLS-1$
096: }
097:
098: /**
099: * Initialize the GUI components and layout.
100: */
101: protected void init() {
102: setLayout(new BorderLayout(0, 5));
103:
104: if (displayName) {
105: setBorder(makeBorder());
106: add(makeTitlePanel(), BorderLayout.NORTH);
107: }
108:
109: JPanel classnameRequestPanel = new JPanel(
110: new BorderLayout(0, 5));
111: classnameRequestPanel.add(createClassnamePanel(),
112: BorderLayout.NORTH);
113: classnameRequestPanel.add(createParameterPanel(),
114: BorderLayout.CENTER);
115:
116: add(classnameRequestPanel, BorderLayout.CENTER);
117: }
118:
119: /**
120: * Create a panel with GUI components allowing the user to select a test
121: * class.
122: *
123: * @return a panel containing the relevant components
124: */
125: private JPanel createClassnamePanel() {
126: List possibleClasses = null;
127:
128: try {
129: // Find all the classes which implement the JavaSamplerClient
130: // interface.
131: possibleClasses = ClassFinder.findClassesThatExtend(
132: JMeterUtils.getSearchPaths(),
133: new Class[] { JavaSamplerClient.class });
134:
135: // Remove the JavaConfig class from the list since it only
136: // implements the interface for error conditions.
137:
138: possibleClasses.remove(JavaSampler.class.getName()
139: + "$ErrorSamplerClient");
140: } catch (Exception e) {
141: log.debug("Exception getting interfaces.", e);
142: }
143:
144: JLabel label = new JLabel(JMeterUtils
145: .getResString("protocol_java_classname")); // $NON-NLS-1$
146:
147: classnameCombo = new JComboBox(possibleClasses.toArray());
148: classnameCombo.addActionListener(this );
149: classnameCombo.setName(CLASSNAMECOMBO);
150: classnameCombo.setEditable(false);
151: label.setLabelFor(classnameCombo);
152:
153: HorizontalPanel panel = new HorizontalPanel();
154: panel.add(label);
155: panel.add(classnameCombo);
156:
157: return panel;
158: }
159:
160: /**
161: * Handle action events for this component. This method currently handles
162: * events for the classname combo box.
163: *
164: * @param evt
165: * the ActionEvent to be handled
166: */
167: public void actionPerformed(ActionEvent evt) {
168: if (evt.getSource() == classnameCombo) {
169: String className = ((String) classnameCombo
170: .getSelectedItem()).trim();
171: try {
172: JavaSamplerClient client = (JavaSamplerClient) Class
173: .forName(
174: className,
175: true,
176: Thread.currentThread()
177: .getContextClassLoader())
178: .newInstance();
179:
180: Arguments currArgs = new Arguments();
181: argsPanel.modifyTestElement(currArgs);
182: Map currArgsMap = currArgs.getArgumentsAsMap();
183:
184: Arguments newArgs = new Arguments();
185: Arguments testParams = null;
186: try {
187: testParams = client.getDefaultParameters();
188: } catch (AbstractMethodError e) {
189: log
190: .warn("JavaSamplerClient doesn't implement "
191: + "getDefaultParameters. Default parameters won't "
192: + "be shown. Please update your client class: "
193: + className);
194: }
195:
196: if (testParams != null) {
197: PropertyIterator i = testParams.getArguments()
198: .iterator();
199: while (i.hasNext()) {
200: Argument arg = (Argument) i.next()
201: .getObjectValue();
202: String name = arg.getName();
203: String value = arg.getValue();
204:
205: // If a user has set parameters in one test, and then
206: // selects a different test which supports the same
207: // parameters, those parameters should have the same
208: // values that they did in the original test.
209: if (currArgsMap.containsKey(name)) {
210: String newVal = (String) currArgsMap
211: .get(name);
212: if (newVal != null && newVal.length() > 0) {
213: value = newVal;
214: }
215: }
216: newArgs.addArgument(name, value);
217: }
218: }
219:
220: argsPanel.configure(newArgs);
221: } catch (Exception e) {
222: log.error("Error getting argument list for "
223: + className, e);
224: }
225: }
226: }
227:
228: /**
229: * Create a panel containing components allowing the user to provide
230: * arguments to be passed to the test class instance.
231: *
232: * @return a panel containing the relevant components
233: */
234: private JPanel createParameterPanel() {
235: argsPanel = new ArgumentsPanel(JMeterUtils
236: .getResString("paramtable")); // $NON-NLS-1$
237: return argsPanel;
238: }
239:
240: /* Overrides AbstractJMeterGuiComponent.configure(TestElement) */
241: public void configure(TestElement config) {
242: super .configure(config);
243:
244: argsPanel.configure((Arguments) config.getProperty(
245: JavaSampler.ARGUMENTS).getObjectValue());
246:
247: classnameCombo.setSelectedItem(config
248: .getPropertyAsString(JavaSampler.CLASSNAME));
249: }
250:
251: /* Implements JMeterGUIComponent.createTestElement() */
252: public TestElement createTestElement() {
253: JavaConfig config = new JavaConfig();
254: modifyTestElement(config);
255: return config;
256: }
257:
258: /* Implements JMeterGUIComponent.modifyTestElement(TestElement) */
259: public void modifyTestElement(TestElement config) {
260: configureTestElement(config);
261: ((JavaConfig) config).setArguments((Arguments) argsPanel
262: .createTestElement());
263: ((JavaConfig) config).setClassname(classnameCombo
264: .getSelectedItem().toString());
265: }
266: }
|