com.nridge.core.base.io.xml.DocumentOpXML.java Source code

Java tutorial

Introduction

Here is the source code for com.nridge.core.base.io.xml.DocumentOpXML.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.base.io.xml;

import com.nridge.core.base.doc.Doc;
import com.nridge.core.base.doc.Document;
import com.nridge.core.base.ds.DSCriteria;
import com.nridge.core.base.field.data.DataField;
import com.nridge.core.base.field.data.DataTextField;
import com.nridge.core.base.io.DocOpInterface;
import com.nridge.core.base.io.IO;
import com.nridge.core.base.std.StrUtl;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import java.io.*;
import java.util.ArrayList;
import java.util.Map;

/**
 * The DocumentOpXML class provides XML helper methods for document
 * operations.
 */
public class DocumentOpXML implements DOMInterface, DocOpInterface {
    private DataField mField;
    private boolean mIsSimple;
    private DSCriteria mCriteria;
    private ArrayList<Document> mDocumentList;

    /**
     * Default constructor.
     */
    public DocumentOpXML() {
        mField = new DataTextField("undefined");
        mDocumentList = new ArrayList<Document>();
    }

    /**
     * Default constructor.
     *
     * @param aName Operation name.
     */
    public DocumentOpXML(String aName) {
        mField = new DataTextField(aName);
        mDocumentList = new ArrayList<Document>();
    }

    /**
     * Constructor accepts a list of document instances as a parameter.
     *
     * @param aName Text field name.
     * @param aDocumentList A list of document instances.
     */
    public DocumentOpXML(String aName, ArrayList<Document> aDocumentList) {
        mField = new DataTextField(aName);
        mDocumentList = aDocumentList;
    }

    /**
     * Constructor accepts a data source criteria as a parameter.
     *
     * @param aName Criteria name.
     * @param aCriteria Data source criteria instance.
     */
    public DocumentOpXML(String aName, DSCriteria aCriteria) {
        mCriteria = aCriteria;
        mField = new DataTextField(aName);
        mDocumentList = new ArrayList<Document>();
    }

    /**
     * Assigns an operation field containing a name and other desired features.
     *
     * @param aField Operation field.
     */
    public void setField(DataField aField) {
        mField = aField;
    }

    /**
     * Returns an operation field.
     *
     * @return Data field instance.
     */
    public DataField getField() {
        return mField;
    }

    /**
     * Assigns standard account features to the operation. Please
     * note that the parent application is responsible for encrypting
     * the account password prior to assigning it in this method.
     *
     * @param anAccountName Account name.
     * @param anAccountPassword Account password.
     */
    public void setAccountNamePassword(String anAccountName, String anAccountPassword) {
        mField.addFeature(Doc.FEATURE_OP_ACCOUNT_NAME, anAccountName);
        mField.addFeature(Doc.FEATURE_OP_ACCOUNT_PASSWORD, anAccountPassword);
    }

    /**
     * Assigns standard account features to the operation. Please
     * note that the parent application is responsible for hashing
     * the account password prior to assigning it in this method.
     *
     * @param anAccountName Account name.
     * @param anAccountPasshash Account password.
     */
    public void setAccountNamePasshash(String anAccountName, String anAccountPasshash) {
        mField.addFeature(Doc.FEATURE_OP_ACCOUNT_NAME, anAccountName);
        mField.addFeature(Doc.FEATURE_OP_ACCOUNT_PASSHASH, anAccountPasshash);
    }

    /**
     * Assigns standard account features to the operation.
     *
     * @param aSessionId Session identifier.
     */
    public void setSessionId(String aSessionId) {
        mField.addFeature(Doc.FEATURE_OP_SESSION, aSessionId);
    }

    /**
     * Adds the document to the internally managed document list.
     *
     * @param aDocument Document instance.
     */
    public void addDocument(Document aDocument) {
        if (aDocument != null)
            mDocumentList.add(aDocument);
    }

    /**
     * Assigns the document list parameter to the internally managed list instance.
     *
     * @param aDocumentList A list of document instances.
     */
    public void setDocumentList(ArrayList<Document> aDocumentList) {
        if (aDocumentList != null)
            mDocumentList = aDocumentList;
    }

    /**
     * Returns a reference to the internally managed list of document instances.
     *
     * @return List of document instances.
     */
    public ArrayList<Document> getDocumentList() {
        return mDocumentList;
    }

    /**
     * Assigns the data source criteria instance.  A criteria instance
     * is only assigned for <code>Doc.OPERATION_FETCH</code> names.
     *
     * @param aCriteria Data source criteria instance.
     */
    public void setCriteria(DSCriteria aCriteria) {
        mCriteria = aCriteria;
    }

