All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.applic.consistency.impl.io.ConsistencyDataXml Maven / Gradle / Ivy

The newest version!
package cdc.applic.consistency.impl.io;

import java.io.IOException;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import cdc.applic.consistency.Composition;
import cdc.applic.consistency.impl.BlockDefImpl;
import cdc.applic.consistency.impl.BlockIncImpl;
import cdc.applic.consistency.impl.ConsistencyDataImpl;
import cdc.applic.consistency.impl.Node;
import cdc.applic.consistency.impl.ReferenceImpl;
import cdc.applic.dictionaries.Dictionary;
import cdc.applic.dictionaries.Registry;
import cdc.applic.dictionaries.impl.RegistryImpl;
import cdc.applic.dictionaries.impl.RepositoryImpl;
import cdc.applic.expressions.Expression;
import cdc.io.xml.AbstractStAXLoader;
import cdc.io.xml.AbstractStAXParser;
import cdc.io.xml.XmlWriter;
import cdc.util.lang.FailureReaction;

public final class ConsistencyDataXml {
    private static final String COMPOSITION = "composition";
    private static final String CONSISTENCY_DATA = "consistency-data";
    private static final String APPLICABILITY = "applicability";
    private static final String ID = "id";
    private static final String BLOCK_DEF = "def";
    private static final String BLOCK_INC = "inc";
    private static final String LABEL = "label";
    private static final String POLICY = "policy";
    private static final String REF = "ref";
    private static final String REGISTRY = "registry";
    private static final String TARGET_ID = "target-id";

    private ConsistencyDataXml() {
    }

    public static final class Printer {
        private Printer() {
        }

        public static void write(XmlWriter writer,
                                 ConsistencyDataImpl data) throws IOException {
            final String namespace = "https://www.gitlab.com/cdc-java";
            final String schema = "https://www.gitlab.com/cdc-java/applic-consistency-data.xsd";
            writer.beginDocument();
            writer.beginElement(CONSISTENCY_DATA);
            writer.addDefaultNamespace(namespace);
            writer.addNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            writer.addAttribute("xsi:schemaLocation",
                                namespace + " " + schema);
            writer.addAttribute(REGISTRY, data.getRegistry().getPath());

            for (final BlockDefImpl root : data.getRootBlocks()) {
                writeNode(writer, data.getRegistry(), root);
            }

            writer.endElement();
            writer.endDocument();
        }

        private static void writeNode(XmlWriter writer,
                                      Dictionary ownerDictionary,
                                      Node node) throws IOException {
            if (node instanceof BlockDefImpl) {
                writeBlockDef(writer, ownerDictionary, (BlockDefImpl) node);
            } else if (node instanceof BlockIncImpl) {
                writeBlockInc(writer, ownerDictionary, (BlockIncImpl) node);
            } else {
                writeReference(writer, ownerDictionary, (ReferenceImpl) node);
            }
        }

        private static void writeBlockDef(XmlWriter writer,
                                          Dictionary ownerDictionary,
                                          BlockDefImpl block) throws IOException {
            writer.beginElement(BLOCK_DEF);

            writer.addAttribute(ID, block.getId());
            if (block.getLabel() != null) {
                writer.addAttribute(LABEL, block.getLabel());
            }
            if (block.getDictionary() != ownerDictionary) {
                writer.addAttribute(POLICY, block.getDictionary().getPath()); // TODO
            }
            if (!block.getApplicability().equals(Expression.TRUE)) {
                writer.addAttribute(APPLICABILITY, block.getApplicability().getContent());
            }
            if (block.getComposition() != Composition.ANY) {
                writer.addAttribute(COMPOSITION, block.getComposition());
            }

            for (final Node child : block.getChildren()) {
                writeNode(writer, block.getDictionary(), child);
            }

            writer.endElement();
        }

        private static void writeBlockInc(XmlWriter writer,
                                          Dictionary ownerDictionary,
                                          BlockIncImpl block) throws IOException {
            writer.beginElement(BLOCK_INC);
            writer.addAttribute(ID, block.getId());
            writer.endElement();
        }

        private static void writeReference(XmlWriter writer,
                                           Dictionary ownerDictionary,
                                           ReferenceImpl ref) throws IOException {
            writer.beginElement(REF);

            writer.addAttribute(ID, ref.getId());
            if (ref.getLabel() != null) {
                writer.addAttribute(LABEL, ref.getLabel());
            }
            if (ref.getDictionary() != ownerDictionary) {
                writer.addAttribute(POLICY, ref.getDictionary().getPath()); // TODO
            }
            if (!ref.getApplicability().equals(Expression.TRUE)) {
                writer.addAttribute(APPLICABILITY, ref.getApplicability().getContent());
            }
            writer.addAttribute(TARGET_ID, ref.getTargetId());

            writer.endElement();
        }
    }

    public static class StAXLoader extends AbstractStAXLoader {
        public StAXLoader(FailureReaction reaction,
                          RepositoryImpl repository) {
            super((reader,
                   systemId) -> new Parser(reader, systemId, reaction, repository));
        }

        private static class Parser extends AbstractStAXParser {
            private final RepositoryImpl repository;

            protected Parser(XMLStreamReader reader,
                             String systemId,
                             FailureReaction reaction,
                             RepositoryImpl repository) {
                super(reader, systemId, reaction);
                this.repository = repository;
            }

