/* 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 java.util.*; /** Helper class for implementing the {@link RecordProvider} interface. * <p>Use of this class will help ensure future compatibility with any XML Manager API changes. * Subclasses should implement the <code>*Impl</code> methods (for example, {@link #hasNextRecordImpl hasNextRecordImpl}) * rather than the declared interface methods such as {@link #hasNextRecord hasNextRecord}. * See the {@link RecordProvider} interface documentation for a description of the calling sequence of the methods * in this class. </p> * <p>The <b><a href="RecordProviderSupport.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 abstract class RecordProviderSupport implements RecordProvider { // protected instance /** Record specification field names, if specified in the {@link RecordSpec} object. * <b>NOTE: may be empty.</b> */ protected String[] iFieldNames = new String[]{}; // public methods /** Helper implementation of {@link RecordProvider#setXmlSpec RecordProvider.setXmlSpec}. * Subclasses should implement {@link #setXmlSpecImpl setXmlSpecImpl}. */ public void setXmlSpec( XmlSpec pXmlSpec ) { XmlSpec xs = (XmlSpec) Internal.null_arg( pXmlSpec ); try { setXmlSpecImpl( xs ); } catch( XmlManagerException xme ) { throw xme; } catch( Exception e ) { throw new XmlManagerException( XmlManagerException.CODE_recordprovider_set, new String[] { "record-provider-class", this.getClass().getName(), "methodname", "setXmlSpecImpl", "setargument", String.valueOf(xs) }, e ); } } /** Helper implementation of {@link RecordProvider#setFieldNames RecordProvider.setFieldNames}. * Subclasses should implement {@link #setFieldNamesImpl setFieldNamesImpl}. */ public void setFieldNames( String[] pFieldNames ) { String[] fn = (String[]) Internal.null_array( pFieldNames ); try { setFieldNamesImpl( fn ); } catch( XmlManagerException xme ) { throw xme; } catch( Exception e ) { throw new XmlManagerException( XmlManagerException.CODE_recordprovider_set, new String[] { "record-provider-class", this.getClass().getName(), "methodname", "setFieldNamesImpl", "setargument", Arrays.asList(fn).toString() }, e ); } } /** Helper implementation of {@link RecordProvider#startProcess RecordProvider.startProcess}. * Subclasses should implement {@link #startProcessImpl startProcessImpl}. */ public void startProcess() { try { startProcessImpl(); } catch( XmlManagerException xme ) { throw xme; } catch( Exception e ) { throw new XmlManagerException( XmlManagerException.CODE_recordprovider_exception, new String[] { "record-provider-class", this.getClass().getName(), "methodname", "startProcessImpl" }, e ); } } /** Helper implementation of {@link RecordProvider#hasNextRecord RecordProvider.hasNextRecord}. * Sub classes should implement {@link #hasNextRecordImpl hasNextRecordImpl}. */ public boolean hasNextRecord() { try { return hasNextRecordImpl(); } catch( XmlManagerException xme ) { throw xme; } catch( Exception e ) { throw new XmlManagerException( XmlManagerException.CODE_recordprovider_exception, new String[] { "record-provider-class", this.getClass().getName(), "methodname", "hasNextRecordImpl" }, e ); } } /** Helper implementation of {@link RecordProvider#nextRecord RecordProvider.nextRecord}. * Sub classes should implement {@link #nextRecordImpl nextRecordImpl}. */ public String[] nextRecord() { try { String[] record = nextRecordImpl(); if( null == record ) { throw new XmlManagerException( XmlManagerException.CODE_null_record, new String[] { "record-provider-class", this.getClass().getName(), "methodname", "nextRecordImpl" } ); } // check for nulls for( int fI = 0; fI < record.length; fI++ ) { if( null == record[fI] ) { record[fI] = ""; } } return record; } catch( XmlManagerException xme ) { throw xme; } catch( Exception e ) { throw new XmlManagerException( XmlManagerException.CODE_recordprovider_exception, new String[] { "record-provider-class", this.getClass().getName(), "methodname", "nextRecordImpl" }, e ); } } /** Helper implementation of {@link RecordProvider#endProcess RecordProvider.endProcess}. * Subclasses should implement {@link #endProcessImpl endProcessImpl}. */ public void endProcess() { try { endProcessImpl(); } catch( XmlManagerException xme ) { throw xme; } catch( Exception e ) { throw new XmlManagerException( XmlManagerException.CODE_recordprovider_exception, new String[] { "record-provider-class", this.getClass().getName(), "methodname", "endProcessImpl" }, e ); } } // protected /** Implement this method to receive the current {@link XmlSpec} settings. * <p>This method is optional for subclasses, as an empty implementation is provided here.</p> * @param pXmlSpec XML specification * @see #setXmlSpec * @see RecordProvider#setXmlSpec */ protected void setXmlSpecImpl( XmlSpec pXmlSpec ) { // empty implementation } /** Implement this method to obtain the record specification field names, if available. * <p>The default implementation stores the field names in the {@link #iFieldNames} member variable. * This method is optional for subclasses, as an implementation is provided here.</p> * @param pFieldNames record field names * @see #setFieldNames * @see RecordProvider#setFieldNames */ protected void setFieldNamesImpl( String[] pFieldNames ) { iFieldNames = (String[]) Internal.null_array( pFieldNames ); } /** Implement this method to receive notification that the saving of XML data is about to start. * <p>This method is optional for subclasses, as an empty implementation is provided here.</p> * @see #startProcess * @see RecordProvider#startProcess */ protected void startProcessImpl() { // empty implementation } /** Return <code>true</code> if there are more data records to save. * <p>This method must be implemented by subclasses.</p> * @see #hasNextRecord * @see RecordProvider#hasNextRecord */ protected abstract boolean hasNextRecordImpl(); /** Indicates that the next data record is to be saved. * <p>This method must be implemented by subclasses.</p> * @see #nextRecord * @see RecordProvider#nextRecord */ protected abstract String[] nextRecordImpl(); /** Implement this method to receive notification that the saving of XML data has ended. * <p>This method is optional for subclasses, as an empty implementation is provided here.</p> * @see #endProcess * @see RecordProvider#endProcess */ protected void endProcessImpl() { // empty implementation } }