-public final class JSONCodecFactory {
- private static final Logger LOG = LoggerFactory.getLogger(JSONCodecFactory.class);
- private static final JSONCodec<Object> NULL_CODEC = new JSONCodec<Object>() {
- @Override
- public Object deserialize(final String input) {
- return null;
- }
-
- @Override
- public String serialize(final Object input) {
- return null;
- }
-
- @Override
- public boolean needQuotes() {
- return false;
- }
-
- @Override
- 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 final LoadingCache<DataSchemaNode, JSONCodec<Object>> codecs =
- CacheBuilder.newBuilder().softValues().build(new CacheLoader<DataSchemaNode, JSONCodec<Object>>() {
- @Override
- 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());
- }
- return createCodec(key,type);
- }
- });
-
- private final SchemaContext schemaContext;
- private final JSONCodec<?> iidCodec;
-
- private JSONCodecFactory(final SchemaContext context) {
- this.schemaContext = Preconditions.checkNotNull(context);
- iidCodec = new JSONStringInstanceIdentifierCodec(context, this);
- }
-
- /**
- * Instantiate a new codec factory attached to a particular context.
- *
- * @param context SchemaContext to which the factory should be bound
- * @return A codec factory instance.
- */
- public static JSONCodecFactory create(final SchemaContext context) {
- return new JSONCodecFactory(context);
- }
-
- @SuppressWarnings("unchecked")
- private JSONCodec<Object> createCodec(final DataSchemaNode key, final TypeDefinition<?> type) {
- if (type instanceof LeafrefTypeDefinition) {
- return createReferencedTypeCodec(key, (LeafrefTypeDefinition) type);
- } else if (type instanceof IdentityrefTypeDefinition) {
- final JSONCodec<?> jsonStringIdentityrefCodec =
- new JSONStringIdentityrefCodec(schemaContext, key.getQName().getModule());
- return (JSONCodec<Object>) jsonStringIdentityrefCodec;
- }
- return createFromSimpleType(type);
- }
-
- private JSONCodec<Object> 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<Object> createFromSimpleType(final TypeDefinition<?> type) {
- if (type instanceof InstanceIdentifierTypeDefinition) {
- return (JSONCodec<Object>) iidCodec;
- }
- if (type instanceof EmptyTypeDefinition) {
- return JSONEmptyCodec.INSTANCE;
- }
-
- 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 DataSchemaNode schema) {
- return codecs.getUnchecked(schema);