com.nridge.core.io.gson.DataTableJSON.java Source code

Java tutorial

Introduction

Here is the source code for com.nridge.core.io.gson.DataTableJSON.java

Source

/*
 * NorthRidge Software, LLC - Copyright (c) 2019.
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 */

package com.nridge.core.io.gson;

import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.nridge.core.base.field.Field;
import com.nridge.core.base.field.FieldRow;
import com.nridge.core.base.field.data.DataField;
import com.nridge.core.base.field.data.DataTable;
import com.nridge.core.base.io.IO;
import com.nridge.core.base.std.StrUtl;
import org.apache.commons.lang3.StringUtils;

import java.io.*;

/**
 * The DataTableJSON provides a collection of methods that can generate/load
 * a JSON representation of a <i>DataTable</i> object.
 * <p>
 * This class utilizes the
 * <a href="https://code.google.com/p/google-gson/">Gson</a>
 * framework to manage these transformations.
 * </p>
 *
 * @author Al Cole
 * @since 1.0
 */
public class DataTableJSON {
    private int mContextTotal;
    private int mContextStart;
    private int mContextLimit;
    private DataTable mDataTable;

    /**
     * Default constructor.
     */
    public DataTableJSON() {
        mDataTable = new DataTable();
    }

    /**
     * Constructor accepts a table as a parameter.
     *
     * @param aDataTable Data table instance.
     */
    public DataTableJSON(DataTable aDataTable) {
        mDataTable = aDataTable;
    }

    /**
     * Constructor accepts a table as a parameter.
     *
     * @param aDataTable Data table instance.
     * @param aStart Context starting offset.
     * @param aLimit Context limit.
     * @param aTotal Context total.
     */
    public DataTableJSON(DataTable aDataTable, int aStart, int aLimit, int aTotal) {
        mContextStart = aStart;
        mContextLimit = aLimit;
        mContextTotal = aTotal;
        mDataTable = aDataTable;
    }

    /**
     * Return an instance to the internally managed data table.
     *
     * @return Data table instance.
     */
    public DataTable getTable() {
        return mDataTable;
    }

    /**
     * Returns the context total value.
     *
     * @return Context total.
     */
    public int getContextTotal() {
        return mContextTotal;
    }

    /**
     * Returns the context starting value.
     *
     * @return Context starting offset.
     */
    public int getContextStart() {
        return mContextStart;
    }

    /**
     * Return the context limit value.
     *
     * @return Context limit value.
     */
    public int getContextLimit() {
        return mContextLimit;
    }

    /**
     * Resets the context values to zero.
     */
    public void resetContext() {
        mContextStart = 0;
        mContextLimit = 0;
        mContextTotal = 0;
    }

    /**
     * Saves the previous assigned bag/table (e.g. via constructor or set method)
     * to the stream specified as a parameter.
     *
     * @param aWriter Json writer stream instance.
     * @param anIsValueObject If true, then a value object is saved.
     *
     * @throws java.io.IOException I/O related exception.
     */
    public void save(JsonWriter aWriter, boolean anIsValueObject) throws IOException {
        String cellValue;
        DataField dataField;

        int rowCount = mDataTable.rowCount();
        int columnCount = mDataTable.columnCount();

        if (anIsValueObject)
            aWriter.name(IO.JSON_TABLE_OBJECT_NAME).beginObject();
        else
            aWriter.beginObject();

        IOJSON.writeNameValue(aWriter, IO.JSON_NAME_MEMBER_NAME, mDataTable.getName());
        IOJSON.writeNameValue(aWriter, IO.JSON_VERSION_MEMBER_NAME, IO.DATATABLE_JSON_FORMAT_VERSION);
        IOJSON.writeNameValue(aWriter, IO.JSON_DIMENSIONS_MEMBER_NAME,
                String.format("%d cols x %d rows", columnCount, rowCount));
        if ((mContextTotal != 0) || (mContextLimit != 0)) {
            aWriter.name(IO.JSON_CONTEXT_OBJECT_NAME).beginObject();
            IOJSON.writeNameValue(aWriter, IO.JSON_START_MEMBER_NAME, mContextStart);
            IOJSON.writeNameValueNonZero(aWriter, IO.JSON_LIMIT_MEMBER_NAME, mContextLimit);
            IOJSON.writeNameValueNonZero(aWriter, IO.JSON_TOTAL_MEMBER_NAME, mContextTotal);
            aWriter.endObject();
        }

        DataBagJSON dataBagJSON = new DataBagJSON(mDataTable.getColumnBag());
        dataBagJSON.save(aWriter, true);

        if (rowCount > 0) {
            aWriter.name(IO.JSON_ROWS_ARRAY_NAME).beginArray();
            for (int row = 0; row < rowCount; row++) {
                aWriter.beginObject();
                for (int col = 0; col < columnCount; col++) {
                    dataField = mDataTable.getFieldByRowCol(row, col);
                    cellValue = dataField.collapse();
                    aWriter.name(IO.JSON_CELL_MEMBER_NAME).value(cellValue);
                }
                aWriter.endObject();
            }
            aWriter.endArray();
        }

        aWriter.endObject();
    }

