001// Copyright 2004, 2005 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry.contrib.table.model.simple; 016 017import java.util.Arrays; 018import java.util.Comparator; 019import java.util.Iterator; 020 021import org.apache.tapestry.contrib.table.model.CTableDataModelEvent; 022import org.apache.tapestry.contrib.table.model.IFullTableModel; 023import org.apache.tapestry.contrib.table.model.ITableColumn; 024import org.apache.tapestry.contrib.table.model.ITableColumnModel; 025import org.apache.tapestry.contrib.table.model.ITableDataModel; 026import org.apache.tapestry.contrib.table.model.ITableDataModelListener; 027import org.apache.tapestry.contrib.table.model.ITableSortingState; 028import org.apache.tapestry.contrib.table.model.common.AbstractTableModel; 029import org.apache.tapestry.contrib.table.model.common.ArrayIterator; 030import org.apache.tapestry.contrib.table.model.common.ReverseComparator; 031 032/** 033 * A simple generic table model implementation. 034 * 035 * @author mindbridge 036 */ 037public class SimpleTableModel extends AbstractTableModel 038 implements IFullTableModel, ITableDataModelListener 039{ 040 private static final long serialVersionUID = 1L; 041 042 private ITableDataModel m_objDataModel = null; 043 private Object[] m_arrRows = null; 044 private ITableColumnModel m_objColumnModel = null; 045 046 private SimpleTableSortingState m_objLastSortingState; 047 048 public SimpleTableModel(Object[] arrData, ITableColumn[] arrColumns) 049 { 050 this(new SimpleListTableDataModel(arrData), new SimpleTableColumnModel(arrColumns)); 051 } 052 053 public SimpleTableModel(Object[] arrData, ITableColumnModel objColumnModel) 054 { 055 this(new SimpleListTableDataModel(arrData), objColumnModel); 056 } 057 058 public SimpleTableModel(ITableDataModel objDataModel, ITableColumnModel objColumnModel) 059 { 060 this(objDataModel, objColumnModel, new SimpleTableState()); 061 } 062 063 public SimpleTableModel(ITableDataModel objDataModel, ITableColumnModel objColumnModel, SimpleTableState objState) 064 { 065 super(objState); 066 067 m_arrRows = null; 068 m_objColumnModel = objColumnModel; 069 m_objLastSortingState = new SimpleTableSortingState(); 070 071 setDataModel(objDataModel); 072 } 073 074 public ITableColumnModel getColumnModel() 075 { 076 return m_objColumnModel; 077 } 078 079 public Iterator getCurrentPageRows() 080 { 081 sortRows(); 082 083 int nPageSize = getPagingState().getPageSize(); 084 if (nPageSize <= 0) 085 return new ArrayIterator(m_arrRows); 086 087 int nCurrentPage = getPagingState().getCurrentPage(); 088 int nFrom = nCurrentPage * nPageSize; 089 int nTo = (nCurrentPage + 1) * nPageSize; 090 091 return new ArrayIterator(m_arrRows, nFrom, nTo); 092 } 093 094 public int getRowCount() 095 { 096 updateRows(); 097 return m_arrRows.length; 098 } 099 100 private void updateRows() 101 { 102 // If it is not null, then there is no need to extract the data 103 if (m_arrRows != null) 104 return; 105 106 // Extract the data from the model 107 m_objLastSortingState = new SimpleTableSortingState(); 108 109 int nRowCount = m_objDataModel.getRowCount(); 110 Object[] arrRows = new Object[nRowCount]; 111 112 int i = 0; 113 for (Iterator it = m_objDataModel.getRows(); it.hasNext();) 114 arrRows[i++] = it.next(); 115 116 m_arrRows = arrRows; 117 } 118 119 protected void sortRows() 120 { 121 updateRows(); 122 123 ITableSortingState objSortingState = getSortingState(); 124 125 // see if there is sorting required 126 String strSortColumn = objSortingState.getSortColumn(); 127 if (strSortColumn == null) 128 return; 129 130 boolean bSortOrder = objSortingState.getSortOrder(); 131 132 // See if the table is already sorted this way. If so, return. 133 if (strSortColumn.equals(m_objLastSortingState.getSortColumn()) 134 && m_objLastSortingState.getSortOrder() == bSortOrder) 135 return; 136 137 ITableColumn objColumn = getColumnModel().getColumn(strSortColumn); 138 if (objColumn == null || !objColumn.getSortable()) 139 return; 140 141 Comparator objCmp = objColumn.getComparator(); 142 if (objCmp == null) 143 return; 144 145 // Okay, we have everything in place. Sort the rows. 146 if (bSortOrder == ITableSortingState.SORT_DESCENDING) 147 objCmp = new ReverseComparator(objCmp); 148 149 Arrays.sort(m_arrRows, objCmp); 150 151 m_objLastSortingState.setSortColumn(strSortColumn, bSortOrder); 152 } 153 154 public void tableDataChanged(CTableDataModelEvent objEvent) 155 { 156 m_arrRows = null; 157 } 158 159 /** 160 * Returns the dataModel. 161 * @return ITableDataModel 162 */ 163 public ITableDataModel getDataModel() 164 { 165 return m_objDataModel; 166 } 167 168 /** 169 * Sets the dataModel. 170 * @param dataModel The dataModel to set 171 */ 172 public void setDataModel(ITableDataModel dataModel) 173 { 174 if (m_objDataModel != null) 175 m_objDataModel.removeTableDataModelListener(this); 176 177 m_objDataModel = dataModel; 178 m_objDataModel.addTableDataModelListener(this); 179 180 m_arrRows = null; 181 } 182 183 public Iterator getRows() { 184 updateRows(); 185 return new ArrayIterator(m_arrRows); 186 } 187 188}