<version>0.7.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>net.java.dev.stax-utils</groupId>
+ <artifactId>stax-utils</artifactId>
+ <version>20070216</version>
+ </dependency>
+
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</Private-Package>
<Import-Package>*,
com.sun.jersey.spi.container.servlet, org.eclipse.jetty.servlets</Import-Package>
+ <Embed-Dependency>stax-utils</Embed-Dependency>
<Web-ContextPath>/restconf</Web-ContextPath>
</instructions>
</configuration>
Draft02.MediaTypes.OPERATION + RestconfService.JSON, MediaType.APPLICATION_JSON })
public class NormalizedNodeJsonBodyWriter implements MessageBodyWriter<NormalizedNodeContext> {
+ private static final int DEFAULT_INDENT_SPACES_NUM = 2;
+
@Override
public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType) {
return type.equals(NormalizedNodeContext.class);
final InstanceIdentifierContext<SchemaNode> context = (InstanceIdentifierContext<SchemaNode>) t.getInstanceIdentifierContext();
SchemaPath path = context.getSchemaNode().getPath();
- final JsonWriter jsonWriter = createJsonWriter(entityStream);
+ final JsonWriter jsonWriter = createJsonWriter(entityStream, t.getWriterParameters().isPrettyPrint());
jsonWriter.beginObject();
writeNormalizedNode(jsonWriter,path,context,data);
jsonWriter.endObject();
return NormalizedNodeWriter.forStreamWriter(streamWriter);
}
- private JsonWriter createJsonWriter(final OutputStream entityStream) {
- // FIXME BUG-2153: Add pretty print support
- return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8));
-
+ private JsonWriter createJsonWriter(final OutputStream entityStream, boolean prettyPrint) {
+ if (prettyPrint) {
+ return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8),
+ DEFAULT_INDENT_SPACES_NUM);
+ } else {
+ return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8));
+ }
}
private JSONCodecFactory getCodecFactory(final InstanceIdentifierContext<?> context) {
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
+import javanet.staxutils.IndentingXMLStreamWriter;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
XMLStreamWriter xmlWriter;
try {
xmlWriter = XML_FACTORY.createXMLStreamWriter(entityStream);
+ if (t.getWriterParameters().isPrettyPrint()) {
+ xmlWriter = new IndentingXMLStreamWriter(xmlWriter);
+ }
} catch (final XMLStreamException e) {
throw new IllegalStateException(e);
} catch (final FactoryConfigurationError e) {
private final InstanceIdentifierContext<? extends SchemaNode> context;
private final NormalizedNode<?,?> data;
+ private final WriterParameters writerParameters;
- public NormalizedNodeContext(final InstanceIdentifierContext<? extends SchemaNode> context, final NormalizedNode<?, ?> data) {
+ public NormalizedNodeContext(final InstanceIdentifierContext<? extends SchemaNode> context,
+ final NormalizedNode<?, ?> data, WriterParameters writerParameters) {
this.context = context;
this.data = data;
+ this.writerParameters = writerParameters;
+ }
+
+ public NormalizedNodeContext(final InstanceIdentifierContext<? extends SchemaNode> context,
+ final NormalizedNode<?, ?> data) {
+ this.context = context;
+ this.data = data;
+ // default writer parameters
+ this.writerParameters = new WriterParameters(false, Integer.MAX_VALUE);
}
public InstanceIdentifierContext<? extends SchemaNode> getInstanceIdentifierContext() {
public NormalizedNode<?, ?> getData() {
return data;
}
+
+ public WriterParameters getWriterParameters() {
+ return writerParameters;
+ }
}
--- /dev/null
+/**
+ * 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.controller.sal.restconf.impl;
+
+import com.google.common.base.Strings;
+import javax.ws.rs.core.UriInfo;
+
+public class QueryParametersParser {
+
+ private enum UriParameters {
+ PRETTY_PRINT("prettyPrint"),
+ DEPTH("depth");
+
+ private String uriParameterName;
+
+ UriParameters(final String uriParameterName) {
+ this.uriParameterName = uriParameterName;
+ }
+
+ @Override
+ public String toString() {
+ return uriParameterName;
+ }
+ }
+
+ public static WriterParameters parseKnownWriterParameters(final UriInfo info) {
+ boolean prettyPrint;
+ int depth;
+ String param = info.getQueryParameters(false).getFirst(UriParameters.DEPTH.toString());
+ if (Strings.isNullOrEmpty(param) || "unbounded".equals(param)) {
+ depth = Integer.MAX_VALUE;
+ } else {
+ try {
+ depth = Integer.valueOf(param);
+ if (depth < 1) {
+ throw new RestconfDocumentedException(new RestconfError(RestconfError.ErrorType.PROTOCOL, RestconfError.ErrorTag.INVALID_VALUE,
+ "Invalid depth parameter: " + depth, null,
+ "The depth parameter must be an integer > 1 or \"unbounded\""));
+ }
+ } catch (final NumberFormatException e) {
+ throw new RestconfDocumentedException(new RestconfError(RestconfError.ErrorType.PROTOCOL, RestconfError.ErrorTag.INVALID_VALUE,
+ "Invalid depth parameter: " + e.getMessage(), null,
+ "The depth parameter must be an integer > 1 or \"unbounded\""));
+ }
+ }
+ param = info.getQueryParameters(false).getFirst(UriParameters.PRETTY_PRINT.toString());
+ prettyPrint = "true".equals(param);
+ return new WriterParameters(prettyPrint, depth);
+ }
+
+}
public class RestconfImpl implements RestconfService {
- private enum UriParameters {
- PRETTY_PRINT("prettyPrint"),
- DEPTH("depth");
-
- private String uriParameterName;
-
- UriParameters(final String uriParameterName) {
- this.uriParameterName = uriParameterName;
- }
-
- @Override
- public String toString() {
- return uriParameterName;
- }
- }
-
private static final RestconfImpl INSTANCE = new RestconfImpl();
private static final int NOTIFICATION_PORT = 8181;
moduleContainerBuilder.withChild(allModuleMap);
return new NormalizedNodeContext(new InstanceIdentifierContext<>(null, modulesSchemaNode,
- null, schemaContext), moduleContainerBuilder.build());
+ null, schemaContext), moduleContainerBuilder.build(),
+ QueryParametersParser.parseKnownWriterParameters(uriInfo));
}
/**
moduleContainerBuilder.withChild(mountPointModulesMap);
return new NormalizedNodeContext(new InstanceIdentifierContext<>(null, modulesSchemaNode,
- mountPoint, controllerContext.getGlobalSchema()), moduleContainerBuilder.build());
+ mountPoint, controllerContext.getGlobalSchema()), moduleContainerBuilder.build(),
+ QueryParametersParser.parseKnownWriterParameters(uriInfo));
}
@Override
Preconditions.checkState(moduleSchemaNode instanceof ListSchemaNode);
return new NormalizedNodeContext(new InstanceIdentifierContext<>(null, moduleSchemaNode, mountPoint,
- schemaContext), moduleMap);
+ schemaContext), moduleMap, QueryParametersParser.parseKnownWriterParameters(uriInfo));
}
@Override
return new NormalizedNodeContext(new InstanceIdentifierContext<>(null, streamsContainerSchemaNode, null,
- schemaContext), streamsContainerBuilder.build());
+ schemaContext), streamsContainerBuilder.build(), QueryParametersParser.parseKnownWriterParameters(uriInfo));
}
@Override
}
return new NormalizedNodeContext(new InstanceIdentifierContext<RpcDefinition>(null,
- resultNodeSchema, mountPoint, schemaContext), resultData);
+ resultNodeSchema, mountPoint, schemaContext), resultData,
+ QueryParametersParser.parseKnownWriterParameters(uriInfo));
}
private DOMRpcResult checkRpcResponse(final CheckedFuture<DOMRpcResult, DOMRpcException> response) {
}
return new NormalizedNodeContext(new InstanceIdentifierContext<>(null, resultNodeSchema, mountPoint,
- schemaContext), resultData);
+ schemaContext), resultData, QueryParametersParser.parseKnownWriterParameters(uriInfo));
}
private RpcDefinition findRpc(final SchemaContext schemaContext, final String identifierDecoded) {
LOG.debug(errMsg + identifier);
throw new RestconfDocumentedException(errMsg, ErrorType.APPLICATION, ErrorTag.DATA_MISSING);
}
- return new NormalizedNodeContext(iiWithData, data);
- }
-
- // FIXME: Move this to proper place
- @SuppressWarnings("unused")
- private Integer parseDepthParameter(final UriInfo info) {
- final String param = info.getQueryParameters(false).getFirst(UriParameters.DEPTH.toString());
- if (Strings.isNullOrEmpty(param) || "unbounded".equals(param)) {
- return null;
- }
-
- try {
- final Integer depth = Integer.valueOf(param);
- if (depth < 1) {
- throw new RestconfDocumentedException(new RestconfError(ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
- "Invalid depth parameter: " + depth, null,
- "The depth parameter must be an integer > 1 or \"unbounded\""));
- }
-
- return depth;
- } catch (final NumberFormatException e) {
- throw new RestconfDocumentedException(new RestconfError(ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
- "Invalid depth parameter: " + e.getMessage(), null,
- "The depth parameter must be an integer > 1 or \"unbounded\""));
- }
+ return new NormalizedNodeContext(iiWithData, data, QueryParametersParser.parseKnownWriterParameters(uriInfo));
}
@Override
- public NormalizedNodeContext readOperationalData(final String identifier, final UriInfo info) {
+ public NormalizedNodeContext readOperationalData(final String identifier, final UriInfo uriInfo) {
final InstanceIdentifierContext<?> iiWithData = controllerContext.toInstanceIdentifier(identifier);
final DOMMountPoint mountPoint = iiWithData.getMountPoint();
NormalizedNode<?, ?> data = null;
LOG.debug(errMsg + identifier);
throw new RestconfDocumentedException(errMsg , ErrorType.APPLICATION, ErrorTag.DATA_MISSING);
}
- return new NormalizedNodeContext(iiWithData, data);
+ return new NormalizedNodeContext(iiWithData, data, QueryParametersParser.parseKnownWriterParameters(uriInfo));
}
@Override
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl;
+
+public class WriterParameters {
+ private final int depth;
+ private final boolean prettyPrint;
+
+ public WriterParameters(final boolean prettyPrint, final int depth) {
+ this.prettyPrint = prettyPrint;
+ this.depth = depth;
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ public boolean isPrettyPrint() {
+ return prettyPrint;
+ }
+}
+