X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Futil%2Fcodec%2FAbstractCodecFactory.java;h=d5103ae6a3e83d86d771eec95b39b5a7c2c8f752;hb=64daa7fd98796351e87e8d1107e6a88d5b28ee3a;hp=b8327594143d1849195271832884f925d82e8814;hpb=0502a8d3a974e214ec889b8a5a3ad503c8e87dd7;p=yangtools.git diff --git a/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/codec/AbstractCodecFactory.java b/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/codec/AbstractCodecFactory.java index b832759414..d5103ae6a3 100644 --- a/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/codec/AbstractCodecFactory.java +++ b/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/codec/AbstractCodecFactory.java @@ -10,11 +10,12 @@ package org.opendaylight.yangtools.yang.data.util.codec; import static com.google.common.base.Verify.verifyNotNull; import static java.util.Objects.requireNonNull; +import com.google.common.annotations.Beta; import java.util.ArrayList; import java.util.List; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.common.QNameModule; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.TypeAware; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; @@ -38,8 +39,7 @@ import org.opendaylight.yangtools.yang.model.api.type.Uint64TypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.Uint8TypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.UnknownTypeDefinition; -import org.opendaylight.yangtools.yang.model.util.AbstractSchemaContextProvider; -import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; +import org.opendaylight.yangtools.yang.model.spi.AbstractEffectiveModelContextProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,17 +51,35 @@ import org.slf4j.LoggerFactory; * @param Codec type * @author Robert Varga */ -public abstract class AbstractCodecFactory> extends AbstractSchemaContextProvider { +public abstract class AbstractCodecFactory> + extends AbstractEffectiveModelContextProvider { + /** + * Helper interface aiding resolution of leafref chains. + */ + @Beta + @FunctionalInterface + public interface LeafrefResolver { + /** + * Resolve specified {@link LeafrefTypeDefinition}. + * + * @param type leafref definition + * @return Resolved type + */ + @NonNull TypeDefinition resolveLeafref(@NonNull LeafrefTypeDefinition type); + } + private static final Logger LOG = LoggerFactory.getLogger(AbstractCodecFactory.class); private final @NonNull CodecCache cache; - protected AbstractCodecFactory(final @NonNull SchemaContext schemaContext, final @NonNull CodecCache cache) { + protected AbstractCodecFactory(final @NonNull EffectiveModelContext schemaContext, + final @NonNull CodecCache cache) { super(schemaContext); this.cache = requireNonNull(cache); } - public final @NonNull T codecFor(final S schema) { + public final @NonNull T codecFor(final S schema, + final LeafrefResolver resolver) { /* * There are many trade-offs to be made here. We need the common case being as fast as possible while reusing * codecs as much as possible. @@ -94,7 +112,7 @@ public abstract class AbstractCodecFactory> ex } // ... and complex types afterwards - ret = createComplexCodecFor(schema, type); + ret = createComplexCodecFor(schema, type, resolver); LOG.trace("Type {} miss complex {}", type, ret); return cache.getComplex(schema, ret); } @@ -206,16 +224,14 @@ public abstract class AbstractCodecFactory> ex return true; } - private T createComplexCodecFor(final SchemaNode schema, final TypeDefinition type) { + private T createComplexCodecFor(final SchemaNode schema, final TypeDefinition type, + final LeafrefResolver resolver) { if (type instanceof UnionTypeDefinition) { - return createComplexUnion(schema, (UnionTypeDefinition) type); + return createComplexUnion(schema, (UnionTypeDefinition) type, resolver); } else if (type instanceof LeafrefTypeDefinition) { - final TypeDefinition target = SchemaContextUtil.getBaseTypeForLeafRef((LeafrefTypeDefinition) type, - getSchemaContext(), schema); - verifyNotNull(target, "Unable to find base type for leafref node %s type %s.", schema, target); - + final TypeDefinition target = resolver.resolveLeafref((LeafrefTypeDefinition) type); final T ret = getSimpleCodecFor(target); - return ret != null ? ret : createComplexCodecFor(schema, target); + return ret != null ? ret : createComplexCodecFor(schema, target, resolver); } else if (type instanceof IdentityrefTypeDefinition) { return identityRefCodec((IdentityrefTypeDefinition) type, schema.getQName().getModule()); } else { @@ -239,7 +255,8 @@ public abstract class AbstractCodecFactory> ex return unionCodec(union, codecs); } - private T createComplexUnion(final SchemaNode schema, final UnionTypeDefinition union) { + private T createComplexUnion(final SchemaNode schema, final UnionTypeDefinition union, + final LeafrefResolver resolver) { final List> types = union.getTypes(); final List codecs = new ArrayList<>(types.size()); @@ -248,11 +265,11 @@ public abstract class AbstractCodecFactory> ex if (codec == null) { codec = getSimpleCodecFor(type); if (codec == null) { - codec = createComplexCodecFor(schema, type); + codec = createComplexCodecFor(schema, type, resolver); } } - codecs.add(verifyNotNull(codec, "Schema %s subtype %s has no codec", schema, type)); + codecs.add(verifyNotNull(codec, "Type %s has no codec", schema, type)); } return unionCodec(union, codecs);