1 package org.opendaylight.controller.sal.rest.impl;
3 import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
5 import java.io.IOException;
6 import java.io.OutputStream;
7 import java.io.OutputStreamWriter;
8 import java.lang.annotation.Annotation;
9 import java.lang.reflect.Type;
10 import java.util.List;
13 import javax.ws.rs.Produces;
14 import javax.ws.rs.WebApplicationException;
15 import javax.ws.rs.core.MediaType;
16 import javax.ws.rs.core.MultivaluedMap;
17 import javax.ws.rs.ext.MessageBodyWriter;
18 import javax.ws.rs.ext.Provider;
20 import org.opendaylight.controller.sal.rest.api.RestconfService;
21 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
22 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
23 import org.opendaylight.yangtools.yang.data.api.Node;
24 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
25 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
26 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
27 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
28 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
30 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
31 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
32 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
33 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
35 import com.google.gson.stream.JsonWriter;
38 @Produces({ API + RestconfService.JSON })
39 public enum StructuredDataToJsonProvider implements MessageBodyWriter<StructuredData> {
43 public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
44 // TODO Auto-generated method stub
49 public long getSize(StructuredData t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
54 public void writeTo(StructuredData t, Class<?> type, Type genericType, Annotation[] annotations,
55 MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
56 throws IOException, WebApplicationException {
57 JsonWriter writer = new JsonWriter(new OutputStreamWriter(entityStream, "UTF-8"));
58 writer.setIndent(" ");
60 convertNodeToJsonAccordingToSchema(writer, t.getData(), t.getSchema());
64 private void convertNodeToJsonAccordingToSchema(JsonWriter writer, Node<?> node, DataSchemaNode dataSchemaNode) throws IOException {
65 if (node instanceof CompositeNode) {
66 if (!(dataSchemaNode instanceof DataNodeContainer)) {
67 throw new IllegalStateException("CompositeNode should be represented as DataNodeContainer");
69 if (dataSchemaNode instanceof ContainerSchemaNode) {
70 writer.name(node.getNodeType().getLocalName());
73 for (Node<?> n : ((CompositeNode) node).getChildren()) {
74 DataSchemaNode foundDataSchemaNode = findSchemaForNode(n, ((DataNodeContainer) dataSchemaNode).getChildNodes());
75 if (foundDataSchemaNode instanceof ListSchemaNode) {
76 if (listName.equals(n.getNodeType().getLocalName())) {
79 listName = n.getNodeType().getLocalName();
81 convertNodeToJsonAccordingToSchema(writer, n, foundDataSchemaNode);
84 } else if (dataSchemaNode instanceof ListSchemaNode) {
85 writer.name(node.getNodeType().getLocalName());
87 List<Node<?>> nodeSiblings = node.getParent().getChildren();
88 for (Node<?> nodeSibling : nodeSiblings) {
89 if (nodeSibling.getNodeType().getLocalName().equals(node.getNodeType().getLocalName())) {
90 DataSchemaNode schemaForNodeSibling = findSchemaForNode(nodeSibling,
91 ((DataNodeContainer) dataSchemaNode.getParent()).getChildNodes());
93 for (Node<?> child : ((CompositeNode) nodeSibling).getChildren()) {
94 DataSchemaNode schemaForChild = findSchemaForNode(child,
95 ((DataNodeContainer) schemaForNodeSibling).getChildNodes());
96 convertNodeToJsonAccordingToSchema(writer, child, schemaForChild);
103 } else if (node instanceof SimpleNode<?>) {
104 if (!(dataSchemaNode instanceof LeafSchemaNode)) {
105 throw new IllegalStateException("SimpleNode should should be represented as LeafSchemaNode");
107 writeLeaf(writer, (LeafSchemaNode) dataSchemaNode, (SimpleNode<?>) node);
111 private DataSchemaNode findSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
112 for (DataSchemaNode dsn : dataSchemaNode) {
113 if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) {
120 private void writeLeaf(JsonWriter writer, LeafSchemaNode leafSchemaNode, SimpleNode<?> data) throws IOException {
121 TypeDefinition<?> type = leafSchemaNode.getType();
123 writer.name(data.getNodeType().getLocalName());
125 if (type instanceof DecimalTypeDefinition) {
126 writer.value((Double.valueOf((String) data.getValue())).doubleValue());
127 } else if (type instanceof IntegerTypeDefinition) {
128 writer.value((Integer.valueOf((String) data.getValue())).intValue());
129 } else if (type instanceof EmptyTypeDefinition) {
130 writer.value("[null]");
132 writer.value(String.valueOf(data.getValue()));