BUG-7054: add YinStatementStreamSource 36/47736/9
authorRobert Varga <rovarga@cisco.com>
Fri, 28 Oct 2016 12:42:04 +0000 (14:42 +0200)
committerRobert Varga <rovarga@cisco.com>
Sat, 29 Oct 2016 23:16:57 +0000 (01:16 +0200)
This is a basic stream source, which traverses a DOM node
and its children, emitting stream events.

Change-Id: I536bd97c4b94a818cdf366b0028251f1100d9667
Signed-off-by: Robert Varga <rovarga@cisco.com>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YinStatementParserImpl.java [deleted file]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc6020/repo/YinStatementStreamSource.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc6020/repo/YinTextToDomTransformer.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YinStatementSourceImpl.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
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc6020/repo/YinStatementStreamSource.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc6020/repo/YinStatementStreamSource.java
new file mode 100644 (file)
index 0000000..3a6d46e
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * 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.rfc6020.repo;
+
+import static org.opendaylight.yangtools.yang.parser.rfc6020.repo.StatementSourceReferenceHandler.extractRef;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import java.net.URI;
+import java.net.URISyntaxException;
+import javax.xml.transform.TransformerException;
+import org.opendaylight.yangtools.concepts.Identifiable;
+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.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YinDomSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.api.YinXmlSchemaSource;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
+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.StatementStreamSource;
+import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * A {@link StatementStreamSource} based on a {@link YinXmlSchemaSource}. Internal implementation works on top
+ * of {@link YinDomSchemaSource} and its DOM document.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public final class YinStatementStreamSource implements Identifiable<SourceIdentifier>, StatementStreamSource {
+    private static final Logger LOG = LoggerFactory.getLogger(YinStatementStreamSource.class);
+    private static final LoadingCache<String, URI> URI_CACHE = CacheBuilder.newBuilder().weakValues().build(
+        new CacheLoader<String, URI>() {
+            @Override
+            public URI load(final String key) throws URISyntaxException {
+                return new URI(key);
+            }
+    });
+    private final SourceIdentifier identifier;
+    private final Node root;
+
+    private YinStatementStreamSource(final SourceIdentifier identifier, final Node root) {
+        this.identifier = Preconditions.checkNotNull(identifier);
+        this.root = Preconditions.checkNotNull(root);
+    }
+
+    public static StatementStreamSource create(final YinXmlSchemaSource source) throws TransformerException {
+        return create(YinDomSchemaSource.transform(source));
+    }
+
+    public static StatementStreamSource create(final YinDomSchemaSource source) {
+        return new YinStatementStreamSource(source.getIdentifier(), source.getSource().getNode());
+    }
+
+    @Override
+    public SourceIdentifier getIdentifier() {
+        return identifier;
+    }
+
+    private static StatementDefinition getValidDefinition(final Node node, final StatementWriter writer,
+            final QNameToStatementDefinition stmtDef, final StatementSourceReference ref) {
+        final URI uri = URI_CACHE.getUnchecked(node.getNamespaceURI());
+        final StatementDefinition def = stmtDef.getByNamespaceAndLocalName(uri, node.getLocalName());
+
+        if (def == null) {
+            SourceException.throwIf(writer.getPhase().equals(ModelProcessingPhase.FULL_DECLARATION), ref,
+                "%s is not a YIN statement or use of extension.", node.getLocalName());
+        }
+        return def;
+    }
+
+    private static void processAttribute(final Attr attr, final StatementWriter writer,
+            final QNameToStatementDefinition stmtDef, final StatementSourceReference ref) {
+        final StatementDefinition def = getValidDefinition(attr, writer, stmtDef, ref);
+        if (def == null) {
+            return;
+        }
+
+        writer.startStatement(def.getStatementName(), ref);
+        final String value = attr.getValue();
+        if (!value.isEmpty()) {
+            writer.argumentValue(value, ref);
+        }
+        writer.endStatement(ref);
+    }
+
+    private static String getArgValue(final Element element, final QName argName, final boolean yinElement) {
+        if (yinElement) {
+            final NodeList children = element.getElementsByTagNameNS(argName.getNamespace().toString(),
+                argName.getLocalName());
+            if (children.getLength() == 0) {
+                return null;
+            }
+            return children.item(0).getTextContent();
+        }
+
+        final Attr attr = element.getAttributeNode(argName.getLocalName());
+        if (attr == null) {
+            return null;
+        }
+
+        return attr.getValue();
+    }
+
+    private static void processElement(final Element element, final StatementWriter writer,
+            final QNameToStatementDefinition stmtDef) {
+        final StatementSourceReference ref = extractRef(element);
+        final StatementDefinition def = getValidDefinition(element, writer, stmtDef, ref);
+        if (def == null) {
+            LOG.debug("Skipping element {}", element);
+            return;
+        }
+
+        final QName argName = def.getArgumentName();
+        final String argValue;
+        final boolean allAttrs;
+        final boolean allElements;
+        if (argName != null) {
+            allAttrs = def.isArgumentYinElement();
+            allElements = !allAttrs;
+
+            argValue = getArgValue(element, argName, allAttrs);
+            SourceException.throwIfNull(argValue, ref, "Statement {} is missing mandatory argument %s",
+                def.getStatementName(), argName);
+        } else {
+            argValue = null;
+            allAttrs = false;
+            allElements = false;
+        }
+
+        // FIXME: this is a hack
+        if (element.getLocalName().equals(Rfc6020Mapping.TYPE.getStatementName().getLocalName())) {
+            LOG.debug("Type statement encountered, arg {}", argValue);
+            Preconditions.checkArgument(argValue != null);
+            if (TypeUtils.isYangTypeBodyStmtString(argValue)) {
+                writer.startStatement(QName.create(YangConstants.RFC6020_YIN_MODULE, argValue), ref);
+            } else {
+                writer.startStatement(QName.create(YangConstants.RFC6020_YIN_MODULE, Rfc6020Mapping
+                    .TYPE.getStatementName().getLocalName()), ref);
+            }
+            writer.argumentValue(argValue, ref);
+        } else {
+            writer.startStatement(def.getStatementName(), ref);
+            if (argValue != null) {
+                writer.argumentValue(argValue, ref);
+            }
+        }
+
+        // First process any statements defined as attributes. We need to skip argument, if present
+        final NamedNodeMap attributes = element.getAttributes();
+        if (attributes != null) {
+            for (int i = 0, len = attributes.getLength(); i < len; ++i) {
+                final Attr attr = (Attr) attributes.item(i);
+                if (allAttrs || !isArgument(argName, attr)) {
+                    processAttribute(attr, writer, stmtDef, ref);
+                }
+            }
+        }
+
+        // Now process child elements, if present
+        final NodeList children = element.getChildNodes();
+        for (int i = 0, len = children.getLength(); i < len; ++i) {
+            final Node child = children.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                if (allElements || !isArgument(argName, child)) {
+                    processElement((Element) child, writer, stmtDef);
+                }
+            }
+        }
+
+        writer.endStatement(ref);
+    }
+
+    private static boolean isArgument(final QName argName, final Node node) {
+        return argName != null && argName.getLocalName().equals(node.getLocalName()) && node.getPrefix() == null;
+    }
+
+    private void walkTree(final StatementWriter writer, final QNameToStatementDefinition stmtDef) {
+        final NodeList children = root.getChildNodes();
+        for (int i = 0, len = children.getLength(); i < len; ++i) {
+            final Node child = children.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                processElement((Element) child, writer, stmtDef);
+            }
+        }
+    }
+
+    @Override
+    public void writePreLinkage(final StatementWriter writer, final QNameToStatementDefinition stmtDef) {
+        walkTree(writer, stmtDef);
+    }
+
+    @Override
+    public void writeLinkage(final StatementWriter writer, final QNameToStatementDefinition stmtDef,
+            final PrefixToModule preLinkagePrefixes) {
+        walkTree(writer, stmtDef);
+    }
+
+    @Override
+    public void writeLinkageAndStatementDefinitions(final StatementWriter writer,
+            final QNameToStatementDefinition stmtDef, final PrefixToModule prefixes) {
+        walkTree(writer, stmtDef);
+    }
+
+    @Override
+    public void writeFull(final StatementWriter writer, final QNameToStatementDefinition stmtDef,
+            final PrefixToModule prefixes) {
+        walkTree(writer, stmtDef);
+    }
+}
index e600f523992ef6b12b8d213e18ff2c9c9019b089..95937d22f31db608d1519e6e7cfdd1ecf5d692d4 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.yangtools.yang.parser.rfc6020.repo;
 
 import com.google.common.annotations.Beta;
 import com.google.common.util.concurrent.Futures;
