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.LeafrefTypeDefinition;
import org.opendaylight.yangtools.yang.model.util.IdentityrefType;
import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Beta
public final class JSONCodecFactory {
private static final Logger LOG = LoggerFactory.getLogger(JSONCodecFactory.class);
- private static final JSONCodec<Object> LEAFREF_DEFAULT_CODEC = new JSONLeafrefCodec();
private static final JSONCodec<Object> NULL_CODEC = new JSONCodec<Object>() {
@Override
public Object deserialize(final String input) {
}
};
- private static TypeDefinition<?> resolveBaseTypeFrom(final TypeDefinition<?> type) {
- TypeDefinition<?> superType = type;
- while (superType.getBaseType() != null) {
- superType = superType.getBaseType();
- }
- return superType;
- }
-
- private final LoadingCache<TypeDefinition<?>, JSONCodec<Object>> codecs =
- CacheBuilder.newBuilder().softValues().build(new CacheLoader<TypeDefinition<?>, JSONCodec<Object>>() {
- @SuppressWarnings("unchecked")
+ private final LoadingCache<DataSchemaNode, JSONCodec<Object>> codecs =
+ CacheBuilder.newBuilder().softValues().build(new CacheLoader<DataSchemaNode, JSONCodec<Object>>() {
@Override
- public JSONCodec<Object> load(final TypeDefinition<?> key) throws Exception {
- final TypeDefinition<?> type = resolveBaseTypeFrom(key);
-
- if (type instanceof InstanceIdentifierType) {
- return (JSONCodec<Object>) iidCodec;
+ public JSONCodec<Object> 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());
}
- if (type instanceof IdentityrefType) {
- return (JSONCodec<Object>) idrefCodec;
- }
- if (type instanceof LeafrefTypeDefinition) {
- return LEAFREF_DEFAULT_CODEC;
- }
-
- final TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> codec = TypeDefinitionAwareCodec.from(type);
- if (codec == null) {
- LOG.debug("Codec for type \"{}\" is not implemented yet.", type.getQName().getLocalName());
- return NULL_CODEC;
- }
-
- return (JSONCodec<Object>) AbstractJSONCodec.create(codec);
+ return createCodec(key,type);
}
});
return new JSONCodecFactory(context);
}
+ private static TypeDefinition<?> resolveBaseTypeFrom(final TypeDefinition<?> type) {
+ TypeDefinition<?> superType = type;
+ while (superType.getBaseType() != null) {
+ superType = superType.getBaseType();
+ }
+ return superType;
+ }
+
+ private JSONCodec<Object> createCodec(DataSchemaNode key, TypeDefinition<?> type) {
+ TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
+ if (baseType instanceof LeafrefTypeDefinition) {
+ return createReferencedTypeCodec(key, (LeafrefTypeDefinition) baseType);
+ }
+ return createFromSimpleType(type);
+ }
+
+ private JSONCodec<Object> createReferencedTypeCodec(DataSchemaNode schema,
+ LeafrefTypeDefinition type) {
+ // FIXME: Verify if this does indeed support leafref of leafref
+ TypeDefinition<?> referencedType =
+ SchemaContextUtil.getBaseTypeForLeafRef(type, getSchemaContext(), schema);
+ return createFromSimpleType(referencedType);
+ }
+
+ @SuppressWarnings("unchecked")
+ private JSONCodec<Object> createFromSimpleType(TypeDefinition<?> type) {
+ final TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
+ if (baseType instanceof InstanceIdentifierType) {
+ return (JSONCodec<Object>) iidCodec;
+ }
+ if (baseType instanceof IdentityrefType) {
+ return (JSONCodec<Object>) idrefCodec;
+ }
+
+ final TypeDefinitionAwareCodec<Object, ?> codec = TypeDefinitionAwareCodec.from(type);
+ if (codec == null) {
+ LOG.debug("Codec for type \"{}\" is not implemented yet.", type.getQName()
+ .getLocalName());
+ return NULL_CODEC;
+ }
+ return (JSONCodec<Object>) AbstractJSONCodec.create(codec);
+ }
+
SchemaContext getSchemaContext() {
return schemaContext;
}
- JSONCodec<Object> codecFor(final TypeDefinition<?> typeDefinition) {
- return codecs.getUnchecked(typeDefinition);
+ JSONCodec<Object> codecFor(DataSchemaNode schema) {
+ return codecs.getUnchecked(schema);
}
+
}
+++ /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.gson.stream.JsonWriter;
-import java.io.IOException;
-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;
- }
-
- /**
- * Serialize specified value with specified JsonWriter.
- *
- * @param writer JsonWriter
- * @param value
- */
- @Override
- public void serializeToWriter(JsonWriter writer, Object value) throws IOException {
- writer.value(serialize(value));
- }
-}
\ No newline at end of file
import java.net.URI;
import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.HashSet;
import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
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.Module;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
/**
* This class parses JSON elements from a GSON JsonReader. It disallows multiple elements of the same name unlike the
}
private Object translateValueByType(final String value, final DataSchemaNode node) {
- final TypeDefinition<? extends Object> typeDefinition = typeDefinition(node);
- if (typeDefinition == null) {
+ if (node instanceof AnyXmlSchemaNode) {
+ /*
+ * FIXME: Figure out some YANG extension dispatch, which will
+ * reuse JSON parsing or XML parsing - anyxml is not well-defined in
+ * JSON.
+ */
return value;
}
-
- return codecs.codecFor(typeDefinition).deserialize(value);
- }
-
- private static TypeDefinition<? extends Object> typeDefinition(final DataSchemaNode node) {
- TypeDefinition<?> baseType = null;
- if (node instanceof LeafListSchemaNode) {
- baseType = ((LeafListSchemaNode) node).getType();
- } else if (node instanceof LeafSchemaNode) {
- baseType = ((LeafSchemaNode) node).getType();
- } else if (node instanceof AnyXmlSchemaNode) {
- return null;
- } else {
- throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.<Object> asList(node).toString());
- }
-
- if (baseType != null) {
- while (baseType.getBaseType() != null) {
- baseType = baseType.getBaseType();
- }
- }
- return baseType;
+ return codecs.codecFor(node).deserialize(value);
}
private void removeNamespace() {