    /**
     * Saves the previous assigned bag/table (e.g. via constructor or set method)
     * to the writer stream specified as a parameter.
     *
     * @param aWriter Json writer stream instance.
     *
     * @throws java.io.IOException I/O related exception.
     */
    public void save(JsonWriter aWriter) throws IOException {
        save(aWriter, false);
    }

    /**
     * Saves the previous assigned bag/table (e.g. via constructor or set method)
     * to the writer stream specified as a parameter.
     *
     * @param anOS Output stream instance.
     *
     * @throws java.io.IOException I/O related exception.
     */
    public void save(OutputStream anOS) throws IOException {
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(anOS);
        JsonWriter jsonWriter = new JsonWriter(outputStreamWriter);
        save(jsonWriter, false);
    }

    /**
     * Saves the previous assigned bag/table (e.g. via constructor or set method)
     * to the writer stream specified as a parameter.
     *
     * @param aPathFileName Output path file name.
     *
     * @throws java.io.IOException I/O related exception.
     */
    public void save(String aPathFileName) throws IOException {
        try (FileOutputStream fileOutputStream = new FileOutputStream(aPathFileName)) {
            save(fileOutputStream);
        }
    }

    /**
     * Parses an JSON stream and loads it into a bag/table.
     *
     * @param aReader Json reader stream instance.
     *
     * @throws java.io.IOException I/O related exception.
     */
    public void load(JsonReader aReader) throws IOException {
        int columnOffset;
        FieldRow fieldRow;
        DataField dataField;
        String jsonName, jsonValue, mvDelimiter;

        resetContext();
        aReader.beginObject();
        while (aReader.hasNext()) {
            jsonName = aReader.nextName();
            if (StringUtils.equals(jsonName, IO.JSON_NAME_MEMBER_NAME))
                mDataTable.setName(aReader.nextString());
            else if (StringUtils.equals(jsonName, IO.JSON_CONTEXT_OBJECT_NAME)) {
                aReader.beginObject();
                while (aReader.hasNext()) {
                    jsonName = aReader.nextName();
                    if (StringUtils.equals(jsonName, IO.JSON_START_MEMBER_NAME))
                        mContextStart = aReader.nextInt();
                    else if (StringUtils.equals(jsonName, IO.JSON_LIMIT_MEMBER_NAME))
                        mContextLimit = aReader.nextInt();
                    else if (StringUtils.equals(jsonName, IO.JSON_TOTAL_MEMBER_NAME))
                        mContextTotal = aReader.nextInt();
                    else
                        aReader.skipValue();
                }
                aReader.endObject();
            } else if (StringUtils.equals(jsonName, IO.JSON_BAG_OBJECT_NAME)) {
                DataBagJSON dataBagJSON = new DataBagJSON();
                dataBagJSON.load(aReader);
                mDataTable.setColumns(dataBagJSON.getBag());
            } else if (StringUtils.equals(jsonName, IO.JSON_ROWS_ARRAY_NAME)) {
                aReader.beginArray();
                while (aReader.hasNext()) {
                    columnOffset = 0;
                    fieldRow = mDataTable.newRow();

                    aReader.beginObject();
                    while (aReader.hasNext()) {
                        jsonName = aReader.nextName();
                        if (StringUtils.equals(jsonName, IO.JSON_CELL_MEMBER_NAME)) {
                            jsonValue = aReader.nextString();
                            dataField = mDataTable.getColumn(columnOffset);
                            if (dataField != null) {
                                if (dataField.isMultiValue()) {
                                    mvDelimiter = dataField.getFeature(Field.FEATURE_MV_DELIMITER);
                                    if (StringUtils.isNotEmpty(mvDelimiter))
                                        fieldRow.setValues(columnOffset,
                                                StrUtl.expandToList(jsonValue, mvDelimiter.charAt(0)));
                                    else
                                        fieldRow.setValues(columnOffset,
                                                StrUtl.expandToList(jsonValue, StrUtl.CHAR_PIPE));
                                } else
                                    fieldRow.setValue(columnOffset, jsonValue);
                                columnOffset++;
                            }
                        } else
                            aReader.skipValue();
                    }
                    aReader.endObject();

                    mDataTable.addRow(fieldRow);

                }
                aReader.endArray();
            } else
                aReader.skipValue();
        }
        aReader.endObject();
    }

    /**
     * Parses an input stream and loads it into a bag/table.
     *
     * @param anIS Input stream instance.
     *
     * @throws java.io.IOException I/O related exception.
     */
    public void load(InputStream anIS) throws IOException {
        InputStreamReader inputStreamReader = new InputStreamReader(anIS);
        JsonReader jsonReader = new JsonReader(inputStreamReader);
        load(jsonReader);
    }

    /**
     * Parses a JSON formatted path/file name and loads it into a bag/table.
     *
     * @param aPathFileName Input path file name.
     *
     * @throws java.io.IOException I/O related exception.
     */
    public void load(String aPathFileName) throws IOException {
        File jsonFile = new File(aPathFileName);
        if (!jsonFile.exists())
            throw new IOException(aPathFileName + ": Does not exist.");

        try (FileInputStream fileInputStream = new FileInputStream(jsonFile)) {
            load(fileInputStream);
        }
    }
}