--- /dev/null
+/*
+ * Copyright (c) 2014 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.yangtools.yang.data.codec.gson;
+
+import com.google.common.base.Preconditions;
+
+import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.yang.data.api.codec.BooleanCodec;
+import org.opendaylight.yangtools.yang.data.api.codec.DecimalCodec;
+import org.opendaylight.yangtools.yang.data.api.codec.Int16Codec;
+import org.opendaylight.yangtools.yang.data.api.codec.Int32Codec;
+import org.opendaylight.yangtools.yang.data.api.codec.Int64Codec;
+import org.opendaylight.yangtools.yang.data.api.codec.Int8Codec;
+import org.opendaylight.yangtools.yang.data.api.codec.Uint16Codec;
+import org.opendaylight.yangtools.yang.data.api.codec.Uint32Codec;
+import org.opendaylight.yangtools.yang.data.api.codec.Uint64Codec;
+import org.opendaylight.yangtools.yang.data.api.codec.Uint8Codec;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+
+/**
+ * Abstract base implementation of {@link JSONCodec}, which wraps a {@link TypeDefinitionAwareCodec}.
+ *
+ * @param <T> Deserialized objec type
+ */
+abstract class AbstractJSONCodec<T> implements JSONCodec<T> {
+ private final Codec<String, T> codec;
+
+ protected AbstractJSONCodec(final Codec<String, T> codec) {
+ this.codec = Preconditions.checkNotNull(codec);
+ }
+
+ /**
+ * Create a proper JSONCodec based on the underlying codec type
+ * @param codec underlying codec
+ * @return A JSONCodec instance
+ */
+ public static <T> JSONCodec<T> create(final Codec<String, T> codec) {
+ if (codec instanceof BooleanCodec || codec instanceof DecimalCodec ||
+ codec instanceof Int8Codec || codec instanceof Int16Codec ||
+ codec instanceof Int32Codec || codec instanceof Int64Codec ||
+ codec instanceof Uint8Codec || codec instanceof Uint16Codec ||
+ codec instanceof Uint32Codec || codec instanceof Uint64Codec) {
+ return new UnquotedJSONCodec<>(codec);
+ }
+
+ return new QuotedJSONCodec<>(codec);
+ }
+
+ @Override
+ public final T deserialize(final String input) {
+ return codec.deserialize(input);
+ }
+
+ @Override
+ public final String serialize(final T input) {
+ return codec.serialize(input);
+ }
+}
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
-import org.opendaylight.yangtools.concepts.Codec;
-import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
@Beta
final class CodecFactory {
private static final Logger LOG = LoggerFactory.getLogger(CodecFactory.class);
- private static final Codec<?, ?> LEAFREF_DEFAULT_CODEC = new LeafrefCodec<String>() {
+ private static final JSONCodec<Object> LEAFREF_DEFAULT_CODEC = new JSONLeafrefCodec();
+ private static final JSONCodec<Object> NULL_CODEC = new JSONCodec<Object>() {
@Override
- public String serialize(final Object data) {
- return String.valueOf(data);
+ public Object deserialize(final String input) {
+ return null;
}
@Override
- public Object deserialize(final String data) {
- return data;
- }
- };
- private static final Codec<?, ?> NULL_CODEC = new Codec<Object, Object>() {
- @Override
- public Object deserialize(final Object input) {
+ public String serialize(final Object input) {
return null;
}
@Override
- public Object serialize(final Object input) {
- return null;
+ public boolean needQuotes() {
+ return false;
}
};
-
private static TypeDefinition<?> resolveBaseTypeFrom(final TypeDefinition<?> type) {
TypeDefinition<?> superType = type;
while (superType.getBaseType() != null) {
return superType;
}
- private final LoadingCache<TypeDefinition<?>, Codec<?, ?>> codecs =
- CacheBuilder.newBuilder().softValues().build(new CacheLoader<TypeDefinition<?>, Codec<?, ?>>() {
+ private final LoadingCache<TypeDefinition<?>, JSONCodec<Object>> codecs =
+ CacheBuilder.newBuilder().softValues().build(new CacheLoader<TypeDefinition<?>, JSONCodec<Object>>() {
+ @SuppressWarnings("unchecked")
@Override
- public Codec<?, ?> load(final TypeDefinition<?> key) throws Exception {
+ public JSONCodec<Object> load(final TypeDefinition<?> key) throws Exception {
final TypeDefinition<?> type = resolveBaseTypeFrom(key);
if (type instanceof InstanceIdentifierType) {
- return iidCodec;
+ return (JSONCodec<Object>) iidCodec;
}
if (type instanceof IdentityrefType) {
- return idrefCodec;
+ return (JSONCodec<Object>) idrefCodec;
}
if (type instanceof LeafrefTypeDefinition) {
return LEAFREF_DEFAULT_CODEC;
return NULL_CODEC;
}
- return codec;
+ return AbstractJSONCodec.create(codec);
}
});
- private final Codec<?, ?> iidCodec;
- private final Codec<?, ?> idrefCodec;
+ private final JSONCodec<?> iidCodec;
+ private final JSONCodec<?> idrefCodec;
private CodecFactory(final SchemaContext context) {
iidCodec = new JSONStringInstanceIdentifierCodec(context);
return new CodecFactory(context);
}
- @SuppressWarnings("unchecked")
- public final Codec<Object, Object> codecFor(final TypeDefinition<?> typeDefinition) {
- return (Codec<Object, Object>) codecs.getUnchecked(typeDefinition);
+ public final JSONCodec<Object> codecFor(final TypeDefinition<?> typeDefinition) {
+ return codecs.getUnchecked(typeDefinition);
}
}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yangtools.yang.data.codec.gson;
+
+import org.opendaylight.yangtools.concepts.Codec;
+
+interface JSONCodec<T> extends Codec<String, T> {
+ boolean needQuotes();
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yangtools.yang.data.codec.gson;
+
+import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
+
+final class JSONLeafrefCodec implements JSONCodec<Object>, LeafrefCodec<String> {
+ @Override
+ public Object deserialize(final String input) {
+ return input;
+ }
+
+ @Override
+ public String serialize(final Object input) {
+ return String.valueOf(input);
+ }
+
+ @Override
+ public boolean needQuotes() {
+ return true;
+ }
+}
\ No newline at end of file
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableSet;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.io.Writer;
-import java.math.BigDecimal;
-import java.math.BigInteger;
import java.net.URI;
-import java.util.Collection;
-import org.opendaylight.yangtools.concepts.Codec;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
* are marked as 'presence'.
*/
private static final boolean DEFAULT_EMIT_EMPTY_CONTAINERS = true;
- private static final Collection<Class<?>> NUMERIC_CLASSES =
- ImmutableSet.<Class<?>>of(Byte.class, Short.class, Integer.class, Long.class, BigInteger.class, BigDecimal.class);
private final SchemaContext schemaContext;
private final SchemaTracker tracker;
@Override
public void leafNode(final NodeIdentifier name, final Object value) throws IOException {
final LeafSchemaNode schema = tracker.leafNode(name);
- final Codec<Object, Object> codec = codecs.codecFor(schema.getType());
+ final JSONCodec<Object> codec = codecs.codecFor(schema.getType());
context.emittingChild(schemaContext, writer, indent);
context.writeJsonIdentifier(schemaContext, writer, name.getNodeType());
- writeValue(codec.serialize(value));
+ writeValue(codec.serialize(value), codec.needQuotes());
}
@Override
@Override
public void leafSetEntryNode(final Object value) throws IOException {
final LeafListSchemaNode schema = tracker.leafSetEntryNode();
- final Codec<Object, Object> codec = codecs.codecFor(schema.getType());
+ final JSONCodec<Object> codec = codecs.codecFor(schema.getType());
context.emittingChild(schemaContext, writer, indent);
- writeValue(codec.serialize(value));
+ writeValue(codec.serialize(value), codec.needQuotes());
}
+ /*
+ * Warning suppressed due to static final constant which triggers a warning
+ * for the call to schema.isPresenceContainer().
+ */
+ @SuppressWarnings("unused")
@Override
public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
final ContainerSchemaNode schema = tracker.startContainerNode(name);
- context = new JSONStreamWriterNamedObjectContext(context, name, schema.isPresenceContainer() || DEFAULT_EMIT_EMPTY_CONTAINERS);
+ context = new JSONStreamWriterNamedObjectContext(context, name, DEFAULT_EMIT_EMPTY_CONTAINERS || schema.isPresenceContainer());
}
@Override
context.emittingChild(schemaContext, writer, indent);
context.writeJsonIdentifier(schemaContext, writer, name.getNodeType());
- writeValue(value);
+ writeValue(String.valueOf(value), true);
}
@Override
context = context.endNode(schemaContext, writer, indent);
}
- private void writeValue(final Object value) throws IOException {
- final String str = String.valueOf(value);
-
- if (!NUMERIC_CLASSES.contains(value.getClass())) {
+ private void writeValue(final String str, final boolean needQuotes) throws IOException {
+ if (needQuotes) {
writer.append('"');
writer.append(str);
writer.append('"');
import java.net.URI;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.util.AbstractModuleStringIdentityrefCodec;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-final class JSONStringIdentityrefCodec extends AbstractModuleStringIdentityrefCodec {
+final class JSONStringIdentityrefCodec extends AbstractModuleStringIdentityrefCodec implements JSONCodec<QName> {
private final SchemaContext context;
JSONStringIdentityrefCodec(final SchemaContext context) {
return module == null ? null : module.getName();
}
+ @Override
+ public boolean needQuotes() {
+ return true;
+ }
}
import java.net.URI;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.util.AbstractModuleStringInstanceIdentifierCodec;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-final class JSONStringInstanceIdentifierCodec extends AbstractModuleStringInstanceIdentifierCodec {
+final class JSONStringInstanceIdentifierCodec extends AbstractModuleStringInstanceIdentifierCodec implements JSONCodec<YangInstanceIdentifier> {
private final SchemaContext context;
JSONStringInstanceIdentifierCodec(final SchemaContext context) {
final Module module = context.findModuleByNamespaceAndRevision(namespace, null);
return module == null ? null : module.getName();
}
+
+ @Override
+ public boolean needQuotes() {
+ return true;
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yangtools.yang.data.codec.gson;
+
+import org.opendaylight.yangtools.concepts.Codec;
+
+/**
+ * A {@link JSONCodec} which needs double quotes in output representation.
+ *
+ * @param <T> Deserialized value type
+ */
+final class QuotedJSONCodec<T> extends AbstractJSONCodec<T> {
+ QuotedJSONCodec(final Codec<String, T> codec) {
+ super(codec);
+ }
+
+ @Override
+ public boolean needQuotes() {
+ return true;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yangtools.yang.data.codec.gson;
+
+import org.opendaylight.yangtools.concepts.Codec;
+
+/**
+ * A {@link JSONCodec} which does not need double quotes in output representation.
+ *
+ * @param <T> Deserialized value type
+ */
+final class UnquotedJSONCodec<T> extends AbstractJSONCodec<T> {
+ UnquotedJSONCodec(final Codec<String, T> codec) {
+ super(codec);
+ }
+
+ @Override
+ public boolean needQuotes() {
+ return false;
+ }
+}
\ No newline at end of file