Search in sources :

Example 1 with Types

use of org.opendaylight.mdsal.binding.model.ri.Types in project mdsal by opendaylight.

the class LeafrefResolutionTest method testLeafRefRelativeAndAbsoluteValidReference.

@Test
public void testLeafRefRelativeAndAbsoluteValidReference() {
    final List<GeneratedType> types = DefaultBindingGenerator.generateFor(YangParserTestUtils.parseYangResource("/leafref-valid.yang"));
    assertEquals(2, types.size());
    final List<MethodSignature> neighborMethods = types.stream().filter(type -> type.getName().equals("Neighbor")).findFirst().orElseThrow().getMethodDefinitions();
    assertEquals(10, neighborMethods.size());
    final MethodSignature getNeighborId = neighborMethods.stream().filter(method -> method.getName().equals("getNeighborId")).findFirst().orElseThrow();
    assertEquals(Types.STRING, getNeighborId.getReturnType());
    final MethodSignature getNeighbor2Id = neighborMethods.stream().filter(method -> method.getName().equals("getNeighbor2Id")).findFirst().orElseThrow();
    assertEquals(Types.STRING, getNeighbor2Id.getReturnType());
}
Also used : List(java.util.List) Assert.assertThrows(org.junit.Assert.assertThrows) MethodSignature(org.opendaylight.mdsal.binding.model.api.MethodSignature) Test(org.junit.Test) YangParserTestUtils(org.opendaylight.yangtools.yang.test.util.YangParserTestUtils) EffectiveModelContext(org.opendaylight.yangtools.yang.model.api.EffectiveModelContext) Assert.assertEquals(org.junit.Assert.assertEquals) Types(org.opendaylight.mdsal.binding.model.ri.Types) GeneratedType(org.opendaylight.mdsal.binding.model.api.GeneratedType) MethodSignature(org.opendaylight.mdsal.binding.model.api.MethodSignature) GeneratedType(org.opendaylight.mdsal.binding.model.api.GeneratedType) Test(org.junit.Test)

Example 2 with Types

use of org.opendaylight.mdsal.binding.model.ri.Types in project mdsal by opendaylight.

the class AbstractTypeObjectGenerator method createUnion.

