Add DatabindContext and its wiring
[netconf.git] / restconf / restconf-nb / src / main / java / org / opendaylight / restconf / nb / rfc8040 / jersey / providers / errors / RestconfDocumentedExceptionMapper.java
index ebc7c5eda68d5419bf5f871cb15e48f09d7c2555..536e163269e9a8a8299a1b910d31576ca68fd641 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.restconf.nb.rfc8040.jersey.providers.errors;
 
 import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
 import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.$YangModuleInfoImpl.qnameOf;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -33,22 +34,17 @@ import org.opendaylight.restconf.common.ErrorTags;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError;
 import org.opendaylight.restconf.nb.rfc8040.MediaTypes;
-import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
+import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.errors.Errors;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.rev170126.errors.errors.Error;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -61,27 +57,25 @@ public final class RestconfDocumentedExceptionMapper implements ExceptionMapper<
     private static final Logger LOG = LoggerFactory.getLogger(RestconfDocumentedExceptionMapper.class);
     private static final MediaType DEFAULT_MEDIA_TYPE = MediaType.APPLICATION_JSON_TYPE;
     private static final Status DEFAULT_STATUS_CODE = Status.INTERNAL_SERVER_ERROR;
-    // Note: we are using container's QName reference to trim imports
-    private static final SchemaPath ERRORS_GROUPING_PATH = SchemaPath.create(true, Errors.QNAME);
     private static final QName ERROR_TYPE_QNAME = qnameOf("error-type");
     private static final QName ERROR_TAG_QNAME = qnameOf("error-tag");
     private static final QName ERROR_APP_TAG_QNAME = qnameOf("error-app-tag");
     private static final QName ERROR_MESSAGE_QNAME = qnameOf("error-message");
-    private static final QName ERROR_INFO_QNAME = qnameOf("error-info");
     private static final QName ERROR_PATH_QNAME = qnameOf("error-path");
-    private static final XMLNamespace IETF_RESTCONF_URI = Errors.QNAME.getModule().getNamespace();
+    static final QName ERROR_INFO_QNAME = qnameOf("error-info");
+
+    private final DatabindProvider databindProvider;
 
     @Context
     private HttpHeaders headers;
-    private final SchemaContextHandler schemaContextHandler;
 
     /**
      * Initialization of the exception mapper.
      *
-     * @param schemaContextHandler Handler that provides actual schema context.
+     * @param databindProvider A {@link DatabindProvider}
      */
-    public RestconfDocumentedExceptionMapper(final SchemaContextHandler schemaContextHandler) {
-        this.schemaContextHandler = schemaContextHandler;
+    public RestconfDocumentedExceptionMapper(final DatabindProvider databindProvider) {
+        this.databindProvider = requireNonNull(databindProvider);
     }
 
     @Override
@@ -123,9 +117,9 @@ public final class RestconfDocumentedExceptionMapper implements ExceptionMapper<
      * @return Built errors container.
      */
     private static ContainerNode buildErrorsContainer(final RestconfDocumentedException exception) {
-        return ImmutableContainerNodeBuilder.create()
+        return Builders.containerBuilder()
             .withNodeIdentifier(NodeIdentifier.create(Errors.QNAME))
-            .withChild(ImmutableUnkeyedListNodeBuilder.create()
+            .withChild(Builders.unkeyedListBuilder()
                 .withNodeIdentifier(NodeIdentifier.create(Error.QNAME))
                 .withValue(exception.getErrors().stream()
                     .map(RestconfDocumentedExceptionMapper::createErrorEntry)
@@ -142,11 +136,10 @@ public final class RestconfDocumentedExceptionMapper implements ExceptionMapper<
      */
     private static UnkeyedListEntryNode createErrorEntry(final RestconfError restconfError) {
         // filling in mandatory leafs
-        final DataContainerNodeBuilder<NodeIdentifier, UnkeyedListEntryNode> entryBuilder =
-            ImmutableUnkeyedListEntryNodeBuilder.create()
-                .withNodeIdentifier(NodeIdentifier.create(Error.QNAME))
-                .withChild(ImmutableNodes.leafNode(ERROR_TYPE_QNAME, restconfError.getErrorType().elementBody()))
-                .withChild(ImmutableNodes.leafNode(ERROR_TAG_QNAME, restconfError.getErrorTag().elementBody()));
+        final var entryBuilder = Builders.unkeyedListEntryBuilder()
+            .withNodeIdentifier(NodeIdentifier.create(Error.QNAME))
+            .withChild(ImmutableNodes.leafNode(ERROR_TYPE_QNAME, restconfError.getErrorType().elementBody()))
+            .withChild(ImmutableNodes.leafNode(ERROR_TAG_QNAME, restconfError.getErrorTag().elementBody()));
 
         // filling in optional fields
         if (restconfError.getErrorMessage() != null) {
@@ -178,8 +171,8 @@ public final class RestconfDocumentedExceptionMapper implements ExceptionMapper<
         try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
              OutputStreamWriter streamStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
         ) {
-            return writeNormalizedNode(errorsContainer, outputStream, new JsonStreamWriterWithDisabledValidation(
-                ERROR_INFO_QNAME, streamStreamWriter, ERRORS_GROUPING_PATH, IETF_RESTCONF_URI, schemaContextHandler));
+            return writeNormalizedNode(errorsContainer, outputStream,
+                new JsonStreamWriterWithDisabledValidation(databindProvider.currentContext(), streamStreamWriter));
         } catch (IOException e) {
             throw new IllegalStateException("Cannot close some of the output JSON writers", e);
         }
@@ -193,8 +186,8 @@ public final class RestconfDocumentedExceptionMapper implements ExceptionMapper<
      */
     private String serializeErrorsContainerToXml(final ContainerNode errorsContainer) {
         try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
-            return writeNormalizedNode(errorsContainer, outputStream, new XmlStreamWriterWithDisabledValidation(
-                ERROR_INFO_QNAME, outputStream, ERRORS_GROUPING_PATH, schemaContextHandler));
+            return writeNormalizedNode(errorsContainer, outputStream,
+                new XmlStreamWriterWithDisabledValidation(databindProvider.currentContext(), outputStream));
         } catch (IOException e) {
             throw new IllegalStateException("Cannot close some of the output XML writers", e);
         }
@@ -366,6 +359,6 @@ public final class RestconfDocumentedExceptionMapper implements ExceptionMapper<
      */
     @VisibleForTesting
     void setHttpHeaders(final HttpHeaders httpHeaders) {
-        this.headers = httpHeaders;
+        headers = httpHeaders;
     }
 }