            @Override
            protected ConsistencyDataImpl parse() throws XMLStreamException {
                trace("parse()");
                // Move to root start tag
                nextTag();

                if (isStartElement(CONSISTENCY_DATA)) {
                    final ConsistencyDataImpl result = parseConsistencyData();
                    next();
                    return result;
                } else {
                    throw unexpectedEvent();
                }
            }

            /**
             * Must be called when cursor is on {@link #CONSISTENCY_DATA} start tag.
             *
             * @return The parsed consistency data.
             * @throws XMLStreamException When an exception occurs.
             */
            private ConsistencyDataImpl parseConsistencyData() throws XMLStreamException {
                trace("parseConsistencyData()");
                expectStartElement("parseConsistencyData()", CONSISTENCY_DATA);

                final String registryName = getAttributeValue(REGISTRY, null);
                final Registry registry = repository.getRegistry(registryName);

                final ConsistencyDataImpl data = new ConsistencyDataImpl(getSystemId(), registry);

                // Move to next start tag or to end tag of repository
                nextTag();

                while (isStartElement(BLOCK_DEF)) {
                    parseRootBlock(data);
                    nextTag();
                }

                return data;
            }

            /**
             * Must be called when cursor is on root {@link #BLOCK_DEF} start tag.
             *
             * @param data The consistency data.
             * @throws XMLStreamException When an exception occurs.
             */
            private void parseRootBlock(ConsistencyDataImpl data) throws XMLStreamException {
                trace("parseRootBlock()");
                expectStartElement("parseRootBlock()", BLOCK_DEF);

                final String id = getAttributeValue(ID, null);
                final String label = getAttributeValue(LABEL, null);
                final String policyPath = getAttributeValue(POLICY, null);
                final String applicability = getAttributeValue(APPLICABILITY, "true");
                final Composition composition = getAttributeAsEnum(COMPOSITION, Composition.class, Composition.ANY);
                final Dictionary dictionary = policyPath == null
                        ? data.getRegistry()
                        : ((RegistryImpl) data.getRegistry()).getPolicy(policyPath);

                final BlockDefImpl block = data.createRootBlock(id,
                                                                label,
                                                                dictionary,
                                                                new Expression(applicability),
                                                                composition);

                nextTag();
                parseBlockDefChildren(data, block);

                expectEndElement("parseRootBlock()", BLOCK_DEF);
            }

            private void parseBlockDefChildren(ConsistencyDataImpl data,
                                               BlockDefImpl block) throws XMLStreamException {
                trace("parseBlockDefChildren()");

                while (reader.isStartElement()) {
                    if (isStartElement(BLOCK_DEF)) {
                        parseBlockDef(data, block);
                    } else if (isStartElement(BLOCK_INC)) {
                        parseBlockInc(data, block);
                    } else if (isStartElement(REF)) {
                        parseReference(data, block);
                    } else {
                        throw unexpectedEvent();
                    }
                    nextTag();
                }
            }

            private void parseBlockDef(ConsistencyDataImpl data,
                                       BlockDefImpl owner) throws XMLStreamException {
                trace("parseBlockDef()");
                expectStartElement("parseBlockDef()", BLOCK_DEF);

                final String id = getAttributeValue(ID, null);
                final String label = getAttributeValue(LABEL, null);
                final String policyPath = getAttributeValue(POLICY, null);
                final String applicability = getAttributeValue(APPLICABILITY, "true");
                final Composition composition = getAttributeAsEnum(COMPOSITION, Composition.class, Composition.ANY);
                final Dictionary dictionary = policyPath == null
                        ? owner.getDictionary()
                        : ((RegistryImpl) owner.getDictionary().getRegistry()).getPolicy(policyPath);

                final BlockDefImpl block = owner.createBlockDef(data,
                                                                id,
                                                                label,
                                                                dictionary,
                                                                new Expression(applicability),
                                                                composition);
                nextTag();
                parseBlockDefChildren(data, block);
                expectEndElement("parseBlockDef()", BLOCK_DEF);
            }

            private void parseBlockInc(ConsistencyDataImpl data,
                                       BlockDefImpl owner) throws XMLStreamException {
                trace("parseBlockInc()");
                expectStartElement("parseBlockInc()", BLOCK_INC);

                final String id = getAttributeValue(ID, null);
                owner.createBlockInc(data, id);
                nextTag();
                expectEndElement("parseBlockInc()", BLOCK_INC);
            }

            private void parseReference(ConsistencyDataImpl data,
                                        BlockDefImpl owner) throws XMLStreamException {
                trace("parseReference()");
                expectStartElement("parseReference()", REF);

                final String id = getAttributeValue(ID, null);
                final String label = getAttributeValue(LABEL, null);
                final String policyPath = getAttributeValue(POLICY, null);
                final String applicability = getAttributeValue(APPLICABILITY, "true");
                final String targetId = getAttributeValue(TARGET_ID, null);
                final Dictionary dictionary = policyPath == null
                        ? data.getRegistry()
                        : ((RegistryImpl) data.getRegistry()).getPolicy(policyPath);

                owner.createReference(data,
                                      id,
                                      label,
                                      dictionary,
                                      new Expression(applicability),
                                      targetId);
                nextTag();
                expectEndElement("parseReference()", REF);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy