BUG-7054: add YinStatementStreamSource
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / impl / YinStatementParserImpl.java
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YinStatementParserImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YinStatementParserImpl.java
deleted file mode 100644 (file)
index d2631f6..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.yangtools.yang.parser.impl;
-
-import com.google.common.base.Preconditions;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.YangConstants;
-import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
-import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
-import org.opendaylight.yangtools.yang.parser.spi.source.DeclarationInTextSource;
-import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
-import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
-import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class YinStatementParserImpl {
-
-    private static final Logger LOG = LoggerFactory.getLogger(YinStatementParserImpl.class);
-
-    private final List<String> toBeSkipped = new ArrayList<>();
-    private final String sourceName;
-    private StatementWriter writer;
-    private QNameToStatementDefinition stmtDef;
-    private PrefixToModule prefixes;
-    private String uriStr;
-    private boolean isType = false;
-    private boolean action = true;
-    private boolean yinElement = false;
-
-    public YinStatementParserImpl(final String sourceName) {
-        this.sourceName = Preconditions.checkNotNull(sourceName);
-    }
-
-    /**
-     *
-     * This method is supposed to be called in pre-linkage phase, when YinStatementParserImpl instance has already been
-     * created.
-     * When done, start walking through YIN source
-     *
-     * @param writer - instance of StatementWriter to emit declared statements
-     * @param stmtDef - map of valid statement definitions for linkage phase
-     *
-     */
-    public void setAttributes(final StatementWriter writer, final QNameToStatementDefinition stmtDef) {
-        this.writer = writer;
-        this.stmtDef = stmtDef;
-    }
-
-    /**
-     * This method is supposed to be called in any phase but pre-linkage, when YinStatementParserImpl instance has already
-     * been created.
-     * When done, start walking through YIN source
-     *
-     * @param writer - instance of StatementWriter to emit declared statements
-     * @param stmtDef - map of valid statement definitions for any phase but linkage
-     * @param prefixes - map of valid prefixes for any phase but linkage
-     *
-     */
-    public void setAttributes(final StatementWriter writer, final QNameToStatementDefinition stmtDef, final PrefixToModule prefixes) {
-        this.writer = writer;
-        this.stmtDef = stmtDef;
-        this.prefixes = prefixes;
-    }
-
-    /**
-     * This method executes parsing YIN source and emitting declared statements via attached StatementWriter
-     *
-     * @param inputReader - instance of XMlStreamReader, allows forward, read-only access to XML.
-     */
-    public void walk(final XMLStreamReader inputReader) {
-        try {
-            while (inputReader.hasNext()) {
-                inputReader.next();
-                if (inputReader.hasName() && inputReader.getEventType() == XMLStreamConstants.START_ELEMENT) {
-                    enterStatement(inputReader);
-                }
-
-                if (inputReader.hasName() && inputReader.getEventType() == XMLStreamConstants.END_ELEMENT) {
-                    exitStatement(inputReader);
-                }
-            }
-        } catch (XMLStreamException e) {
-            LOG.warn("Fatal error detecting the next state of XMLStreamReader", e);
-        } catch (URISyntaxException e) {
-            LOG.warn("Given string {} violates RFC2396", uriStr, e);
-        }
-    }
-
-    private void startStatement(final QName identifier, final StatementSourceReference ref) {
-        writer.startStatement(identifier, ref);
-    }
-
-    private void argumentValue(final XMLStreamReader inputReader, final StatementSourceReference ref, final QName identifier, final boolean
-            yinElement) {
-        if (yinElement) {
-            writeTextOnlyElement(inputReader, ref);
-        } else {
-            writeNormalizedAttributeValue(inputReader, identifier, ref);
-        }
-    }
-
-    private void endStatement(final StatementSourceReference ref) {
-        writer.endStatement(ref);
-    }
-
-    private void enterStatement(final XMLStreamReader inputReader) throws URISyntaxException {
-        final StatementSourceReference ref = DeclarationInTextSource.atPosition(sourceName, inputReader
-                .getLocation().getLineNumber(), inputReader.getLocation().getColumnNumber());
-        uriStr = inputReader.getNamespaceURI();
-        final QName identifier = new QName(new URI(uriStr), getElementFullName(inputReader));
-        if (yinElement && toBeSkipped.isEmpty()) {
-            //at yin element, it has be read as argument
-            argumentValue(inputReader, ref, identifier, true);
-        } else {
-            if (isStatementWithYinElement(identifier, stmtDef)) {
-                //at statement with yin element, so next statement will be read as argument
-                yinElement = true;
-            }
-
-            final QName validStatementDefinition = Utils.getValidStatementDefinition(prefixes, stmtDef, identifier);
-
-            //main part -> valid statement for actual phase
-            if (stmtDef != null && validStatementDefinition != null && toBeSkipped.isEmpty()) {
-                if (identifier.equals(Rfc6020Mapping.TYPE.getStatementName())) {
-                    isType = true;
-                } else {
-                    startStatement(validStatementDefinition, ref);
-                    if (isStatementWithYinElement(identifier, stmtDef)) {
-                        action = false;
-                    }
-                }
-            } else {
-                //if statement not found through all phases, throw exception
-                SourceException.throwIf(writer.getPhase().equals(ModelProcessingPhase.FULL_DECLARATION), ref,
-                    "%s is not a YIN statement or use of extension.", identifier.getLocalName());
-
-                //otherwise skip it (statement not to be read yet)
-                action = false;
-                toBeSkipped.add(getElementFullName(inputReader));
-            }
-
-            if (isType) {
-                writeTypeStmtAndArg(inputReader, identifier, ref);
-            } else if (action & isStatementWithArgument(identifier, stmtDef)) {
-                argumentValue(inputReader, ref, identifier, false);
-            } else {
-                action = true;
-            }
-        }
-    }
-
-    private void exitStatement(final XMLStreamReader inputReader) throws URISyntaxException {
-        final String statementName = getElementFullName(inputReader);
-        final QName identifier = new QName(new URI(inputReader.getNamespaceURI()), statementName);
-        final StatementSourceReference ref = DeclarationInTextSource.atPosition(sourceName, inputReader
-                .getLocation().getLineNumber(), inputReader.getLocation().getColumnNumber());
-        final QName validStatementDefinition = Utils.getValidStatementDefinition(prefixes, stmtDef, identifier);
-
-        if ((stmtDef != null && validStatementDefinition != null && toBeSkipped.isEmpty()) && !yinElement) {
-            endStatement(ref);
-        }
-
-        //back to normal mode
-        if (yinElement) {
-            yinElement = false;
-        }
-
-        if (toBeSkipped.contains(statementName)) {
-            toBeSkipped.remove(statementName);
-        }
-    }
-
-    private void writeTextOnlyElement(final XMLStreamReader inputReader, final StatementSourceReference ref) {
-        try {
-            writer.argumentValue(inputReader.getElementText(), ref);
-        } catch (XMLStreamException e) {
-            LOG.warn("Current event is not a START_ELEMENT or a non text element is encountered ", ref, e);
-        }
-    }
-
-    private void writeNormalizedAttributeValue(final XMLStreamReader inputReader, final QName
-            identifier, final StatementSourceReference ref) {
-        final String attributeValue = getAttributeValue(inputReader, identifier, stmtDef);
-        if (attributeValue != null) {
-            writer.argumentValue(attributeValue, ref);
-        }
-    }
-
-    private void writeTypeStmtAndArg(final XMLStreamReader inputReader, final QName identifier, final StatementSourceReference ref) {
-        String argument = getAttributeValue(inputReader, identifier, stmtDef);
-        if (TypeUtils.isYangTypeBodyStmtString(argument)) {
-            startStatement(new QName(YangConstants.RFC6020_YIN_NAMESPACE, argument), ref);
-        } else {
-            startStatement(new QName(YangConstants.RFC6020_YIN_NAMESPACE, Rfc6020Mapping
-                    .TYPE.getStatementName().getLocalName()), ref);
-        }
-        argumentValue(inputReader, ref, identifier, false);
-        isType = false;
-    }
-
-    private static String getElementFullName(final XMLStreamReader inputReader) {
-        if (!inputReader.getPrefix().isEmpty()) {
-            return inputReader.getPrefix() + ":" + inputReader.getLocalName();
-        } else {
-            return inputReader.getLocalName();
-        }
-    }
-
-    private boolean isStatementWithArgument(final QName identifier, final QNameToStatementDefinition stmtDef) {
-        StatementDefinition statementDefinition = getStatementDefinition(identifier, stmtDef);
-        if (statementDefinition == null) {
-            return false;
-        } else if (((StatementSupport<?, ?, ?>) statementDefinition).getPublicView().getArgumentName() == null) {
-            return false;
-        }
-        return true;
-    }
-
-    private boolean isStatementWithYinElement(final QName identifier, final QNameToStatementDefinition stmtDef) {
-        StatementDefinition statementDefinition = getStatementDefinition(identifier, stmtDef);
-        if (statementDefinition == null) {
-            return false;
-        }
-        return statementDefinition.isArgumentYinElement();
-    }
-
-    private String getAttributeValue(final XMLStreamReader inputReader, final QName identifier, final QNameToStatementDefinition
-            stmtDef) {
-        String namespace = null;
-        return inputReader.getAttributeValue(namespace, (((StatementSupport<?, ?, ?>) getStatementDefinition(identifier, stmtDef))
-                .getPublicView()).getArgumentName().getLocalName());
-    }
-
-    private StatementDefinition getStatementDefinition(final QName identifier, final QNameToStatementDefinition stmtDef) {
-        final QName trimPrefixIdentifier = Utils.trimPrefix(identifier);
-        return stmtDef.getByNamespaceAndLocalName(trimPrefixIdentifier.getNamespace(),
-                trimPrefixIdentifier.getLocalName());
-    }
-}
\ No newline at end of file