com.thelastcheck.io.base.RecordImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.thelastcheck.io.base.RecordImpl.java

Source

/*******************************************************************************
 * Copyright (c) 2009-2015 The Last Check, LLC, All Rights Reserved
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package com.thelastcheck.io.base;

import com.thelastcheck.commons.base.exception.InvalidDataException;
import com.thelastcheck.commons.base.fields.OnUsField;
import com.thelastcheck.commons.base.fields.RoutingNumber;
import com.thelastcheck.commons.base.utils.ToXmlBuilder;
import com.thelastcheck.commons.buffer.ByteArray;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.util.Date;
import java.util.TimeZone;

public abstract class RecordImpl implements Record, Cloneable {

    private ByteArray record;
    private int recordPosition;
    private long offsetPosition;
    protected static final String INVALID_FIELD_NUMBER = "Invalid Field Number";

    public RecordImpl() {
        super();
    }

    public RecordImpl(int recordLength, String encoding) {
        this.record = new ByteArray(recordLength, encoding);
    }

    public RecordImpl(ByteArray record) {
        this.record = record;
    }

    public Object clone() throws CloneNotSupportedException {
        RecordImpl object;
        object = (RecordImpl) super.clone();
        object.record = (ByteArray) record.clone();
        return object;
    }

    public Object getField(int fieldNumber) throws InvalidDataException {
        return getField(field(fieldNumber));
    }

    public Record setField(String value, int fieldNumber) {
        setField(value, field(fieldNumber));
        return this;
    }

    public Record setField(long value, int fieldNumber) {
        setField(value, field(fieldNumber));
        return this;
    }

    public Record setField(int value, int fieldNumber) {
        setField(value, field(fieldNumber));
        return this;
    }

    public String fieldName(int fieldNumber) {
        return field(fieldNumber).name();
    }

    /**
     * 
     * @param field
     *            The field to be obtained.
     * 
     * @return A string containing the field from the buffer converted based on
     *         the defined encoding.
     * @throws InvalidDataException
     */
    protected Object getField(Field field) throws InvalidDataException {
        return field.extract(record);
    }

    protected String getFieldAsString(Field field) {
        return field.extractAsString(record);
    }

    protected RoutingNumber getFieldAsRoutingNumber(Field field) {
        return field.extractStringAsRoutingNumber(record);
    }

    protected OnUsField getFieldAsOnUsField(Field field) {
        return field.extractStringAsOnUsField(record);
    }

    protected ByteArray getFieldAsByteArray(Field field) {
        return field.extractAsByteArray(record);
    }

    protected Date getFieldAsDate(Field field) throws InvalidDataException {
        return field.extractStringAsDate(record);
    }

    protected Date getFieldAsDate(Field field, TimeZone zone) throws InvalidDataException {
        return field.extractStringAsDate(record, zone);
    }

    protected Date getFieldAsTime(Field field) throws InvalidDataException {
        return field.extractStringAsTime(record);
    }

    protected Date getFieldAsTime(Field field, TimeZone zone) throws InvalidDataException {
        return field.extractStringAsTime(record, zone);
    }

    protected long getFieldAsLong(Field field) throws InvalidDataException {
        return field.extractStringAsLong(record);
    }

    protected int getFieldAsInt(Field field) throws InvalidDataException {
        return field.extractStringAsInt(record);
    }

    /**
     * 
     * @param value
     *            The new value to be stored in the buffer.
     * @param field
     *            The field to be updated.
     * 
     */
    protected void setField(String value, Field field) {
        field.insert(value, record);
    }

    protected void setFieldRight(String value, Field field) {
        field.insertRight(value, record);
    }

    protected void setField(ByteArray value, Field field) {
        field.insert(value, record);
    }

    protected void setFieldDate(Date value, Field field) {
        field.insertDate(value, record);
    }

    protected void setFieldDate(Date value, Field field, TimeZone zone) {
        field.insertDate(value, record, zone);
    }

    protected void setFieldTime(Date value, Field field) {
        field.insertTime(value, record);
    }

    protected void setFieldTime(Date value, Field field, TimeZone zone) {
        field.insertTime(value, record, zone);
    }

    protected void setField(RoutingNumber value, Field field) {
        field.insert(value, record);
    }

    protected void setField(OnUsField value, Field field) {
        field.insert(value, record);
    }

    protected void setField(long value, Field field) {
        field.insertAsString(value, record);
    }

    protected void setField(int value, Field field) {
        field.insertAsString(value, record);
    }

    /**
     * This is a routine that is used to allocate a new record for a field that
     * has changed length. A new buffer is allocated and all of the defined
     * fields for this record are copied, except for the field being replaced.
     * It is up to the caller of this routine to actually store the new field
     * value.
     * 
     * @param currentLength
     *            the current length of the field
     * @param newLength
     *            the new length of the field
     * @param replaceLengthField
     *            the field number of the length field associated with the field
     * @param replacedField
     *            the field number of field being replaced
     */
    protected void allocateNewRecord(int currentLength, int newLength, int replaceLengthField, int replacedField) {
        ByteArray currentRecord = record();
        ByteArray newRecord = new ByteArray(currentRecord.getLength() - currentLength + newLength,
                currentRecord.getEncoding());
        // save off all the current component fields
        ByteArray[] currentValues = new ByteArray[numberOfFields() + 1];
        for (int i = 1; i <= numberOfFields(); i++) {
            Field field = field(i);
            if (i == replacedField)
                continue;
            currentValues[i] = field.extractAsByteArray(currentRecord);
        }
        record(newRecord);
        resetDynamicFields();
        // set values back into the current component fields
        for (int i = 1; i <= numberOfFields(); i++) {
            Field field = field(i);
            if (i == replacedField)
                continue;
            // if this is the field containing the length, use the new length
            // value.
            if (i == replaceLengthField) {
                field.insertAsString(newLength, newRecord);
            } else {
                field.insert(currentValues[i], newRecord);
            }
        }
        return;
    }

    public int length() {
        return record.getLength();
    }

    public ByteArray record() {
        return record;
    }

    /**
     * Certain records are variable in size and can change size based on the
     * values placed in the fields. This method is for sub-classes who need to
     * reset the record after a field manipulation requires a change in the
     * record size.
     * 
     * @param record
     *            the record to set
     */
    protected void record(ByteArray record) {
        this.record = record;
    }

    public int recordPosition() {
        return recordPosition;
    }

    public Record recordPosition(int position) {
        recordPosition = position;
        return this;
    }

    public long offsetPosition() {
        return offsetPosition;
    }

    public Record offsetPosition(long offset) {
        offsetPosition = offset;
        return this;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.tlc.io.Record#numberOfFields()
     */
    public abstract int numberOfFields();

    /**
     * Get the field definition for a specified field based on the field number.
     * 
     * @param fieldNumber
     * @return An Field object defining the field.
     */
    protected abstract Field field(int fieldNumber);

    /**
     * This method is intended to allow the reset of dynamic fields back to
     * their initial state. This is for fields whose definition may depend on
     * values of other fields. If those fields change, reseting the dynamic
     * fields forces them to be recalculated when needed.
     */
    protected abstract void resetDynamicFields();

    public String toString() {
        ToStringStyle style = ToStringStyle.MULTI_LINE_STYLE;
        ToStringBuilder sb = new ToStringBuilder(this, style);
        sb.append("position", recordPosition);
        sb.append("offset", offsetPosition);
        int fieldNumber = 1;
        int maxFields = numberOfFields();
        while (fieldNumber <= maxFields) {
            Field field = field(fieldNumber);
            field.formatToString(record, sb);
            fieldNumber++;
        }
        return sb.toString();
    }

    public String toXml() {
        return toXml(true);
    }

    public String toXml(boolean useAttributes) {
        String recordName = this.getClass().getSimpleName();
        int pos = recordName.lastIndexOf("Impl");
        if (pos != -1) {
            recordName = recordName.substring(0, pos);
        }
        ToXmlBuilder xb = new ToXmlBuilder(recordName, useAttributes, 512);
        int fieldNumber = 1;
        int maxFields = numberOfFields();
        while (fieldNumber <= maxFields) {
            Field field = field(fieldNumber);
            field.formatToXml(record, xb);
            fieldNumber++;
        }
        return xb.toString();
    }

}