You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jmeter-dev@jakarta.apache.org by se...@apache.org on 2009/09/07 22:55:40 UTC
svn commit: r812274 - in /jakarta/jmeter/trunk:
src/core/org/apache/jmeter/testbeans/
src/core/org/apache/jmeter/testbeans/gui/
src/jorphan/org/apache/jorphan/gui/ xdocs/
Author: sebb
Date: Mon Sep 7 20:55:39 2009
New Revision: 812274
URL: http://svn.apache.org/viewvc?rev=812274&view=rev
Log:
Add TestBean Table Editor support.
[code copied from branches/java1.5_prototype-was_trunk]
Added:
jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TableEditor.java (with props)
jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TestBeanPropertyEditor.java (with props)
Modified:
jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/BeanInfoSupport.java
jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/TestBeanHelper.java
jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/GenericTestBeanCustomizer.java
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/gui/ObjectTableModel.java
jakarta/jmeter/trunk/xdocs/changes.xml
Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/BeanInfoSupport.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/BeanInfoSupport.java?rev=812274&r1=812273&r2=812274&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/BeanInfoSupport.java (original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/BeanInfoSupport.java Mon Sep 7 20:55:39 2009
@@ -72,6 +72,8 @@
public static final String NOT_OTHER = GenericTestBeanCustomizer.NOT_OTHER;
+ public static final String MULTILINE = "multiline";
+
public static final String DEFAULT = GenericTestBeanCustomizer.DEFAULT;
public static final String RESOURCE_BUNDLE = GenericTestBeanCustomizer.RESOURCE_BUNDLE;
Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/TestBeanHelper.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/TestBeanHelper.java?rev=812274&r1=812273&r2=812274&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/TestBeanHelper.java (original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/TestBeanHelper.java Mon Sep 7 20:55:39 2009
@@ -22,9 +22,16 @@
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.LinkedList;
+import org.apache.jmeter.testbeans.gui.TableEditor;
import org.apache.jmeter.testelement.TestElement;
+import org.apache.jmeter.testelement.property.CollectionProperty;
import org.apache.jmeter.testelement.property.JMeterProperty;
+import org.apache.jmeter.testelement.property.MultiProperty;
+import org.apache.jmeter.testelement.property.PropertyIterator;
+import org.apache.jmeter.testelement.property.TestElementProperty;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.jorphan.util.Converter;
import org.apache.log.Logger;
@@ -67,7 +74,7 @@
// Obtain a value of the appropriate type for this property.
JMeterProperty jprop = el.getProperty(desc[x].getName());
Class<?> type = desc[x].getPropertyType();
- Object value = Converter.convert(jprop.getStringValue(), type);
+ Object value = unwrapProperty(desc[x], jprop, type);
if (log.isDebugEnabled()) {
log.debug("Setting " + jprop.getName() + "=" + value);
@@ -90,6 +97,54 @@
}
/**
+ * @param desc
+ * @param x
+ * @param jprop
+ * @param type
+ * @return
+ */
+ private static Object unwrapProperty(PropertyDescriptor desc, JMeterProperty jprop, Class<?> type) {
+ Object value;
+ if(jprop instanceof TestElementProperty)
+ {
+ TestElement te = ((TestElementProperty)jprop).getElement();
+ if(te instanceof TestBean)
+ {
+ prepare(te);
+ }
+ value = te;
+ }
+ else if(jprop instanceof MultiProperty)
+ {
+ value = unwrapCollection((MultiProperty)jprop,(String)desc.getValue(TableEditor.CLASSNAME));
+ }
+ else value = Converter.convert(jprop.getStringValue(), type);
+ return value;
+ }
+
+ private static Object unwrapCollection(MultiProperty prop,String type)
+ {
+ if(prop instanceof CollectionProperty)
+ {
+ Collection<Object> values = new LinkedList<Object>();
+ PropertyIterator iter = prop.iterator();
+ while(iter.hasNext())
+ {
+ try
+ {
+ values.add(unwrapProperty(null,iter.next(),Class.forName(type)));
+ }
+ catch(Exception e)
+ {
+ log.error("Couldn't convert object: " + prop.getObjectValue() + " to " + type,e);
+ }
+ }
+ return values;
+ }
+ return null;
+ }
+
+ /**
* Utility method that invokes a method and does the error handling around
* the invocation.
*
@@ -101,7 +156,7 @@
try {
return method.invoke(invokee, params);
} catch (IllegalArgumentException e) {
- log.error("This should never happen.", e);
+ log.error("This should never happen. "+invokee.getClass().getName()+" "+method.getName()+" "+params.length+" "+params[0].getClass().getName(), e);
throw new Error(e.toString()); // Programming error: bail out.
} catch (IllegalAccessException e) {
log.error("This should never happen.", e);
Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/GenericTestBeanCustomizer.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/GenericTestBeanCustomizer.java?rev=812274&r1=812273&r2=812274&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/GenericTestBeanCustomizer.java (original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/GenericTestBeanCustomizer.java Mon Sep 7 20:55:39 2009
@@ -220,6 +220,10 @@
log.debug("Editor for property " + name + " is wrapped in " + propertyEditor);
}
}
+ if(propertyEditor instanceof TestBeanPropertyEditor)
+ {
+ ((TestBeanPropertyEditor)propertyEditor).setDescriptor(descriptors[i]);
+ }
if (propertyEditor.getCustomEditor() instanceof JScrollPane) {
scrollerCount++;
}
Added: jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TableEditor.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TableEditor.java?rev=812274&view=auto
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TableEditor.java (added)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TableEditor.java Mon Sep 7 20:55:39 2009
@@ -0,0 +1,268 @@
+/*
+ * 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.testbeans.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.beans.PropertyDescriptor;
+import java.beans.PropertyEditorSupport;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.swing.CellEditor;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+
+import org.apache.jmeter.testelement.property.TestElementProperty;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.gui.ObjectTableModel;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.jorphan.reflect.Functor;
+import org.apache.log.Logger;
+
+public class TableEditor extends PropertyEditorSupport implements FocusListener,TestBeanPropertyEditor,TableModelListener {
+ private static final Logger log = LoggingManager.getLoggerForClass();
+
+ public static final String CLASSNAME = "tableObject.classname"; // $NON-NLS-1$
+ public static final String HEADERS = "table.headers"; // $NON-NLS-1$
+ public static final String OBJECT_PROPERTIES = "tableObject.properties"; // $NON-NLS-1$
+
+ private JTable table;
+ private ObjectTableModel model;
+ private Class<?> clazz;
+ private PropertyDescriptor descriptor;
+ private final JButton addButton,removeButton,clearButton;
+
+ public TableEditor() {
+ addButton = new JButton(JMeterUtils.getResString("add")); // $NON-NLS-1$
+ addButton.addActionListener(new AddListener());
+ removeButton = new JButton(JMeterUtils.getResString("remove")); // $NON-NLS-1$
+ removeButton.addActionListener(new RemoveListener());
+ clearButton = new JButton(JMeterUtils.getResString("clear")); // $NON-NLS-1$
+ clearButton.addActionListener(new ClearListener());
+ }
+
+ @Override
+ public String getAsText() {
+ return null;
+ }
+
+ @Override
+ public Component getCustomEditor() {
+ JComponent pane = makePanel();
+ pane.doLayout();
+ pane.validate();
+ return pane;
+ }
+
+ private JComponent makePanel()
+ {
+ JPanel p = new JPanel(new BorderLayout());
+ JScrollPane scroller = new JScrollPane(table);
+ scroller.setPreferredSize(scroller.getMinimumSize());
+ p.add(scroller,BorderLayout.CENTER);
+ JPanel south = new JPanel();
+ south.add(addButton);
+ south.add(removeButton);
+ south.add(clearButton);
+ p.add(south,BorderLayout.SOUTH);
+ return p;
+ }
+
+ @Override
+ public Object getValue() {
+ return model.getObjectList();
+ }
+
+ @Override
+ public void setAsText(String text) throws IllegalArgumentException {
+ //not interested in this method.
+ }
+
+ @Override
+ public void setValue(Object value) {
+ if(value != null)
+ {
+ model.setRows(convertCollection((Collection<?>)value));
+ }
+ else model.clearData();
+ this.firePropertyChange();
+ }
+
+ private Collection<Object> convertCollection(Collection<?> values)
+ {
+ List<Object> l = new LinkedList<Object>();
+ for(Object obj : values)
+ {
+ if(obj instanceof TestElementProperty)
+ {
+ l.add(((TestElementProperty)obj).getElement());
+ }
+ else
+ {
+ l.add(obj);
+ }
+ }
+ return l;
+ }
+
+ @Override
+ public boolean supportsCustomEditor() {
+ return true;
+ }
+
+ /**
+ * For the table editor, the tag must simply be the name of the class of object it will hold
+ * where each row holds one object.
+ */
+ public void setDescriptor(PropertyDescriptor descriptor) {
+ try {
+ this.descriptor = descriptor;
+ clazz = Class.forName((String)descriptor.getValue(CLASSNAME));
+ initializeModel();
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("The Table Editor requires one TAG be set - the name of the object to represent a row",e);
+ }
+ }
+
+ void initializeModel()
+ {
+ if(clazz == String.class)
+ {
+ model = new ObjectTableModel((String[])descriptor.getValue(HEADERS),new Functor[0],new Functor[0],new Class[]{String.class});
+ model.addTableModelListener(this);
+ }
+ else
+ {
+ String[] props = (String[])descriptor.getValue(OBJECT_PROPERTIES);
+ Functor[] writers = new Functor[props.length];
+ Functor[] readers = new Functor[props.length];
+ Class<?>[] editors = new Class[props.length];
+ int count = 0;
+ for(String propName : props)
+ {
+ propName = propName.substring(0,1).toUpperCase() + propName.substring(1);
+ writers[count] = createWriter(clazz,propName);
+ readers[count] = createReader(clazz,propName);
+ editors[count] = getArgForWriter(clazz,propName);
+ count++;
+ }
+ model = new ObjectTableModel((String[])descriptor.getValue(HEADERS),readers,writers,editors);
+ model.addTableModelListener(this);
+ }
+ table = new JTable(model);
+ table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ table.addFocusListener(this);
+ }
+
+ Functor createWriter(Class<?> c,String propName)
+ {
+ String setter = "set" + propName; // $NON-NLS-1$
+ return new Functor(setter);
+ }
+
+ Functor createReader(Class<?> c,String propName)
+ {
+ String getter = "get" + propName; // $NON-NLS-1$
+ try
+ {
+ c.getMethod(getter,new Class[0]);
+ return new Functor(getter);
+ }
+ catch(Exception e) { return new Functor("is" + propName); }
+ }
+
+ Class<?> getArgForWriter(Class<?> c,String propName)
+ {
+ String setter = "set" + propName; // $NON-NLS-1$
+ for(Method m : c.getMethods())
+ {
+ if(m.getName().equals(setter))
+ {
+ return m.getParameterTypes()[0];
+ }
+ }
+ return null;
+ }
+
+ public void tableChanged(TableModelEvent e) {
+ this.firePropertyChange();
+ }
+
+ public void focusGained(FocusEvent e) {
+
+ }
+
+ public void focusLost(FocusEvent e) {
+ CellEditor ce = table.getCellEditor(table.getEditingRow(),table.getEditingColumn());
+ Component editor = table.getEditorComponent();
+ if(ce != null && (editor == null || editor != e.getOppositeComponent()))
+ {
+ ce.stopCellEditing();
+ }
+ else if(editor != null)
+ {
+ editor.addFocusListener(this);
+ }
+ this.firePropertyChange();
+ }
+
+ private class AddListener implements ActionListener
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ try
+ {
+ model.addRow(clazz.newInstance());
+ }catch(Exception err)
+ {
+ log.error("The class type given to TableEditor was not instantiable. ",err);
+ }
+ }
+ }
+
+ private class RemoveListener implements ActionListener
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ model.removeRow(table.getSelectedRow());
+ }
+ }
+
+ private class ClearListener implements ActionListener
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ model.clearData();
+ }
+ }
+
+}
Propchange: jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TableEditor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TableEditor.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TestBeanPropertyEditor.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TestBeanPropertyEditor.java?rev=812274&view=auto
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TestBeanPropertyEditor.java (added)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TestBeanPropertyEditor.java Mon Sep 7 20:55:39 2009
@@ -0,0 +1,28 @@
+/*
+ * 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.testbeans.gui;
+
+import java.beans.PropertyDescriptor;
+import java.beans.PropertyEditor;
+
+public interface TestBeanPropertyEditor extends PropertyEditor {
+
+ public void setDescriptor(PropertyDescriptor descriptor);
+
+}
Propchange: jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TestBeanPropertyEditor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/jmeter/trunk/src/core/org/apache/jmeter/testbeans/gui/TestBeanPropertyEditor.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified: jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/gui/ObjectTableModel.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/gui/ObjectTableModel.java?rev=812274&r1=812273&r2=812274&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/gui/ObjectTableModel.java (original)
+++ jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/gui/ObjectTableModel.java Mon Sep 7 20:55:39 2009
@@ -235,6 +235,7 @@
*
* @return false if at least one Functor cannot be found.
*/
+ @SuppressWarnings("deprecation")
public boolean checkFunctors(Object _value, Class<?> caller){
Object value;
if (_value == null && objectClass != null) {
@@ -270,4 +271,16 @@
}
return status;
}
+
+ public Object getObjectList() { // used by TableEditor
+ return objects;
+ }
+
+ public void setRows(Iterable<?> rows) { // used by TableEditor
+ clearData();
+ for(Object val : rows)
+ {
+ addRow(val);
+ }
+ }
}
Modified: jakarta/jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=812274&r1=812273&r2=812274&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/changes.xml (original)
+++ jakarta/jmeter/trunk/xdocs/changes.xml Mon Sep 7 20:55:39 2009
@@ -147,6 +147,7 @@
<h2>Non-functional changes</h2>
<ul>
+<li>Add TestBean Table Editor support</li>
</ul>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: jmeter-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jmeter-dev-help@jakarta.apache.org