X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-codec-gson%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Fcodec%2Fgson%2FJSONCodecFactory.java;h=1d6ffc827724a1670da028bdc5a34cc9810ccc43;hb=e704e6a6d1cc4db7ac1e1f53b54ec3bf51aaecc3;hp=c99d46404885c0b6c9b9e04dc24a64e0dbe0106f;hpb=6445362084c167640d41a1dec9127899fb54b8c0;p=yangtools.git diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONCodecFactory.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONCodecFactory.java index c99d464048..1d6ffc8277 100644 --- a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONCodecFactory.java +++ b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONCodecFactory.java @@ -9,17 +9,24 @@ package org.opendaylight.yangtools.yang.data.codec.gson; import com.google.common.annotations.Beta; import com.google.common.base.Preconditions; +import com.google.common.base.Verify; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.gson.stream.JsonWriter; import java.io.IOException; import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition; -import org.opendaylight.yangtools.yang.model.util.IdentityrefType; -import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType; +import org.opendaylight.yangtools.yang.model.util.DerivedType; +import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +37,6 @@ import org.slf4j.LoggerFactory; @Beta public final class JSONCodecFactory { private static final Logger LOG = LoggerFactory.getLogger(JSONCodecFactory.class); - private static final JSONCodec LEAFREF_DEFAULT_CODEC = new JSONLeafrefCodec(); private static final JSONCodec NULL_CODEC = new JSONCodec() { @Override public Object deserialize(final String input) { @@ -48,55 +54,34 @@ public final class JSONCodecFactory { } @Override - public void serializeToWriter(JsonWriter writer, Object value) throws IOException { + public void serializeToWriter(final JsonWriter writer, final Object value) throws IOException { // NOOP since codec is unkwown. LOG.warn("Call of the serializeToWriter method on JSONCodecFactory.NULL_CODEC object. No operation performed."); } }; - private static TypeDefinition resolveBaseTypeFrom(final TypeDefinition type) { - TypeDefinition superType = type; - while (superType.getBaseType() != null) { - superType = superType.getBaseType(); - } - return superType; - } - - private final LoadingCache, JSONCodec> codecs = - CacheBuilder.newBuilder().softValues().build(new CacheLoader, JSONCodec>() { - @SuppressWarnings("unchecked") + private final LoadingCache> codecs = + CacheBuilder.newBuilder().softValues().build(new CacheLoader>() { @Override - public JSONCodec load(final TypeDefinition key) throws Exception { - final TypeDefinition type = resolveBaseTypeFrom(key); - - if (type instanceof InstanceIdentifierType) { - return (JSONCodec) iidCodec; - } - if (type instanceof IdentityrefType) { - return (JSONCodec) idrefCodec; - } - if (type instanceof LeafrefTypeDefinition) { - return LEAFREF_DEFAULT_CODEC; + public JSONCodec load(final DataSchemaNode key) throws Exception { + final TypeDefinition type; + if (key instanceof LeafSchemaNode) { + type = ((LeafSchemaNode) key).getType(); + } else if (key instanceof LeafListSchemaNode) { + type = ((LeafListSchemaNode) key).getType(); + } else { + throw new IllegalArgumentException("Not supported node type " + key.getClass().getName()); } - - final TypeDefinitionAwareCodec> codec = TypeDefinitionAwareCodec.from(type); - if (codec == null) { - LOG.debug("Codec for type \"{}\" is not implemented yet.", type.getQName().getLocalName()); - return NULL_CODEC; - } - - return (JSONCodec) AbstractJSONCodec.create(codec); + return createCodec(key,type); } }); private final SchemaContext schemaContext; private final JSONCodec iidCodec; - private final JSONCodec idrefCodec; private JSONCodecFactory(final SchemaContext context) { this.schemaContext = Preconditions.checkNotNull(context); - iidCodec = new JSONStringInstanceIdentifierCodec(context); - idrefCodec = new JSONStringIdentityrefCodec(context); + iidCodec = new JSONStringInstanceIdentifierCodec(context, this); } /** @@ -109,11 +94,52 @@ public final class JSONCodecFactory { return new JSONCodecFactory(context); } + @SuppressWarnings("unchecked") + private JSONCodec createCodec(final DataSchemaNode key, final TypeDefinition type) { + final TypeDefinition normalizedType = DerivedType.from(type); + if (normalizedType instanceof LeafrefTypeDefinition) { + return createReferencedTypeCodec(key, (LeafrefTypeDefinition) normalizedType); + } else if (normalizedType instanceof IdentityrefTypeDefinition) { + final JSONCodec jsonStringIdentityrefCodec = + new JSONStringIdentityrefCodec(schemaContext, key.getQName().getModule()); + return (JSONCodec) jsonStringIdentityrefCodec; + } + return createFromSimpleType(normalizedType); + } + + private JSONCodec createReferencedTypeCodec(final DataSchemaNode schema, + final LeafrefTypeDefinition type) { + // FIXME: Verify if this does indeed support leafref of leafref + final TypeDefinition referencedType = + SchemaContextUtil.getBaseTypeForLeafRef(type, getSchemaContext(), schema); + Verify.verifyNotNull(referencedType, "Unable to find base type for leafref node '%s'.", schema.getPath()); + return createCodec(schema, referencedType); + } + + @SuppressWarnings("unchecked") + private JSONCodec createFromSimpleType(final TypeDefinition type) { + if (type instanceof InstanceIdentifierTypeDefinition) { + return (JSONCodec) iidCodec; + } + if (type instanceof EmptyTypeDefinition) { + return JSONEmptyCodec.INSTANCE; + } + + final TypeDefinitionAwareCodec codec = TypeDefinitionAwareCodec.from(type); + if (codec == null) { + LOG.debug("Codec for type \"{}\" is not implemented yet.", type.getQName() + .getLocalName()); + return NULL_CODEC; + } + return (JSONCodec) AbstractJSONCodec.create(codec); + } + SchemaContext getSchemaContext() { return schemaContext; } - JSONCodec codecFor(final TypeDefinition typeDefinition) { - return codecs.getUnchecked(typeDefinition); + JSONCodec codecFor(final DataSchemaNode schema) { + return codecs.getUnchecked(schema); } + }