package au.com.vaadinutils.fields; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.vaadin.data.Item; import com.vaadin.data.Property; import com.vaadin.ui.Table; /** * A simple class designed to display a PoJo in a table * * By default each of the public getters are displayed in order as a column. * * You can pass in a set of visible columns where the names correspond to the * getters name. * * @author bsutton * */ public class PoJoTable<T> extends Table { private static final long serialVersionUID = 1L; transient Logger logger = LogManager.getLogger(PoJoTable.class); private Class<T> pojoClass; private ArrayList<Column> columns; private String[] visibleColumns; public PoJoTable() { } /** * @param clazz * the class of the Pojo that is to be displayed. * @param visibleColumns * the list of columns from the pojo (getters) that are to be * displayed. */ public PoJoTable(Class<T> clazz, String[] visibleColumns) { this.pojoClass = clazz; this.visibleColumns = visibleColumns; initColumns(); } public void addRow(T pojo) { Item item = this.getItem(pojo); // If the same item is sent again we just update it. if (item == null) item = this.addItem(pojo); for (Column column : columns) { try { @SuppressWarnings("unchecked") Property<Object> property = item.getItemProperty(column.name); property.setValue(column.getValue(pojo)); } catch (RuntimeException e) { logger.error(e, e); throw e; } } } private void initColumns() { Class<T> objClass = this.pojoClass; columns = new ArrayList<Column>(); // Get the public methods associated with this class. Method[] methods = objClass.getMethods(); for (Method method : methods) { String name = method.getName(); if (name.startsWith("get") || name.startsWith("is")) { Column column = new Column(method); if (this.visibleColumns == null || isVisible(column)) { columns.add(column); this.addContainerProperty(column.name, column.type, null); } } } if (columns.size() == 0) throw new IllegalArgumentException("The PoJo class does not have any public getters."); // check all of the visible columsn are available. if (columns.size() != visibleColumns.length) { for (String visible : visibleColumns) { boolean found = false; for (Column column : columns) { if (column.name.equals(visible)) { found = true; break; } } if (found == false) { throw new IllegalArgumentException("The getter was not found for the required visible column " + visible + "."); } } } } private boolean isVisible(Column column) { boolean isVisible = false; for (String name : visibleColumns) { if (column.getName().equals(name)) isVisible = true; } return isVisible; } class Column { private String name; private Method method; private Class<?> type; public Column(Method method) { this.method = method; String getterName = method.getName(); if (getterName.startsWith("get")) { this.name = getterName.substring(3); } else { // must be is this.name = getterName.substring(2); } this.type = method.getReturnType(); } public Object getName() { return name; } public Object getValue(T pojo) { Object ret = null; try { ret = method.invoke(pojo); } catch (IllegalAccessException e) { logger.error(e, e); } catch (InvocationTargetException e) { logger.error(e, e); } catch (IllegalArgumentException e) { logger.error(e, e); } return ret; } } }