import org.opendaylight.yangtools.concepts.Codec;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType;
import org.opendaylight.yangtools.util.ClassLoaderUtils;
import org.opendaylight.yangtools.yang.binding.BaseIdentity;
import org.opendaylight.yangtools.yang.binding.BindingMapping;
import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
} catch (Exception e) {
throw new IllegalStateException("Unable to load codec for " + valueType, e);
}
+ } else if(rootType instanceof LeafrefTypeDefinition) {
+ Entry<GeneratedType, Object> typeWithSchema = context.getTypeWithSchema(valueType);
+ Object schema = typeWithSchema.getValue();
+ Preconditions.checkState(schema instanceof TypeDefinition<?>);
+ return getCodec(valueType, (TypeDefinition<?>) schema);
}
return ValueTypeCodec.getCodecFor(valueType, instantiatedType);
}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.binding.data.codec.test;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map.Entry;
+import javassist.ClassPool;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.augment.rev140709.ThirdParty;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.augment.rev140709.TreeComplexLeaves;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.augment.rev140709.TreeComplexLeavesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.binding.rev140701.Int32StringUnion;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.binding.rev140701.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.binding.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.binding.rev140701.two.level.list.TopLevelListKey;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+
+public class LeafReferenceTest extends AbstractBindingRuntimeTest {
+
+ private static final TopLevelListKey TOP_FOO_KEY = new TopLevelListKey("foo");
+ private static final InstanceIdentifier<TreeComplexLeaves> BA_TOP_LEVEL_LIST = InstanceIdentifier.builder(Top.class)
+ .child(TopLevelList.class, TOP_FOO_KEY).augmentation(TreeComplexLeaves.class).toInstance();
+
+ private BindingNormalizedNodeCodecRegistry registry;
+
+ @Override
+ public void setup() {
+ super.setup();
+ JavassistUtils utils = JavassistUtils.forClassPool(ClassPool.getDefault());
+ registry = new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(utils));
+ registry.onBindingRuntimeContextUpdated(getRuntimeContext());
+ }
+
+ @Test
+ public void testCaseWithLeafReferencesType() {
+ TreeComplexLeaves binding = new TreeComplexLeavesBuilder()
+ .setIdentity(ThirdParty.class)
+ .setIdentityRef(ThirdParty.class)
+ .setSimpleType(10)
+ .setSimpleTypeRef(10)
+ .setSchemaUnawareUnion(new Int32StringUnion("foo"))
+ .setSchemaUnawareUnionRef(new Int32StringUnion(10))
+ .build();
+ Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> dom = registry.toNormalizedNode(BA_TOP_LEVEL_LIST, binding);
+ Entry<InstanceIdentifier<?>, DataObject> readed = registry.fromNormalizedNode(dom.getKey(),dom.getValue());
+ TreeComplexLeaves readedAugment = ((TreeComplexLeaves) readed.getValue());
+
+ assertEquals(binding,readedAugment);
+
+ }
+
+
+
+}
import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findNodeInSchemaContext;
import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
-
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef,
typedef);
if (type != null) {
- genCtx.get(module).addTypedefType(typedef.getPath(), type);
+ final ModuleContext ctx = genCtx.get(module);
+ ctx.addTypedefType(typedef.getPath(), type);
+ ctx.addTypeToSchema(type,typedef);
}
}
}
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
public final class ModuleContext {
private GeneratedTypeBuilder moduleNode;
return Collections.unmodifiableMap(typeToSchema);
}
+ protected void addTypeToSchema(Type type, TypeDefinition<?> typedef) {
+ typeToSchema.put(type, typedef);
+ }
+
}
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.yangtools.sal.binding.generator.util;
import com.google.common.base.Optional;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimap;
-
import java.util.AbstractMap;
import java.util.AbstractMap.SimpleEntry;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-
import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
for (ModuleContext ctx : modules.values()) {
augmentationToSchema.putAll(ctx.getTypeToAugmentation());
typeToDefiningSchema.putAll(ctx.getTypeToSchema());
+
+ ctx.getTypedefs();
augmentableToAugmentations.putAll(ctx.getAugmentableToAugmentations());
choiceToCases.putAll(ctx.getChoiceToCases());
identities.putAll(ctx.getIdentities());
return new ReferencedTypeImpl(type.getPackage().getName(), type.getSimpleName());
}
+ /**
+ * Returns schema ({@link DataSchemaNode}, {@link AugmentationSchema} or {@link TypeDefinition})
+ * from which supplied class was generated. Returned schema may be augmented with
+ * additional information, which was not available at compile type
+ * (e.g. third party augmentations).
+ *
+ * @param type Binding Class for which schema should be retrieved.
+ * @return Instance of generated type (definition of Java API), along with
+ * {@link DataSchemaNode}, {@link AugmentationSchema} or {@link TypeDefinition}
+ * which was used to generate supplied class.
+ */
public Entry<GeneratedType, Object> getTypeWithSchema(final Class<?> type) {
Object schema = typeToDefiningSchema.get(referencedType(type));
Type definedType = typeToDefiningSchema.inverse().get(schema);
Preconditions.checkNotNull(schema);
Preconditions.checkNotNull(definedType);
+ if(definedType instanceof GeneratedTypeBuilder) {
+ return new SimpleEntry<>(((GeneratedTypeBuilder) definedType).toInstance(), schema);
+ }
+ Preconditions.checkArgument(definedType instanceof GeneratedType,"Type {} is not GeneratedType",type);
+ return new SimpleEntry<>((GeneratedType) definedType,schema);
- return new SimpleEntry<>(((GeneratedTypeBuilder) definedType).toInstance(), schema);
}
public ImmutableMap<Type, Entry<Type, Type>> getChoiceCaseChildren(final DataNodeContainer schema) {
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.yangtools.test.binding.rev140701;
+
+
+/**
+ * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation.
+ * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32).
+ * The reason behind putting it under src/main/java is:
+ * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent
+ * loss of user code.
+ */
+public class Int32StringUnionBuilder {
+
+ public static Int32StringUnion getDefaultInstance(final String defaultValue) {
+ try {
+ return new Int32StringUnion(Integer.parseInt(defaultValue));
+ } catch (NumberFormatException e) {
+ return new Int32StringUnion(defaultValue);
+ }
+ }
+
+}
"Test model for testing data broker with nested lists.";
}
+ identity third-party {
+ base test:test-root;
+ }
+
grouping leaf-from-grouping {
leaf leaf-from-grouping {
type string;
type string;
}
}
-
}
augment "/test:top/test:top-level-list" {
uses leaf-from-grouping;
}
+ augment "/test:top/test:top-level-list" {
+ ext:augment-identifier tree-complex-leaves;
+ leaf simple-type {
+ type int32;
+ }
+ leaf identity {
+ type test:test-identityref;
+ }
+ leaf schema-unaware-union {
+ type test:int32-string-union;
+ }
+
+ leaf simple-type-ref {
+ type leafref {
+ path "../simple-type";
+ }
+ }
+ leaf identity-ref {
+ type leafref {
+ path "../identity";
+ }
+ }
+ leaf schema-unaware-union-ref {
+ type leafref {
+ path "../schema-unaware-union";
+ }
+ }
+ }
+
+
augment "/test:put-top/test:input/test:top-level-list" {
ext:augment-identifier rpc-leaf-only-uses-augment;
uses leaf-from-grouping;
"Test model for testing data broker with nested lists.";
}
+ typedef int32-string-union {
+ type union {
+ type int32;
+ type string;
+ }
+ }
+
+ identity test-root;
+
+ identity test-one {
+ base test-root;
+ }
+
+ identity test-two {
+ base test-root;
+ }
+
+ typedef test-identityref {
+ type identityref {
+ base test-root;
+ }
+ }
+
grouping two-level-list {
list top-level-list {
description