@NonNull
private static GeneratedTransferObject createUnion(final List<GeneratedType> auxiliaryGeneratedTypes, final TypeBuilderFactory builderFactory, final EffectiveStatement<?, ?> definingStatement, final UnionDependencies dependencies, final JavaTypeName typeName, final ModuleGenerator module, final TypeEffectiveStatement<?> type, final boolean isTypedef, final TypeDefinition<?> typedef) {
    final GeneratedUnionBuilder builder = builderFactory.newGeneratedUnionBuilder(typeName);
    builder.addImplementsType(BindingTypes.TYPE_OBJECT);
    builder.setIsUnion(true);
    // builder.setSchemaPath(typedef.getPath());
    builder.setModuleName(module.statement().argument().getLocalName());
    builderFactory.addCodegenInformation(definingStatement, builder);
    annotateDeprecatedIfNecessary(definingStatement, builder);
    // Pattern string is the key, XSD regex is the value. The reason for this choice is that the pattern carries
    // also negation information and hence guarantees uniqueness.
    final Map<String, String> expressions = new HashMap<>();
    // Linear list of properties generated from subtypes. We need this information for runtime types, as it allows
    // direct mapping of type to corresponding property -- without having to resort to re-resolving the leafrefs
    // again.
    final List<String> typeProperties = new ArrayList<>();
    for (EffectiveStatement<?, ?> stmt : type.effectiveSubstatements()) {
        if (stmt instanceof TypeEffectiveStatement) {
            final TypeEffectiveStatement<?> subType = (TypeEffectiveStatement<?>) stmt;
            final QName subName = subType.argument();
            final String localName = subName.getLocalName();
            String propSource = localName;
            final Type generatedType;
            if (TypeDefinitions.UNION.equals(subName)) {
                final JavaTypeName subUnionName = typeName.createEnclosed(provideAvailableNameForGenTOBuilder(typeName.simpleName()));
                final GeneratedTransferObject subUnion = createUnion(auxiliaryGeneratedTypes, builderFactory, definingStatement, dependencies, subUnionName, module, subType, isTypedef, subType.getTypeDefinition());
                builder.addEnclosingTransferObject(subUnion);
                propSource = subUnionName.simpleName();
                generatedType = subUnion;
            } else if (TypeDefinitions.ENUMERATION.equals(subName)) {
                final Enumeration subEnumeration = createEnumeration(builderFactory, typeName.createEnclosed(BindingMapping.getClassName(localName), "$"), module, (EnumTypeDefinition) subType.getTypeDefinition());
                builder.addEnumeration(subEnumeration);
                generatedType = subEnumeration;
            } else if (TypeDefinitions.BITS.equals(subName)) {
                final GeneratedTransferObject subBits = createBits(builderFactory, typeName.createEnclosed(BindingMapping.getClassName(localName), "$"), module, subType.getTypeDefinition(), isTypedef);
                builder.addEnclosingTransferObject(subBits);
                generatedType = subBits;
            } else if (TypeDefinitions.IDENTITYREF.equals(subName)) {
                generatedType = verifyNotNull(dependencies.identityTypes.get(stmt), "Cannot resolve identityref %s in %s", stmt, definingStatement).methodReturnType(builderFactory);
            } else if (TypeDefinitions.LEAFREF.equals(subName)) {
                generatedType = verifyNotNull(dependencies.leafTypes.get(stmt), "Cannot resolve leafref %s in %s", stmt, definingStatement).methodReturnType(builderFactory);
            } else {
                Type baseType = SIMPLE_TYPES.get(subName);
                if (baseType == null) {
                    // This has to be a reference to a typedef, let's lookup it up and pick up its type
                    final AbstractTypeObjectGenerator<?, ?> baseGen = verifyNotNull(dependencies.baseTypes.get(subName), "Cannot resolve base type %s in %s", subName, definingStatement);
                    baseType = baseGen.methodReturnType(builderFactory);
                    // FIXME: This is legacy behaviour for leafrefs:
                    if (baseGen.refType instanceof TypeReference.Leafref) {
                        // if there already is a compatible property, do not generate a new one
                        final Type search = baseType;
                        final String matching = builder.getProperties().stream().filter(prop -> search == ((GeneratedPropertyBuilderImpl) prop).getReturnType()).findFirst().map(GeneratedPropertyBuilder::getName).orElse(null);
                        if (matching != null) {
                            typeProperties.add(matching);
                            continue;
                        }
                        // ... otherwise generate this weird property name
                        propSource = BindingMapping.getUnionLeafrefMemberName(builder.getName(), baseType.getName());
                    }
                }
                expressions.putAll(resolveRegExpressions(subType.getTypeDefinition()));
                generatedType = restrictType(baseType, BindingGeneratorUtil.getRestrictions(type.getTypeDefinition()), builderFactory);
            }
            final String propName = BindingMapping.getPropertyName(propSource);
            typeProperties.add(propName);
            if (builder.containsProperty(propName)) {
                /*
                     *  FIXME: this is not okay, as we are ignoring multiple base types. For example in the case of:
                     *
                     *    type union {
                     *      type string {
                     *        length 1..5;
                     *      }
                     *      type string {
                     *        length 8..10;
                     *      }
                     *    }
                     *
                     *  We are ending up losing the information about 8..10 being an alternative. This is also the case
                     *  for leafrefs -- we are performing property compression as well (see above). While it is alluring
                     *  to merge these into 'length 1..5|8..10', that may not be generally feasible.
                     *
                     *  We should resort to a counter of conflicting names, i.e. the second string would be mapped to
                     *  'string1' or similar.
                     */
                continue;
            }
            final GeneratedPropertyBuilder propBuilder = builder.addProperty(propName).setReturnType(generatedType);
            builder.addEqualsIdentity(propBuilder);
            builder.addHashIdentity(propBuilder);
            builder.addToStringProperty(propBuilder);
        }
    }
    // Record property names if needed
    builder.setTypePropertyNames(typeProperties);
    addStringRegExAsConstant(builder, expressions);
    addUnits(builder, typedef);
    makeSerializable(builder);
    final GeneratedTransferObject ret = builder.build();
    // Define a corresponding union builder. Typedefs are always anchored at a Java package root,
    // so we are placing the builder alongside the union.
    final GeneratedTOBuilder unionBuilder = builderFactory.newGeneratedTOBuilder(unionBuilderName(typeName));
    unionBuilder.setIsUnionBuilder(true);
    unionBuilder.addMethod("getDefaultInstance").setAccessModifier(AccessModifier.PUBLIC).setStatic(true).setReturnType(ret).addParameter(Types.STRING, "defaultValue");
    auxiliaryGeneratedTypes.add(unionBuilder.build());
    return ret;
}
Also used : PathEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.PathEffectiveStatement) GeneratedProperty(org.opendaylight.mdsal.binding.model.api.GeneratedProperty) LoggerFactory(org.slf4j.LoggerFactory) AbstractEnumerationBuilder(org.opendaylight.mdsal.binding.model.ri.generated.type.builder.AbstractEnumerationBuilder) PatternExpression(org.opendaylight.yangtools.yang.model.api.stmt.PatternExpression) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Nullable(org.eclipse.jdt.annotation.Nullable) Map(java.util.Map) TypeDefinition(org.opendaylight.yangtools.yang.model.api.TypeDefinition) AccessModifier(org.opendaylight.mdsal.binding.model.api.AccessModifier) StringTypeDefinition(org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition) Bit(org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit) RuntimeType(org.opendaylight.mdsal.binding.runtime.api.RuntimeType) RangeEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.RangeEffectiveStatement) ImmutableMap(com.google.common.collect.ImmutableMap) Type(org.opendaylight.mdsal.binding.model.api.Type) TypeDefinitions(org.opendaylight.yangtools.yang.model.api.type.TypeDefinitions) BindingTypes(org.opendaylight.mdsal.binding.model.ri.BindingTypes) ResolvedLeafref(org.opendaylight.mdsal.binding.generator.impl.reactor.TypeReference.ResolvedLeafref) Enumeration(org.opendaylight.mdsal.binding.model.api.Enumeration) GeneratedTypeBuilderBase(org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilderBase) Collectors(java.util.stream.Collectors) MethodSignatureBuilder(org.opendaylight.mdsal.binding.model.api.type.builder.MethodSignatureBuilder) List(java.util.List) YangConstants(org.opendaylight.yangtools.yang.common.YangConstants) BitsTypeDefinition(org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition) Optional(java.util.Optional) BindingGeneratorUtil(org.opendaylight.mdsal.binding.generator.BindingGeneratorUtil) NonNull(org.eclipse.jdt.annotation.NonNull) LengthEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.LengthEffectiveStatement) Verify.verifyNotNull(com.google.common.base.Verify.verifyNotNull) HashMap(java.util.HashMap) GeneratedPropertyBuilder(org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedPropertyBuilder) ConcreteType(org.opendaylight.mdsal.binding.model.api.ConcreteType) ModifierKind(org.opendaylight.yangtools.yang.model.api.type.ModifierKind) BaseYangTypes(org.opendaylight.mdsal.binding.model.ri.BaseYangTypes) ArrayList(java.util.ArrayList) TypeConstants(org.opendaylight.mdsal.binding.model.ri.TypeConstants) Verify.verify(com.google.common.base.Verify.verify) GeneratedTransferObject(org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject) PatternConstraint(org.opendaylight.yangtools.yang.model.api.type.PatternConstraint) EffectiveStatement(org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement) GeneratedTOBuilder(org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTOBuilder) Immutable(org.opendaylight.yangtools.concepts.Immutable) RegexPatterns(org.opendaylight.yangtools.yang.binding.RegexPatterns) Logger(org.slf4j.Logger) Maps(com.google.common.collect.Maps) QName(org.opendaylight.yangtools.yang.common.QName) BindingMapping(org.opendaylight.mdsal.binding.spec.naming.BindingMapping) JavaTypeName(org.opendaylight.mdsal.binding.model.api.JavaTypeName) EnumTypeDefinition(org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition) TypeObject(org.opendaylight.yangtools.yang.binding.TypeObject) PatternEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.PatternEffectiveStatement) ValueRange(org.opendaylight.yangtools.yang.model.api.stmt.ValueRange) Restrictions(org.opendaylight.mdsal.binding.model.api.Restrictions) GeneratedPropertyBuilderImpl(org.opendaylight.mdsal.binding.model.ri.generated.type.builder.GeneratedPropertyBuilderImpl) BaseEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.BaseEffectiveStatement) Types(org.opendaylight.mdsal.binding.model.ri.Types) TypeEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement) GeneratedType(org.opendaylight.mdsal.binding.model.api.GeneratedType) Enumeration(org.opendaylight.mdsal.binding.model.api.Enumeration) HashMap(java.util.HashMap) QName(org.opendaylight.yangtools.yang.common.QName) EnumTypeDefinition(org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition) ArrayList(java.util.ArrayList) GeneratedTOBuilder(org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTOBuilder) GeneratedTransferObject(org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject) ResolvedLeafref(org.opendaylight.mdsal.binding.generator.impl.reactor.TypeReference.ResolvedLeafref) RuntimeType(org.opendaylight.mdsal.binding.runtime.api.RuntimeType) Type(org.opendaylight.mdsal.binding.model.api.Type) ConcreteType(org.opendaylight.mdsal.binding.model.api.ConcreteType) GeneratedType(org.opendaylight.mdsal.binding.model.api.GeneratedType) TypeEffectiveStatement(org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement) GeneratedPropertyBuilder(org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedPropertyBuilder) JavaTypeName(org.opendaylight.mdsal.binding.model.api.JavaTypeName) NonNull(org.eclipse.jdt.annotation.NonNull)

Aggregations

List (java.util.List)2 GeneratedType (org.opendaylight.mdsal.binding.model.api.GeneratedType)2 Types (org.opendaylight.mdsal.binding.model.ri.Types)2 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)1 Verify.verify (com.google.common.base.Verify.verify)1 Verify.verifyNotNull (com.google.common.base.Verify.verifyNotNull)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 Maps (com.google.common.collect.Maps)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 Optional (java.util.Optional)1 Collectors (java.util.stream.Collectors)1 NonNull (org.eclipse.jdt.annotation.NonNull)1 Nullable (org.eclipse.jdt.annotation.Nullable)1 Assert.assertEquals (org.junit.Assert.assertEquals)1 Assert.assertThrows (org.junit.Assert.assertThrows)1 Test (org.junit.Test)1 BindingGeneratorUtil (org.opendaylight.mdsal.binding.generator.BindingGeneratorUtil)1 ResolvedLeafref (org.opendaylight.mdsal.binding.generator.impl.reactor.TypeReference.ResolvedLeafref)1