Added ExceptionMapper to RFC-8040 impl
[netconf.git] / restconf / restconf-nb-rfc8040 / src / main / java / org / opendaylight / restconf / nb / rfc8040 / jersey / providers / errors / StreamWriterWithDisabledValidation.java
diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/errors/StreamWriterWithDisabledValidation.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/errors/StreamWriterWithDisabledValidation.java
new file mode 100644 (file)
index 0000000..c5c6568
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2019 FRINX s.r.o. 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.restconf.nb.rfc8040.jersey.providers.errors;
+
+import java.io.IOException;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.ForwardingNormalizedNodeStreamWriter;
+
+/**
+ * Created delegating writer to special-case error-info as error-info is defined as an empty container in the restconf
+ * yang schema but we create a leaf node so we can output it. The delegate stream writer validates the node type against
+ * the schema and thus will expect a LeafSchemaNode but the schema has a ContainerSchemaNode so, to avoid an error,
+ * we override the leafNode behavior for error-info.
+ */
+abstract class StreamWriterWithDisabledValidation extends ForwardingNormalizedNodeStreamWriter {
+
+    private final QName excludedQName;
+    private boolean inOurLeaf;
+
+    /**
+     * Creation of the {@link NormalizedNode} stream-writer with {@link QName} that is excluded from type-check.
+     *
+     * @param excludedQName QName of the element that is excluded from type-check.
+     */
+    StreamWriterWithDisabledValidation(final QName excludedQName) {
+        this.excludedQName = excludedQName;
+    }
+
+    @Override
+    public void startLeafNode(final NodeIdentifier name) throws IOException {
+        if (name.getNodeType().equals(excludedQName)) {
+            inOurLeaf = true;
+            startLeafNodeWithDisabledValidation(name);
+        } else {
+            super.startLeafNode(name);
+        }
+    }
+
+    /**
+     * Writing of the excluded leaf to the output stream.
+     *
+     * @param nodeIdentifier Node identifier of the leaf to be written to output stream.
+     * @throws IOException Writing of the leaf to output stream failed.
+     */
+    abstract void startLeafNodeWithDisabledValidation(NodeIdentifier nodeIdentifier) throws IOException;
+
+    @Override
+    public void scalarValue(final Object value) throws IOException {
+        if (inOurLeaf) {
+            scalarValueWithDisabledValidation(value);
+        } else {
+            super.scalarValue(value);
+        }
+    }
+
+    /**
+     * Writing of the value of the excluded leaf to the output stream.
+     *
+     * @param value Value of the excluded leaf.
+     * @throws IOException Writing of the leaf value to the output stream failed.
+     */
+    abstract void scalarValueWithDisabledValidation(Object value) throws IOException;
+
+    @Override
+    public void endNode() throws IOException {
+        if (inOurLeaf) {
+            inOurLeaf = false;
+            endNodeWithDisabledValidation();
+        } else {
+            super.endNode();
+        }
+    }
+
+    /**
+     * Writing of the end element with disabled validation.
+     *
+     * @throws IOException Writing of the end element to the output stream failed.
+     */
+    abstract void endNodeWithDisabledValidation() throws IOException;
+}
\ No newline at end of file