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 static com.google.common.base.Verify.verifyNotNull;
12 import com.google.common.annotations.Beta;
13 import java.util.List;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.opendaylight.yangtools.yang.common.QNameModule;
16 import org.opendaylight.yangtools.yang.data.impl.codec.AbstractIntegerStringCodec;
17 import org.opendaylight.yangtools.yang.data.impl.codec.BinaryStringCodec;
18 import org.opendaylight.yangtools.yang.data.impl.codec.BitsStringCodec;
19 import org.opendaylight.yangtools.yang.data.impl.codec.BooleanStringCodec;
20 import org.opendaylight.yangtools.yang.data.impl.codec.DecimalStringCodec;
21 import org.opendaylight.yangtools.yang.data.impl.codec.EnumStringCodec;
22 import org.opendaylight.yangtools.yang.data.impl.codec.StringStringCodec;
23 import org.opendaylight.yangtools.yang.data.util.codec.AbstractCodecFactory;
24 import org.opendaylight.yangtools.yang.data.util.codec.CodecCache;
25 import org.opendaylight.yangtools.yang.data.util.codec.LazyCodecCache;
26 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
27 import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
28 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
29 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
30 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
31 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
32 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
33 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
34 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
35 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
36 import org.opendaylight.yangtools.yang.model.api.type.Int16TypeDefinition;
37 import org.opendaylight.yangtools.yang.model.api.type.Int32TypeDefinition;
38 import org.opendaylight.yangtools.yang.model.api.type.Int64TypeDefinition;
39 import org.opendaylight.yangtools.yang.model.api.type.Int8TypeDefinition;
40 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
41 import org.opendaylight.yangtools.yang.model.api.type.Uint16TypeDefinition;
42 import org.opendaylight.yangtools.yang.model.api.type.Uint32TypeDefinition;
43 import org.opendaylight.yangtools.yang.model.api.type.Uint64TypeDefinition;
44 import org.opendaylight.yangtools.yang.model.api.type.Uint8TypeDefinition;
45 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
46 import org.opendaylight.yangtools.yang.model.api.type.UnknownTypeDefinition;
47 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
50 * Factory for creating JSON equivalents of codecs. Each instance of this object is bound to
51 * a particular {@link EffectiveModelContext}, but can be reused by multiple {@link JSONNormalizedNodeStreamWriter}s.
54 public abstract class JSONCodecFactory extends AbstractCodecFactory<JSONCodec<?>> {
55 JSONCodecFactory(final @NonNull EffectiveModelContext context, final @NonNull CodecCache<JSONCodec<?>> cache) {
56 super(context, cache);
60 protected final JSONCodec<?> binaryCodec(final BinaryTypeDefinition type) {
61 return new QuotedJSONCodec<>(BinaryStringCodec.from(type));
65 protected final JSONCodec<?> booleanCodec(final BooleanTypeDefinition type) {
66 return new BooleanJSONCodec(BooleanStringCodec.from(type));
70 protected final JSONCodec<?> bitsCodec(final BitsTypeDefinition type) {
71 return new QuotedJSONCodec<>(BitsStringCodec.from(type));
75 protected final JSONCodec<?> decimalCodec(final DecimalTypeDefinition type) {
76 return wrapDecimalCodec(DecimalStringCodec.from(type));
80 protected final JSONCodec<?> emptyCodec(final EmptyTypeDefinition type) {
81 return EmptyJSONCodec.INSTANCE;
85 protected final JSONCodec<?> enumCodec(final EnumTypeDefinition type) {
86 return new QuotedJSONCodec<>(EnumStringCodec.from(type));
90 protected final JSONCodec<?> identityRefCodec(final IdentityrefTypeDefinition type, final QNameModule module) {
91 return new IdentityrefJSONCodec(getEffectiveModelContext(), module);
95 protected final JSONCodec<?> int8Codec(final Int8TypeDefinition type) {
96 return new NumberJSONCodec<>(AbstractIntegerStringCodec.from(type));
100 protected final JSONCodec<?> int16Codec(final Int16TypeDefinition type) {
101 return new NumberJSONCodec<>(AbstractIntegerStringCodec.from(type));
105 protected final JSONCodec<?> int32Codec(final Int32TypeDefinition type) {
106 return new NumberJSONCodec<>(AbstractIntegerStringCodec.from(type));
110 protected final JSONCodec<?> int64Codec(final Int64TypeDefinition type) {
111 return wrapIntegerCodec(AbstractIntegerStringCodec.from(type));
115 protected final JSONCodec<?> stringCodec(final StringTypeDefinition type) {
116 return new QuotedJSONCodec<>(StringStringCodec.from(type));
120 protected final JSONCodec<?> uint8Codec(final Uint8TypeDefinition type) {
121 return new NumberJSONCodec<>(AbstractIntegerStringCodec.from(type));
125 protected final JSONCodec<?> uint16Codec(final Uint16TypeDefinition type) {
126 return new NumberJSONCodec<>(AbstractIntegerStringCodec.from(type));
130 protected final JSONCodec<?> uint32Codec(final Uint32TypeDefinition type) {
131 return new NumberJSONCodec<>(AbstractIntegerStringCodec.from(type));
135 protected final JSONCodec<?> uint64Codec(final Uint64TypeDefinition type) {
136 return wrapIntegerCodec(AbstractIntegerStringCodec.from(type));
140 protected final JSONCodec<?> unionCodec(final UnionTypeDefinition type, final List<JSONCodec<?>> codecs) {
141 return UnionJSONCodec.create(type, codecs);
145 protected final JSONCodec<?> unknownCodec(final UnknownTypeDefinition type) {
146 return NullJSONCodec.INSTANCE;
150 protected abstract JSONCodec<?> instanceIdentifierCodec(InstanceIdentifierTypeDefinition type);
152 // Returns a one-off factory for the purposes of normalizing an anydata tree.
154 // FIXME: 7.0.0: this is really ugly, as we should be able to tell if the new context is the same as ours and
155 // whether our cache is thread-safe -- in which case we should just return this.
156 // The supplier/cache/factory layout needs to be reworked so that this call ends up being equivalent
157 // to JSONCodecFactorySupplier.getShared() in case this factory is not thread safe.
159 // The above is not currently possible, as we cannot reference JSONCodecFactorySupplier from the
160 // factory due to that potentially creating a circular reference.
161 final JSONCodecFactory rebaseTo(final EffectiveModelContext newSchemaContext) {
162 return rebaseTo(newSchemaContext, new LazyCodecCache<>());
165 abstract JSONCodecFactory rebaseTo(EffectiveModelContext newSchemaContext, CodecCache<JSONCodec<?>> newCache);
167 abstract JSONCodec<?> wrapDecimalCodec(DecimalStringCodec decimalCodec);
169 abstract JSONCodec<?> wrapIntegerCodec(AbstractIntegerStringCodec<?, ?> integerCodec);
171 final JSONCodec<?> codecFor(final TypedDataSchemaNode currentNode) {
172 return codecFor(currentNode, type -> verifyNotNull(
173 SchemaContextUtil.getBaseTypeForLeafRef(type, getEffectiveModelContext(), currentNode),
174 "Unable to find base type for leafref node %s type %s.", currentNode, type));