2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.data.codec.gson;
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.Preconditions;
12 import com.google.common.cache.CacheBuilder;
13 import com.google.common.cache.CacheLoader;
14 import com.google.common.cache.LoadingCache;
15 import com.google.gson.stream.JsonWriter;
16 import java.io.IOException;
17 import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
18 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
19 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
20 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
21 import org.opendaylight.yangtools.yang.model.util.IdentityrefType;
22 import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
27 * Factory for creating JSON equivalents of codecs. Each instance of this object is bound to
28 * a particular {@link SchemaContext}, but can be reused by multiple {@link JSONNormalizedNodeStreamWriter}s.
31 public final class JSONCodecFactory {
32 private static final Logger LOG = LoggerFactory.getLogger(JSONCodecFactory.class);
33 private static final JSONCodec<Object> LEAFREF_DEFAULT_CODEC = new JSONLeafrefCodec();
34 private static final JSONCodec<Object> NULL_CODEC = new JSONCodec<Object>() {
36 public Object deserialize(final String input) {
41 public String serialize(final Object input) {
46 public boolean needQuotes() {
51 public void serializeToWriter(JsonWriter writer, Object value) throws IOException {
52 // NOOP since codec is unkwown.
53 LOG.warn("Call of the serializeToWriter method on JSONCodecFactory.NULL_CODEC object. No operation performed.");
57 private static TypeDefinition<?> resolveBaseTypeFrom(final TypeDefinition<?> type) {
58 TypeDefinition<?> superType = type;
59 while (superType.getBaseType() != null) {
60 superType = superType.getBaseType();
65 private final LoadingCache<TypeDefinition<?>, JSONCodec<Object>> codecs =
66 CacheBuilder.newBuilder().softValues().build(new CacheLoader<TypeDefinition<?>, JSONCodec<Object>>() {
67 @SuppressWarnings("unchecked")
69 public JSONCodec<Object> load(final TypeDefinition<?> key) throws Exception {
70 final TypeDefinition<?> type = resolveBaseTypeFrom(key);
72 if (type instanceof InstanceIdentifierType) {
73 return (JSONCodec<Object>) iidCodec;
75 if (type instanceof IdentityrefType) {
76 return (JSONCodec<Object>) idrefCodec;
78 if (type instanceof LeafrefTypeDefinition) {
79 return LEAFREF_DEFAULT_CODEC;
82 final TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> codec = TypeDefinitionAwareCodec.from(type);
84 LOG.debug("Codec for type \"{}\" is not implemented yet.", type.getQName().getLocalName());
88 return (JSONCodec<Object>) AbstractJSONCodec.create(codec);
92 private final SchemaContext schemaContext;
93 private final JSONCodec<?> iidCodec;
94 private final JSONCodec<?> idrefCodec;
96 private JSONCodecFactory(final SchemaContext context) {
97 this.schemaContext = Preconditions.checkNotNull(context);
98 iidCodec = new JSONStringInstanceIdentifierCodec(context);
99 idrefCodec = new JSONStringIdentityrefCodec(context);
103 * Instantiate a new codec factory attached to a particular context.
105 * @param context SchemaContext to which the factory should be bound
106 * @return A codec factory instance.
108 public static JSONCodecFactory create(final SchemaContext context) {
109 return new JSONCodecFactory(context);
112 SchemaContext getSchemaContext() {
113 return schemaContext;
116 JSONCodec<Object> codecFor(final TypeDefinition<?> typeDefinition) {
117 return codecs.getUnchecked(typeDefinition);