    /**
     * Returns a reference to an internally managed criteria instance.
     *
     * @return Data source criteria instance if the operation was
     * <code>Doc.OPERATION_FETCH</code> or <i>null</i> otherwise.
     */
    public DSCriteria getCriteria() {
        return mCriteria;
    }

    /**
     * Assigns a simple format flag.
     *
     * @param anIsSimple Is output format simple?
     */
    public void setIsSimpleFlag(boolean anIsSimple) {
        mIsSimple = anIsSimple;
    }

    /**
     * Saves the previous assigned document list (e.g. via constructor or set method)
     * to the print writer stream wrapped in a tag name specified in the parameter.
     *
     * @param aPW PrintWriter stream instance.
     * @param aTagName Document tag name.
     * @param anIndentAmount Indentation count.
     *
     * @throws java.io.IOException I/O related exception.
     */
    public void save(PrintWriter aPW, String aTagName, int anIndentAmount) throws IOException {
        DocumentXML documentXML;

        if (mCriteria == null) {
            IOXML.indentLine(aPW, anIndentAmount);
            aPW.printf("<%s", IO.XML_OPERATION_NODE_NAME);
            IOXML.writeAttrNameValue(aPW, Doc.FEATURE_OP_NAME, mField.getName());
            int docCount = mDocumentList.size();
            if (docCount > 0)
                IOXML.writeAttrNameValue(aPW, "count", mDocumentList.size());
            for (Map.Entry<String, String> featureEntry : mField.getFeatures().entrySet())
                IOXML.writeAttrNameValue(aPW, featureEntry.getKey(), featureEntry.getValue());

            if (docCount == 0)
                aPW.printf("/>%n");
            else {
                aPW.printf(">%n");
                for (Document document : mDocumentList) {
                    documentXML = new DocumentXML(document);
                    documentXML.setIsSimpleFlag(mIsSimple);
                    documentXML.setSaveFieldsWithoutValues(true);
                    documentXML.save(aPW, aTagName, anIndentAmount + 1);
                }
                IOXML.indentLine(aPW, anIndentAmount);
                aPW.printf("</%s>%n", IO.XML_OPERATION_NODE_NAME);
            }
        } else {
            IOXML.indentLine(aPW, anIndentAmount);
            aPW.printf("<%s", IO.XML_OPERATION_NODE_NAME);
            IOXML.writeAttrNameValue(aPW, Doc.FEATURE_OP_NAME, mField.getName());
            for (Map.Entry<String, String> featureEntry : mField.getFeatures().entrySet())
                IOXML.writeAttrNameValue(aPW, featureEntry.getKey(), featureEntry.getValue());
            aPW.printf(">%n");
            DSCriteriaXML dsCriteriaXML = new DSCriteriaXML(mCriteria);
            dsCriteriaXML.save(aPW, IO.XML_CRITERIA_NODE_NAME, anIndentAmount + 1);
            IOXML.indentLine(aPW, anIndentAmount);
            aPW.printf("</%s>%n", IO.XML_OPERATION_NODE_NAME);
        }
    }

    /**
     * Saves the previous assigned document list (e.g. via constructor or set method)
     * to the print writer stream specified as a parameter.
     *
     * @param aPW PrintWriter stream instance.
     * @throws java.io.IOException I/O related exception.
     */
    @Override
    public void save(PrintWriter aPW) throws IOException {
        save(aPW, IO.XML_DOCUMENT_NODE_NAME, 0);
    }

    /**
     * Saves the previous assigned document list (e.g. via constructor or set method)
     * to the path/file name specified as a parameter.
     *
     * @param aPathFileName Absolute file name.
     * @throws java.io.IOException I/O related exception.
     */
    @Override
    public void save(String aPathFileName) throws IOException {
        try (PrintWriter printWriter = new PrintWriter(aPathFileName, StrUtl.CHARSET_UTF_8)) {
            save(printWriter);
        }
    }

    /**
     * Saves the previous assigned document list (e.g. via constructor or set method)
     * to a string and returns it.
     *
     * @throws java.io.IOException I/O related exception.
     */
    public String saveAsString() throws IOException {
        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);
        save(printWriter);
        printWriter.close();

