/* Copyright (c) 2005 Ricebridge. All Rights Reserved. * * This file is available under the terms and conditions of the * Ricebridge "Open Source API" policy; Ricebridge grants use of this * copyrighted work under the terms of a BSD-style license only. See * http://www.opensource.org/licenses/bsd-license.php for more * information. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * - Neither the name of the Ricebridge nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.ricebridge.xmlman; import org.jostraca.util.Internal; import org.jostraca.util.Standard; import javax.swing.table.TableModel; import java.util.*; /** An implementation of {@link RecordProvider} that provides data records for saving * from a {@link TableModel} object. * <p>This class is used to implement the * {@link XmlManager#saveTableModel(File,RecordSpec,TableModel) saveTableModel(*,RecordSpec,TableModel)} * methods in {@link XmlManager}. * It simply reads the next data record from the specified <code>TableModel</code>, * maintaining an internal index of the current record.</p> * <p><code>TableModelRecordProvider</code> is designed to be subclassed. You can change the default implementation by calling the * {@link com.ricebridge.xmlman.in.XmlManagerStoreBase#setTableModelRecordProviderClass setTableModelRecordProviderClass} method of * {@link com.ricebridge.xmlman.in.XmlManagerStore}, and providing a subclass of <code>TableModelRecordProvider</code>. * <code>XmlManagerStore</code> can be accessed using {@link XmlManager#getXmlManagerStore}.</p> * <p>The <b><a href="TableModelRecordProvider.java.html">Source Code</a></b> of this Java class * is available under a <a href="http://www.opensource.org/licenses/bsd-license.php">BSD-style license</a>.</p> */ public class TableModelRecordProvider extends RecordProviderSupport { // public /** Output headers as first data record * (name for {@link XmlSpec#setProperty XmlSpec.setProperty}: <code>TableModel.saveHeaders</code>). */ public static final String PROP_TableModel_saveHeaders = "TableModel.saveHeaders"; // protected instance /** {@link TableModel} containing source data. */ protected TableModel iTableModel = null; /** Save the table headers as first data record. See {@link #setXmlSpecImpl setXmlSpecImpl}. */ protected boolean iSaveHeaders = false; /** Table headers. */ protected String[] iHeaders = null; /** Indicate that internal state is at the first record. */ protected boolean iFirstRecord = true; /** Number of data fields in record, determined by number of columns in table. */ protected int iFieldCount = 0; /** Index of current record. */ protected long iRecordIndex = 0; // constructors /** Create uninitialised for use with {@link #setTableModel setTableModel}. */ public TableModelRecordProvider() { // init with setTableModel } /** Create initialised. See {@link #setTableModel setTableModel} for details. * @param pTableModel <code>TableModel</code> providing data */ public TableModelRecordProvider( TableModel pTableModel ) { setTableModel( pTableModel ); } // public methods /** Set the <code>TableModel</code> providing data to save. * <p>The default number of fields per record is taken from * {@link TableModel#getColumnCount()} * and the headers (output as the first record when the <code>TableModel.saveHeaders</code> property is true), * are taken from {@link TableModel#getColumnName(int)}. </p> * @param pTableModel <code>TableModel</code> providing data */ public void setTableModel( TableModel pTableModel ) { iTableModel = (TableModel) Internal.null_arg( pTableModel ); iFieldCount = iTableModel.getColumnCount(); if( iSaveHeaders && 0 < iFieldCount ) { iHeaders = new String[ iFieldCount ]; for( int cI = 0; cI < iFieldCount; cI++ ) { iHeaders[cI] = iTableModel.getColumnName( cI ); } } else { iSaveHeaders = false; } } // RecordProviderSupport methods /** Handle property settings for saving {@link TableModel TableModels}. * <p>You can change these using {@link XmlSpec}.</p> * @see RecordListener#setXmlSpec * @see #PROP_TableModel_saveHeaders */ protected void setXmlSpecImpl( XmlSpec pXmlSpec ) { iSaveHeaders = pXmlSpec.getBooleanProperty( PROP_TableModel_saveHeaders ); } /** Start the saving process. */ protected void startProcessImpl() { iFirstRecord = true; iRecordIndex = 0; } /** Check if there are any more records. */ protected boolean hasNextRecordImpl() { boolean hasNextRecord = false; if( iSaveHeaders && iFirstRecord ) { hasNextRecord = true; } else { hasNextRecord = ( iRecordIndex < iTableModel.getRowCount() ); } return hasNextRecord; } /** Return next data record as a <code>String[]</code> array. */ protected String[] nextRecordImpl() { String[] record = new String[iFieldCount]; if( iSaveHeaders && iFirstRecord ) { for( int fI = 0; fI < iFieldCount; fI++ ) { record[fI] = iHeaders[ fI ]; } } else { for( int fI = 0; fI < iFieldCount; fI++ ) { record[fI] = String.valueOf( iTableModel.getValueAt( (int) iRecordIndex, fI ) ); } iRecordIndex++; } return record; } }