import java.io.OutputStreamWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
-import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.Provider;
import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
import org.opendaylight.restconf.common.context.NormalizedNodeContext;
-import org.opendaylight.restconf.nb.rfc8040.Rfc8040;
+import org.opendaylight.restconf.nb.rfc8040.MediaTypes;
import org.opendaylight.restconf.nb.rfc8040.jersey.providers.api.RestconfNormalizedNodeWriter;
-import org.opendaylight.restconf.nb.rfc8040.utils.RestconfConstants;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.common.XMLNamespace;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter;
import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
@Provider
-@Produces({ Rfc8040.MediaTypes.DATA + RestconfConstants.JSON, MediaType.APPLICATION_JSON })
+@Produces({ MediaTypes.APPLICATION_YANG_DATA_JSON, MediaType.APPLICATION_JSON })
public class NormalizedNodeJsonBodyWriter implements MessageBodyWriter<NormalizedNodeContext> {
private static final int DEFAULT_INDENT_SPACES_NUM = 2;
final MediaType mediaType,
final MultivaluedMap<String, Object> httpHeaders,
final OutputStream entityStream) throws IOException, WebApplicationException {
- final NormalizedNode<?, ?> data = context.getData();
+ final NormalizedNode data = context.getData();
if (data == null) {
return;
}
jsonWriter.endObject();
jsonWriter.flush();
}
+
+ if (httpHeaders != null) {
+ for (final Map.Entry<String, Object> entry : context.getNewHeaders().entrySet()) {
+ httpHeaders.add(entry.getKey(), entry.getValue());
+ }
+ }
}
private static void writeNormalizedNode(final JsonWriter jsonWriter,
- final SchemaPath path, final InstanceIdentifierContext<SchemaNode> context, final NormalizedNode<?, ?> data,
+ final SchemaPath path, final InstanceIdentifierContext<SchemaNode> context, final NormalizedNode data,
final Integer depth, final List<Set<QName>> fields) throws IOException {
final RestconfNormalizedNodeWriter nnWriter;
jsonWriter,
depth,
fields);
- final Module module = context.getSchemaContext().findModule(data.getNodeType().getModule()).get();
+ final Module module = context.getSchemaContext().findModule(data.getIdentifier().getNodeType().getModule())
+ .get();
+ jsonWriter.name(module.getName() + ":output");
+ jsonWriter.beginObject();
+ writeChildren(nnWriter, (ContainerNode) data);
+ jsonWriter.endObject();
+ } else if (context.getSchemaNode() instanceof ActionDefinition) {
+ /*
+ * ActionDefinition is not supported as initial codec in JSONStreamWriter,
+ * so we need to emit initial output declaration..
+ */
+ nnWriter = createNormalizedNodeWriter(context,
+ ((ActionDefinition) context.getSchemaNode()).getOutput().getPath(), jsonWriter, depth, fields);
+ final Module module = context.getSchemaContext().findModule(data.getIdentifier().getNodeType().getModule())
+ .get();
jsonWriter.name(module.getName() + ":output");
jsonWriter.beginObject();
writeChildren(nnWriter, (ContainerNode) data);
if (data instanceof MapEntryNode) {
// Restconf allows returning one list item. We need to wrap it
// in map node in order to serialize it properly
- nnWriter.write(
- ImmutableNodes.mapNodeBuilder(data.getNodeType()).withChild((MapEntryNode) data).build());
+ nnWriter.write(ImmutableNodes.mapNodeBuilder(data.getIdentifier().getNodeType())
+ .withChild((MapEntryNode) data)
+ .build());
} else {
nnWriter.write(data);
}
nnWriter.flush();
}
- private static void writeChildren(final RestconfNormalizedNodeWriter nnWriter,
- final ContainerNode data) throws IOException {
- for (final DataContainerChild<? extends PathArgument, ?> child : data.getValue()) {
+ private static void writeChildren(final RestconfNormalizedNodeWriter nnWriter, final ContainerNode data)
+ throws IOException {
+ for (final DataContainerChild child : data.body()) {
nnWriter.write(child);
}
}
final JSONCodecFactory codecs = getCodecFactory(context);
final NormalizedNodeStreamWriter streamWriter = JSONNormalizedNodeStreamWriter.createNestedWriter(
- codecs, path, initialNamespaceFor(schema, depth), jsonWriter);
+ codecs, path, initialNamespaceFor(schema), jsonWriter);
return ParameterAwareNormalizedNodeWriter.forStreamWriter(streamWriter, depth, fields);
}
- private static URI initialNamespaceFor(final SchemaNode schema, final Integer depth) {
+ private static XMLNamespace initialNamespaceFor(final SchemaNode schema) {
if (schema instanceof RpcDefinition) {
return schema.getQName().getNamespace();
}
// For top-level elements we always want to use namespace prefix, hence use a null initial namespace
- if (depth == null || depth == 0 || schema instanceof SchemaContext) {
- return null;
- }
- return schema instanceof DataSchemaNode && !((DataSchemaNode)schema).isAugmenting()
- ? schema.getQName().getNamespace() : null;
+ return null;
}
private static JsonWriter createJsonWriter(final OutputStream entityStream, final boolean prettyPrint) {