*/
package org.opendaylight.yangtools.yang.data.codec.gson;
+import static com.google.common.base.Verify.verifyNotNull;
+
import com.google.common.annotations.Beta;
import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.data.util.codec.CodecCache;
import org.opendaylight.yangtools.yang.data.util.codec.LazyCodecCache;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
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.SchemaContextUtil;
/**
* Factory for creating JSON equivalents of codecs. Each instance of this object is bound to
abstract JSONCodec<?> wrapDecimalCodec(DecimalStringCodec decimalCodec);
abstract JSONCodec<?> wrapIntegerCodec(AbstractIntegerStringCodec<?, ?> integerCodec);
+
+ final JSONCodec<?> codecFor(final TypedDataSchemaNode currentNode) {
+ return codecFor(currentNode, type -> verifyNotNull(
+ SchemaContextUtil.getBaseTypeForLeafRef(type, getEffectiveModelContext(), currentNode),
+ "Unable to find base type for leafref node %s type %s.", currentNode, type));
+ }
}
package org.opendaylight.yangtools.yang.data.codec.xml;
+import static com.google.common.base.Verify.verifyNotNull;
import static java.util.Objects.requireNonNull;
import com.google.common.annotations.Beta;
import org.opendaylight.yangtools.yang.data.util.codec.AbstractCodecFactory;
import org.opendaylight.yangtools.yang.data.util.codec.SharedCodecCache;
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.type.BinaryTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
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.SchemaContextUtil;
/**
* A thread-safe factory for instantiating {@link XmlCodec}s.
protected XmlCodec<?> unknownCodec(final UnknownTypeDefinition type) {
return NullXmlCodec.INSTANCE;
}
+
+ <T extends SchemaNode & TypeAware> XmlCodec<?> codecFor(final T currentNode) {
+ return codecFor(currentNode, type -> verifyNotNull(
+ SchemaContextUtil.getBaseTypeForLeafRef(type, getEffectiveModelContext(), currentNode),
+ "Unable to find base type for leafref node %s type %s.", currentNode, type));
+ }
}
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.model.api.type.UnionTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.UnknownTypeDefinition;
import org.opendaylight.yangtools.yang.model.spi.AbstractEffectiveModelContextProvider;
-import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
*/
public abstract class AbstractCodecFactory<T extends TypeAwareCodec<?, ?, ?>>
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<T> cache;
this.cache = requireNonNull(cache);
}
- public final <S extends TypeAware & SchemaNode> @NonNull T codecFor(final S schema) {
+ public final <S extends TypeAware & SchemaNode> @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.
}
// ... 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);
}
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,
- getEffectiveModelContext(), 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 {
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<TypeDefinition<?>> types = union.getTypes();
final List<T> codecs = new ArrayList<>(types.size());
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);