-import java.io.IOException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.transform.dom.DOMSource;
 import org.opendaylight.yangtools.util.xml.UntrustedXML;
@@ -19,7 +18,6 @@ import org.opendaylight.yangtools.yang.model.repo.api.YinTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
 import org.opendaylight.yangtools.yang.model.repo.util.SchemaSourceTransformer;
 import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
 
 /**
@@ -30,21 +28,23 @@ import org.xml.sax.helpers.DefaultHandler;
  */
 @Beta
 public final class YinTextToDomTransformer extends SchemaSourceTransformer<YinTextSchemaSource, YinDomSchemaSource> {
+
+    @Deprecated
+    public static final Transformation<YinTextSchemaSource, YinDomSchemaSource> TRANSFORMATION = input -> {
+        final Document doc = UntrustedXML.newDocumentBuilder().newDocument();
+        final SAXParser parser = UntrustedXML.newSAXParser();
+        final DefaultHandler handler = new StatementSourceReferenceHandler(doc, null);
+        parser.parse(input.openStream(), handler);
+
+        return Futures.immediateCheckedFuture(YinDomSchemaSource.create(input.getIdentifier(), new DOMSource(doc)));
+    };
+
     private YinTextToDomTransformer(final SchemaRepository provider, final SchemaSourceRegistry consumer) {
-        super(provider, YinTextSchemaSource.class, consumer, YinDomSchemaSource.class,
-            input -> Futures.immediateCheckedFuture(parseDocument(input)));
+        super(provider, YinTextSchemaSource.class, consumer, YinDomSchemaSource.class, TRANSFORMATION);
     }
 
     public static YinTextToDomTransformer create(final SchemaRepository provider, final SchemaSourceRegistry consumer) {
         return new YinTextToDomTransformer(provider, consumer);
     }
 
-    private static YinDomSchemaSource parseDocument(final YinTextSchemaSource source) throws IOException, SAXException {
-        final Document doc = UntrustedXML.newDocumentBuilder().newDocument();
-        final SAXParser parser = UntrustedXML.newSAXParser();
-        final DefaultHandler handler = new StatementSourceReferenceHandler(doc, null);
-        parser.parse(source.openStream(), handler);
-
-        return YinDomSchemaSource.create(source.getIdentifier(), new DOMSource(doc));
-    }
 }
