/*
* SoapUI, Copyright (C) 2004-2016 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/
package com.eviware.soapui.support.components;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.support.PropertyChangeNotifier;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.components.JPropertiesTable.PropertyDescriptor;
import com.eviware.soapui.support.components.JPropertiesTable.PropertyFormatter;
import com.eviware.soapui.support.swing.JTableFactory;
import org.apache.commons.beanutils.PropertyUtils;
import org.jdesktop.swingx.JXTable;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
/**
* Table for displaying property name/value pairs
*/
@SuppressWarnings("serial")
public class JDebugPropertiesTable<T> {
public final static Object[] BOOLEAN_OPTIONS = new Object[]{Boolean.TRUE, Boolean.FALSE};
private PropertiesTableModel<T> tableModel;
private JXTable table;
public JDebugPropertiesTable(T propertyObject) {
tableModel = new PropertiesTableModel<T>(propertyObject);
table = new PTable(tableModel);
table.getColumnModel().getColumn(0).setHeaderValue("Property");
table.getColumnModel().getColumn(1).setHeaderValue("Value");
table.getColumnModel().getColumn(0).setCellRenderer(new PropertiesTableCellRenderer());
table.getColumnModel().getColumn(1).setCellRenderer(new PropertiesTableCellRenderer());
table.setBackground(Color.WHITE);
}
public void removeNotify() {
getTableModel().release();
table.removeNotify();
}
public void addNotify() {
getTableModel().attach();
table.addNotify();
}
public void setPropertyObject(T propertyObject) {
tableModel.setPropertyObject(propertyObject);
}
public PropertiesTableModel<?> getTableModel() {
return tableModel;
}
public PropertyDescriptor addProperty(String caption, String name) {
return addProperty(caption, name, false);
}
public PropertyDescriptor addProperty(String caption, String name, boolean editable) {
return addProperty(caption, name, editable, null);
}
public PropertyDescriptor addProperty(String caption, String name, boolean editable, PropertyFormatter formatter) {
return tableModel.addProperty(caption, name, editable, formatter);
}
public static final class PropertiesTableModel<T> extends AbstractTableModel implements PropertyChangeListener {
private List<PropertyDescriptor> properties = new ArrayList<PropertyDescriptor>();
private T propertyObject;
private boolean attached;
public PropertiesTableModel(T propertyObject) {
this.propertyObject = propertyObject;
}
public void attach() {
if (!attached && propertyObject instanceof PropertyChangeNotifier) {
((PropertyChangeNotifier) propertyObject).addPropertyChangeListener(this);
attached = true;
}
}
public void setPropertyObject(T propertyObject) {
release();
this.propertyObject = propertyObject;
attach();
fireTableDataChanged();
}
public PropertyDescriptor addProperty(String caption, String name, boolean editable, PropertyFormatter formatter) {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(caption, name, editable, formatter);
properties.add(propertyDescriptor);
return propertyDescriptor;
}
public PropertyDescriptor addProperty(String caption, String name, Object[] options) {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(caption, name, options);
properties.add(propertyDescriptor);
fireTableStructureChanged();
return propertyDescriptor;
}
public int getRowCount() {
return properties.size();
}
public int getColumnCount() {
return 2;
}
public Object getValueAt(int rowIndex, int columnIndex) {
if (propertyObject == null) {
return null;
}
try {
PropertyDescriptor propertyDescriptor = properties.get(rowIndex);
switch (columnIndex) {
case 0:
return propertyDescriptor.getCaption();
case 1: {
Object value = PropertyUtils.getSimpleProperty(propertyObject, propertyDescriptor.getName());
return propertyDescriptor.getFormatter().format(propertyDescriptor.getName(), value);
}
}
} catch (IllegalAccessException e) {
SoapUI.logError(e);
} catch (InvocationTargetException e) {
SoapUI.logError(e);
} catch (NoSuchMethodException e) {
SoapUI.logError(e);
}
return null;
}
public PropertyDescriptor getPropertyDescriptorAt(int row) {
return properties.get(row);
}
public void propertyChange(PropertyChangeEvent evt) {
fireTableDataChanged();
}
public void release() {
if (propertyObject instanceof PropertyChangeNotifier && attached) {
((PropertyChangeNotifier) propertyObject).removePropertyChangeListener(this);
attached = false;
}
}
public PropertyDescriptor addPropertyShadow(String caption, String name, boolean editable) {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(caption, name, editable);
properties.add(propertyDescriptor);
return propertyDescriptor;
}
}
private class PropertiesTableCellRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
JLabel component = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
component.setToolTipText(value.toString());
Font newLabelFont = new Font(component.getFont().getName(), Font.BOLD, component.getFont().getSize());
component.setFont(newLabelFont);
return component;
}
}
public PropertyDescriptor addProperty(String caption, String name, Object[] options) {
return tableModel.addProperty(caption, name, options);
}
private class PTable extends JXTable {
public PTable(TableModel tableModel) {
super(tableModel);
if (UISupport.isMac()) {
JTableFactory.setGridAttributes(this);
}
}
public TableCellEditor getCellEditor(int row, int column) {
if (column == 0) {
return super.getCellEditor(row, column);
} else {
return tableModel.getPropertyDescriptorAt(row).getCellEditor();
}
}
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component defaultRenderer = super.prepareRenderer(renderer, row, column);
JTableFactory.applyStripesToRenderer(row, defaultRenderer);
return defaultRenderer;
}
@Override
public boolean getShowVerticalLines() {
return UISupport.isMac() ? false : super.getShowVerticalLines();
}
}
public PropertyDescriptor addPropertyShadow(String caption, String name, boolean editable) {
return tableModel.addPropertyShadow(caption, name, editable);
}
public JTable getTable() {
return table;
}
}