/*********************************************************************** * This file is part of iDempiere ERP Open Source * * http://www.idempiere.org * * * * Copyright (C) Contributors * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * * MA 02110-1301, USA. * * * * Contributors: * * - hengsin * **********************************************************************/ package org.compiere.minigrid; import java.io.Serializable; import java.math.BigDecimal; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.compiere.apps.form.Match; import org.compiere.model.MRole; import org.compiere.model.PO; import org.compiere.util.KeyNamePair; /** * Headless implementation of {@link IMiniTable}.
* This support the use/test of some UI API (for e.g {@link Match} in headless environment (for e.g unit test). * @author hengsin * */ public class MiniTableImpl implements IMiniTable { /** Array of table details. */ private List m_tableColumns = new ArrayList(); private List> model = new ArrayList>(); private ColumnInfo[] m_layout; private int m_keyColumnIndex; private int m_selectedRow = -1; public MiniTableImpl() { } /** * @param layout */ public MiniTableImpl(ColumnInfo[] layout) { prepareTable(layout, null, null, false, null); } @Override public boolean isCellEditable(int row, int column) { return false; } @Override public Object getValueAt(int row, int column) { if (column < m_tableColumns.size()) { String columnName = m_tableColumns.get(column).getHeaderValue(); if (row < model.size()) { return model.get(row).get(columnName); } } return null; } @Override public void setValueAt(Object value, int row, int column) { if (column < m_tableColumns.size()) { String columnName = m_tableColumns.get(column).getHeaderValue(); if (row < model.size()) { model.get(row).put(columnName, value); } } } @Override public int convertColumnIndexToModel(int viewColumnIndex) { return viewColumnIndex; } @Override public void setColumnReadOnly(int index, boolean readOnly) { } @Override public String prepareTable(ColumnInfo[] layout, String from, String where, boolean multiSelection, String tableName) { m_layout = layout; m_tableColumns.clear(); model.clear(); StringBuilder sql = new StringBuilder ("SELECT "); for (int columnIndex = 0; columnIndex < layout.length; columnIndex++) { // create sql if (columnIndex > 0) { sql.append(", "); } sql.append(layout[columnIndex].getColSQL()); // adding ID column if (layout[columnIndex].isKeyPairCol()) { sql.append(",").append(layout[columnIndex].getKeyPairColSQL()); } addColumn(layout[columnIndex].getColHeader(), layout[columnIndex].getColDescription(), layout[columnIndex].getAD_Reference_ID(), layout[columnIndex].getColClass()); if (layout[columnIndex].getColClass() == IDColumn.class) { m_keyColumnIndex = columnIndex; } } sql.append( " FROM ").append(from); sql.append(" WHERE ").append(where); String finalSQL = MRole.getDefault().addAccessSQL(sql.toString(), tableName, MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO); return finalSQL; } @Override public void addColumn(String header) { addColumn(header, null, 0, null); } @Override public void setColumnClass(int index, Class classType, boolean readOnly, String header) { if (index < m_tableColumns.size()) { m_tableColumns.get(index).setColumnClass(classType); } } @Override public void setColumnClass(int index, Class classType, boolean readOnly) { if (index < m_tableColumns.size()) { m_tableColumns.get(index).setColumnClass(classType); } } @Override public void loadTable(ResultSet rs) { model.clear(); try { while (rs.next()) { Map row = new HashMap(); int rsColOffset = 1; for (int col = 0; col < m_layout.length; col++) { //reset the data value Object data = null; Class columnClass = m_layout[col].getColClass(); int rsColIndex = col + rsColOffset; if (columnClass == IDColumn.class) { data = new IDColumn(rs.getInt(rsColIndex)); } else if (columnClass == Boolean.class) { data = Boolean.valueOf(rs.getString(rsColIndex).equals("Y")); } else if (columnClass == Timestamp.class) { data = rs.getTimestamp(rsColIndex); } else if (columnClass == BigDecimal.class) { data = rs.getBigDecimal(rsColIndex); } else if (columnClass == Double.class) { data = Double.valueOf(rs.getDouble(rsColIndex)); } else if (columnClass == Integer.class) { data = Integer.valueOf(rs.getInt(rsColIndex)); } else if (columnClass == KeyNamePair.class) { String display = rs.getString(rsColIndex); int key = rs.getInt(rsColIndex + 1); data = new KeyNamePair(key, display); rsColOffset++; } else { String s = rs.getString(rsColIndex); if (s != null) { data = s.trim(); // problems with NCHAR } else { data=null; } } // store in underlying model row.put(m_tableColumns.get(col).headerValue, data); } model.add(row); } } catch (SQLException exception) { throw new RuntimeException(exception); } } @Override public void loadTable(PO[] pos) { model.clear(); for (int poIndex = 0; poIndex < pos.length; poIndex++) { PO myPO = pos[poIndex]; Map row = new HashMap(); for (int col = 0; col < m_layout.length; col++) { String columnName = m_layout[col].getColSQL(); Object data = myPO.get_Value(columnName); if (data != null) { Class columnClass = m_layout[col].getColClass(); if (columnClass == IDColumn.class) { data = new IDColumn(((Integer)data).intValue()); } else if (columnClass == Double.class) { data = Double.valueOf(((BigDecimal)data).doubleValue()); } } // store row.put(m_tableColumns.get(col).headerValue, data); } model.add(row); } } @Override public T getSelectedRowKey() { int row = getSelectedRow(); // make common function return getRowKeyAt (row); } /** * get key of record at index * @param index * @return */ @SuppressWarnings("unchecked") public T getRowKeyAt (int index){ if (index < 0 || m_keyColumnIndex < 0 || index >= model.size()) return null; Object data = model.get(index).get(m_tableColumns.get(m_keyColumnIndex).headerValue); if (data instanceof IDColumn) { data = ((IDColumn)data).getRecord_ID(); } if (data instanceof Integer) { return (T)data; } return null; } @Override public int getSelectedRow() { return m_selectedRow; } public void setSelectedRow(int selected) { if (selected < model.size()) m_selectedRow = selected; } @Override public void setRowCount(int rowCount) { while (model.size() < rowCount) { model.add(new HashMap()); } } @Override public ColumnInfo[] getLayoutInfo() { return m_layout; } @Override public int getColumnCount() { return m_tableColumns.size(); } @Override public int getRowCount() { return model.size(); } @Override public void setMultiSelection(boolean multiSelection) { } @Override public boolean isMultiSelection() { return false; } @Override public int getColorCode(int row) { return 0; } @Override public void setColorCompare(Object dataCompare) { } @Override public void repaint() { } @Override public void autoSize() { } @Override public void setShowTotals(boolean show) { } /** * Add Table Column and specify the column header. * * @param header name of column header * @param description * @param colClass */ public void addColumn (String header, String description, int AD_Reference_ID, Class colClass) { TableColumn column = new TableColumn(); column.setHeaderValue(header); column.setTooltipText(description); column.setAD_Reference_ID(AD_Reference_ID); column.setColumnClass(colClass); m_tableColumns.add(column); } // addColumn }