New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Copying Test Elements between test plans #2199
Comments
Roman Bargezi (migrated from Bugzilla): The patch does not address the DnD across instances. Created attachment Enh46677_CopyPasteAccrossInstances.patch: Proposed enhancement as patch to build revision 1196526 of JMeter Enh46677_CopyPasteAccrossInstances.patchIndex: src/core/org/apache/jmeter/gui/action/Copy.java
===================================================================
--- src/core/org/apache/jmeter/gui/action/Copy.java (revision 1197485)
+++ src/core/org/apache/jmeter/gui/action/Copy.java (working copy)
@@ -23,24 +23,29 @@
*/
package org.apache.jmeter.gui.action;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
import java.awt.event.ActionEvent;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
+import javax.swing.JOptionPane;
+
import org.apache.jmeter.gui.GuiPackage;
import org.apache.jmeter.gui.tree.JMeterTreeListener;
import org.apache.jmeter.gui.tree.JMeterTreeNode;
import org.apache.jmeter.testelement.TestElement;
+import org.apache.jmeter.util.JMeterTreeNodeTransferable;
+import org.apache.jmeter.util.JMeterUtils;
/**
* Implements the Copy menu command
*/
public class Copy extends AbstractAction {
+
private static JMeterTreeNode copiedNode = null;
- private static JMeterTreeNode copiedNodes[] = null;
-
private static final HashSet<String> commands = new HashSet<String>();
static {
@@ -63,15 +68,15 @@
}
public static JMeterTreeNode[] getCopiedNodes() {
- if (copiedNodes == null) { // can be null if Copy has yet to be used
- return null;
- }
- for (int i = 0; i < copiedNodes.length; i++) {
- if (copiedNodes[i] == null) {
- return null;
+ Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+ if(clipboard.isDataFlavorAvailable(JMeterTreeNodeTransferable.JMETER_TREE_NODE_ARRAY_DATA_FLAVOR)) {
+ try {
+ return (JMeterTreeNode[]) clipboard.getData(JMeterTreeNodeTransferable.JMETER_TREE_NODE_ARRAY_DATA_FLAVOR);
+ } catch (Exception ex) {
+ JOptionPane.showMessageDialog(GuiPackage.getInstance().getMainFrame(), JMeterUtils.getResString("clipboard_node_read_error")+":\n" + ex.getLocalizedMessage(), JMeterUtils.getResString("error_title"), JOptionPane.ERROR_MESSAGE);
}
}
- return cloneTreeNodes(copiedNodes);
+ return null;
}
public static JMeterTreeNode getCopiedNode() {
@@ -93,9 +98,13 @@
}
public static void setCopiedNodes(JMeterTreeNode nodes[]) {
- copiedNodes = new JMeterTreeNode[nodes.length];
- for (int i = 0; i < nodes.length; i++) {
- copiedNodes[i] = cloneTreeNode(nodes[i]);
+ Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+ try {
+ JMeterTreeNodeTransferable transferable = new JMeterTreeNodeTransferable();
+ transferable.setTransferData(nodes);
+ clipboard.setContents(transferable, null);
+ } catch (Exception ex) {
+ JOptionPane.showMessageDialog(GuiPackage.getInstance().getMainFrame(), JMeterUtils.getResString("clipboard_node_read_error")+":\n" + ex.getLocalizedMessage(), JMeterUtils.getResString("error_title"), JOptionPane.ERROR_MESSAGE);
}
}
Index: src/core/org/apache/jmeter/resources/messages.properties
===================================================================
--- src/core/org/apache/jmeter/resources/messages.properties (revision 1197485)
+++ src/core/org/apache/jmeter/resources/messages.properties (working copy)
@@ -125,6 +125,8 @@
clear_all=Clear All
clear_cache_per_iter=Clear cache each iteration?
clear_cookies_per_iter=Clear cookies each iteration?
+clipboard_node_read_error=Error retrieving nodes from clipboard
+clipboard_node_write_error=Error coping nodes to clipboard
column_delete_disallowed=Deleting this column is not permitted
column_number=Column number of CSV file | next | *alias
compare=Compare
Index: src/core/org/apache/jmeter/util/JMeterTreeNodeTransferable.java
===================================================================
--- src/core/org/apache/jmeter/util/JMeterTreeNodeTransferable.java (revision 0)
+++ src/core/org/apache/jmeter/util/JMeterTreeNodeTransferable.java (revision 0)
@@ -0,0 +1,68 @@
+package org.apache.jmeter.util;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.jmeter.gui.tree.JMeterTreeNode;
+
+/**
+ * Simple implementation of a transferable for {@link JMeterTreeNode} arrays based on serialization.
+ */
+public class JMeterTreeNodeTransferable implements Transferable {
+
+ private static final long serialVersionUID = 192L;
+
+ public final static DataFlavor JMETER_TREE_NODE_ARRAY_DATA_FLAVOR = new DataFlavor(JMeterTreeNode[].class, JMeterTreeNode[].class.getName());
+
+ private final static DataFlavor[] DATA_FLAVORS = new DataFlavor[]{JMETER_TREE_NODE_ARRAY_DATA_FLAVOR};
+
+ private byte[] data = null;
+
+ @Override
+ public DataFlavor[] getTransferDataFlavors() {
+ return DATA_FLAVORS;
+ }
+
+ @Override
+ public boolean isDataFlavorSupported(DataFlavor flavor) {
+ return flavor.match(JMETER_TREE_NODE_ARRAY_DATA_FLAVOR);
+ }
+
+ @Override
+ public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
+ if(!isDataFlavorSupported(flavor)) {
+ throw new UnsupportedFlavorException(flavor);
+ }
+ if(data != null) {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ObjectInput ois = new ObjectInputStream(bis);
+ try {
+ JMeterTreeNode[] nodes = (JMeterTreeNode[]) ois.readObject();
+ return nodes;
+ } catch (ClassNotFoundException cnfe) {
+ throw new IOException("Failed to read object stream.", cnfe);
+ } finally {
+ ois.close();
+ bis.close();
+ }
+ }
+ return null;
+ }
+
+ public void setTransferData(JMeterTreeNode[] nodes) throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(nodes);
+ oos.close();
+ bos.close();
+ data = bos.toByteArray();
+ }
+
+} |
@pmouawad (migrated from Bugzilla):
while it is working OK with Menu Copy/paste. Can you check if you have the same behaviour under Windows ? Another point, it makes hypothesis all JMeterTreeNode userdata are Serializable, not sure it is always the case. |
Roman Bargezi (migrated from Bugzilla): |
@pmouawad (migrated from Bugzilla): There remains an issue on ModuleController where reference is not pasted correctly. Patch needs upgrade to JDK6. Created attachment BUG_46677.patch: Updated patch BUG_46677.patchIndex: src/core/org/apache/jmeter/util/JMeterTreeNodeTransferable.java
===================================================================
--- src/core/org/apache/jmeter/util/JMeterTreeNodeTransferable.java (revision 0)
+++ src/core/org/apache/jmeter/util/JMeterTreeNodeTransferable.java (revision 0)
@@ -0,0 +1,96 @@
+/*
+ * 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.util;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.jmeter.gui.tree.JMeterTreeNode;
+
+/**
+ * Simple implementation of a transferable for {@link JMeterTreeNode} arrays based on serialization.
+ */
+public class JMeterTreeNodeTransferable implements Transferable {
+
+ public final static DataFlavor JMETER_TREE_NODE_ARRAY_DATA_FLAVOR = new DataFlavor(JMeterTreeNode[].class, JMeterTreeNode[].class.getName());
+
+ private final static DataFlavor[] DATA_FLAVORS = new DataFlavor[]{JMETER_TREE_NODE_ARRAY_DATA_FLAVOR};
+
+ private byte[] data = null;
+
+ @Override
+ public DataFlavor[] getTransferDataFlavors() {
+ return DATA_FLAVORS;
+ }
+
+ @Override
+ public boolean isDataFlavorSupported(DataFlavor flavor) {
+ return flavor.match(JMETER_TREE_NODE_ARRAY_DATA_FLAVOR);
+ }
+
+ @Override
+ public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
+ if(!isDataFlavorSupported(flavor)) {
+ throw new UnsupportedFlavorException(flavor);
+ }
+ if(data != null) {
+ ObjectInput ois = null;
+ try {
+ ois = new ObjectInputStream(new ByteArrayInputStream(data));
+ JMeterTreeNode[] nodes = (JMeterTreeNode[]) ois.readObject();
+ return nodes;
+ } catch (ClassNotFoundException cnfe) {
+ throw new IOException("Failed to read object stream.", cnfe);
+ } finally {
+ if(ois != null) {
+ try {
+ ois.close();
+ } catch (Exception e) {
+ // NOOP
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public void setTransferData(JMeterTreeNode[] nodes) throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = null;
+ try {
+ oos = new ObjectOutputStream(bos);
+ oos.writeObject(nodes);
+ data = bos.toByteArray();
+ } finally {
+ if(oos != null) {
+ try {
+ oos.close();
+ } catch (Exception e) {
+ // NOOP
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Index: src/core/org/apache/jmeter/gui/action/Copy.java
===================================================================
--- src/core/org/apache/jmeter/gui/action/Copy.java (revision 1392846)
+++ src/core/org/apache/jmeter/gui/action/Copy.java (working copy)
@@ -23,24 +23,27 @@
*/
package org.apache.jmeter.gui.action;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
import java.awt.event.ActionEvent;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
+import javax.swing.JOptionPane;
+
import org.apache.jmeter.gui.GuiPackage;
import org.apache.jmeter.gui.tree.JMeterTreeListener;
import org.apache.jmeter.gui.tree.JMeterTreeNode;
import org.apache.jmeter.testelement.TestElement;
+import org.apache.jmeter.util.JMeterTreeNodeTransferable;
+import org.apache.jmeter.util.JMeterUtils;
/**
* Implements the Copy menu command
*/
public class Copy extends AbstractAction {
- private static JMeterTreeNode copiedNode = null;
-
- private static JMeterTreeNode copiedNodes[] = null;
-
+
private static final HashSet<String> commands = new HashSet<String>();
static {
@@ -63,26 +66,16 @@
}
public static JMeterTreeNode[] getCopiedNodes() {
- if (copiedNodes == null) { // can be null if Copy has yet to be used
- return null;
- }
- for (int i = 0; i < copiedNodes.length; i++) {
- if (copiedNodes[i] == null) {
- return null;
+
+ Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+ if(clipboard.isDataFlavorAvailable(JMeterTreeNodeTransferable.JMETER_TREE_NODE_ARRAY_DATA_FLAVOR)) {
+ try {
+ return (JMeterTreeNode[]) clipboard.getData(JMeterTreeNodeTransferable.JMETER_TREE_NODE_ARRAY_DATA_FLAVOR);
+ } catch (Exception ex) {
+ JOptionPane.showMessageDialog(GuiPackage.getInstance().getMainFrame(), JMeterUtils.getResString("clipboard_node_read_error")+":\n" + ex.getLocalizedMessage(), JMeterUtils.getResString("error_title"), JOptionPane.ERROR_MESSAGE);
}
}
- return cloneTreeNodes(copiedNodes);
- }
-
- public static JMeterTreeNode getCopiedNode() {
- if (copiedNode == null) {
- return null;
- }
- return cloneTreeNode(copiedNode);
- }
-
- public static void setCopiedNode(JMeterTreeNode node) {
- copiedNode = cloneTreeNode(node);
+ return null;
}
public static JMeterTreeNode cloneTreeNode(JMeterTreeNode node) {
@@ -93,9 +86,13 @@
}
public static void setCopiedNodes(JMeterTreeNode nodes[]) {
- copiedNodes = new JMeterTreeNode[nodes.length];
- for (int i = 0; i < nodes.length; i++) {
- copiedNodes[i] = cloneTreeNode(nodes[i]);
+ Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+ try {
+ JMeterTreeNodeTransferable transferable = new JMeterTreeNodeTransferable();
+ transferable.setTransferData(nodes);
+ clipboard.setContents(transferable, null);
+ } catch (Exception ex) {
+ JOptionPane.showMessageDialog(GuiPackage.getInstance().getMainFrame(), JMeterUtils.getResString("clipboard_node_read_error")+":\n" + ex.getLocalizedMessage(), JMeterUtils.getResString("error_title"), JOptionPane.ERROR_MESSAGE);
}
}
|
@pmouawad (migrated from Bugzilla): Are you OK with this ? Thanks |
Sebb (migrated from Bugzilla):
Those are questions for the dev list, rather than here.
|
@pmouawad (migrated from Bugzilla): URL: http://svn.apache.org/viewvc?rev=1413259&view=rev Added: |
Noel O'Brien (Bug 46677):
I suggest the following enhancements to JMeter to make test element copying more seamless and more straightforward:
Enable test elements to be left in the Workspace between the loading of test plans, this will allow users to copy elements between test plans.
Enable drag & drop and copy/paste between separate instances of JMeter.
Votes in Bugzilla: 1
OS: All
Duplicates:
The text was updated successfully, but these errors were encountered: