From 4fe05e3764786355c7f698d4b439abb53e3acb02 Mon Sep 17 00:00:00 2001
From: Philippe Mouawad
Date: Sat, 29 Jun 2013 20:08:15 +0000
Subject: [PATCH] Bug 55085 - UX Improvement : Ability to create New Test Plan
from Templates Bugzilla Id: 55085
git-svn-id: https://svn.apache.org/repos/asf/jmeter/trunk@1498018 13f79535-47bb-0310-9956-ffa450edef68
Former-commit-id: f184d4a74d64018466fe8bf0d9f2fd168d0b3323
---
bin/jmeter.properties | 6 +-
bin/templates/jdbc.jmx | 93 ++++++++
bin/templates/recording.jmx | 158 +++++++++++++
bin/templates/templates.xml | 53 +++++
.../apache/jmeter/gui/action/ActionNames.java | 1 +
.../gui/action/SelectTemplateDialog.java | 222 ++++++++++++++++++
.../jmeter/gui/action/TemplateCommand.java | 54 +++++
.../jmeter/gui/action/template/Template.java | 65 +++++
.../gui/action/template/TemplateManager.java | 140 +++++++++++
.../apache/jmeter/gui/util/JMeterMenuBar.java | 6 +
.../jmeter/resources/messages.properties | 4 +
.../jmeter/resources/messages_fr.properties | 4 +
xdocs/changes.xml | 1 +
13 files changed, 806 insertions(+), 1 deletion(-)
create mode 100644 bin/templates/jdbc.jmx
create mode 100644 bin/templates/recording.jmx
create mode 100644 bin/templates/templates.xml
create mode 100644 src/core/org/apache/jmeter/gui/action/SelectTemplateDialog.java
create mode 100644 src/core/org/apache/jmeter/gui/action/TemplateCommand.java
create mode 100644 src/core/org/apache/jmeter/gui/action/template/Template.java
create mode 100644 src/core/org/apache/jmeter/gui/action/template/TemplateManager.java
diff --git a/bin/jmeter.properties b/bin/jmeter.properties
index 14fed36ded..acaf1912d6 100644
--- a/bin/jmeter.properties
+++ b/bin/jmeter.properties
@@ -935,4 +935,8 @@ user.properties=user.properties
# Should JMeter automatically load additional system properties?
# File name to look for (comment to disable)
-system.properties=system.properties
\ No newline at end of file
+system.properties=system.properties
+
+# Comma separated list of files that contain reference to templates and their description
+# Path must be relative to jmeter root folder
+#template.files=/bin/templates/templates.xml
\ No newline at end of file
diff --git a/bin/templates/jdbc.jmx b/bin/templates/jdbc.jmx
new file mode 100644
index 0000000000..0ca8a700b5
--- /dev/null
+++ b/bin/templates/jdbc.jmx
@@ -0,0 +1,93 @@
+
+
+
+
+
+ false
+ false
+
+
+
+
+
+
+
+ true
+ Select 1
+ 5000
+ jdbcConfig
+ jdbc:postgresql://hostname:port/dbname
+ org.postgresql.Driver
+ true
+ password
+ 10
+ 10000
+ DEFAULT
+ 60000
+ username
+
+
+
+ continue
+
+ false
+ 1
+
+ 1
+ 1
+ 1370729701000
+ 1370729701000
+ false
+
+
+
+
+
+ jdbcConfig
+ select column1 from table
+
+
+ Select Statement
+
+ col1
+
+
+
+
+ false
+
+ saveConfig
+
+
+ true
+ true
+ true
+
+ true
+ true
+ true
+ false
+ false
+ true
+ false
+ false
+ false
+ false
+ true
+ false
+ false
+ true
+ true
+ 0
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+
diff --git a/bin/templates/recording.jmx b/bin/templates/recording.jmx
new file mode 100644
index 0000000000..7c713abb9f
--- /dev/null
+++ b/bin/templates/recording.jmx
@@ -0,0 +1,158 @@
+
+
+
+
+
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
+ true
+
+
+
+ continue
+
+ false
+ 1
+
+ 1
+ 1
+ 1370726934000
+ 1370726934000
+ false
+
+
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+
+ true
+ true
+ true
+
+ true
+ true
+ true
+ false
+ false
+ true
+ false
+ false
+ false
+ false
+ true
+ false
+ false
+ true
+ true
+ 0
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+ true
+
+
+
+ 8888
+
+ .*\.jpg
+ .*\.js
+ .*\.png
+ .*\.gif
+ .*\.bmp
+ .*\.swf
+ .*\.css
+
+
+ true
+ 4
+ false
+
+ false
+ true
+ true
+ false
+ true
+
+
+
+
+
+ false
+
+ saveConfig
+
+
+ true
+ true
+ true
+
+ true
+ true
+ true
+ false
+ false
+ true
+ false
+ false
+ false
+ false
+ true
+ false
+ false
+ true
+ true
+ 0
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
diff --git a/bin/templates/templates.xml b/bin/templates/templates.xml
new file mode 100644
index 0000000000..2c2b5f1ea6
--- /dev/null
+++ b/bin/templates/templates.xml
@@ -0,0 +1,53 @@
+
+
+ Recording
+ /bin/templates/recording.jmx
+ Template showing how to record
+ JMeter Configuration
+
+
+ - JMeter Server Proxy port is set to 8888, you may want to change
+
+
+
+ Browser Configuration
+ Configure your browser so that is uses the JMeter proxy, set:
+
+ - the host of the machine that runs JMeter
+ - the port you setup in JMeter Server Proxy
+
+
+ Useful links
+
+
+
+
+ ]]>
+
+
+ JDBC Load Test
+ /bin/templates/jdbc.jmx
+
+ Template showing how to Load Test an SQL query on Database
+ JMeter Configuration
+
+
+ - Add the database driver to jmeter/lib folder
+ - Configure the host, port, username and password in JDBC Configuration
+ - Modify the SQL query to match your query
+
+
+ Useful links
+
+
+
+
+ ]]>
+
+
\ No newline at end of file
diff --git a/src/core/org/apache/jmeter/gui/action/ActionNames.java b/src/core/org/apache/jmeter/gui/action/ActionNames.java
index fd02ae45a2..1f0132c2ff 100644
--- a/src/core/org/apache/jmeter/gui/action/ActionNames.java
+++ b/src/core/org/apache/jmeter/gui/action/ActionNames.java
@@ -62,6 +62,7 @@ public final class ActionNames {
public static final String MERGE = "merge"; // $NON-NLS-1$
public static final String OPEN = "open"; // $NON-NLS-1$
public static final String OPEN_RECENT = "open_recent"; // $NON-NLS-1$
+ public static final String CREATE_FROM_TEMPLATE = "create_from_template"; // $NON-NLS-1$
public static final String PASTE = "Paste"; // $NON-NLS-1$
public static final String REMOTE_EXIT = "remote_exit"; // $NON-NLS-1$
public static final String REMOTE_EXIT_ALL = "remote_exit_all"; // $NON-NLS-1$
diff --git a/src/core/org/apache/jmeter/gui/action/SelectTemplateDialog.java b/src/core/org/apache/jmeter/gui/action/SelectTemplateDialog.java
new file mode 100644
index 0000000000..d92865c407
--- /dev/null
+++ b/src/core/org/apache/jmeter/gui/action/SelectTemplateDialog.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jmeter.gui.action;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Set;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ActionMap;
+import javax.swing.InputMap;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JRootPane;
+import javax.swing.JScrollPane;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.jmeter.gui.action.template.Template;
+import org.apache.jmeter.gui.action.template.TemplateManager;
+import org.apache.jmeter.swing.HtmlPane;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.gui.ComponentUtil;
+import org.apache.jorphan.gui.JLabeledChoice;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.jorphan.util.JOrphanUtils;
+import org.apache.log.Logger;
+
+/**
+ * Dialog used for Templates selection
+ * @since 2.10
+ */
+public class SelectTemplateDialog extends JDialog implements ChangeListener, ActionListener {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4436834972710248247L;
+
+ private static final Logger log = LoggingManager.getLoggerForClass();
+
+ private JLabeledChoice templateList;
+
+ private HtmlPane helpDoc = new HtmlPane();
+
+ private JButton createFromTemplateButton;
+
+ private JButton cancelButton;
+
+ private JScrollPane scroller = new JScrollPane(helpDoc);
+
+ public SelectTemplateDialog() {
+ super((JFrame) null, JMeterUtils.getResString("template_title"), true); //$NON-NLS-1$
+ init();
+ }
+
+ @Override
+ protected JRootPane createRootPane() {
+ JRootPane rootPane = new JRootPane();
+ // Hide Window on ESC
+ Action escapeAction = new AbstractAction("ESCAPE") { //$NON-NLS-1$
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6543764044868772971L;
+
+ @Override
+ public void actionPerformed(ActionEvent actionEvent) {
+ setVisible(false);
+ }
+ };
+ // Do search on Enter
+ Action enterAction = new AbstractAction("ENTER") { //$NON-NLS-1$
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3661361497864527363L;
+
+ @Override
+ public void actionPerformed(ActionEvent actionEvent) {
+ doOpen(actionEvent);
+ }
+ };
+ ActionMap actionMap = rootPane.getActionMap();
+ actionMap.put(escapeAction.getValue(Action.NAME), escapeAction);
+ actionMap.put(enterAction.getValue(Action.NAME), enterAction);
+ InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
+ inputMap.put(KeyStrokes.ESC, escapeAction.getValue(Action.NAME));
+ inputMap.put(KeyStrokes.ENTER, enterAction.getValue(Action.NAME));
+
+ return rootPane;
+ }
+
+ private void init() {
+ initializeTemplateList();
+ this.getContentPane().setLayout(new BorderLayout(10, 10));
+ JPanel comboPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
+ comboPanel.add(templateList);
+ this.getContentPane().add(comboPanel, BorderLayout.NORTH);
+ helpDoc.setContentType("text/html"); //$NON-NLS-1$
+ helpDoc.setEditable(false);
+ fillDescription();
+ JPanel jPanel = new JPanel(new GridLayout(1,1));
+ scroller.setPreferredSize(new Dimension(300, 400));
+ jPanel.setPreferredSize(new Dimension(310, 410));
+ jPanel.add(scroller);
+ this.getContentPane().add(jPanel, BorderLayout.CENTER);
+
+ JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
+
+ createFromTemplateButton = new JButton(JMeterUtils.getResString("template_create_from")); //$NON-NLS-1$
+ createFromTemplateButton.addActionListener(this);
+
+ cancelButton = new JButton(JMeterUtils.getResString("cancel")); //$NON-NLS-1$
+ cancelButton.addActionListener(this);
+ buttonsPanel.add(createFromTemplateButton);
+ buttonsPanel.add(cancelButton);
+ this.getContentPane().add(buttonsPanel, BorderLayout.SOUTH);
+
+ this.pack();
+ ComponentUtil.centerComponentInWindow(this);
+ }
+
+ private void initializeTemplateList() {
+ Set templatesAsSet = TemplateManager.getInstance().getTemplateNames();
+ String[] templateNames = templatesAsSet.toArray(new String[templatesAsSet.size()]);
+ Arrays.sort(templateNames, new Comparator() {
+ @Override
+ public int compare(String o1, String o2) {
+ return o1.compareToIgnoreCase(o2);
+ }
+ });
+ templateList = new JLabeledChoice(JMeterUtils.getResString("template_choose"), templateNames); //$NON-NLS-1$
+ templateList.addChangeListener(this);
+ }
+
+ /**
+ * Do search
+ * @param e {@link ActionEvent}
+ */
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if(e.getSource()==cancelButton) {
+ this.setVisible(false);
+ return;
+ }
+ doOpen(e);
+ }
+
+ @Override
+ public void stateChanged(ChangeEvent event) {
+ fillDescription();
+ }
+
+ /**
+ *
+ */
+ protected void fillDescription() {
+ String selectedTemplate = templateList.getText();
+ Template template = TemplateManager.getInstance().getTemplateByName(selectedTemplate);
+ helpDoc.setText(template.getDescription());
+ }
+
+ /**
+ * @param e {@link ActionEvent}
+ */
+ private void doOpen(ActionEvent e) {
+ InputStream inputStream = null;
+ OutputStream outputStream = null;
+ try {
+ String selectedTemplate = templateList.getText();
+ Template template = TemplateManager.getInstance().getTemplateByName(selectedTemplate);
+ File fileToCopy = new File(JMeterUtils.getJMeterHome(), template.getFileName());
+ File targetFile = new File( System.getProperty("user.dir"),
+ template.getFileName().substring(template.getFileName().lastIndexOf("/")));
+ inputStream = new BufferedInputStream(new FileInputStream(fileToCopy));
+ outputStream = new BufferedOutputStream(new FileOutputStream(targetFile));
+ IOUtils.copy(inputStream, outputStream);
+ outputStream.close();
+ Load.loadProjectFile(e, targetFile, false);
+ this.setVisible(false);
+ } catch (Exception e1) {
+ throw new Error(e1);
+ } finally {
+ JOrphanUtils.closeQuietly(inputStream);
+ JOrphanUtils.closeQuietly(outputStream);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/core/org/apache/jmeter/gui/action/TemplateCommand.java b/src/core/org/apache/jmeter/gui/action/TemplateCommand.java
new file mode 100644
index 0000000000..dee7cdfe12
--- /dev/null
+++ b/src/core/org/apache/jmeter/gui/action/TemplateCommand.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jmeter.gui.action;
+
+import java.awt.event.ActionEvent;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Open Templates
+ * @since 2.10
+ */
+public class TemplateCommand extends AbstractAction {
+
+ private static final Set commands = new HashSet();
+
+ static {
+ commands.add(ActionNames.CREATE_FROM_TEMPLATE);
+ }
+
+ private SelectTemplateDialog dialog = new SelectTemplateDialog();
+ /**
+ * @see Command#doAction(ActionEvent)
+ */
+ @Override
+ public void doAction(ActionEvent e) {
+ dialog.setVisible(true);
+ }
+
+
+ /**
+ * @see Command#getActionNames()
+ */
+ @Override
+ public Set getActionNames() {
+ return commands;
+ }
+}
diff --git a/src/core/org/apache/jmeter/gui/action/template/Template.java b/src/core/org/apache/jmeter/gui/action/template/Template.java
new file mode 100644
index 0000000000..f1f11b21ba
--- /dev/null
+++ b/src/core/org/apache/jmeter/gui/action/template/Template.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jmeter.gui.action.template;
+
+/**
+ * Template Bean
+ * @since 2.10
+ */
+public class Template {
+ private String name;
+ private String fileName;
+ private String description;
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+ /**
+ * @param name the name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+ /**
+ * @return the relativeFileName
+ */
+ public String getFileName() {
+ return fileName;
+ }
+ /**
+ * @param relativeFileName the relativeFileName to set
+ */
+ public void setFileName(String relativeFileName) {
+ fileName = relativeFileName;
+ }
+ /**
+ * @return the description
+ */
+ public String getDescription() {
+ return description;
+ }
+ /**
+ * @param description the description to set
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+}
\ No newline at end of file
diff --git a/src/core/org/apache/jmeter/gui/action/template/TemplateManager.java b/src/core/org/apache/jmeter/gui/action/template/TemplateManager.java
new file mode 100644
index 0000000000..aa15904098
--- /dev/null
+++ b/src/core/org/apache/jmeter/gui/action/template/TemplateManager.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jmeter.gui.action.template;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.jorphan.util.JOrphanUtils;
+import org.apache.log.Logger;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
+/**
+ * Manages Test Plan templates
+ * @since 2.10
+ */
+public class TemplateManager {
+ private class Templates {
+ private Map templates = new HashMap();
+ }
+ private static final String TEMPLATE_FILES = JMeterUtils.getPropDefault("template.files", // $NON-NLS-1$
+ "/bin/templates/templates.xml");
+
+ private static final Logger log = LoggingManager.getLoggerForClass();
+
+ private static final TemplateManager SINGLETON = new TemplateManager();
+
+ private Map templates = new HashMap();
+
+ private XStream xstream = initXStream();
+
+ /**
+ *
+ * @return
+ */
+ public static final TemplateManager getInstance() {
+ return SINGLETON;
+ }
+
+ private TemplateManager() {
+ try {
+ templates = readTemplates();
+ } catch(IOException e) {
+ log.error("Error loading templates from files referenced in templates.files property:"+
+ TEMPLATE_FILES, e);
+ }
+ }
+
+ private XStream initXStream() {
+ XStream xstream = new XStream(new DomDriver());
+ xstream.alias("template", Template.class);
+ xstream.alias("templates", Templates.class);
+
+ // templates i
+ xstream.addImplicitMap(Templates.class,
+ // field TemplateManager#templates
+ "templates", // $NON-NLS-1$
+ Template.class,
+ // field Template#name
+ "name" // $NON-NLS-1$
+ );
+
+ return xstream;
+ }
+
+ public void addTemplate(Template template) {
+ templates.put(template.getName(), template);
+ }
+
+ /**
+ * @return Set the templates names
+ */
+ public Set getTemplateNames() {
+ return templates.keySet();
+ }
+
+
+ private Map readTemplates() throws FileNotFoundException {
+ Map templates = new HashMap();
+
+ String[] templateFiles = TEMPLATE_FILES.split(",");
+ for (int i = 0; i < templateFiles.length; i++) {
+ if(!StringUtils.isEmpty(templateFiles[i])) {
+ InputStream inputStream = null;
+ File f = new File(JMeterUtils.getJMeterHome(),
+ templateFiles[i]);
+ try {
+ if(f.exists() && f.canRead()) {
+ log.info("Reading templates from:"+f.getAbsolutePath());
+ inputStream = new BufferedInputStream(new FileInputStream(f));
+
+ templates.putAll(((Templates) xstream.fromXML(inputStream)).templates);
+ } else {
+ log.warn("Ignoring template file:'"+f.getAbsolutePath()+"' as it does not exist or is not readable");
+ }
+ } catch(Exception ex) {
+ log.warn("Ignoring template file:'"+f.getAbsolutePath()+"', an error occured parsing the file", ex);
+ } finally {
+ JOrphanUtils.closeQuietly(inputStream);
+ }
+ }
+ }
+ return templates;
+ }
+
+ /**
+ * @param selectedTemplate Template name
+ * @return {@link Template}
+ */
+ public Template getTemplateByName(String selectedTemplate) {
+ return templates.get(selectedTemplate);
+ }
+}
diff --git a/src/core/org/apache/jmeter/gui/util/JMeterMenuBar.java b/src/core/org/apache/jmeter/gui/util/JMeterMenuBar.java
index 9d460ed370..855fdd7d48 100644
--- a/src/core/org/apache/jmeter/gui/util/JMeterMenuBar.java
+++ b/src/core/org/apache/jmeter/gui/util/JMeterMenuBar.java
@@ -66,6 +66,8 @@ public class JMeterMenuBar extends JMenuBar implements LocaleChangeListener {
private JMenuItem file_load;
+ private JMenuItem create_from_template;
+
private List file_load_recent_files;
private JMenuItem file_merge;
@@ -460,6 +462,9 @@ public class JMeterMenuBar extends JMenuBar implements LocaleChangeListener {
// is selected is ROOT, which does not allow items to be inserted.
file_load.setEnabled(false);
+ create_from_template = makeMenuItemRes("create_from_template", 'T', ActionNames.CREATE_FROM_TEMPLATE); //$NON-NLS-1$
+ create_from_template.setEnabled(true);
+
file_close = makeMenuItemRes("menu_close", 'C', ActionNames.CLOSE, KeyStrokes.CLOSE); //$NON-NLS-1$
file_exit = makeMenuItemRes("exit", 'X', ActionNames.EXIT, KeyStrokes.EXIT); //$NON-NLS-1$
@@ -473,6 +478,7 @@ public class JMeterMenuBar extends JMenuBar implements LocaleChangeListener {
fileMenu.add(file_close);
fileMenu.add(file_load);
+ fileMenu.add(create_from_template);
fileMenu.add(file_merge);
fileMenu.addSeparator();
fileMenu.add(file_save);
diff --git a/src/core/org/apache/jmeter/resources/messages.properties b/src/core/org/apache/jmeter/resources/messages.properties
index 12aca6ca8b..e0b7e85936 100644
--- a/src/core/org/apache/jmeter/resources/messages.properties
+++ b/src/core/org/apache/jmeter/resources/messages.properties
@@ -206,6 +206,7 @@ counter_config_title=Counter
counter_per_user=Track counter independently for each user
counter_reset_per_tg_iteration=Reset counter on each Thread Group Iteration
countlim=Size limit
+create_from_template=New from templates
csvread_file_file_name=CSV file to get values from | *alias
cut=Cut
cut_paste_function=Copy and paste function string
@@ -1042,7 +1043,10 @@ tcp_request_data=Text to send
tcp_sample_title=TCP Sampler
tcp_timeout=Timeout (milliseconds)\:
teardown_on_shutdown=Run tearDown Thread Groups after shutdown of main threads
+template_choose=Select Template
+template_create_from=Create
template_field=Template\:
+template_title=Create from Template
test=Test
test_action_action=Action
test_action_duration=Duration (milliseconds)
diff --git a/src/core/org/apache/jmeter/resources/messages_fr.properties b/src/core/org/apache/jmeter/resources/messages_fr.properties
index f1a2bf642c..d589568756 100644
--- a/src/core/org/apache/jmeter/resources/messages_fr.properties
+++ b/src/core/org/apache/jmeter/resources/messages_fr.properties
@@ -194,6 +194,7 @@ counter_config_title=Compteur
counter_per_user=Suivre le compteur ind\u00E9pendamment pour chaque unit\u00E9 de test
counter_reset_per_tg_iteration=R\u00E9initialiser le compteur \u00E0 chaque it\u00E9ration du groupe d'unit\u00E9s
countlim=Limiter le nombre d'\u00E9l\u00E9ments retourn\u00E9s \u00E0
+create_from_template=Mod\u00E8les
cssjquery_attribute=Attribut
cssjquery_impl=Impl\u00E9mentation CSS/JQuery\:
cssjquery_render_no_text=Les donn\u00E9es de r\u00E9ponse ne sont pas du texte.
@@ -1035,7 +1036,10 @@ tcp_request_data=Texte \u00E0 envoyer \:
tcp_sample_title=Requ\u00EAte TCP
tcp_timeout=Expiration (millisecondes) \:
teardown_on_shutdown=Ex\u00E9cuter le Groupe d'unit\u00E9s de fin m\u00EAme apr\u00E8s un arr\u00EAt manuel des Groupes d'unit\u00E9s principaux
+template_choose=Choisir le mod\u00E8le
+template_create_from=Cr\u00E9er
template_field=Canevas \:
+template_title=Cr\u00E9er \u00E0 partir du mod\u00E8le
test=Test
test_action_action=Action \:
test_action_duration=Dur\u00E9e (millisecondes) \:
diff --git a/xdocs/changes.xml b/xdocs/changes.xml
index e99e4658b7..155c4f7602 100644
--- a/xdocs/changes.xml
+++ b/xdocs/changes.xml
@@ -217,6 +217,7 @@ Transaction Controller now sets Response Code of Generated Parent Sampler (if Ge
54864 - Enable multi selection drag & drop in the tree without having to start dragging before releasing Shift or Control
54945 - Add Shutdown Hook to enable trapping kill or CTRL+C signals
54990 - Download large files avoiding outOfMemory
+55085 - UX Improvement : Ability to create New Test Plan from Templates
Non-functional changes