*/
package org.opendaylight.yangtools.yang.data.codec.gson;
-import com.google.common.base.Preconditions;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.gson.stream.JsonWriter;
import java.io.IOException;
-import java.io.Writer;
import java.net.URI;
-import javax.annotation.Nonnull;
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
/**
- * Abstract base class for a single level of {@link JSONNormalizedNodeStreamWriter}
- * recursion. Provides the base API towards the writer, which is then specialized
- * by subclasses.
+ * Abstract base class for a single level of {@link JSONNormalizedNodeStreamWriter} recursion. Provides the base API
+ * towards the writer, which is then specialized by subclasses.
*/
abstract class JSONStreamWriterContext {
private final JSONStreamWriterContext parent;
private final boolean mandatory;
private final int depth;
- private boolean emittedMyself = false;
- private boolean haveChild = false;
+
+ private boolean emittedMyself;
+ private boolean inChild;
/**
* Construct a new context.
}
/**
- * Write a child JSON node identifier, optionally prefixing it with the module name
- * corresponding to its namespace.
+ * Write a child JSON node identifier, optionally prefixing it with the module name corresponding to its namespace.
*
* @param schema Schema context
* @param writer Output writer
* @param qname Namespace/name tuple
* @throws IOException when the writer reports it
*/
- final void writeChildJsonIdentifier(final SchemaContext schema, final Writer writer, final QName qname) throws IOException {
- writer.append('"');
+ final void writeChildJsonIdentifier(final SchemaContext schema, final JsonWriter writer, final QName qname)
+ throws IOException {
+ final StringBuilder sb = new StringBuilder();
// Prepend module name if namespaces do not match
- final URI ns = qname.getNamespace();
- if (!ns.equals(getNamespace())) {
- final Module module = schema.findModuleByNamespaceAndRevision(ns, null);
- Preconditions.checkArgument(module != null, "Could not find module for namespace {}", ns);
-
- writer.append(module.getName());
- writer.append(':');
+ final QNameModule module = qname.getModule();
+ if (!module.getNamespace().equals(getNamespace())) {
+ final Optional<String> modules = schema.findModule(module).map(Module::getName);
+ checkArgument(modules.isPresent(), "Could not find module for namespace {}", module);
+ sb.append(modules.get()).append(':');
}
+ sb.append(qname.getLocalName());
- writer.append(qname.getLocalName());
- writer.append("\":");
+ writer.name(sb.toString());
}
/**
- * Write our JSON node identifier, optionally prefixing it with the module name
- * corresponding to its namespace.
+ * Write our JSON node identifier, optionally prefixing it with the module name corresponding to its namespace.
*
* @param schema Schema context
* @param writer Output writer
* @param qname Namespace/name tuple
* @throws IOException when the writer reports it
*/
- protected final void writeMyJsonIdentifier(final SchemaContext schema, final Writer writer, final QName qname) throws IOException {
+ protected final void writeMyJsonIdentifier(final SchemaContext schema, final JsonWriter writer, final QName qname)
+ throws IOException {
parent.writeChildJsonIdentifier(schema, writer, qname);
}
*
* @return Namespace as URI
*/
- protected abstract @Nonnull URI getNamespace();
+ protected abstract @NonNull URI getNamespace();
/**
* Emit the start of an element.
*
* @param schema Schema context
* @param writer Output writer
- * @throws IOException
+ * @throws IOException when the writer reports it
*/
- protected abstract void emitStart(final SchemaContext schema, final Writer writer) throws IOException;
+ protected abstract void emitStart(SchemaContext schema, JsonWriter writer) throws IOException;
/**
* Emit the end of an element.
*
* @param schema Schema context
* @param writer Output writer
- * @throws IOException
+ * @throws IOException when writer reports it
*/
- protected abstract void emitEnd(final Writer writer) throws IOException;
+ protected abstract void emitEnd(JsonWriter writer) throws IOException;
- private final void emitMyself(final SchemaContext schema, final Writer writer, final String indent) throws IOException {
+ private void emitMyself(final SchemaContext schema, final JsonWriter writer) throws IOException {
if (!emittedMyself) {
if (parent != null) {
- parent.emittingChild(schema, writer, indent);
+ parent.emitMyself(schema, writer);
}
emitStart(schema, writer);
*
* @param schema Schema context
* @param writer Output writer
- * @param indent Indentation string
* @throws IOException when writer reports it
*/
- final void emittingChild(final SchemaContext schema, final Writer writer, final String indent) throws IOException {
- emitMyself(schema, writer, indent);
- if (haveChild) {
- writer.append(',');
- }
-
- if (indent != null) {
- writer.append('\n');
-
- for (int i = 0; i < depth; i++) {
- writer.append(indent);
- }
- }
- haveChild = true;
+ final void emittingChild(final SchemaContext schema, final JsonWriter writer) throws IOException {
+ checkState(!inChild, "Duplicate child encountered");
+ emitMyself(schema, writer);
+ inChild = true;
}
/**
*
* @param schema Schema context
* @param writer Output writer
- * @param indent Indentation string
* @return Parent node context
* @throws IOException when writer reports it
* @throws IllegalArgumentException if this node cannot be ended (e.g. root)
*/
- final JSONStreamWriterContext endNode(final SchemaContext schema, final Writer writer, final String indent) throws IOException {
+ final JSONStreamWriterContext endNode(final SchemaContext schema, final JsonWriter writer) throws IOException {
+ if (inChild) {
+ inChild = false;
+ return this;
+ }
if (!emittedMyself && mandatory) {
- emitMyself(schema, writer, indent);
+ emitMyself(schema, writer);
}
-
if (emittedMyself) {
emitEnd(writer);
}
return parent;
}
+ @Override
+ public final String toString() {
+ return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
+ }
+
+ protected ToStringHelper addToStringAttributes(final ToStringHelper helper) {
+ return helper;
+ }
}