index 7a4fcdc60a23e4545087d6b42eb107fe970fa206..193dda56748b32eae786dbe53e8420b1f0e6621e 100644 (file)
 
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
-import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ForwardingObject;
+import com.google.common.io.ByteSource;
 import com.google.common.io.ByteStreams;
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
+import com.google.common.io.Files;
 import java.io.File;
-import java.io.IOException;
 import java.io.InputStream;
-import java.net.URISyntaxException;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import org.opendaylight.yangtools.yang.parser.impl.YinStatementParserImpl;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YinDomSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.api.YinTextSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc6020.repo.YinStatementStreamSource;
+import org.opendaylight.yangtools.yang.parser.rfc6020.repo.YinTextToDomTransformer;
 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.StatementStreamSource;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
-import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  *
  * This class represents implementation of StatementStreamSource
  * in order to emit YIN statements using supplied StatementWriter
  *
+ * @deprecated Scheduled for removal. Use {@link YinStatementStreamSource} instead.
  */
-public class YinStatementSourceImpl implements StatementStreamSource {
+@Deprecated
+public final class YinStatementSourceImpl extends ForwardingObject implements StatementStreamSource {
+    private final StatementStreamSource delegate;
 
-    private static final Logger LOG = LoggerFactory.getLogger(YinStatementSourceImpl.class);
-    private static XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
+    private YinStatementSourceImpl(final YinDomSchemaSource source) {
+        this.delegate = YinStatementStreamSource.create(source);
+    }
 
-    private YinStatementParserImpl yinStatementModelParser;
-    private XMLStreamReader streamReader;
-    private InputStream inputStream;
-    private String fileName;
-    private boolean isAbsolute;
+    @Override
+    public StatementStreamSource delegate() {
+        return delegate;
+    }
 
-    // FIXME IO exception: input stream closed when called from StmtTestUtils parserseYinSources method
     public YinStatementSourceImpl(final InputStream inputStream) {
-        yinStatementModelParser = new YinStatementParserImpl(inputStream.toString());
-        this.inputStream = new BufferedInputStream(inputStream);
-        this.inputStream.mark(Integer.MAX_VALUE);
+        this(newStreamSource(inputStream));
     }
 
-    public YinStatementSourceImpl(final String fileName, final boolean isAbsolute) {
-        yinStatementModelParser = new YinStatementParserImpl(fileName);
-        this.fileName = Preconditions.checkNotNull(fileName);
-        this.isAbsolute = isAbsolute;
+    private static YinDomSchemaSource newStreamSource(final InputStream inputStream) {
+        final SourceIdentifier id = YinTextSchemaSource.identifierFromFilename(inputStream.toString());
+
+        try {
+            final YinTextSchemaSource text = YinTextSchemaSource.delegateForByteSource(id,
+                ByteSource.wrap(ByteStreams.toByteArray(inputStream)));
+            return YinTextToDomTransformer.TRANSFORMATION.apply(text).get();
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
     }
 
-    @Override
-    public void writePreLinkage(StatementWriter writer, QNameToStatementDefinition stmtDef) {
-        initializeReader();
-        yinStatementModelParser.setAttributes(writer, stmtDef);
-        yinStatementModelParser.walk(streamReader);
+    private static YinDomSchemaSource newStreamSource(final String fileName, final boolean isAbsolute) {
+        try {
+            final File file;
+            if (isAbsolute) {
+                file = new File(fileName);
+            } else {
+                file = new File(YinStatementSourceImpl.class.getResource(fileName).toURI());
+            }
+
+            final YinTextSchemaSource text = YinTextSchemaSource.delegateForByteSource(
+                YinTextSchemaSource.identifierFromFilename(file.getName()), Files.asByteSource(file));
+
+            return YinTextToDomTransformer.TRANSFORMATION.apply(text).get();
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
     }
 
-    @Override
-    public void writeLinkage(StatementWriter writer, QNameToStatementDefinition stmtDef, final PrefixToModule preLinkagePrefixes) {
-        initializeReader();
-        yinStatementModelParser.setAttributes(writer, stmtDef, preLinkagePrefixes);
-        yinStatementModelParser.walk(streamReader);
+    public YinStatementSourceImpl(final String fileName, final boolean isAbsolute) {
+        this(newStreamSource(fileName, isAbsolute));
     }
 
     @Override
-    public void writeLinkageAndStatementDefinitions(StatementWriter writer, QNameToStatementDefinition stmtDef,
-            PrefixToModule prefixes) {
-        initializeReader();
-        yinStatementModelParser.setAttributes(writer, stmtDef, prefixes);
-        yinStatementModelParser.walk(streamReader);
+    public void writePreLinkage(final StatementWriter writer, final QNameToStatementDefinition stmtDef) {
+        delegate.writePreLinkage(writer, stmtDef);
     }
 
     @Override
-    public void writeFull(StatementWriter writer, QNameToStatementDefinition stmtDef, PrefixToModule prefixes) {
-        initializeReader();
-        yinStatementModelParser.setAttributes(writer, stmtDef, prefixes);
-        yinStatementModelParser.walk(streamReader);
-        closeReader();
+    public void writeLinkage(final StatementWriter writer, final QNameToStatementDefinition stmtDef,
+            final PrefixToModule preLinkagePrefixes) {
+        delegate.writeLinkage(writer, stmtDef, preLinkagePrefixes);
+
     }
 
-    private void initializeReader() {
-        try {
-            if (fileName != null) {
-                inputStream = loadFile(fileName, isAbsolute);
-                streamReader = xmlInputFactory.createXMLStreamReader(inputStream);
-            } else {
-                inputStream.reset();
-                streamReader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(ByteStreams.toByteArray
-                        (inputStream)));
-            }
-        } catch (XMLStreamException e) {
-            LOG.warn("Error while creating XMLStreamReader from input stream", e);
-        } catch (URISyntaxException e) {
-            LOG.warn("File name {} cannot be parsed as URI reference", fileName, e);
-        } catch (IOException e) {
-            LOG.warn("File {} cannot be found or read into string ", fileName, e);
-        }
+    @Override
+    public void writeLinkageAndStatementDefinitions(final StatementWriter writer, final QNameToStatementDefinition stmtDef,
+            final PrefixToModule prefixes) {
+        delegate.writeLinkageAndStatementDefinitions(writer, stmtDef, prefixes);
     }
 
-    private void closeReader() {
-        try {
-            inputStream.close();
-            streamReader.close();
-        } catch (XMLStreamException e) {
-            LOG.warn("Error occured while freeing associated resources", e);
-        } catch (IOException e) {
-            LOG.warn("I/O error occured during closing the input stream", e);
-        }
+    @Override
+    public void writeFull(final StatementWriter writer, final QNameToStatementDefinition stmtDef,
+            final PrefixToModule prefixes) {
+        delegate().writeFull(writer, stmtDef, prefixes);
     }
 
-    private InputStream loadFile(final String fileName, boolean isAbsolute) throws URISyntaxException, IOException {
-        final File file;
-        if (isAbsolute) {
-            file = new File(fileName);
-        } else {
-            file = new File(getClass().getResource(fileName).toURI());
-        }
 
-        return new NamedFileInputStream(file, fileName);
-    }
 }
\ No newline at end of file