        return stringWriter.toString();
    }

    private void loadOperation(Element anElement) throws IOException {
        Attr nodeAttr;
        Node nodeItem;
        Document document;
        Element nodeElement;
        DocumentXML documentXML;
        DSCriteriaXML criteriaXML;
        String nodeName, nodeValue;

        mCriteria = null;
        mDocumentList.clear();
        mField.clearFeatures();

        String attrValue = anElement.getAttribute(Doc.FEATURE_OP_NAME);
        if (StringUtils.isNotEmpty(attrValue)) {
            mField.setName(attrValue);
            NamedNodeMap namedNodeMap = anElement.getAttributes();
            int attrCount = namedNodeMap.getLength();
            for (int attrOffset = 0; attrOffset < attrCount; attrOffset++) {
                nodeAttr = (Attr) namedNodeMap.item(attrOffset);
                nodeName = nodeAttr.getNodeName();
                nodeValue = nodeAttr.getNodeValue();

                if (StringUtils.isNotEmpty(nodeValue)) {
                    if ((!StringUtils.equalsIgnoreCase(nodeName, Doc.FEATURE_OP_NAME))
                            && (!StringUtils.equalsIgnoreCase(nodeName, Doc.FEATURE_OP_COUNT)))
                        mField.addFeature(nodeName, nodeValue);
                }
            }
        }

        NodeList nodeList = anElement.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            nodeItem = nodeList.item(i);

            if (nodeItem.getNodeType() != Node.ELEMENT_NODE)
                continue;

            nodeName = nodeItem.getNodeName();
            if (nodeName.equalsIgnoreCase(IO.XML_CRITERIA_NODE_NAME)) {
                nodeElement = (Element) nodeItem;
                criteriaXML = new DSCriteriaXML();
                criteriaXML.load(nodeElement);
                mCriteria = criteriaXML.getCriteria();
            } else if (StringUtils.startsWithIgnoreCase(nodeName, IO.XML_DOCUMENT_NODE_NAME)) {
                nodeElement = (Element) nodeItem;
                documentXML = new DocumentXML();
                documentXML.load(nodeElement);
                document = documentXML.getDocument();
                if (document != null)
                    mDocumentList.add(document);
            }
        }
    }

    /**
     * Parses an XML DOM element and loads it into a document list.
     *
     * @param anElement DOM element.
     * @throws java.io.IOException I/O related exception.
     */
    @Override
    public void load(Element anElement) throws IOException {
        String nodeName = anElement.getNodeName();
        if (StringUtils.equalsIgnoreCase(nodeName, IO.XML_OPERATION_NODE_NAME))
            loadOperation(anElement);
    }

    /**
     * Parses an XML DOM element and loads it into a document list.
     *
     * @param aDocument XML document instance.
     *
     * @throws java.io.IOException                            I/O related exception.
     * @throws javax.xml.parsers.ParserConfigurationException XML parser related exception.
     * @throws org.xml.sax.SAXException                       XML parser related exception.
     * @throws TransformerException Transformer exception.
     */
    public void load(org.w3c.dom.Document aDocument)
            throws ParserConfigurationException, IOException, SAXException, TransformerException {
        aDocument.getDocumentElement().normalize();
        load(aDocument.getDocumentElement());
    }

    /**
     * Parses an XML DOM element and loads it into a document list.
     *
     * @param anIS Input stream.
     *
     * @throws java.io.IOException                            I/O related exception.
     * @throws javax.xml.parsers.ParserConfigurationException XML parser related exception.
     * @throws org.xml.sax.SAXException                       XML parser related exception.
     * @throws TransformerException Transformer exception.
     */
    @Override
    public void load(InputStream anIS)
            throws ParserConfigurationException, IOException, SAXException, TransformerException {
        DocumentBuilderFactory docBldFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docBldFactory.newDocumentBuilder();
        InputSource inputSource = new InputSource(anIS);
        org.w3c.dom.Document xmlDocument = docBuilder.parse(inputSource);
        load(xmlDocument);
    }

    /**
     * Parses an XML file identified by the path/file name parameter
     * and loads it into a document list.
     *
     * @param aPathFileName Absolute file name.
     *
     * @throws java.io.IOException                            I/O related exception.
     * @throws javax.xml.parsers.ParserConfigurationException XML parser related exception.
     * @throws org.xml.sax.SAXException                       XML parser related exception.
     */
    @Override
    public void load(String aPathFileName) throws IOException, ParserConfigurationException, SAXException {
        File xmlFile = new File(aPathFileName);
        if (!xmlFile.exists())
            throw new IOException(aPathFileName + ": Does not exist.");

        DocumentBuilderFactory docBldFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docBldFactory.newDocumentBuilder();
        org.w3c.dom.Document xmlDocument = docBuilder.parse(new File(aPathFileName));
        xmlDocument.getDocumentElement().normalize();

        load(xmlDocument.getDocumentElement());
    }
}