From 59787cce8cce649341d38cfa7faf36de0c2613bd Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Fri, 2 Mar 2018 20:55:58 +0100 Subject: [PATCH] Split up TypeProviderImpl This class needs to be split up into compile-time and runtime implementations to eliminate polluting runtime with information required only for code generators. Rename the baseline to AbstractTypeProvider and provide two distinct subclasses, CodegenTypeProvider and RuntimeTypeProvider. JIRA: MDSAL-312 Change-Id: Ia3a8b0677dee2252820cd9ee6c709e2e896b135f Signed-off-by: Robert Varga --- .../generator/impl/AbstractTypeGenerator.java | 14 +- .../generator/impl/CodegenTypeGenerator.java | 4 +- .../generator/impl/RuntimeTypeGenerator.java | 5 +- .../yang/types/AbstractTypeProvider.java | 1758 +++++++++++++++++ .../yang/types/CodegenTypeProvider.java | 53 + .../yang/types/RuntimeTypeProvider.java | 36 + .../binding/yang/types/TypeProviderImpl.java | 1757 +--------------- .../impl/TypeProviderIntegrationTest.java | 7 +- .../mdsal/binding/yang/types/Bug4621.java | 3 +- .../yang/types/TypeProviderImplTest.java | 11 +- .../binding/yang/types/TypeProviderTest.java | 122 +- 11 files changed, 1942 insertions(+), 1828 deletions(-) create mode 100644 binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/AbstractTypeProvider.java create mode 100644 binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/CodegenTypeProvider.java create mode 100644 binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/RuntimeTypeProvider.java diff --git a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/AbstractTypeGenerator.java b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/AbstractTypeGenerator.java index 03f14d511b..24717088cd 100644 --- a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/AbstractTypeGenerator.java +++ b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/AbstractTypeGenerator.java @@ -12,7 +12,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static java.util.Objects.requireNonNull; import static org.opendaylight.mdsal.binding.model.util.BindingGeneratorUtil.computeDefaultSUID; -import static org.opendaylight.mdsal.binding.model.util.BindingGeneratorUtil.encodeAngleBrackets; import static org.opendaylight.mdsal.binding.model.util.BindingGeneratorUtil.packageNameForAugmentedGeneratedType; import static org.opendaylight.mdsal.binding.model.util.BindingGeneratorUtil.packageNameForGeneratedType; import static org.opendaylight.mdsal.binding.model.util.BindingTypes.DATA_OBJECT; @@ -63,8 +62,8 @@ import org.opendaylight.mdsal.binding.model.util.Types; import org.opendaylight.mdsal.binding.model.util.generated.type.builder.GeneratedPropertyBuilderImpl; import org.opendaylight.mdsal.binding.model.util.generated.type.builder.GeneratedTOBuilderImpl; import org.opendaylight.mdsal.binding.model.util.generated.type.builder.GeneratedTypeBuilderImpl; +import org.opendaylight.mdsal.binding.yang.types.AbstractTypeProvider; import org.opendaylight.mdsal.binding.yang.types.GroupingDefinitionDependencySort; -import org.opendaylight.mdsal.binding.yang.types.TypeProviderImpl; import org.opendaylight.yangtools.yang.binding.BaseIdentity; import org.opendaylight.yangtools.yang.binding.BindingMapping; import org.opendaylight.yangtools.yang.binding.DataContainer; @@ -157,7 +156,7 @@ abstract class AbstractTypeGenerator { /** * Provide methods for converting YANG types to JAVA types. */ - private final TypeProviderImpl typeProvider; + private final AbstractTypeProvider typeProvider; /** * Holds reference to schema context to resolve data of augmented element @@ -165,7 +164,7 @@ abstract class AbstractTypeGenerator { */ private final SchemaContext schemaContext; - AbstractTypeGenerator(final SchemaContext context, final TypeProviderImpl typeProvider) { + AbstractTypeGenerator(final SchemaContext context, final AbstractTypeProvider typeProvider) { this.schemaContext = requireNonNull(context); this.typeProvider = requireNonNull(typeProvider); @@ -186,7 +185,7 @@ abstract class AbstractTypeGenerator { return checkNotNull(genCtx.get(module), "Module context not found for module %s", module); } - final TypeProviderImpl typeProvider() { + final AbstractTypeProvider typeProvider() { return typeProvider; } @@ -683,8 +682,7 @@ abstract class AbstractTypeGenerator { if (enumTypeDef != null && typeBuilder != null && enumTypeDef.getQName().getLocalName() != null) { final String enumerationName = BindingMapping.getClassName(enumName); final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName); - final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription().orElse(null)); - enumBuilder.setDescription(enumTypedefDescription); + typeProvider.addEnumDescription(enumBuilder, enumTypeDef); enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); ModuleContext ctx = genCtx.get(module); ctx.addInnerTypedefType(enumTypeDef.getPath(), enumBuilder); @@ -1584,7 +1582,7 @@ abstract class AbstractTypeGenerator { genTOBuilder.setTypedef(true); genTOBuilder.setIsUnion(true); - TypeProviderImpl.addUnitsToGenTO(genTOBuilder, typeDef.getUnits().orElse(null)); + AbstractTypeProvider.addUnitsToGenTO(genTOBuilder, typeDef.getUnits().orElse(null)); diff --git a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/CodegenTypeGenerator.java b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/CodegenTypeGenerator.java index ba08f9c983..2affbe04c5 100644 --- a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/CodegenTypeGenerator.java +++ b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/CodegenTypeGenerator.java @@ -19,7 +19,7 @@ import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilde import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilderBase; import org.opendaylight.mdsal.binding.model.api.type.builder.TypeMemberBuilder; import org.opendaylight.mdsal.binding.model.util.TypeComments; -import org.opendaylight.mdsal.binding.yang.types.TypeProviderImpl; +import org.opendaylight.mdsal.binding.yang.types.CodegenTypeProvider; import org.opendaylight.yangtools.yang.model.api.DocumentedNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; @@ -27,7 +27,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode; final class CodegenTypeGenerator extends AbstractTypeGenerator { CodegenTypeGenerator(final SchemaContext context) { - super(context, new TypeProviderImpl(context)); + super(context, new CodegenTypeProvider(context)); } List toTypes(final Set modules) { diff --git a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/RuntimeTypeGenerator.java b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/RuntimeTypeGenerator.java index 59a3d18e4f..f496927d20 100644 --- a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/RuntimeTypeGenerator.java +++ b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/RuntimeTypeGenerator.java @@ -19,7 +19,7 @@ import org.opendaylight.mdsal.binding.model.api.Type; import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilder; import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilderBase; import org.opendaylight.mdsal.binding.model.api.type.builder.TypeMemberBuilder; -import org.opendaylight.mdsal.binding.yang.types.TypeProviderImpl; +import org.opendaylight.mdsal.binding.yang.types.RuntimeTypeProvider; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; import org.opendaylight.yangtools.yang.model.api.DocumentedNode; @@ -30,8 +30,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode; final class RuntimeTypeGenerator extends AbstractTypeGenerator { RuntimeTypeGenerator(final SchemaContext context) { - // TODO: instantiate a different subclass of TypeProviderImpl - super(context, new TypeProviderImpl(context)); + super(context, new RuntimeTypeProvider(context)); } BindingRuntimeTypes toTypeMapping() { diff --git a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/AbstractTypeProvider.java b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/AbstractTypeProvider.java new file mode 100644 index 0000000000..24562f11c9 --- /dev/null +++ b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/AbstractTypeProvider.java @@ -0,0 +1,1758 @@ +/* + * Copyright (c) 2013 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.mdsal.binding.yang.types; + +import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode; +import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNodeForRelativeXPath; +import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule; + +import com.google.common.annotations.Beta; +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.common.io.BaseEncoding; +import java.io.Serializable; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.TreeMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.opendaylight.mdsal.binding.generator.spi.TypeProvider; +import org.opendaylight.mdsal.binding.model.api.AccessModifier; +import org.opendaylight.mdsal.binding.model.api.ConcreteType; +import org.opendaylight.mdsal.binding.model.api.Enumeration; +import org.opendaylight.mdsal.binding.model.api.GeneratedProperty; +import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject; +import org.opendaylight.mdsal.binding.model.api.Restrictions; +import org.opendaylight.mdsal.binding.model.api.Type; +import org.opendaylight.mdsal.binding.model.api.type.builder.EnumBuilder; +import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedPropertyBuilder; +import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTOBuilder; +import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilderBase; +import org.opendaylight.mdsal.binding.model.api.type.builder.MethodSignatureBuilder; +import org.opendaylight.mdsal.binding.model.util.BindingGeneratorUtil; +import org.opendaylight.mdsal.binding.model.util.TypeConstants; +import org.opendaylight.mdsal.binding.model.util.Types; +import org.opendaylight.mdsal.binding.model.util.generated.type.builder.EnumerationBuilderImpl; +import org.opendaylight.mdsal.binding.model.util.generated.type.builder.GeneratedPropertyBuilderImpl; +import org.opendaylight.mdsal.binding.model.util.generated.type.builder.GeneratedTOBuilderImpl; +import org.opendaylight.yangtools.yang.binding.BindingMapping; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +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.BitsTypeDefinition.Bit; +import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; +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.ModifierKind; +import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; +import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; +import org.opendaylight.yangtools.yang.model.util.ModuleDependencySort; +import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl; +import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; +import org.opendaylight.yangtools.yang.model.util.type.BaseTypes; +import org.opendaylight.yangtools.yang.model.util.type.CompatUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Beta +public abstract class AbstractTypeProvider implements TypeProvider { + private static final Logger LOG = LoggerFactory.getLogger(AbstractTypeProvider.class); + private static final Pattern GROUPS_PATTERN = Pattern.compile("\\[(.*?)\\]"); + private static final Pattern NUMBERS_PATTERN = Pattern.compile("[0-9]+\\z"); + + // Backwards compatibility: Union types used to be instantiated in YANG namespace, which is no longer + // the case, as unions are emitted to their correct schema path. + private static final SchemaPath UNION_PATH = SchemaPath.create(true, + org.opendaylight.yangtools.yang.model.util.BaseTypes.UNION_QNAME); + + /** + * Contains the schema data red from YANG files. + */ + private final SchemaContext schemaContext; + + /** + * Map>> + */ + private final Map, Map>> genTypeDefsContextMap = new HashMap<>(); + + /** + * The map which maps schema paths to JAVA Type. + */ + private final Map referencedTypes = new HashMap<>(); + private final Map> additionalTypes = new HashMap<>(); + + /** + * Creates new instance of class TypeProviderImpl. + * + * @param schemaContext + * contains the schema data red from YANG files + * @throws IllegalArgumentException + * if schemaContext equal null. + */ + AbstractTypeProvider(final SchemaContext schemaContext) { + Preconditions.checkArgument(schemaContext != null, "Schema Context cannot be null!"); + + this.schemaContext = schemaContext; + resolveTypeDefsFromContext(); + } + + /** + * Puts refType to map with key refTypePath + * + * @param refTypePath + * schema path used as the map key + * @param refType + * type which represents the map value + * @throws IllegalArgumentException + *
    + *
  • if refTypePath equal null
  • + *
  • if refType equal null
  • + *
+ * + */ + public void putReferencedType(final SchemaPath refTypePath, final Type refType) { + Preconditions.checkArgument(refTypePath != null, + "Path reference of Enumeration Type Definition cannot be NULL!"); + Preconditions.checkArgument(refType != null, "Reference to Enumeration Type cannot be NULL!"); + referencedTypes.put(refTypePath, refType); + } + + public Map> getAdditionalTypes() { + return additionalTypes; + } + + /** + * + * Converts basic YANG type type to JAVA Type. + * + * @param type + * string with YANG name of type + * @return JAVA Type for YANG type type + * @see TypeProvider#javaTypeForYangType(String) + */ + @Override + @Deprecated + public Type javaTypeForYangType(final String type) { + return BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(type); + } + + @Override + public Type javaTypeForSchemaDefinitionType(final TypeDefinition typeDefinition, final SchemaNode parentNode) { + return javaTypeForSchemaDefinitionType(typeDefinition, parentNode, null); + } + + /** + * Converts schema definition type typeDefinition to JAVA + * Type + * + * @param typeDefinition + * type definition which is converted to JAVA type + * @throws IllegalArgumentException + *
    + *
  • if typeDefinition equal null
  • + *
  • if Qname of typeDefinition equal null
  • + *
  • if name of typeDefinition equal null
  • + *
+ */ + @Override + public Type javaTypeForSchemaDefinitionType(final TypeDefinition typeDefinition, final SchemaNode parentNode, + final Restrictions r) { + Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!"); + Preconditions.checkArgument(typeDefinition.getQName() != null, + "Type Definition cannot have non specified QName (QName cannot be NULL!)"); + final String typedefName = typeDefinition.getQName().getLocalName(); + Preconditions.checkArgument(typedefName != null, "Type Definitions Local Name cannot be NULL!"); + + // Deal with base types + if (typeDefinition.getBaseType() == null) { + // We have to deal with differing handling of decimal64. The old parser used a fixed Decimal64 type + // and generated an enclosing ExtendedType to hold any range constraints. The new parser instantiates + // a base type which holds these constraints. + if (typeDefinition instanceof DecimalTypeDefinition) { + final Type ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition, + parentNode, r); + if (ret != null) { + return ret; + } + } + + // Deal with leafrefs/identityrefs + Type ret = javaTypeForLeafrefOrIdentityRef(typeDefinition, parentNode); + if (ret != null) { + return ret; + } + + // FIXME: it looks as though we could be using the same codepath as above... + ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(typeDefinition.getQName().getLocalName()); + if (ret == null) { + LOG.debug("Failed to resolve Java type for {}", typeDefinition); + } + + return ret; + } + + Type returnType = javaTypeForExtendedType(typeDefinition); + if (r != null && returnType instanceof GeneratedTransferObject) { + final GeneratedTransferObject gto = (GeneratedTransferObject) returnType; + final Module module = findParentModule(schemaContext, parentNode); + final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); + final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, + typeDefinition.getPath()); + final String genTOName = BindingMapping.getClassName(typedefName); + final String name = packageName + "." + genTOName; + if (!returnType.getFullyQualifiedName().equals(name)) { + returnType = shadedTOWithRestrictions(gto, r); + } + } + return returnType; + } + + private static GeneratedTransferObject shadedTOWithRestrictions(final GeneratedTransferObject gto, + final Restrictions r) { + final GeneratedTOBuilder gtob = new GeneratedTOBuilderImpl(gto.getPackageName(), gto.getName()); + final GeneratedTransferObject parent = gto.getSuperType(); + if (parent != null) { + gtob.setExtendsType(parent); + } + gtob.setRestrictions(r); + for (GeneratedProperty gp : gto.getProperties()) { + final GeneratedPropertyBuilder gpb = gtob.addProperty(gp.getName()); + gpb.setValue(gp.getValue()); + gpb.setReadOnly(gp.isReadOnly()); + gpb.setAccessModifier(gp.getAccessModifier()); + gpb.setReturnType(gp.getReturnType()); + gpb.setFinal(gp.isFinal()); + gpb.setStatic(gp.isStatic()); + } + return gtob.toInstance(); + } + + private boolean isLeafRefSelfReference(final LeafrefTypeDefinition leafref, final SchemaNode parentNode) { + final SchemaNode leafRefValueNode; + final RevisionAwareXPath leafRefXPath = leafref.getPathStatement(); + final RevisionAwareXPath leafRefStrippedXPath = new RevisionAwareXPathImpl( + GROUPS_PATTERN.matcher(leafRefXPath.toString()).replaceAll(""), leafRefXPath.isAbsolute()); + + ///// skip leafrefs in augments - they're checked once augments are resolved + final Iterator iterator = parentNode.getPath().getPathFromRoot().iterator(); + boolean isAugmenting = false; + DataNodeContainer current = null; + DataSchemaNode dataChildByName; + + while (iterator.hasNext() && !isAugmenting) { + final QName next = iterator.next(); + if (current == null) { + dataChildByName = schemaContext.getDataChildByName(next); + } else { + dataChildByName = current.getDataChildByName(next); + } + if (dataChildByName != null) { + isAugmenting = dataChildByName.isAugmenting(); + } else { + return false; + } + if (dataChildByName instanceof DataNodeContainer) { + current = (DataNodeContainer) dataChildByName; + } + } + if (isAugmenting) { + return false; + } + ///// + + final Module parentModule = getParentModule(parentNode); + if (!leafRefStrippedXPath.isAbsolute()) { + leafRefValueNode = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemaContext, parentModule, + parentNode, leafRefStrippedXPath); + } else { + leafRefValueNode = SchemaContextUtil.findDataSchemaNode(schemaContext, parentModule, leafRefStrippedXPath); + } + return leafRefValueNode != null ? leafRefValueNode.equals(parentNode) : false; + } + + /** + * Returns JAVA Type for instances of the type + * LeafrefTypeDefinition or + * IdentityrefTypeDefinition. + * + * @param typeDefinition + * type definition which is converted to JAVA Type + * @return JAVA Type instance for typeDefinition + */ + private Type javaTypeForLeafrefOrIdentityRef(final TypeDefinition typeDefinition, final SchemaNode parentNode) { + if (typeDefinition instanceof LeafrefTypeDefinition) { + final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition; + Preconditions.checkArgument(!isLeafRefSelfReference(leafref, parentNode), + "Leafref %s is referencing itself, incoming StackOverFlowError detected.", leafref); + return provideTypeForLeafref(leafref, parentNode); + } else if (typeDefinition instanceof IdentityrefTypeDefinition) { + return provideTypeForIdentityref((IdentityrefTypeDefinition) typeDefinition); + } + + return null; + } + + /** + * Returns JAVA Type for instances of the type + * ExtendedType. + * + * @param typeDefinition + * type definition which is converted to JAVA Type + * @return JAVA Type instance for typeDefinition + */ + private Type javaTypeForExtendedType(final TypeDefinition typeDefinition) { + final String typedefName = typeDefinition.getQName().getLocalName(); + final TypeDefinition baseTypeDef = baseTypeDefForExtendedType(typeDefinition); + Type returnType = javaTypeForLeafrefOrIdentityRef(baseTypeDef, typeDefinition); + if (returnType == null) { + if (baseTypeDef instanceof EnumTypeDefinition) { + final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDef; + returnType = provideTypeForEnum(enumTypeDef, typedefName, typeDefinition); + } else { + final Module module = findParentModule(schemaContext, typeDefinition); + final Restrictions r = BindingGeneratorUtil.getRestrictions(typeDefinition); + if (module != null) { + final Map, Map> modulesByDate = genTypeDefsContextMap.get( + module.getName()); + final Map genTOs = modulesByDate.get(module.getRevision()); + if (genTOs != null) { + returnType = genTOs.get(typedefName); + } + if (returnType == null) { + returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType( + baseTypeDef, typeDefinition, r); + } + } + } + } + return returnType; + } + + /** + * Seeks for identity reference idref the JAVA + * type.
+ *
+ * + * Example:
+ * If identy which is referenced via idref has name Idn + * then returning type is {@code Class}
+ * + * @param idref + * identityref type definition for which JAVA Type + * is sought + * @return JAVA Type of the identity which is referenced through + * idref + */ + private Type provideTypeForIdentityref(final IdentityrefTypeDefinition idref) { + final Collection identities = idref.getIdentities(); + if (identities.size() > 1) { + LOG.warn("Identity reference {} has multiple identities, using only the first one", idref); + } + + final QName baseIdQName = identities.iterator().next().getQName(); + final Module module = schemaContext.findModule(baseIdQName.getModule()).orElse(null); + IdentitySchemaNode identity = null; + for (IdentitySchemaNode id : module.getIdentities()) { + if (id.getQName().equals(baseIdQName)) { + identity = id; + } + } + Preconditions.checkArgument(identity != null, "Target identity '" + baseIdQName + "' do not exists"); + + final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); + final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, + identity.getPath()); + final String genTypeName = BindingMapping.getClassName(identity.getQName()); + + final Type baseType = Types.typeForClass(Class.class); + final Type paramType = Types.wildcardTypeFor(packageName, genTypeName); + return Types.parameterizedTypeFor(baseType, paramType); + } + + /** + * Converts typeDefinition to concrete JAVA Type. + * + * @param typeDefinition + * type definition which should be converted to JAVA + * Type + * @return JAVA Type which represents + * typeDefinition + * @throws IllegalArgumentException + *
    + *
  • if typeDefinition equal null
  • + *
  • if Q name of typeDefinition
  • + *
  • if name of typeDefinition
  • + *
+ */ + public Type generatedTypeForExtendedDefinitionType(final TypeDefinition typeDefinition, final SchemaNode parentNode) { + Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!"); + if (typeDefinition.getQName() == null) { + throw new IllegalArgumentException( + "Type Definition cannot have non specified QName (QName cannot be NULL!)"); + } + Preconditions.checkArgument(typeDefinition.getQName().getLocalName() != null, + "Type Definitions Local Name cannot be NULL!"); + + final TypeDefinition baseTypeDef = baseTypeDefForExtendedType(typeDefinition); + if (baseTypeDef instanceof LeafrefTypeDefinition || baseTypeDef instanceof IdentityrefTypeDefinition) { + /* + * This is backwards compatibility baggage from way back when. The problem at hand is inconsistency between + * the fact that identity is mapped to a Class, which is also returned from leaves which specify it like + * this: + * + * identity iden; + * + * container foo { + * leaf foo { + * type identityref { + * base iden; + * } + * } + * } + * + * This results in getFoo() returning Class, which looks fine on the surface, but gets more + * dicey when we throw in: + * + * typedef bar-ref { + * type identityref { + * base iden; + * } + * } + * + * container bar { + * leaf bar { + * type bar-ref; + * } + * } + * + * Now we have competing requirements: typedef would like us to use encapsulation to capture the defined + * type, while getBar() wants us to retain shape with getFoo(), as it should not matter how the identityref + * is formed. + * + * In this particular case getFoo() won just after the Binding Spec was frozen, hence we do not generate + * an encapsulation for identityref typedefs. + * + * In case you are thinking we could get by having foo-ref map to a subclass of Iden, that is not a good + * option, as it would look as though it is the product of a different construct: + * + * identity bar-ref { + * base iden; + * } + * + * Leading to a rather nice namespace clash and also slight incompatibility with unknown third-party + * sub-identities of iden. + * + * The story behind leafrefs is probably similar, but that needs to be ascertained. + */ + return null; + } + + final Module module = findParentModule(schemaContext, parentNode); + if (module != null) { + final Map, Map> modulesByDate = genTypeDefsContextMap.get( + module.getName()); + final Map genTOs = modulesByDate.get(module.getRevision()); + if (genTOs != null) { + return genTOs.get(typeDefinition.getQName().getLocalName()); + } + } + return null; + } + + /** + * Gets base type definition for extendTypeDef. The method is + * recursively called until non ExtendedType type is found. + * + * @param extendTypeDef + * type definition for which is the base type definition sought + * @return type definition which is base type for extendTypeDef + * @throws IllegalArgumentException + * if extendTypeDef equal null + */ + private static TypeDefinition baseTypeDefForExtendedType(final TypeDefinition extendTypeDef) { + Preconditions.checkArgument(extendTypeDef != null, "Type Definition reference cannot be NULL!"); + + TypeDefinition ret = extendTypeDef; + while (ret.getBaseType() != null) { + ret = ret.getBaseType(); + } + + return ret; + } + + /** + * Converts leafrefType to JAVA Type. + * + * The path of leafrefType is followed to find referenced node + * and its Type is returned. + * + * @param leafrefType + * leafref type definition for which is the type sought + * @return JAVA Type of data schema node which is referenced in + * leafrefType + * @throws IllegalArgumentException + *
    + *
  • if leafrefType equal null
  • + *
  • if path statement of leafrefType equal null
  • + *
+ * + */ + public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType, final SchemaNode parentNode) { + Type returnType = null; + Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!"); + + Preconditions.checkArgument(leafrefType.getPathStatement() != null, + "The Path Statement for Leafref Type Definition cannot be NULL!"); + + final RevisionAwareXPath xpath = leafrefType.getPathStatement(); + final String strXPath = xpath.toString(); + + if (strXPath != null) { + if (strXPath.indexOf('[') == -1) { + final Module module = findParentModule(schemaContext, parentNode); + Preconditions.checkArgument(module != null, "Failed to find module for parent %s", parentNode); + + final SchemaNode dataNode; + if (xpath.isAbsolute()) { + dataNode = findDataSchemaNode(schemaContext, module, xpath); + } else { + dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath); + } + Preconditions.checkArgument(dataNode != null, "Failed to find leafref target: %s in module %s (%s)", + strXPath, this.getParentModule(parentNode).getName(), parentNode.getQName().getModule()); + + if (leafContainsEnumDefinition(dataNode)) { + returnType = referencedTypes.get(dataNode.getPath()); + } else if (leafListContainsEnumDefinition(dataNode)) { + returnType = Types.listTypeFor(referencedTypes.get(dataNode.getPath())); + } else { + returnType = resolveTypeFromDataSchemaNode(dataNode); + } + } else { + returnType = Types.typeForClass(Object.class); + } + } + Preconditions.checkArgument(returnType != null, "Failed to find leafref target: %s in module %s (%s)", + strXPath, this.getParentModule(parentNode).getName(), parentNode.getQName().getModule(), this); + return returnType; + } + + /** + * Checks if dataNode is LeafSchemaNode and if it + * so then checks if it is of type EnumTypeDefinition. + * + * @param dataNode + * data schema node for which is checked if it is leaf and if it + * is of enum type + * @return boolean value + *
    + *
  • true - if dataNode is leaf of type enumeration
  • + *
  • false - other cases
  • + *
+ */ + private static boolean leafContainsEnumDefinition(final SchemaNode dataNode) { + if (dataNode instanceof LeafSchemaNode) { + final LeafSchemaNode leaf = (LeafSchemaNode) dataNode; + if (CompatUtils.compatLeafType(leaf) instanceof EnumTypeDefinition) { + return true; + } + } + return false; + } + + /** + * Checks if dataNode is LeafListSchemaNode and if + * it so then checks if it is of type EnumTypeDefinition. + * + * @param dataNode + * data schema node for which is checked if it is leaflist and if + * it is of enum type + * @return boolean value + *
    + *
  • true - if dataNode is leaflist of type + * enumeration
  • + *
  • false - other cases
  • + *
+ */ + private static boolean leafListContainsEnumDefinition(final SchemaNode dataNode) { + if (dataNode instanceof LeafListSchemaNode) { + final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode; + if (leafList.getType() instanceof EnumTypeDefinition) { + return true; + } + } + return false; + } + + /** + * Converts enumTypeDef to + * {@link Enumeration + * enumeration}. + * + * @param enumTypeDef + * enumeration type definition which is converted to enumeration + * @param enumName + * string with name which is used as the enumeration name + * @return enumeration type which is built with data (name, enum values) + * from enumTypeDef + * @throws IllegalArgumentException + *
    + *
  • if enumTypeDef equals null
  • + *
  • if enum values of enumTypeDef equal null
  • + *
  • if Q name of enumTypeDef equal null
  • + *
  • if name of enumTypeDef equal null
  • + *
+ */ + private Enumeration provideTypeForEnum(final EnumTypeDefinition enumTypeDef, final String enumName, + final SchemaNode parentNode) { + Preconditions.checkArgument(enumTypeDef != null, "EnumTypeDefinition reference cannot be NULL!"); + Preconditions.checkArgument(enumTypeDef.getValues() != null, + "EnumTypeDefinition MUST contain at least ONE value definition!"); + Preconditions.checkArgument(enumTypeDef.getQName() != null, "EnumTypeDefinition MUST contain NON-NULL QName!"); + Preconditions.checkArgument(enumTypeDef.getQName().getLocalName() != null, + "Local Name in EnumTypeDefinition QName cannot be NULL!"); + + final String enumerationName = BindingMapping.getClassName(enumName); + + final Module module = findParentModule(schemaContext, parentNode); + final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); + + final EnumerationBuilderImpl enumBuilder = new EnumerationBuilderImpl(basePackageName, enumerationName); + addEnumDescription(enumBuilder, enumTypeDef); + enumTypeDef.getReference().ifPresent(enumBuilder::setReference); + enumBuilder.setModuleName(module.getName()); + enumBuilder.setSchemaPath(enumTypeDef.getPath().getPathFromRoot()); + enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); + return enumBuilder.toInstance(null); + } + + /** + * Adds enumeration to typeBuilder. The enumeration data are + * taken from enumTypeDef. + * + * @param enumTypeDef + * enumeration type definition is source of enumeration data for + * typeBuilder + * @param enumName + * string with the name of enumeration + * @param typeBuilder + * generated type builder to which is enumeration added + * @return enumeration type which contains enumeration data form + * enumTypeDef + * @throws IllegalArgumentException + *
    + *
  • if enumTypeDef equals null
  • + *
  • if enum values of enumTypeDef equal null
  • + *
  • if Q name of enumTypeDef equal null
  • + *
  • if name of enumTypeDef equal null
  • + *
  • if name of typeBuilder equal null
  • + *
+ * + */ + private Enumeration addInnerEnumerationToTypeBuilder(final EnumTypeDefinition enumTypeDef, + final String enumName, final GeneratedTypeBuilderBase typeBuilder) { + Preconditions.checkArgument(enumTypeDef != null, "EnumTypeDefinition reference cannot be NULL!"); + Preconditions.checkArgument(enumTypeDef.getValues() != null, + "EnumTypeDefinition MUST contain at least ONE value definition!"); + Preconditions.checkArgument(enumTypeDef.getQName() != null, "EnumTypeDefinition MUST contain NON-NULL QName!"); + Preconditions.checkArgument(enumTypeDef.getQName().getLocalName() != null, + "Local Name in EnumTypeDefinition QName cannot be NULL!"); + Preconditions.checkArgument(typeBuilder != null, "Generated Type Builder reference cannot be NULL!"); + + final String enumerationName = BindingMapping.getClassName(enumName); + + final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName); + + addEnumDescription(enumBuilder, enumTypeDef); + enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); + return enumBuilder.toInstance(enumBuilder); + } + + public abstract void addEnumDescription(EnumBuilder enumBuilder, EnumTypeDefinition enumTypeDef); + + abstract void addCodegenInformation(GeneratedTypeBuilderBase genTOBuilder, TypeDefinition typeDef); + + /** + * Converts dataNode to JAVA Type. + * + * @param dataNode + * contains information about YANG type + * @return JAVA Type representation of dataNode + */ + private Type resolveTypeFromDataSchemaNode(final SchemaNode dataNode) { + Type returnType = null; + if (dataNode != null) { + if (dataNode instanceof LeafSchemaNode) { + final LeafSchemaNode leaf = (LeafSchemaNode) dataNode; + final TypeDefinition type = CompatUtils.compatLeafType(leaf); + returnType = javaTypeForSchemaDefinitionType(type, leaf); + } else if (dataNode instanceof LeafListSchemaNode) { + final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode; + returnType = javaTypeForSchemaDefinitionType(leafList.getType(), leafList); + } + } + return returnType; + } + + /** + * Passes through all modules and through all its type definitions and + * convert it to generated types. + * + * The modules are firstly sorted by mutual dependencies. The modules are + * sequentially passed. All type definitions of a module are at the + * beginning sorted so that type definition with less amount of references + * to other type definition are processed first.
+ * For each module is created mapping record in the map + * {@link AbstractTypeProvider#genTypeDefsContextMap genTypeDefsContextMap} + * which map current module name to the map which maps type names to + * returned types (generated types). + * + */ + private void resolveTypeDefsFromContext() { + final Set modules = schemaContext.getModules(); + Preconditions.checkArgument(modules != null, "Set of Modules cannot be NULL!"); + final List modulesSortedByDependency = ModuleDependencySort.sort(modules); + + for (Module module : modulesSortedByDependency) { + Map, Map> dateTypeMap = genTypeDefsContextMap.get(module.getName()); + if (dateTypeMap == null) { + dateTypeMap = new HashMap<>(); + } + dateTypeMap.put(module.getRevision(), Collections.emptyMap()); + genTypeDefsContextMap.put(module.getName(), dateTypeMap); + } + + for (Module module : modulesSortedByDependency) { + if (module != null) { + final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); + if (basePackageName != null) { + final List> typeDefinitions = TypedefResolver.getAllTypedefs(module); + for (TypeDefinition typedef : sortTypeDefinitionAccordingDepth(typeDefinitions)) { + typedefToGeneratedType(basePackageName, module, typedef); + } + } + } + } + } + + /** + * + * @param basePackageName + * string with name of package to which the module belongs + * @param module + * string with the name of the module for to which the + * typedef belongs + * @param typedef + * type definition of the node for which should be creted JAVA + * Type (usually generated TO) + * @return JAVA Type representation of typedef or + * null value if basePackageName or + * modulName or typedef or Q name of + * typedef equals null + */ + private Type typedefToGeneratedType(final String basePackageName, final Module module, final TypeDefinition typedef) { + final String moduleName = module.getName(); + final Optional moduleRevision = module.getRevision(); + if (basePackageName != null && moduleName != null && typedef != null && typedef.getQName() != null) { + final String typedefName = typedef.getQName().getLocalName(); + final TypeDefinition innerTypeDefinition = typedef.getBaseType(); + // See generatedTypeForExtendedDefinitionType() above for rationale behind this special case. + if (!(innerTypeDefinition instanceof LeafrefTypeDefinition) + && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) { + Type returnType = null; + if (innerTypeDefinition.getBaseType() != null) { + returnType = provideGeneratedTOFromExtendedType(typedef, innerTypeDefinition, basePackageName, module.getName()); + } else if (innerTypeDefinition instanceof UnionTypeDefinition) { + final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDef(basePackageName, + (UnionTypeDefinition) innerTypeDefinition, typedefName, typedef); + genTOBuilder.setTypedef(true); + genTOBuilder.setIsUnion(true); + addUnitsToGenTO(genTOBuilder, typedef.getUnits().orElse(null)); + makeSerializable((GeneratedTOBuilderImpl) genTOBuilder); + returnType = genTOBuilder.toInstance(); + // union builder + final GeneratedTOBuilder unionBuilder = new GeneratedTOBuilderImpl(genTOBuilder.getPackageName(), + genTOBuilder.getName() + "Builder"); + unionBuilder.setIsUnionBuilder(true); + final MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance"); + method.setReturnType(returnType); + method.addParameter(Types.STRING, "defaultValue"); + method.setAccessModifier(AccessModifier.PUBLIC); + method.setStatic(true); + Set types = additionalTypes.get(module); + if (types == null) { + types = Sets. newHashSet(unionBuilder.toInstance()); + additionalTypes.put(module, types); + } else { + types.add(unionBuilder.toInstance()); + } + } else if (innerTypeDefinition instanceof EnumTypeDefinition) { + // enums are automatically Serializable + final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition; + // TODO units for typedef enum + returnType = provideTypeForEnum(enumTypeDef, typedefName, typedef); + } else if (innerTypeDefinition instanceof BitsTypeDefinition) { + final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition; + final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForBitsTypeDefinition( + basePackageName, bitsTypeDefinition, typedefName, module.getName()); + genTOBuilder.setTypedef(true); + addUnitsToGenTO(genTOBuilder, typedef.getUnits().orElse(null)); + makeSerializable((GeneratedTOBuilderImpl) genTOBuilder); + returnType = genTOBuilder.toInstance(); + } else { + final Type javaType = javaTypeForSchemaDefinitionType(innerTypeDefinition, typedef); + returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType, module.getName()); + } + if (returnType != null) { + final Map, Map> modulesByDate = + genTypeDefsContextMap.get(moduleName); + Map typeMap = modulesByDate.get(moduleRevision); + if (typeMap != null) { + if (typeMap.isEmpty()) { + typeMap = new HashMap<>(4); + modulesByDate.put(moduleRevision, typeMap); + } + typeMap.put(typedefName, returnType); + } + return returnType; + } + } + } + return null; + } + + /** + * Wraps base YANG type to generated TO. + * + * @param basePackageName + * string with name of package to which the module belongs + * @param typedef + * type definition which is converted to the TO + * @param javaType + * JAVA Type to which is typedef mapped + * @return generated transfer object which representjavaType + */ + private GeneratedTransferObject wrapJavaTypeIntoTO(final String basePackageName, final TypeDefinition typedef, + final Type javaType, final String moduleName) { + Preconditions.checkNotNull(javaType, "javaType cannot be null"); + final String propertyName = "value"; + + final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef, moduleName); + genTOBuilder.setRestrictions(BindingGeneratorUtil.getRestrictions(typedef)); + final GeneratedPropertyBuilder genPropBuilder = genTOBuilder.addProperty(propertyName); + genPropBuilder.setReturnType(javaType); + genTOBuilder.addEqualsIdentity(genPropBuilder); + genTOBuilder.addHashIdentity(genPropBuilder); + genTOBuilder.addToStringProperty(genPropBuilder); + if (typedef.getStatus() == Status.DEPRECATED) { + genTOBuilder.addAnnotation("", "Deprecated"); + } + if (javaType instanceof ConcreteType && "String".equals(javaType.getName()) && typedef.getBaseType() != null) { + addStringRegExAsConstant(genTOBuilder, resolveRegExpressionsFromTypedef(typedef)); + } + addUnitsToGenTO(genTOBuilder, typedef.getUnits().orElse(null)); + genTOBuilder.setTypedef(true); + makeSerializable((GeneratedTOBuilderImpl) genTOBuilder); + return genTOBuilder.toInstance(); + } + + /** + * Converts output list of generated TO builders to one TO builder (first + * from list) which contains the remaining builders as its enclosing TO. + * + * @param basePackageName + * string with name of package to which the module belongs + * @param typedef + * type definition which should be of type + * UnionTypeDefinition + * @param typeDefName + * string with name for generated TO + * @return generated TO builder with the list of enclosed generated TO + * builders + */ + public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDef(final String basePackageName, + final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode) { + final List builders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName, + typedef, typeDefName, parentNode); + Preconditions.checkState(!builders.isEmpty(), "No GeneratedTOBuilder objects generated from union %s", typedef); + + final GeneratedTOBuilder resultTOBuilder = builders.remove(0); + builders.forEach(resultTOBuilder::addEnclosingTransferObject); + + resultTOBuilder.addProperty("value").setReturnType(Types.CHAR_ARRAY); + return resultTOBuilder; + } + + /** + * Converts typedef to generated TO with + * typeDefName. Every union type from typedef is + * added to generated TO builder as property. + * + * @param basePackageName + * string with name of package to which the module belongs + * @param typedef + * type definition which should be of type + * UnionTypeDefinition + * @param typeDefName + * string with name for generated TO + * @return generated TO builder which represents typedef + * @throws NullPointerException + *
    + *
  • if basePackageName is null
  • + *
  • if typedef is null
  • + *
  • if Qname of typedef is null
  • + *
+ */ + public List provideGeneratedTOBuildersForUnionTypeDef(final String basePackageName, + final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode) { + Preconditions.checkNotNull(basePackageName, "Base Package Name cannot be NULL!"); + Preconditions.checkNotNull(typedef, "Type Definition cannot be NULL!"); + Preconditions.checkNotNull(typedef.getQName(), "Type definition QName cannot be NULL!"); + + final List generatedTOBuilders = new ArrayList<>(); + final List> unionTypes = typedef.getTypes(); + final Module module = findParentModule(schemaContext, parentNode); + + final GeneratedTOBuilderImpl unionGenTOBuilder; + if (typeDefName != null && !typeDefName.isEmpty()) { + final String typeName = BindingMapping.getClassName(typeDefName); + unionGenTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName); + unionGenTOBuilder.setSchemaPath(typedef.getPath().getPathFromRoot()); + unionGenTOBuilder.setModuleName(module.getName()); + addCodegenInformation(unionGenTOBuilder, typedef); + } else { + unionGenTOBuilder = typedefToTransferObject(basePackageName, typedef, module.getName()); + } + + generatedTOBuilders.add(unionGenTOBuilder); + unionGenTOBuilder.setIsUnion(true); + + // 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 expressions = new HashMap<>(); + for (TypeDefinition unionType : unionTypes) { + final String unionTypeName = unionType.getQName().getLocalName(); + + // If we have a base type we should follow the type definition backwards, except for identityrefs, as those + // do not follow type encapsulation -- we use the general case for that. + if (unionType.getBaseType() != null && !(unionType instanceof IdentityrefTypeDefinition)) { + resolveExtendedSubtypeAsUnion(unionGenTOBuilder, unionType, expressions, parentNode); + } else if (unionType instanceof UnionTypeDefinition) { + generatedTOBuilders.addAll(resolveUnionSubtypeAsUnion(unionGenTOBuilder, + (UnionTypeDefinition) unionType, basePackageName, parentNode)); + } else if (unionType instanceof EnumTypeDefinition) { + final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType, + unionTypeName, unionGenTOBuilder); + updateUnionTypeAsProperty(unionGenTOBuilder, enumeration, unionTypeName); + } else { + final Type javaType = javaTypeForSchemaDefinitionType(unionType, parentNode); + updateUnionTypeAsProperty(unionGenTOBuilder, javaType, unionTypeName); + } + } + addStringRegExAsConstant(unionGenTOBuilder, expressions); + + storeGenTO(typedef, unionGenTOBuilder, parentNode); + + return generatedTOBuilders; + } + + /** + * Wraps code which handle case when union subtype is also of the type + * UnionType. + * + * In this case the new generated TO is created for union subtype (recursive + * call of method + * {@link #provideGeneratedTOBuildersForUnionTypeDef(String, UnionTypeDefinition, + * String, SchemaNode)} + * provideGeneratedTOBuilderForUnionTypeDef} and in parent TO builder + * parentUnionGenTOBuilder is created property which type is + * equal to new generated TO. + * + * @param parentUnionGenTOBuilder + * generated TO builder to which is the property with the child + * union subtype added + * @param basePackageName + * string with the name of the module package + * @param unionSubtype + * type definition which represents union subtype + * @return list of generated TO builders. The number of the builders can be + * bigger one due to recursive call of + * provideGeneratedTOBuildersForUnionTypeDef method. + */ + private List resolveUnionSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder, + final UnionTypeDefinition unionSubtype, final String basePackageName, final SchemaNode parentNode) { + final String newTOBuilderName = provideAvailableNameForGenTOBuilder(parentUnionGenTOBuilder.getName()); + final List subUnionGenTOBUilders = provideGeneratedTOBuildersForUnionTypeDef( + basePackageName, unionSubtype, newTOBuilderName, parentNode); + + final GeneratedPropertyBuilder propertyBuilder; + propertyBuilder = parentUnionGenTOBuilder.addProperty(BindingMapping.getPropertyName(newTOBuilderName)); + propertyBuilder.setReturnType(subUnionGenTOBUilders.get(0)); + parentUnionGenTOBuilder.addEqualsIdentity(propertyBuilder); + parentUnionGenTOBuilder.addToStringProperty(propertyBuilder); + + return subUnionGenTOBUilders; + } + + /** + * Wraps code which handle case when union subtype is of the type + * ExtendedType. + * + * If TO for this type already exists it is used for the creation of the + * property in parentUnionGenTOBuilder. In other case the base + * type is used for the property creation. + * + * @param parentUnionGenTOBuilder + * generated TO builder in which new property is created + * @param unionSubtype + * type definition of the ExtendedType type which + * represents union subtype + * @param expressions + * list of strings with the regular expressions + * @param parentNode + * parent Schema Node for Extended Subtype + * + */ + private void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder, + final TypeDefinition unionSubtype, final Map expressions, final SchemaNode parentNode) { + final String unionTypeName = unionSubtype.getQName().getLocalName(); + final Type genTO = findGenTO(unionTypeName, unionSubtype); + if (genTO != null) { + updateUnionTypeAsProperty(parentUnionGenTOBuilder, genTO, genTO.getName()); + return; + } + + final TypeDefinition baseType = baseTypeDefForExtendedType(unionSubtype); + if (unionTypeName.equals(baseType.getQName().getLocalName())) { + final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(baseType, + parentNode); + if (javaType != null) { + updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, unionTypeName); + } + } else if (baseType instanceof LeafrefTypeDefinition) { + final Type javaType = javaTypeForSchemaDefinitionType(baseType, parentNode); + boolean typeExist = false; + for (GeneratedPropertyBuilder generatedPropertyBuilder : parentUnionGenTOBuilder.getProperties()) { + final Type origType = ((GeneratedPropertyBuilderImpl) generatedPropertyBuilder).getReturnType(); + if (origType != null && javaType != null && javaType == origType) { + typeExist = true; + break; + } + } + if (!typeExist && javaType != null) { + updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, + javaType.getName() + parentUnionGenTOBuilder.getName() + "Value"); + } + } + if (baseType instanceof StringTypeDefinition) { + expressions.putAll(resolveRegExpressionsFromTypedef(unionSubtype)); + } + } + + /** + * Searches for generated TO for searchedTypeDef type + * definition in {@link #genTypeDefsContextMap genTypeDefsContextMap} + * + * @param searchedTypeName + * string with name of searchedTypeDef + * @return generated TO for searchedTypeDef or + * null it it doesn't exist + */ + private Type findGenTO(final String searchedTypeName, final SchemaNode parentNode) { + final Module typeModule = findParentModule(schemaContext, parentNode); + if (typeModule != null && typeModule.getName() != null) { + final Map, Map> modulesByDate = genTypeDefsContextMap.get(typeModule.getName()); + final Map genTOs = modulesByDate.get(typeModule.getRevision()); + if (genTOs != null) { + return genTOs.get(searchedTypeName); + } + } + return null; + } + + /** + * Stores generated TO created from genTOBuilder for + * newTypeDef to {@link #genTypeDefsContextMap + * genTypeDefsContextMap} if the module for newTypeDef exists + * + * @param newTypeDef + * type definition for which is genTOBuilder created + * @param genTOBuilder + * generated TO builder which is converted to generated TO and + * stored + */ + private void storeGenTO(final TypeDefinition newTypeDef, final GeneratedTOBuilder genTOBuilder, final SchemaNode parentNode) { + if (!(newTypeDef instanceof UnionTypeDefinition)) { + final Module parentModule = findParentModule(schemaContext, parentNode); + if (parentModule != null && parentModule.getName() != null) { + final Map, Map> modulesByDate = genTypeDefsContextMap.get(parentModule.getName()); + final Map genTOsMap = modulesByDate.get(parentModule.getRevision()); + genTOsMap.put(newTypeDef.getQName().getLocalName(), genTOBuilder.toInstance()); + } + } + } + + /** + * Adds a new property with the name propertyName and with type + * type to unonGenTransObject. + * + * @param unionGenTransObject + * generated TO to which should be property added + * @param type + * JAVA type of the property which should be added + * to unionGentransObject + * @param propertyName + * string with name of property which should be added to + * unionGentransObject + */ + private static void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type, final String propertyName) { + if (unionGenTransObject != null && type != null && !unionGenTransObject.containsProperty(propertyName)) { + final GeneratedPropertyBuilder propBuilder = unionGenTransObject + .addProperty(BindingMapping.getPropertyName(propertyName)); + propBuilder.setReturnType(type); + + unionGenTransObject.addEqualsIdentity(propBuilder); + unionGenTransObject.addHashIdentity(propBuilder); + unionGenTransObject.addToStringProperty(propBuilder); + } + } + + /** + * Converts typedef to the generated TO builder. + * + * @param basePackageName + * string with name of package to which the module belongs + * @param typedef + * type definition from which is the generated TO builder created + * @return generated TO builder which contains data from + * typedef and basePackageName + */ + private GeneratedTOBuilderImpl typedefToTransferObject(final String basePackageName, + final TypeDefinition typedef, final String moduleName) { + + final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, typedef.getPath()); + final String typeDefTOName = typedef.getQName().getLocalName(); + + if (packageName != null && typeDefTOName != null) { + final String genTOName = BindingMapping.getClassName(typeDefTOName); + final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTOName); + newType.setSchemaPath(typedef.getPath().getPathFromRoot()); + newType.setModuleName(moduleName); + addCodegenInformation(newType, typedef); + return newType; + } + return null; + } + + /** + * Converts typeDef which should be of the type + * BitsTypeDefinition to GeneratedTOBuilder. + * + * All the bits of the typeDef are added to returning generated TO as + * properties. + * + * @param basePackageName + * string with name of package to which the module belongs + * @param typeDef + * type definition from which is the generated TO builder created + * @param typeDefName + * string with the name for generated TO builder + * @return generated TO builder which represents typeDef + * @throws IllegalArgumentException + *
    + *
  • if typeDef equals null
  • + *
  • if basePackageName equals null
  • + *
+ */ + public GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName, + final TypeDefinition typeDef, final String typeDefName, final String moduleName) { + + Preconditions.checkArgument(typeDef != null, "typeDef cannot be NULL!"); + Preconditions.checkArgument(basePackageName != null, "Base Package Name cannot be NULL!"); + + if (typeDef instanceof BitsTypeDefinition) { + final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) typeDef; + + final String typeName = BindingMapping.getClassName(typeDefName); + final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName); + genTOBuilder.setSchemaPath(typeDef.getPath().getPathFromRoot()); + genTOBuilder.setModuleName(moduleName); + genTOBuilder.setBaseType(typeDef); + addCodegenInformation(genTOBuilder, typeDef); + + final List bitList = bitsTypeDefinition.getBits(); + GeneratedPropertyBuilder genPropertyBuilder; + for (Bit bit : bitList) { + final String name = bit.getName(); + genPropertyBuilder = genTOBuilder.addProperty(BindingMapping.getPropertyName(name)); + genPropertyBuilder.setReadOnly(true); + genPropertyBuilder.setReturnType(BaseYangTypes.BOOLEAN_TYPE); + + genTOBuilder.addEqualsIdentity(genPropertyBuilder); + genTOBuilder.addHashIdentity(genPropertyBuilder); + genTOBuilder.addToStringProperty(genPropertyBuilder); + } + + return genTOBuilder; + } + return null; + } + + /** + * Converts the pattern constraints from typedef to the list of + * the strings which represents these constraints. + * + * @param typedef + * extended type in which are the pattern constraints sought + * @return list of strings which represents the constraint patterns + * @throws IllegalArgumentException + * if typedef equals null + * + */ + private static Map resolveRegExpressionsFromTypedef(final TypeDefinition typedef) { + if (!(typedef instanceof StringTypeDefinition)) { + return ImmutableMap.of(); + } + + // TODO: run diff against base ? + final List patternConstraints = ((StringTypeDefinition) typedef).getPatternConstraints(); + final Map regExps = Maps.newHashMapWithExpectedSize(patternConstraints.size()); + for (PatternConstraint patternConstraint : patternConstraints) { + String regEx = patternConstraint.getJavaPatternString(); + + // The pattern can be inverted + final Optional optModifier = patternConstraint.getModifier(); + if (optModifier.isPresent()) { + regEx = applyModifier(optModifier.get(), regEx); + } + + regExps.put(regEx, patternConstraint.getRegularExpressionString()); + } + + return regExps; + } + + private static String applyModifier(final ModifierKind modifier, final String pattern) { + switch (modifier) { + case INVERT_MATCH: + return BindingMapping.negatePatternString(pattern); + default: + LOG.warn("Ignoring unhandled modifier {}", modifier); + return pattern; + } + } + + /** + * + * Adds to the genTOBuilder the constant which contains regular + * expressions from the regularExpressions + * + * @param genTOBuilder + * generated TO builder to which are + * regular expressions added + * @param expressions + * list of string which represent regular expressions + */ + private static void addStringRegExAsConstant(final GeneratedTOBuilder genTOBuilder, + final Map expressions) { + if (!expressions.isEmpty()) { + genTOBuilder.addConstant(Types.listTypeFor(BaseYangTypes.STRING_TYPE), TypeConstants.PATTERN_CONSTANT_NAME, + ImmutableMap.copyOf(expressions)); + } + } + + /** + * Creates generated TO with data about inner extended type + * innerExtendedType, about the package name + * typedefName and about the generated TO name + * typedefName. + * + * It is supposed that innerExtendedType is already present in + * {@link AbstractTypeProvider#genTypeDefsContextMap genTypeDefsContextMap} to + * be possible set it as extended type for the returning generated TO. + * + * @param typedef + * Type Definition + * @param innerExtendedType + * extended type which is part of some other extended type + * @param basePackageName + * string with the package name of the module + * @param moduleName + * Module Name + * @return generated TO which extends generated TO for + * innerExtendedType + * @throws IllegalArgumentException + *
    + *
  • if extendedType equals null
  • + *
  • if basePackageName equals null
  • + *
  • if typedefName equals null
  • + *
+ */ + private GeneratedTransferObject provideGeneratedTOFromExtendedType(final TypeDefinition typedef, final TypeDefinition innerExtendedType, final String basePackageName, final String moduleName) { + Preconditions.checkArgument(innerExtendedType != null, "Extended type cannot be NULL!"); + Preconditions.checkArgument(basePackageName != null, "String with base package name cannot be NULL!"); + + final String typedefName = typedef.getQName().getLocalName(); + final String classTypedefName = BindingMapping.getClassName(typedefName); + final String innerTypeDef = innerExtendedType.getQName().getLocalName(); + final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, classTypedefName); + genTOBuilder.setSchemaPath(typedef.getPath().getPathFromRoot()); + genTOBuilder.setModuleName(moduleName); + genTOBuilder.setTypedef(true); + addCodegenInformation(genTOBuilder, typedef); + + final Restrictions r = BindingGeneratorUtil.getRestrictions(typedef); + genTOBuilder.setRestrictions(r); + if (typedef.getStatus() == Status.DEPRECATED) { + genTOBuilder.addAnnotation("", "Deprecated"); + } + + if (baseTypeDefForExtendedType(innerExtendedType) instanceof UnionTypeDefinition) { + genTOBuilder.setIsUnion(true); + } + + Map, Map> modulesByDate = null; + Map typeMap = null; + final Module parentModule = findParentModule(schemaContext, innerExtendedType); + if (parentModule != null) { + modulesByDate = genTypeDefsContextMap.get(parentModule.getName()); + typeMap = modulesByDate.get(parentModule.getRevision()); + } + + if (typeMap != null) { + final Type type = typeMap.get(innerTypeDef); + if (type instanceof GeneratedTransferObject) { + genTOBuilder.setExtendsType((GeneratedTransferObject) type); + } + } + addUnitsToGenTO(genTOBuilder, typedef.getUnits().orElse(null)); + makeSerializable(genTOBuilder); + + return genTOBuilder.toInstance(); + } + + /** + * Add {@link Serializable} to implemented interfaces of this TO. Also + * compute and add serialVersionUID property. + * + * @param gto + * transfer object which needs to be serializable + */ + private static void makeSerializable(final GeneratedTOBuilderImpl gto) { + gto.addImplementsType(Types.typeForClass(Serializable.class)); + final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID"); + prop.setValue(Long.toString(BindingGeneratorUtil.computeDefaultSUID(gto))); + gto.setSUID(prop); + } + + /** + * Finds out for each type definition how many immersion (depth) is + * necessary to get to the base type. Every type definition is inserted to + * the map which key is depth and value is list of type definitions with + * equal depth. In next step are lists from this map concatenated to one + * list in ascending order according to their depth. All type definitions + * are in the list behind all type definitions on which depends. + * + * @param unsortedTypeDefinitions + * list of type definitions which should be sorted by depth + * @return list of type definitions sorted according their each other + * dependencies (type definitions which are depend on other type + * definitions are in list behind them). + */ + private static List> sortTypeDefinitionAccordingDepth( + final Collection> unsortedTypeDefinitions) { + final List> sortedTypeDefinition = new ArrayList<>(); + + final Map>> typeDefinitionsDepths = new TreeMap<>(); + for (TypeDefinition unsortedTypeDefinition : unsortedTypeDefinitions) { + final Integer depth = getTypeDefinitionDepth(unsortedTypeDefinition); + List> typeDefinitionsConcreteDepth = typeDefinitionsDepths.get(depth); + if (typeDefinitionsConcreteDepth == null) { + typeDefinitionsConcreteDepth = new ArrayList<>(); + typeDefinitionsDepths.put(depth, typeDefinitionsConcreteDepth); + } + typeDefinitionsConcreteDepth.add(unsortedTypeDefinition); + } + + // SortedMap guarantees order corresponding to keys in ascending order + for (List> v : typeDefinitionsDepths.values()) { + sortedTypeDefinition.addAll(v); + } + + return sortedTypeDefinition; + } + + /** + * Returns how many immersion is necessary to get from the type definition + * to the base type. + * + * @param typeDefinition + * type definition for which is depth sought. + * @return number of immersions which are necessary to get from the type + * definition to the base type + */ + private static int getTypeDefinitionDepth(final TypeDefinition typeDefinition) { + // FIXME: rewrite this in a non-recursive manner + if (typeDefinition == null) { + return 1; + } + final TypeDefinition baseType = typeDefinition.getBaseType(); + if (baseType == null) { + return 1; + } + + int depth = 1; + if (baseType.getBaseType() != null) { + depth = depth + getTypeDefinitionDepth(baseType); + } else if (baseType instanceof UnionTypeDefinition) { + final List> childTypeDefinitions = ((UnionTypeDefinition) baseType).getTypes(); + int maxChildDepth = 0; + int childDepth = 1; + for (TypeDefinition childTypeDefinition : childTypeDefinitions) { + childDepth = childDepth + getTypeDefinitionDepth(childTypeDefinition); + if (childDepth > maxChildDepth) { + maxChildDepth = childDepth; + } + } + return maxChildDepth; + } + return depth; + } + + /** + * Returns string which contains the same value as name but + * integer suffix is incremented by one. If name contains no + * number suffix then number 1 is added. + * + * @param name + * string with name of augmented node + * @return string with the number suffix incremented by one (or 1 is added) + */ + private static String provideAvailableNameForGenTOBuilder(final String name) { + final Matcher mtch = NUMBERS_PATTERN.matcher(name); + if (mtch.find()) { + final int newSuffix = Integer.parseInt(name.substring(mtch.start())) + 1; + return name.substring(0, mtch.start()) + newSuffix; + } + + return name + 1; + } + + public static void addUnitsToGenTO(final GeneratedTOBuilder to, final String units) { + if (!Strings.isNullOrEmpty(units)) { + to.addConstant(Types.STRING, "_UNITS", "\"" + units + "\""); + final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("UNITS"); + prop.setReturnType(Types.STRING); + to.addToStringProperty(prop); + } + } + + @Override + public String getTypeDefaultConstruction(final LeafSchemaNode node) { + return getTypeDefaultConstruction(node, (String) node.getType().getDefaultValue().orElse(null)); + } + + public String getTypeDefaultConstruction(final LeafSchemaNode node, final String defaultValue) { + final TypeDefinition type = CompatUtils.compatLeafType(node); + final QName typeQName = type.getQName(); + final TypeDefinition base = baseTypeDefForExtendedType(type); + Preconditions.checkNotNull(type, "Cannot provide default construction for null type of %s", node); + Preconditions.checkNotNull(defaultValue, "Cannot provide default construction for null default statement of %s", + node); + + final StringBuilder sb = new StringBuilder(); + String result = null; + if (base instanceof BinaryTypeDefinition) { + result = binaryToDef(defaultValue); + } else if (base instanceof BitsTypeDefinition) { + String parentName; + String className; + final Module parent = getParentModule(node); + final Iterator path = node.getPath().getPathFromRoot().iterator(); + path.next(); + if (!path.hasNext()) { + parentName = BindingMapping.getClassName(parent.getName()) + "Data"; + final String basePackageName = BindingMapping.getRootPackageName(parent.getQNameModule()); + className = basePackageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName()); + } else { + final String basePackageName = BindingMapping.getRootPackageName(parent.getQNameModule()); + final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, type.getPath()); + parentName = BindingMapping.getClassName(parent.getName()); + className = packageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName()); + } + result = bitsToDef((BitsTypeDefinition) base, className, defaultValue, type.getBaseType() != null); + } else if (base instanceof BooleanTypeDefinition) { + result = typeToBooleanDef(defaultValue); + } else if (base instanceof DecimalTypeDefinition) { + result = typeToDef(BigDecimal.class, defaultValue); + } else if (base instanceof EmptyTypeDefinition) { + result = typeToBooleanDef(defaultValue); + } else if (base instanceof EnumTypeDefinition) { + final char[] defValArray = defaultValue.toCharArray(); + final char first = Character.toUpperCase(defaultValue.charAt(0)); + defValArray[0] = first; + final String newDefVal = new String(defValArray); + String className; + if (type.getBaseType() != null) { + final Module m = getParentModule(type); + final String basePackageName = BindingMapping.getRootPackageName(m.getQNameModule()); + final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, type.getPath()); + className = packageName + "." + BindingMapping.getClassName(typeQName); + } else { + final Module parentModule = getParentModule(node); + final String basePackageName = BindingMapping.getRootPackageName(parentModule.getQNameModule()); + final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, node.getPath()); + className = packageName + "." + BindingMapping.getClassName(node.getQName()); + } + result = className + "." + newDefVal; + } else if (base instanceof IdentityrefTypeDefinition) { + throw new UnsupportedOperationException("Cannot get default construction for identityref type"); + } else if (base instanceof InstanceIdentifierTypeDefinition) { + throw new UnsupportedOperationException("Cannot get default construction for instance-identifier type"); + } else if (BaseTypes.isInt8(base)) { + result = typeToValueOfDef(Byte.class, defaultValue); + } else if (BaseTypes.isInt16(base)) { + result = typeToValueOfDef(Short.class, defaultValue); + } else if (BaseTypes.isInt32(base)) { + result = typeToValueOfDef(Integer.class, defaultValue); + } else if (BaseTypes.isInt64(base)) { + result = typeToValueOfDef(Long.class, defaultValue); + } else if (base instanceof LeafrefTypeDefinition) { + result = leafrefToDef(node, (LeafrefTypeDefinition) base, defaultValue); + } else if (base instanceof StringTypeDefinition) { + result = "\"" + defaultValue + "\""; + } else if (BaseTypes.isUint8(base)) { + result = typeToValueOfDef(Short.class, defaultValue); + } else if (BaseTypes.isUint16(base)) { + result = typeToValueOfDef(Integer.class, defaultValue); + } else if (BaseTypes.isUint32(base)) { + result = typeToValueOfDef(Long.class, defaultValue); + } else if (BaseTypes.isUint64(base)) { + switch (defaultValue) { + case "0": + result = "java.math.BigInteger.ZERO"; + break; + case "1": + result = "java.math.BigInteger.ONE"; + break; + case "10": + result = "java.math.BigInteger.TEN"; + break; + default: + result = typeToDef(BigInteger.class, defaultValue); + } + } else if (base instanceof UnionTypeDefinition) { + result = unionToDef(node); + } else { + result = ""; + } + sb.append(result); + + if (type.getBaseType() != null && !(base instanceof LeafrefTypeDefinition) + && !(base instanceof EnumTypeDefinition) && !(base instanceof UnionTypeDefinition)) { + final Module m = getParentModule(type); + final String basePackageName = BindingMapping.getRootPackageName(m.getQNameModule()); + final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, type.getPath()); + final String className = packageName + "." + BindingMapping.getClassName(typeQName); + sb.insert(0, "new " + className + "("); + sb.insert(sb.length(), ')'); + } + + return sb.toString(); + } + + private static String typeToDef(final Class clazz, final String defaultValue) { + return "new " + clazz.getName() + "(\"" + defaultValue + "\")"; + } + + private static String typeToValueOfDef(final Class clazz, final String defaultValue) { + return clazz.getName() + ".valueOf(\"" + defaultValue + "\")"; + } + + private static String typeToBooleanDef(final String defaultValue) { + switch (defaultValue) { + case "false": + return "java.lang.Boolean.FALSE"; + case "true": + return "java.lang.Boolean.TRUE"; + default: + return typeToValueOfDef(Boolean.class, defaultValue); + } + } + + private static String binaryToDef(final String defaultValue) { + final StringBuilder sb = new StringBuilder(); + final BaseEncoding en = BaseEncoding.base64(); + final byte[] encoded = en.decode(defaultValue); + sb.append("new byte[] {"); + for (int i = 0; i < encoded.length; i++) { + sb.append(encoded[i]); + if (i != encoded.length - 1) { + sb.append(", "); + } + } + sb.append('}'); + return sb.toString(); + } + + private static final Comparator BIT_NAME_COMPARATOR = (o1, o2) -> o1.getName().compareTo(o2.getName()); + + private static String bitsToDef(final BitsTypeDefinition type, final String className, final String defaultValue, final boolean isExt) { + final List bits = new ArrayList<>(type.getBits()); + Collections.sort(bits, BIT_NAME_COMPARATOR); + final StringBuilder sb = new StringBuilder(); + if (!isExt) { + sb.append("new "); + sb.append(className); + sb.append('('); + } + for (int i = 0; i < bits.size(); i++) { + if (bits.get(i).getName().equals(defaultValue)) { + sb.append(true); + } else { + sb.append(false); + } + if (i != bits.size() - 1) { + sb.append(", "); + } + } + if (!isExt) { + sb.append(')'); + } + return sb.toString(); + } + + private Module getParentModule(final SchemaNode node) { + final QName qname = node.getPath().getPathFromRoot().iterator().next(); + return schemaContext.findModule(qname.getModule()).orElse(null); + } + + private String leafrefToDef(final LeafSchemaNode parentNode, final LeafrefTypeDefinition leafrefType, final String defaultValue) { + Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!"); + Preconditions.checkArgument(leafrefType.getPathStatement() != null, + "The Path Statement for Leafref Type Definition cannot be NULL!"); + + final RevisionAwareXPath xpath = leafrefType.getPathStatement(); + final String strXPath = xpath.toString(); + + if (strXPath != null) { + if (strXPath.indexOf('[') == -1) { + final Module module = findParentModule(schemaContext, parentNode); + if (module != null) { + final SchemaNode dataNode; + if (xpath.isAbsolute()) { + dataNode = findDataSchemaNode(schemaContext, module, xpath); + } else { + dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath); + } + final String result = getTypeDefaultConstruction((LeafSchemaNode) dataNode, defaultValue); + return result; + } + } else { + return "new java.lang.Object()"; + } + } + + return null; + } + + private String unionToDef(final LeafSchemaNode node) { + final TypeDefinition type = CompatUtils.compatLeafType(node); + String parentName; + String className; + + if (type.getBaseType() != null) { + final QName typeQName = type.getQName(); + Module module = null; + final Set modules = schemaContext.findModules(typeQName.getNamespace()); + if (modules.size() > 1) { + for (Module m : modules) { + if (m.getRevision().equals(typeQName.getRevision())) { + module = m; + break; + } + } + if (module == null) { + final List modulesList = new ArrayList<>(modules); + Collections.sort(modulesList, (o1, o2) -> Revision.compare(o1.getRevision(), o2.getRevision())); + module = modulesList.get(0); + } + } else { + module = modules.iterator().next(); + } + + final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); + className = basePackageName + "." + BindingMapping.getClassName(typeQName); + } else { + final Iterator path = node.getPath().getPathFromRoot().iterator(); + final QName first = path.next(); + final Module parent = schemaContext.findModule(first.getModule()).orElse(null); + final String basePackageName = BindingMapping.getRootPackageName(parent.getQNameModule()); + if (!path.hasNext()) { + parentName = BindingMapping.getClassName(parent.getName()) + "Data"; + className = basePackageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName()); + } else { + final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, UNION_PATH); + className = packageName + "." + BindingMapping.getClassName(node.getQName()); + } + } + return union(className, (String) node.getType().getDefaultValue().orElse(null), node); + } + + private static String union(final String className, final String defaultValue, final LeafSchemaNode node) { + final StringBuilder sb = new StringBuilder(); + sb.append("new "); + sb.append(className); + sb.append("(\""); + sb.append(defaultValue); + sb.append("\".toCharArray())"); + return sb.toString(); + } + + @Override + public String getConstructorPropertyName(final SchemaNode node) { + return node instanceof TypeDefinition ? "value" : ""; + } + + @Override + public String getParamNameFromType(final TypeDefinition type) { + return BindingMapping.getPropertyName(type.getQName().getLocalName()); + } + +} diff --git a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/CodegenTypeProvider.java b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/CodegenTypeProvider.java new file mode 100644 index 0000000000..2fbb19c843 --- /dev/null +++ b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/CodegenTypeProvider.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.mdsal.binding.yang.types; + +import static org.opendaylight.mdsal.binding.model.util.BindingGeneratorUtil.encodeAngleBrackets; + +import com.google.common.annotations.Beta; +import java.util.Optional; +import org.opendaylight.mdsal.binding.model.api.type.builder.EnumBuilder; +import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilderBase; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; + +/** + * {@link AbstractTypeProvider} which generates full metadata, suitable for codegen purposes. For runtime purposes, + * considering using {@link RuntimeTypeProvider}. + */ +@Beta +// FIXME: make this class final after TypeProviderImpl is gone +public class CodegenTypeProvider extends AbstractTypeProvider { + /** + * Creates new instance of class TypeProviderImpl. + * + * @param schemaContext contains the schema data read from YANG files + * @throws IllegalArgumentException if schemaContext is null. + */ + public CodegenTypeProvider(final SchemaContext schemaContext) { + super(schemaContext); + } + + @Override + public void addEnumDescription(final EnumBuilder enumBuilder, final EnumTypeDefinition enumTypeDef) { + final Optional optDesc = enumTypeDef.getDescription(); + if (optDesc.isPresent()) { + enumBuilder.setDescription(encodeAngleBrackets(optDesc.get())); + } + } + + @Override + void addCodegenInformation(final GeneratedTypeBuilderBase genTOBuilder, final TypeDefinition typeDef) { + final Optional optDesc = typeDef.getDescription(); + if (optDesc.isPresent()) { + genTOBuilder.setDescription(encodeAngleBrackets(optDesc.get())); + } + typeDef.getReference().ifPresent(genTOBuilder::setReference); + } +} diff --git a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/RuntimeTypeProvider.java b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/RuntimeTypeProvider.java new file mode 100644 index 0000000000..be12dd1a15 --- /dev/null +++ b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/RuntimeTypeProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.mdsal.binding.yang.types; + +import com.google.common.annotations.Beta; +import org.opendaylight.mdsal.binding.model.api.type.builder.EnumBuilder; +import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilderBase; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; + +/** + * {@link AbstractTypeProvider} which generates enough type information for runtime support. For a codegen-compatible + * provider use {@link CodegenTypeProvider}. + */ +@Beta +public final class RuntimeTypeProvider extends AbstractTypeProvider { + public RuntimeTypeProvider(final SchemaContext schemaContext) { + super(schemaContext); + } + + @Override + public void addEnumDescription(final EnumBuilder enumBuilder, final EnumTypeDefinition enumTypeDef) { + // No-op + } + + @Override + void addCodegenInformation(final GeneratedTypeBuilderBase genTOBuilder, final TypeDefinition typeDef) { + // No-op + } +} diff --git a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/TypeProviderImpl.java b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/TypeProviderImpl.java index cd5ce24a89..aa14e0f98a 100644 --- a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/TypeProviderImpl.java +++ b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/TypeProviderImpl.java @@ -7,1758 +7,23 @@ */ package org.opendaylight.mdsal.binding.yang.types; -import static org.opendaylight.mdsal.binding.model.util.BindingGeneratorUtil.encodeAngleBrackets; -import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode; -import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNodeForRelativeXPath; -import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule; - -import com.google.common.base.Preconditions; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.common.io.BaseEncoding; -import java.io.Serializable; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.TreeMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.opendaylight.mdsal.binding.generator.spi.TypeProvider; -import org.opendaylight.mdsal.binding.model.api.AccessModifier; -import org.opendaylight.mdsal.binding.model.api.ConcreteType; -import org.opendaylight.mdsal.binding.model.api.Enumeration; -import org.opendaylight.mdsal.binding.model.api.GeneratedProperty; -import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject; -import org.opendaylight.mdsal.binding.model.api.Restrictions; -import org.opendaylight.mdsal.binding.model.api.Type; -import org.opendaylight.mdsal.binding.model.api.type.builder.EnumBuilder; -import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedPropertyBuilder; -import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTOBuilder; -import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilderBase; -import org.opendaylight.mdsal.binding.model.api.type.builder.MethodSignatureBuilder; -import org.opendaylight.mdsal.binding.model.util.BindingGeneratorUtil; -import org.opendaylight.mdsal.binding.model.util.TypeConstants; -import org.opendaylight.mdsal.binding.model.util.Types; -import org.opendaylight.mdsal.binding.model.util.generated.type.builder.EnumerationBuilderImpl; -import org.opendaylight.mdsal.binding.model.util.generated.type.builder.GeneratedPropertyBuilderImpl; -import org.opendaylight.mdsal.binding.model.util.generated.type.builder.GeneratedTOBuilderImpl; -import org.opendaylight.yangtools.yang.binding.BindingMapping; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.Revision; -import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; -import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; -import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; -import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; -import org.opendaylight.yangtools.yang.model.api.Module; -import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.api.SchemaNode; -import org.opendaylight.yangtools.yang.model.api.SchemaPath; -import org.opendaylight.yangtools.yang.model.api.Status; -import org.opendaylight.yangtools.yang.model.api.TypeDefinition; -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.BitsTypeDefinition.Bit; -import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition; -import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition; -import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition; -import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition; -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.ModifierKind; -import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; -import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition; -import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; -import org.opendaylight.yangtools.yang.model.util.ModuleDependencySort; -import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl; -import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; -import org.opendaylight.yangtools.yang.model.util.type.BaseTypes; -import org.opendaylight.yangtools.yang.model.util.type.CompatUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class TypeProviderImpl implements TypeProvider { - private static final Logger LOG = LoggerFactory.getLogger(TypeProviderImpl.class); - private static final Pattern GROUPS_PATTERN = Pattern.compile("\\[(.*?)\\]"); - private static final Pattern NUMBERS_PATTERN = Pattern.compile("[0-9]+\\z"); - - // Backwards compatibility: Union types used to be instantiated in YANG namespace, which is no longer - // the case, as unions are emitted to their correct schema path. - private static final SchemaPath UNION_PATH = SchemaPath.create(true, - org.opendaylight.yangtools.yang.model.util.BaseTypes.UNION_QNAME); - - /** - * Contains the schema data red from YANG files. - */ - private final SchemaContext schemaContext; - - /** - * Map>> - */ - private final Map, Map>> genTypeDefsContextMap = new HashMap<>(); - - /** - * The map which maps schema paths to JAVA Type. - */ - private final Map referencedTypes = new HashMap<>(); - private final Map> additionalTypes = new HashMap<>(); +/** + * {@link AbstractTypeProvider} which generates full metadata, suitable for codegen purposes. For runtime purposes, + * considering using {@link RuntimeTypeProvider}. + * + * @deprecated Use {@link CodegenTypeProvider} instead. + */ +@Deprecated +public final class TypeProviderImpl extends CodegenTypeProvider { /** * Creates new instance of class TypeProviderImpl. * - * @param schemaContext - * contains the schema data red from YANG files - * @throws IllegalArgumentException - * if schemaContext equal null. + * @param schemaContext contains the schema data read from YANG files + * @throws IllegalArgumentException if schemaContext is null. */ public TypeProviderImpl(final SchemaContext schemaContext) { - Preconditions.checkArgument(schemaContext != null, "Schema Context cannot be null!"); - - this.schemaContext = schemaContext; - resolveTypeDefsFromContext(); - } - - /** - * Puts refType to map with key refTypePath - * - * @param refTypePath - * schema path used as the map key - * @param refType - * type which represents the map value - * @throws IllegalArgumentException - *
    - *
  • if refTypePath equal null
  • - *
  • if refType equal null
  • - *
- * - */ - public void putReferencedType(final SchemaPath refTypePath, final Type refType) { - Preconditions.checkArgument(refTypePath != null, - "Path reference of Enumeration Type Definition cannot be NULL!"); - Preconditions.checkArgument(refType != null, "Reference to Enumeration Type cannot be NULL!"); - referencedTypes.put(refTypePath, refType); - } - - public Map> getAdditionalTypes() { - return additionalTypes; - } - - /** - * - * Converts basic YANG type type to JAVA Type. - * - * @param type - * string with YANG name of type - * @return JAVA Type for YANG type type - * @see TypeProvider#javaTypeForYangType(String) - */ - @Override - @Deprecated - public Type javaTypeForYangType(final String type) { - return BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(type); - } - - @Override - public Type javaTypeForSchemaDefinitionType(final TypeDefinition typeDefinition, final SchemaNode parentNode) { - return javaTypeForSchemaDefinitionType(typeDefinition, parentNode, null); - } - - /** - * Converts schema definition type typeDefinition to JAVA - * Type - * - * @param typeDefinition - * type definition which is converted to JAVA type - * @throws IllegalArgumentException - *
    - *
  • if typeDefinition equal null
  • - *
  • if Qname of typeDefinition equal null
  • - *
  • if name of typeDefinition equal null
  • - *
- */ - @Override - public Type javaTypeForSchemaDefinitionType(final TypeDefinition typeDefinition, final SchemaNode parentNode, - final Restrictions r) { - Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!"); - Preconditions.checkArgument(typeDefinition.getQName() != null, - "Type Definition cannot have non specified QName (QName cannot be NULL!)"); - final String typedefName = typeDefinition.getQName().getLocalName(); - Preconditions.checkArgument(typedefName != null, "Type Definitions Local Name cannot be NULL!"); - - // Deal with base types - if (typeDefinition.getBaseType() == null) { - // We have to deal with differing handling of decimal64. The old parser used a fixed Decimal64 type - // and generated an enclosing ExtendedType to hold any range constraints. The new parser instantiates - // a base type which holds these constraints. - if (typeDefinition instanceof DecimalTypeDefinition) { - final Type ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition, - parentNode, r); - if (ret != null) { - return ret; - } - } - - // Deal with leafrefs/identityrefs - Type ret = javaTypeForLeafrefOrIdentityRef(typeDefinition, parentNode); - if (ret != null) { - return ret; - } - - // FIXME: it looks as though we could be using the same codepath as above... - ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(typeDefinition.getQName().getLocalName()); - if (ret == null) { - LOG.debug("Failed to resolve Java type for {}", typeDefinition); - } - - return ret; - } - - Type returnType = javaTypeForExtendedType(typeDefinition); - if (r != null && returnType instanceof GeneratedTransferObject) { - final GeneratedTransferObject gto = (GeneratedTransferObject) returnType; - final Module module = findParentModule(schemaContext, parentNode); - final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); - final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, - typeDefinition.getPath()); - final String genTOName = BindingMapping.getClassName(typedefName); - final String name = packageName + "." + genTOName; - if (!returnType.getFullyQualifiedName().equals(name)) { - returnType = shadedTOWithRestrictions(gto, r); - } - } - return returnType; - } - - private static GeneratedTransferObject shadedTOWithRestrictions(final GeneratedTransferObject gto, - final Restrictions r) { - final GeneratedTOBuilder gtob = new GeneratedTOBuilderImpl(gto.getPackageName(), gto.getName()); - final GeneratedTransferObject parent = gto.getSuperType(); - if (parent != null) { - gtob.setExtendsType(parent); - } - gtob.setRestrictions(r); - for (GeneratedProperty gp : gto.getProperties()) { - final GeneratedPropertyBuilder gpb = gtob.addProperty(gp.getName()); - gpb.setValue(gp.getValue()); - gpb.setReadOnly(gp.isReadOnly()); - gpb.setAccessModifier(gp.getAccessModifier()); - gpb.setReturnType(gp.getReturnType()); - gpb.setFinal(gp.isFinal()); - gpb.setStatic(gp.isStatic()); - } - return gtob.toInstance(); - } - - private boolean isLeafRefSelfReference(final LeafrefTypeDefinition leafref, final SchemaNode parentNode) { - final SchemaNode leafRefValueNode; - final RevisionAwareXPath leafRefXPath = leafref.getPathStatement(); - final RevisionAwareXPath leafRefStrippedXPath = new RevisionAwareXPathImpl( - GROUPS_PATTERN.matcher(leafRefXPath.toString()).replaceAll(""), leafRefXPath.isAbsolute()); - - ///// skip leafrefs in augments - they're checked once augments are resolved - final Iterator iterator = parentNode.getPath().getPathFromRoot().iterator(); - boolean isAugmenting = false; - DataNodeContainer current = null; - DataSchemaNode dataChildByName; - - while (iterator.hasNext() && !isAugmenting) { - final QName next = iterator.next(); - if (current == null) { - dataChildByName = schemaContext.getDataChildByName(next); - } else { - dataChildByName = current.getDataChildByName(next); - } - if (dataChildByName != null) { - isAugmenting = dataChildByName.isAugmenting(); - } else { - return false; - } - if (dataChildByName instanceof DataNodeContainer) { - current = (DataNodeContainer) dataChildByName; - } - } - if (isAugmenting) { - return false; - } - ///// - - final Module parentModule = getParentModule(parentNode); - if (!leafRefStrippedXPath.isAbsolute()) { - leafRefValueNode = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemaContext, parentModule, - parentNode, leafRefStrippedXPath); - } else { - leafRefValueNode = SchemaContextUtil.findDataSchemaNode(schemaContext, parentModule, leafRefStrippedXPath); - } - return leafRefValueNode != null ? leafRefValueNode.equals(parentNode) : false; - } - - /** - * Returns JAVA Type for instances of the type - * LeafrefTypeDefinition or - * IdentityrefTypeDefinition. - * - * @param typeDefinition - * type definition which is converted to JAVA Type - * @return JAVA Type instance for typeDefinition - */ - private Type javaTypeForLeafrefOrIdentityRef(final TypeDefinition typeDefinition, final SchemaNode parentNode) { - if (typeDefinition instanceof LeafrefTypeDefinition) { - final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition; - Preconditions.checkArgument(!isLeafRefSelfReference(leafref, parentNode), - "Leafref %s is referencing itself, incoming StackOverFlowError detected.", leafref); - return provideTypeForLeafref(leafref, parentNode); - } else if (typeDefinition instanceof IdentityrefTypeDefinition) { - return provideTypeForIdentityref((IdentityrefTypeDefinition) typeDefinition); - } - - return null; - } - - /** - * Returns JAVA Type for instances of the type - * ExtendedType. - * - * @param typeDefinition - * type definition which is converted to JAVA Type - * @return JAVA Type instance for typeDefinition - */ - private Type javaTypeForExtendedType(final TypeDefinition typeDefinition) { - final String typedefName = typeDefinition.getQName().getLocalName(); - final TypeDefinition baseTypeDef = baseTypeDefForExtendedType(typeDefinition); - Type returnType = javaTypeForLeafrefOrIdentityRef(baseTypeDef, typeDefinition); - if (returnType == null) { - if (baseTypeDef instanceof EnumTypeDefinition) { - final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDef; - returnType = provideTypeForEnum(enumTypeDef, typedefName, typeDefinition); - } else { - final Module module = findParentModule(schemaContext, typeDefinition); - final Restrictions r = BindingGeneratorUtil.getRestrictions(typeDefinition); - if (module != null) { - final Map, Map> modulesByDate = genTypeDefsContextMap.get( - module.getName()); - final Map genTOs = modulesByDate.get(module.getRevision()); - if (genTOs != null) { - returnType = genTOs.get(typedefName); - } - if (returnType == null) { - returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType( - baseTypeDef, typeDefinition, r); - } - } - } - } - return returnType; - } - - /** - * Seeks for identity reference idref the JAVA - * type.
- *
- * - * Example:
- * If identy which is referenced via idref has name Idn - * then returning type is {@code Class}
- * - * @param idref - * identityref type definition for which JAVA Type - * is sought - * @return JAVA Type of the identity which is referenced through - * idref - */ - private Type provideTypeForIdentityref(final IdentityrefTypeDefinition idref) { - final Collection identities = idref.getIdentities(); - if (identities.size() > 1) { - LOG.warn("Identity reference {} has multiple identities, using only the first one", idref); - } - - final QName baseIdQName = identities.iterator().next().getQName(); - final Module module = schemaContext.findModule(baseIdQName.getModule()).orElse(null); - IdentitySchemaNode identity = null; - for (IdentitySchemaNode id : module.getIdentities()) { - if (id.getQName().equals(baseIdQName)) { - identity = id; - } - } - Preconditions.checkArgument(identity != null, "Target identity '" + baseIdQName + "' do not exists"); - - final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); - final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, - identity.getPath()); - final String genTypeName = BindingMapping.getClassName(identity.getQName()); - - final Type baseType = Types.typeForClass(Class.class); - final Type paramType = Types.wildcardTypeFor(packageName, genTypeName); - return Types.parameterizedTypeFor(baseType, paramType); - } - - /** - * Converts typeDefinition to concrete JAVA Type. - * - * @param typeDefinition - * type definition which should be converted to JAVA - * Type - * @return JAVA Type which represents - * typeDefinition - * @throws IllegalArgumentException - *
    - *
  • if typeDefinition equal null
  • - *
  • if Q name of typeDefinition
  • - *
  • if name of typeDefinition
  • - *
- */ - public Type generatedTypeForExtendedDefinitionType(final TypeDefinition typeDefinition, final SchemaNode parentNode) { - Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!"); - if (typeDefinition.getQName() == null) { - throw new IllegalArgumentException( - "Type Definition cannot have non specified QName (QName cannot be NULL!)"); - } - Preconditions.checkArgument(typeDefinition.getQName().getLocalName() != null, - "Type Definitions Local Name cannot be NULL!"); - - final TypeDefinition baseTypeDef = baseTypeDefForExtendedType(typeDefinition); - if (baseTypeDef instanceof LeafrefTypeDefinition || baseTypeDef instanceof IdentityrefTypeDefinition) { - /* - * This is backwards compatibility baggage from way back when. The problem at hand is inconsistency between - * the fact that identity is mapped to a Class, which is also returned from leaves which specify it like - * this: - * - * identity iden; - * - * container foo { - * leaf foo { - * type identityref { - * base iden; - * } - * } - * } - * - * This results in getFoo() returning Class, which looks fine on the surface, but gets more - * dicey when we throw in: - * - * typedef bar-ref { - * type identityref { - * base iden; - * } - * } - * - * container bar { - * leaf bar { - * type bar-ref; - * } - * } - * - * Now we have competing requirements: typedef would like us to use encapsulation to capture the defined - * type, while getBar() wants us to retain shape with getFoo(), as it should not matter how the identityref - * is formed. - * - * In this particular case getFoo() won just after the Binding Spec was frozen, hence we do not generate - * an encapsulation for identityref typedefs. - * - * In case you are thinking we could get by having foo-ref map to a subclass of Iden, that is not a good - * option, as it would look as though it is the product of a different construct: - * - * identity bar-ref { - * base iden; - * } - * - * Leading to a rather nice namespace clash and also slight incompatibility with unknown third-party - * sub-identities of iden. - * - * The story behind leafrefs is probably similar, but that needs to be ascertained. - */ - return null; - } - - final Module module = findParentModule(schemaContext, parentNode); - if (module != null) { - final Map, Map> modulesByDate = genTypeDefsContextMap.get( - module.getName()); - final Map genTOs = modulesByDate.get(module.getRevision()); - if (genTOs != null) { - return genTOs.get(typeDefinition.getQName().getLocalName()); - } - } - return null; - } - - /** - * Gets base type definition for extendTypeDef. The method is - * recursively called until non ExtendedType type is found. - * - * @param extendTypeDef - * type definition for which is the base type definition sought - * @return type definition which is base type for extendTypeDef - * @throws IllegalArgumentException - * if extendTypeDef equal null - */ - private static TypeDefinition baseTypeDefForExtendedType(final TypeDefinition extendTypeDef) { - Preconditions.checkArgument(extendTypeDef != null, "Type Definition reference cannot be NULL!"); - - TypeDefinition ret = extendTypeDef; - while (ret.getBaseType() != null) { - ret = ret.getBaseType(); - } - - return ret; - } - - /** - * Converts leafrefType to JAVA Type. - * - * The path of leafrefType is followed to find referenced node - * and its Type is returned. - * - * @param leafrefType - * leafref type definition for which is the type sought - * @return JAVA Type of data schema node which is referenced in - * leafrefType - * @throws IllegalArgumentException - *
    - *
  • if leafrefType equal null
  • - *
  • if path statement of leafrefType equal null
  • - *
- * - */ - public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType, final SchemaNode parentNode) { - Type returnType = null; - Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!"); - - Preconditions.checkArgument(leafrefType.getPathStatement() != null, - "The Path Statement for Leafref Type Definition cannot be NULL!"); - - final RevisionAwareXPath xpath = leafrefType.getPathStatement(); - final String strXPath = xpath.toString(); - - if (strXPath != null) { - if (strXPath.indexOf('[') == -1) { - final Module module = findParentModule(schemaContext, parentNode); - Preconditions.checkArgument(module != null, "Failed to find module for parent %s", parentNode); - - final SchemaNode dataNode; - if (xpath.isAbsolute()) { - dataNode = findDataSchemaNode(schemaContext, module, xpath); - } else { - dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath); - } - Preconditions.checkArgument(dataNode != null, "Failed to find leafref target: %s in module %s (%s)", - strXPath, this.getParentModule(parentNode).getName(), parentNode.getQName().getModule()); - - if (leafContainsEnumDefinition(dataNode)) { - returnType = referencedTypes.get(dataNode.getPath()); - } else if (leafListContainsEnumDefinition(dataNode)) { - returnType = Types.listTypeFor(referencedTypes.get(dataNode.getPath())); - } else { - returnType = resolveTypeFromDataSchemaNode(dataNode); - } - } else { - returnType = Types.typeForClass(Object.class); - } - } - Preconditions.checkArgument(returnType != null, "Failed to find leafref target: %s in module %s (%s)", - strXPath, this.getParentModule(parentNode).getName(), parentNode.getQName().getModule(), this); - return returnType; - } - - /** - * Checks if dataNode is LeafSchemaNode and if it - * so then checks if it is of type EnumTypeDefinition. - * - * @param dataNode - * data schema node for which is checked if it is leaf and if it - * is of enum type - * @return boolean value - *
    - *
  • true - if dataNode is leaf of type enumeration
  • - *
  • false - other cases
  • - *
- */ - private static boolean leafContainsEnumDefinition(final SchemaNode dataNode) { - if (dataNode instanceof LeafSchemaNode) { - final LeafSchemaNode leaf = (LeafSchemaNode) dataNode; - if (CompatUtils.compatLeafType(leaf) instanceof EnumTypeDefinition) { - return true; - } - } - return false; - } - - /** - * Checks if dataNode is LeafListSchemaNode and if - * it so then checks if it is of type EnumTypeDefinition. - * - * @param dataNode - * data schema node for which is checked if it is leaflist and if - * it is of enum type - * @return boolean value - *
    - *
  • true - if dataNode is leaflist of type - * enumeration
  • - *
  • false - other cases
  • - *
- */ - private static boolean leafListContainsEnumDefinition(final SchemaNode dataNode) { - if (dataNode instanceof LeafListSchemaNode) { - final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode; - if (leafList.getType() instanceof EnumTypeDefinition) { - return true; - } - } - return false; - } - - /** - * Converts enumTypeDef to - * {@link Enumeration - * enumeration}. - * - * @param enumTypeDef - * enumeration type definition which is converted to enumeration - * @param enumName - * string with name which is used as the enumeration name - * @return enumeration type which is built with data (name, enum values) - * from enumTypeDef - * @throws IllegalArgumentException - *
    - *
  • if enumTypeDef equals null
  • - *
  • if enum values of enumTypeDef equal null
  • - *
  • if Q name of enumTypeDef equal null
  • - *
  • if name of enumTypeDef equal null
  • - *
- */ - private Enumeration provideTypeForEnum(final EnumTypeDefinition enumTypeDef, final String enumName, - final SchemaNode parentNode) { - Preconditions.checkArgument(enumTypeDef != null, "EnumTypeDefinition reference cannot be NULL!"); - Preconditions.checkArgument(enumTypeDef.getValues() != null, - "EnumTypeDefinition MUST contain at least ONE value definition!"); - Preconditions.checkArgument(enumTypeDef.getQName() != null, "EnumTypeDefinition MUST contain NON-NULL QName!"); - Preconditions.checkArgument(enumTypeDef.getQName().getLocalName() != null, - "Local Name in EnumTypeDefinition QName cannot be NULL!"); - - final String enumerationName = BindingMapping.getClassName(enumName); - - final Module module = findParentModule(schemaContext, parentNode); - final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); - - final EnumerationBuilderImpl enumBuilder = new EnumerationBuilderImpl(basePackageName, enumerationName); - final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription().orElse(null)); - enumBuilder.setDescription(enumTypedefDescription); - enumBuilder.setReference(enumTypeDef.getReference().orElse(null)); - enumBuilder.setModuleName(module.getName()); - enumBuilder.setSchemaPath(enumTypeDef.getPath().getPathFromRoot()); - enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); - return enumBuilder.toInstance(null); - } - - /** - * Adds enumeration to typeBuilder. The enumeration data are - * taken from enumTypeDef. - * - * @param enumTypeDef - * enumeration type definition is source of enumeration data for - * typeBuilder - * @param enumName - * string with the name of enumeration - * @param typeBuilder - * generated type builder to which is enumeration added - * @return enumeration type which contains enumeration data form - * enumTypeDef - * @throws IllegalArgumentException - *
    - *
  • if enumTypeDef equals null
  • - *
  • if enum values of enumTypeDef equal null
  • - *
  • if Q name of enumTypeDef equal null
  • - *
  • if name of enumTypeDef equal null
  • - *
  • if name of typeBuilder equal null
  • - *
- * - */ - private static Enumeration addInnerEnumerationToTypeBuilder(final EnumTypeDefinition enumTypeDef, - final String enumName, final GeneratedTypeBuilderBase typeBuilder) { - Preconditions.checkArgument(enumTypeDef != null, "EnumTypeDefinition reference cannot be NULL!"); - Preconditions.checkArgument(enumTypeDef.getValues() != null, - "EnumTypeDefinition MUST contain at least ONE value definition!"); - Preconditions.checkArgument(enumTypeDef.getQName() != null, "EnumTypeDefinition MUST contain NON-NULL QName!"); - Preconditions.checkArgument(enumTypeDef.getQName().getLocalName() != null, - "Local Name in EnumTypeDefinition QName cannot be NULL!"); - Preconditions.checkArgument(typeBuilder != null, "Generated Type Builder reference cannot be NULL!"); - - final String enumerationName = BindingMapping.getClassName(enumName); - - final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName); - final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription().orElse(null)); - enumBuilder.setDescription(enumTypedefDescription); - enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); - return enumBuilder.toInstance(enumBuilder); - } - - /** - * Converts dataNode to JAVA Type. - * - * @param dataNode - * contains information about YANG type - * @return JAVA Type representation of dataNode - */ - private Type resolveTypeFromDataSchemaNode(final SchemaNode dataNode) { - Type returnType = null; - if (dataNode != null) { - if (dataNode instanceof LeafSchemaNode) { - final LeafSchemaNode leaf = (LeafSchemaNode) dataNode; - final TypeDefinition type = CompatUtils.compatLeafType(leaf); - returnType = javaTypeForSchemaDefinitionType(type, leaf); - } else if (dataNode instanceof LeafListSchemaNode) { - final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode; - returnType = javaTypeForSchemaDefinitionType(leafList.getType(), leafList); - } - } - return returnType; - } - - /** - * Passes through all modules and through all its type definitions and - * convert it to generated types. - * - * The modules are firstly sorted by mutual dependencies. The modules are - * sequentially passed. All type definitions of a module are at the - * beginning sorted so that type definition with less amount of references - * to other type definition are processed first.
- * For each module is created mapping record in the map - * {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap} - * which map current module name to the map which maps type names to - * returned types (generated types). - * - */ - private void resolveTypeDefsFromContext() { - final Set modules = schemaContext.getModules(); - Preconditions.checkArgument(modules != null, "Set of Modules cannot be NULL!"); - final List modulesSortedByDependency = ModuleDependencySort.sort(modules); - - for (Module module : modulesSortedByDependency) { - Map, Map> dateTypeMap = genTypeDefsContextMap.get(module.getName()); - if (dateTypeMap == null) { - dateTypeMap = new HashMap<>(); - } - dateTypeMap.put(module.getRevision(), Collections.emptyMap()); - genTypeDefsContextMap.put(module.getName(), dateTypeMap); - } - - for (Module module : modulesSortedByDependency) { - if (module != null) { - final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); - if (basePackageName != null) { - final List> typeDefinitions = TypedefResolver.getAllTypedefs(module); - for (TypeDefinition typedef : sortTypeDefinitionAccordingDepth(typeDefinitions)) { - typedefToGeneratedType(basePackageName, module, typedef); - } - } - } - } - } - - /** - * - * @param basePackageName - * string with name of package to which the module belongs - * @param module - * string with the name of the module for to which the - * typedef belongs - * @param typedef - * type definition of the node for which should be creted JAVA - * Type (usually generated TO) - * @return JAVA Type representation of typedef or - * null value if basePackageName or - * modulName or typedef or Q name of - * typedef equals null - */ - private Type typedefToGeneratedType(final String basePackageName, final Module module, final TypeDefinition typedef) { - final String moduleName = module.getName(); - final Optional moduleRevision = module.getRevision(); - if (basePackageName != null && moduleName != null && typedef != null && typedef.getQName() != null) { - final String typedefName = typedef.getQName().getLocalName(); - final TypeDefinition innerTypeDefinition = typedef.getBaseType(); - // See generatedTypeForExtendedDefinitionType() above for rationale behind this special case. - if (!(innerTypeDefinition instanceof LeafrefTypeDefinition) - && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) { - Type returnType = null; - if (innerTypeDefinition.getBaseType() != null) { - returnType = provideGeneratedTOFromExtendedType(typedef, innerTypeDefinition, basePackageName, module.getName()); - } else if (innerTypeDefinition instanceof UnionTypeDefinition) { - final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDef(basePackageName, - (UnionTypeDefinition) innerTypeDefinition, typedefName, typedef); - genTOBuilder.setTypedef(true); - genTOBuilder.setIsUnion(true); - addUnitsToGenTO(genTOBuilder, typedef.getUnits().orElse(null)); - makeSerializable((GeneratedTOBuilderImpl) genTOBuilder); - returnType = genTOBuilder.toInstance(); - // union builder - final GeneratedTOBuilder unionBuilder = new GeneratedTOBuilderImpl(genTOBuilder.getPackageName(), - genTOBuilder.getName() + "Builder"); - unionBuilder.setIsUnionBuilder(true); - final MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance"); - method.setReturnType(returnType); - method.addParameter(Types.STRING, "defaultValue"); - method.setAccessModifier(AccessModifier.PUBLIC); - method.setStatic(true); - Set types = additionalTypes.get(module); - if (types == null) { - types = Sets. newHashSet(unionBuilder.toInstance()); - additionalTypes.put(module, types); - } else { - types.add(unionBuilder.toInstance()); - } - } else if (innerTypeDefinition instanceof EnumTypeDefinition) { - // enums are automatically Serializable - final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition; - // TODO units for typedef enum - returnType = provideTypeForEnum(enumTypeDef, typedefName, typedef); - } else if (innerTypeDefinition instanceof BitsTypeDefinition) { - final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition; - final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForBitsTypeDefinition( - basePackageName, bitsTypeDefinition, typedefName, module.getName()); - genTOBuilder.setTypedef(true); - addUnitsToGenTO(genTOBuilder, typedef.getUnits().orElse(null)); - makeSerializable((GeneratedTOBuilderImpl) genTOBuilder); - returnType = genTOBuilder.toInstance(); - } else { - final Type javaType = javaTypeForSchemaDefinitionType(innerTypeDefinition, typedef); - returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType, module.getName()); - } - if (returnType != null) { - final Map, Map> modulesByDate = - genTypeDefsContextMap.get(moduleName); - Map typeMap = modulesByDate.get(moduleRevision); - if (typeMap != null) { - if (typeMap.isEmpty()) { - typeMap = new HashMap<>(4); - modulesByDate.put(moduleRevision, typeMap); - } - typeMap.put(typedefName, returnType); - } - return returnType; - } - } - } - return null; - } - - /** - * Wraps base YANG type to generated TO. - * - * @param basePackageName - * string with name of package to which the module belongs - * @param typedef - * type definition which is converted to the TO - * @param javaType - * JAVA Type to which is typedef mapped - * @return generated transfer object which representjavaType - */ - private static GeneratedTransferObject wrapJavaTypeIntoTO(final String basePackageName, - final TypeDefinition typedef, final Type javaType, final String moduleName) { - Preconditions.checkNotNull(javaType, "javaType cannot be null"); - final String propertyName = "value"; - - final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef, moduleName); - genTOBuilder.setRestrictions(BindingGeneratorUtil.getRestrictions(typedef)); - final GeneratedPropertyBuilder genPropBuilder = genTOBuilder.addProperty(propertyName); - genPropBuilder.setReturnType(javaType); - genTOBuilder.addEqualsIdentity(genPropBuilder); - genTOBuilder.addHashIdentity(genPropBuilder); - genTOBuilder.addToStringProperty(genPropBuilder); - if (typedef.getStatus() == Status.DEPRECATED) { - genTOBuilder.addAnnotation("", "Deprecated"); - } - if (javaType instanceof ConcreteType && "String".equals(javaType.getName()) && typedef.getBaseType() != null) { - addStringRegExAsConstant(genTOBuilder, resolveRegExpressionsFromTypedef(typedef)); - } - addUnitsToGenTO(genTOBuilder, typedef.getUnits().orElse(null)); - genTOBuilder.setTypedef(true); - makeSerializable((GeneratedTOBuilderImpl) genTOBuilder); - return genTOBuilder.toInstance(); - } - - /** - * Converts output list of generated TO builders to one TO builder (first - * from list) which contains the remaining builders as its enclosing TO. - * - * @param basePackageName - * string with name of package to which the module belongs - * @param typedef - * type definition which should be of type - * UnionTypeDefinition - * @param typeDefName - * string with name for generated TO - * @return generated TO builder with the list of enclosed generated TO - * builders - */ - public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDef(final String basePackageName, - final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode) { - final List builders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName, - typedef, typeDefName, parentNode); - Preconditions.checkState(!builders.isEmpty(), "No GeneratedTOBuilder objects generated from union %s", typedef); - - final GeneratedTOBuilder resultTOBuilder = builders.remove(0); - builders.forEach(resultTOBuilder::addEnclosingTransferObject); - - resultTOBuilder.addProperty("value").setReturnType(Types.CHAR_ARRAY); - return resultTOBuilder; - } - - /** - * Converts typedef to generated TO with - * typeDefName. Every union type from typedef is - * added to generated TO builder as property. - * - * @param basePackageName - * string with name of package to which the module belongs - * @param typedef - * type definition which should be of type - * UnionTypeDefinition - * @param typeDefName - * string with name for generated TO - * @return generated TO builder which represents typedef - * @throws NullPointerException - *
    - *
  • if basePackageName is null
  • - *
  • if typedef is null
  • - *
  • if Qname of typedef is null
  • - *
- */ - public List provideGeneratedTOBuildersForUnionTypeDef(final String basePackageName, - final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode) { - Preconditions.checkNotNull(basePackageName, "Base Package Name cannot be NULL!"); - Preconditions.checkNotNull(typedef, "Type Definition cannot be NULL!"); - Preconditions.checkNotNull(typedef.getQName(), "Type definition QName cannot be NULL!"); - - final List generatedTOBuilders = new ArrayList<>(); - final List> unionTypes = typedef.getTypes(); - final Module module = findParentModule(schemaContext, parentNode); - - final GeneratedTOBuilderImpl unionGenTOBuilder; - if (typeDefName != null && !typeDefName.isEmpty()) { - final String typeName = BindingMapping.getClassName(typeDefName); - unionGenTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName); - final String typedefDescription = encodeAngleBrackets(typedef.getDescription().orElse(null)); - unionGenTOBuilder.setDescription(typedefDescription); - typedef.getReference().ifPresent(unionGenTOBuilder::setReference); - unionGenTOBuilder.setSchemaPath(typedef.getPath().getPathFromRoot()); - unionGenTOBuilder.setModuleName(module.getName()); - } else { - unionGenTOBuilder = typedefToTransferObject(basePackageName, typedef, module.getName()); - } - - generatedTOBuilders.add(unionGenTOBuilder); - unionGenTOBuilder.setIsUnion(true); - - // 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 expressions = new HashMap<>(); - for (TypeDefinition unionType : unionTypes) { - final String unionTypeName = unionType.getQName().getLocalName(); - - // If we have a base type we should follow the type definition backwards, except for identityrefs, as those - // do not follow type encapsulation -- we use the general case for that. - if (unionType.getBaseType() != null && !(unionType instanceof IdentityrefTypeDefinition)) { - resolveExtendedSubtypeAsUnion(unionGenTOBuilder, unionType, expressions, parentNode); - } else if (unionType instanceof UnionTypeDefinition) { - generatedTOBuilders.addAll(resolveUnionSubtypeAsUnion(unionGenTOBuilder, - (UnionTypeDefinition) unionType, basePackageName, parentNode)); - } else if (unionType instanceof EnumTypeDefinition) { - final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType, - unionTypeName, unionGenTOBuilder); - updateUnionTypeAsProperty(unionGenTOBuilder, enumeration, unionTypeName); - } else { - final Type javaType = javaTypeForSchemaDefinitionType(unionType, parentNode); - updateUnionTypeAsProperty(unionGenTOBuilder, javaType, unionTypeName); - } - } - addStringRegExAsConstant(unionGenTOBuilder, expressions); - - storeGenTO(typedef, unionGenTOBuilder, parentNode); - - return generatedTOBuilders; - } - - /** - * Wraps code which handle case when union subtype is also of the type - * UnionType. - * - * In this case the new generated TO is created for union subtype (recursive - * call of method - * {@link #provideGeneratedTOBuildersForUnionTypeDef(String, UnionTypeDefinition, - * String, SchemaNode)} - * provideGeneratedTOBuilderForUnionTypeDef} and in parent TO builder - * parentUnionGenTOBuilder is created property which type is - * equal to new generated TO. - * - * @param parentUnionGenTOBuilder - * generated TO builder to which is the property with the child - * union subtype added - * @param basePackageName - * string with the name of the module package - * @param unionSubtype - * type definition which represents union subtype - * @return list of generated TO builders. The number of the builders can be - * bigger one due to recursive call of - * provideGeneratedTOBuildersForUnionTypeDef method. - */ - private List resolveUnionSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder, - final UnionTypeDefinition unionSubtype, final String basePackageName, final SchemaNode parentNode) { - final String newTOBuilderName = provideAvailableNameForGenTOBuilder(parentUnionGenTOBuilder.getName()); - final List subUnionGenTOBUilders = provideGeneratedTOBuildersForUnionTypeDef( - basePackageName, unionSubtype, newTOBuilderName, parentNode); - - final GeneratedPropertyBuilder propertyBuilder; - propertyBuilder = parentUnionGenTOBuilder.addProperty(BindingMapping.getPropertyName(newTOBuilderName)); - propertyBuilder.setReturnType(subUnionGenTOBUilders.get(0)); - parentUnionGenTOBuilder.addEqualsIdentity(propertyBuilder); - parentUnionGenTOBuilder.addToStringProperty(propertyBuilder); - - return subUnionGenTOBUilders; - } - - /** - * Wraps code which handle case when union subtype is of the type - * ExtendedType. - * - * If TO for this type already exists it is used for the creation of the - * property in parentUnionGenTOBuilder. In other case the base - * type is used for the property creation. - * - * @param parentUnionGenTOBuilder - * generated TO builder in which new property is created - * @param unionSubtype - * type definition of the ExtendedType type which - * represents union subtype - * @param expressions - * list of strings with the regular expressions - * @param parentNode - * parent Schema Node for Extended Subtype - * - */ - private void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder, - final TypeDefinition unionSubtype, final Map expressions, final SchemaNode parentNode) { - final String unionTypeName = unionSubtype.getQName().getLocalName(); - final Type genTO = findGenTO(unionTypeName, unionSubtype); - if (genTO != null) { - updateUnionTypeAsProperty(parentUnionGenTOBuilder, genTO, genTO.getName()); - return; - } - - final TypeDefinition baseType = baseTypeDefForExtendedType(unionSubtype); - if (unionTypeName.equals(baseType.getQName().getLocalName())) { - final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(baseType, - parentNode); - if (javaType != null) { - updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, unionTypeName); - } - } else if (baseType instanceof LeafrefTypeDefinition) { - final Type javaType = javaTypeForSchemaDefinitionType(baseType, parentNode); - boolean typeExist = false; - for (GeneratedPropertyBuilder generatedPropertyBuilder : parentUnionGenTOBuilder.getProperties()) { - final Type origType = ((GeneratedPropertyBuilderImpl) generatedPropertyBuilder).getReturnType(); - if (origType != null && javaType != null && javaType == origType) { - typeExist = true; - break; - } - } - if (!typeExist && javaType != null) { - updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, - javaType.getName() + parentUnionGenTOBuilder.getName() + "Value"); - } - } - if (baseType instanceof StringTypeDefinition) { - expressions.putAll(resolveRegExpressionsFromTypedef(unionSubtype)); - } - } - - /** - * Searches for generated TO for searchedTypeDef type - * definition in {@link #genTypeDefsContextMap genTypeDefsContextMap} - * - * @param searchedTypeName - * string with name of searchedTypeDef - * @return generated TO for searchedTypeDef or - * null it it doesn't exist - */ - private Type findGenTO(final String searchedTypeName, final SchemaNode parentNode) { - final Module typeModule = findParentModule(schemaContext, parentNode); - if (typeModule != null && typeModule.getName() != null) { - final Map, Map> modulesByDate = genTypeDefsContextMap.get(typeModule.getName()); - final Map genTOs = modulesByDate.get(typeModule.getRevision()); - if (genTOs != null) { - return genTOs.get(searchedTypeName); - } - } - return null; - } - - /** - * Stores generated TO created from genTOBuilder for - * newTypeDef to {@link #genTypeDefsContextMap - * genTypeDefsContextMap} if the module for newTypeDef exists - * - * @param newTypeDef - * type definition for which is genTOBuilder created - * @param genTOBuilder - * generated TO builder which is converted to generated TO and - * stored - */ - private void storeGenTO(final TypeDefinition newTypeDef, final GeneratedTOBuilder genTOBuilder, final SchemaNode parentNode) { - if (!(newTypeDef instanceof UnionTypeDefinition)) { - final Module parentModule = findParentModule(schemaContext, parentNode); - if (parentModule != null && parentModule.getName() != null) { - final Map, Map> modulesByDate = genTypeDefsContextMap.get(parentModule.getName()); - final Map genTOsMap = modulesByDate.get(parentModule.getRevision()); - genTOsMap.put(newTypeDef.getQName().getLocalName(), genTOBuilder.toInstance()); - } - } - } - - /** - * Adds a new property with the name propertyName and with type - * type to unonGenTransObject. - * - * @param unionGenTransObject - * generated TO to which should be property added - * @param type - * JAVA type of the property which should be added - * to unionGentransObject - * @param propertyName - * string with name of property which should be added to - * unionGentransObject - */ - private static void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type, final String propertyName) { - if (unionGenTransObject != null && type != null && !unionGenTransObject.containsProperty(propertyName)) { - final GeneratedPropertyBuilder propBuilder = unionGenTransObject - .addProperty(BindingMapping.getPropertyName(propertyName)); - propBuilder.setReturnType(type); - - unionGenTransObject.addEqualsIdentity(propBuilder); - unionGenTransObject.addHashIdentity(propBuilder); - unionGenTransObject.addToStringProperty(propBuilder); - } - } - - /** - * Converts typedef to the generated TO builder. - * - * @param basePackageName - * string with name of package to which the module belongs - * @param typedef - * type definition from which is the generated TO builder created - * @return generated TO builder which contains data from - * typedef and basePackageName - */ - private static GeneratedTOBuilderImpl typedefToTransferObject(final String basePackageName, final TypeDefinition typedef, final String moduleName) { - - final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, typedef.getPath()); - final String typeDefTOName = typedef.getQName().getLocalName(); - - if (packageName != null && typeDefTOName != null) { - final String genTOName = BindingMapping.getClassName(typeDefTOName); - final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTOName); - final String typedefDescription = encodeAngleBrackets(typedef.getDescription().orElse(null)); - - newType.setDescription(typedefDescription); - typedef.getReference().ifPresent(newType::setReference); - newType.setSchemaPath(typedef.getPath().getPathFromRoot()); - newType.setModuleName(moduleName); - - return newType; - } - return null; + super(schemaContext); } - - /** - * Converts typeDef which should be of the type - * BitsTypeDefinition to GeneratedTOBuilder. - * - * All the bits of the typeDef are added to returning generated TO as - * properties. - * - * @param basePackageName - * string with name of package to which the module belongs - * @param typeDef - * type definition from which is the generated TO builder created - * @param typeDefName - * string with the name for generated TO builder - * @return generated TO builder which represents typeDef - * @throws IllegalArgumentException - *
    - *
  • if typeDef equals null
  • - *
  • if basePackageName equals null
  • - *
- */ - public GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName, - final TypeDefinition typeDef, final String typeDefName, final String moduleName) { - - Preconditions.checkArgument(typeDef != null, "typeDef cannot be NULL!"); - Preconditions.checkArgument(basePackageName != null, "Base Package Name cannot be NULL!"); - - if (typeDef instanceof BitsTypeDefinition) { - final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) typeDef; - - final String typeName = BindingMapping.getClassName(typeDefName); - final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName); - final String typedefDescription = encodeAngleBrackets(typeDef.getDescription().orElse(null)); - - genTOBuilder.setDescription(typedefDescription); - typeDef.getReference().ifPresent(genTOBuilder::setReference); - genTOBuilder.setSchemaPath(typeDef.getPath().getPathFromRoot()); - genTOBuilder.setModuleName(moduleName); - genTOBuilder.setBaseType(typeDef); - - final List bitList = bitsTypeDefinition.getBits(); - GeneratedPropertyBuilder genPropertyBuilder; - for (Bit bit : bitList) { - final String name = bit.getName(); - genPropertyBuilder = genTOBuilder.addProperty(BindingMapping.getPropertyName(name)); - genPropertyBuilder.setReadOnly(true); - genPropertyBuilder.setReturnType(BaseYangTypes.BOOLEAN_TYPE); - - genTOBuilder.addEqualsIdentity(genPropertyBuilder); - genTOBuilder.addHashIdentity(genPropertyBuilder); - genTOBuilder.addToStringProperty(genPropertyBuilder); - } - - return genTOBuilder; - } - return null; - } - - /** - * Converts the pattern constraints from typedef to the list of - * the strings which represents these constraints. - * - * @param typedef - * extended type in which are the pattern constraints sought - * @return list of strings which represents the constraint patterns - * @throws IllegalArgumentException - * if typedef equals null - * - */ - private static Map resolveRegExpressionsFromTypedef(final TypeDefinition typedef) { - if (!(typedef instanceof StringTypeDefinition)) { - return ImmutableMap.of(); - } - - // TODO: run diff against base ? - final List patternConstraints = ((StringTypeDefinition) typedef).getPatternConstraints(); - final Map regExps = Maps.newHashMapWithExpectedSize(patternConstraints.size()); - for (PatternConstraint patternConstraint : patternConstraints) { - String regEx = patternConstraint.getJavaPatternString(); - - // The pattern can be inverted - final Optional optModifier = patternConstraint.getModifier(); - if (optModifier.isPresent()) { - regEx = applyModifier(optModifier.get(), regEx); - } - - regExps.put(regEx, patternConstraint.getRegularExpressionString()); - } - - return regExps; - } - - private static String applyModifier(final ModifierKind modifier, final String pattern) { - switch (modifier) { - case INVERT_MATCH: - return BindingMapping.negatePatternString(pattern); - default: - LOG.warn("Ignoring unhandled modifier {}", modifier); - return pattern; - } - } - - /** - * - * Adds to the genTOBuilder the constant which contains regular - * expressions from the regularExpressions - * - * @param genTOBuilder - * generated TO builder to which are - * regular expressions added - * @param expressions - * list of string which represent regular expressions - */ - private static void addStringRegExAsConstant(final GeneratedTOBuilder genTOBuilder, - final Map expressions) { - if (!expressions.isEmpty()) { - genTOBuilder.addConstant(Types.listTypeFor(BaseYangTypes.STRING_TYPE), TypeConstants.PATTERN_CONSTANT_NAME, - ImmutableMap.copyOf(expressions)); - } - } - - /** - * Creates generated TO with data about inner extended type - * innerExtendedType, about the package name - * typedefName and about the generated TO name - * typedefName. - * - * It is supposed that innerExtendedType is already present in - * {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap} to - * be possible set it as extended type for the returning generated TO. - * - * @param typedef - * Type Definition - * @param innerExtendedType - * extended type which is part of some other extended type - * @param basePackageName - * string with the package name of the module - * @param moduleName - * Module Name - * @return generated TO which extends generated TO for - * innerExtendedType - * @throws IllegalArgumentException - *
    - *
  • if extendedType equals null
  • - *
  • if basePackageName equals null
  • - *
  • if typedefName equals null
  • - *
- */ - private GeneratedTransferObject provideGeneratedTOFromExtendedType(final TypeDefinition typedef, final TypeDefinition innerExtendedType, final String basePackageName, final String moduleName) { - Preconditions.checkArgument(innerExtendedType != null, "Extended type cannot be NULL!"); - Preconditions.checkArgument(basePackageName != null, "String with base package name cannot be NULL!"); - - final String typedefName = typedef.getQName().getLocalName(); - final String classTypedefName = BindingMapping.getClassName(typedefName); - final String innerTypeDef = innerExtendedType.getQName().getLocalName(); - final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, classTypedefName); - final String typedefDescription = encodeAngleBrackets(typedef.getDescription().orElse(null)); - - genTOBuilder.setDescription(typedefDescription); - typedef.getReference().ifPresent(genTOBuilder::setReference); - genTOBuilder.setSchemaPath(typedef.getPath().getPathFromRoot()); - genTOBuilder.setModuleName(moduleName); - genTOBuilder.setTypedef(true); - final Restrictions r = BindingGeneratorUtil.getRestrictions(typedef); - genTOBuilder.setRestrictions(r); - if (typedef.getStatus() == Status.DEPRECATED) { - genTOBuilder.addAnnotation("", "Deprecated"); - } - - if (baseTypeDefForExtendedType(innerExtendedType) instanceof UnionTypeDefinition) { - genTOBuilder.setIsUnion(true); - } - - Map, Map> modulesByDate = null; - Map typeMap = null; - final Module parentModule = findParentModule(schemaContext, innerExtendedType); - if (parentModule != null) { - modulesByDate = genTypeDefsContextMap.get(parentModule.getName()); - typeMap = modulesByDate.get(parentModule.getRevision()); - } - - if (typeMap != null) { - final Type type = typeMap.get(innerTypeDef); - if (type instanceof GeneratedTransferObject) { - genTOBuilder.setExtendsType((GeneratedTransferObject) type); - } - } - addUnitsToGenTO(genTOBuilder, typedef.getUnits().orElse(null)); - makeSerializable(genTOBuilder); - - return genTOBuilder.toInstance(); - } - - /** - * Add {@link Serializable} to implemented interfaces of this TO. Also - * compute and add serialVersionUID property. - * - * @param gto - * transfer object which needs to be serializable - */ - private static void makeSerializable(final GeneratedTOBuilderImpl gto) { - gto.addImplementsType(Types.typeForClass(Serializable.class)); - final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID"); - prop.setValue(Long.toString(BindingGeneratorUtil.computeDefaultSUID(gto))); - gto.setSUID(prop); - } - - /** - * Finds out for each type definition how many immersion (depth) is - * necessary to get to the base type. Every type definition is inserted to - * the map which key is depth and value is list of type definitions with - * equal depth. In next step are lists from this map concatenated to one - * list in ascending order according to their depth. All type definitions - * are in the list behind all type definitions on which depends. - * - * @param unsortedTypeDefinitions - * list of type definitions which should be sorted by depth - * @return list of type definitions sorted according their each other - * dependencies (type definitions which are depend on other type - * definitions are in list behind them). - */ - private static List> sortTypeDefinitionAccordingDepth( - final Collection> unsortedTypeDefinitions) { - final List> sortedTypeDefinition = new ArrayList<>(); - - final Map>> typeDefinitionsDepths = new TreeMap<>(); - for (TypeDefinition unsortedTypeDefinition : unsortedTypeDefinitions) { - final Integer depth = getTypeDefinitionDepth(unsortedTypeDefinition); - List> typeDefinitionsConcreteDepth = typeDefinitionsDepths.get(depth); - if (typeDefinitionsConcreteDepth == null) { - typeDefinitionsConcreteDepth = new ArrayList<>(); - typeDefinitionsDepths.put(depth, typeDefinitionsConcreteDepth); - } - typeDefinitionsConcreteDepth.add(unsortedTypeDefinition); - } - - // SortedMap guarantees order corresponding to keys in ascending order - for (List> v : typeDefinitionsDepths.values()) { - sortedTypeDefinition.addAll(v); - } - - return sortedTypeDefinition; - } - - /** - * Returns how many immersion is necessary to get from the type definition - * to the base type. - * - * @param typeDefinition - * type definition for which is depth sought. - * @return number of immersions which are necessary to get from the type - * definition to the base type - */ - private static int getTypeDefinitionDepth(final TypeDefinition typeDefinition) { - // FIXME: rewrite this in a non-recursive manner - if (typeDefinition == null) { - return 1; - } - final TypeDefinition baseType = typeDefinition.getBaseType(); - if (baseType == null) { - return 1; - } - - int depth = 1; - if (baseType.getBaseType() != null) { - depth = depth + getTypeDefinitionDepth(baseType); - } else if (baseType instanceof UnionTypeDefinition) { - final List> childTypeDefinitions = ((UnionTypeDefinition) baseType).getTypes(); - int maxChildDepth = 0; - int childDepth = 1; - for (TypeDefinition childTypeDefinition : childTypeDefinitions) { - childDepth = childDepth + getTypeDefinitionDepth(childTypeDefinition); - if (childDepth > maxChildDepth) { - maxChildDepth = childDepth; - } - } - return maxChildDepth; - } - return depth; - } - - /** - * Returns string which contains the same value as name but - * integer suffix is incremented by one. If name contains no - * number suffix then number 1 is added. - * - * @param name - * string with name of augmented node - * @return string with the number suffix incremented by one (or 1 is added) - */ - private static String provideAvailableNameForGenTOBuilder(final String name) { - final Matcher mtch = NUMBERS_PATTERN.matcher(name); - if (mtch.find()) { - final int newSuffix = Integer.parseInt(name.substring(mtch.start())) + 1; - return name.substring(0, mtch.start()) + newSuffix; - } - - return name + 1; - } - - public static void addUnitsToGenTO(final GeneratedTOBuilder to, final String units) { - if (!Strings.isNullOrEmpty(units)) { - to.addConstant(Types.STRING, "_UNITS", "\"" + units + "\""); - final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("UNITS"); - prop.setReturnType(Types.STRING); - to.addToStringProperty(prop); - } - } - - @Override - public String getTypeDefaultConstruction(final LeafSchemaNode node) { - return getTypeDefaultConstruction(node, (String) node.getType().getDefaultValue().orElse(null)); - } - - public String getTypeDefaultConstruction(final LeafSchemaNode node, final String defaultValue) { - final TypeDefinition type = CompatUtils.compatLeafType(node); - final QName typeQName = type.getQName(); - final TypeDefinition base = baseTypeDefForExtendedType(type); - Preconditions.checkNotNull(type, "Cannot provide default construction for null type of %s", node); - Preconditions.checkNotNull(defaultValue, "Cannot provide default construction for null default statement of %s", - node); - - final StringBuilder sb = new StringBuilder(); - String result = null; - if (base instanceof BinaryTypeDefinition) { - result = binaryToDef(defaultValue); - } else if (base instanceof BitsTypeDefinition) { - String parentName; - String className; - final Module parent = getParentModule(node); - final Iterator path = node.getPath().getPathFromRoot().iterator(); - path.next(); - if (!path.hasNext()) { - parentName = BindingMapping.getClassName(parent.getName()) + "Data"; - final String basePackageName = BindingMapping.getRootPackageName(parent.getQNameModule()); - className = basePackageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName()); - } else { - final String basePackageName = BindingMapping.getRootPackageName(parent.getQNameModule()); - final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, type.getPath()); - parentName = BindingMapping.getClassName(parent.getName()); - className = packageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName()); - } - result = bitsToDef((BitsTypeDefinition) base, className, defaultValue, type.getBaseType() != null); - } else if (base instanceof BooleanTypeDefinition) { - result = typeToBooleanDef(defaultValue); - } else if (base instanceof DecimalTypeDefinition) { - result = typeToDef(BigDecimal.class, defaultValue); - } else if (base instanceof EmptyTypeDefinition) { - result = typeToBooleanDef(defaultValue); - } else if (base instanceof EnumTypeDefinition) { - final char[] defValArray = defaultValue.toCharArray(); - final char first = Character.toUpperCase(defaultValue.charAt(0)); - defValArray[0] = first; - final String newDefVal = new String(defValArray); - String className; - if (type.getBaseType() != null) { - final Module m = getParentModule(type); - final String basePackageName = BindingMapping.getRootPackageName(m.getQNameModule()); - final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, type.getPath()); - className = packageName + "." + BindingMapping.getClassName(typeQName); - } else { - final Module parentModule = getParentModule(node); - final String basePackageName = BindingMapping.getRootPackageName(parentModule.getQNameModule()); - final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, node.getPath()); - className = packageName + "." + BindingMapping.getClassName(node.getQName()); - } - result = className + "." + newDefVal; - } else if (base instanceof IdentityrefTypeDefinition) { - throw new UnsupportedOperationException("Cannot get default construction for identityref type"); - } else if (base instanceof InstanceIdentifierTypeDefinition) { - throw new UnsupportedOperationException("Cannot get default construction for instance-identifier type"); - } else if (BaseTypes.isInt8(base)) { - result = typeToValueOfDef(Byte.class, defaultValue); - } else if (BaseTypes.isInt16(base)) { - result = typeToValueOfDef(Short.class, defaultValue); - } else if (BaseTypes.isInt32(base)) { - result = typeToValueOfDef(Integer.class, defaultValue); - } else if (BaseTypes.isInt64(base)) { - result = typeToValueOfDef(Long.class, defaultValue); - } else if (base instanceof LeafrefTypeDefinition) { - result = leafrefToDef(node, (LeafrefTypeDefinition) base, defaultValue); - } else if (base instanceof StringTypeDefinition) { - result = "\"" + defaultValue + "\""; - } else if (BaseTypes.isUint8(base)) { - result = typeToValueOfDef(Short.class, defaultValue); - } else if (BaseTypes.isUint16(base)) { - result = typeToValueOfDef(Integer.class, defaultValue); - } else if (BaseTypes.isUint32(base)) { - result = typeToValueOfDef(Long.class, defaultValue); - } else if (BaseTypes.isUint64(base)) { - switch (defaultValue) { - case "0": - result = "java.math.BigInteger.ZERO"; - break; - case "1": - result = "java.math.BigInteger.ONE"; - break; - case "10": - result = "java.math.BigInteger.TEN"; - break; - default: - result = typeToDef(BigInteger.class, defaultValue); - } - } else if (base instanceof UnionTypeDefinition) { - result = unionToDef(node); - } else { - result = ""; - } - sb.append(result); - - if (type.getBaseType() != null && !(base instanceof LeafrefTypeDefinition) - && !(base instanceof EnumTypeDefinition) && !(base instanceof UnionTypeDefinition)) { - final Module m = getParentModule(type); - final String basePackageName = BindingMapping.getRootPackageName(m.getQNameModule()); - final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, type.getPath()); - final String className = packageName + "." + BindingMapping.getClassName(typeQName); - sb.insert(0, "new " + className + "("); - sb.insert(sb.length(), ')'); - } - - return sb.toString(); - } - - private static String typeToDef(final Class clazz, final String defaultValue) { - return "new " + clazz.getName() + "(\"" + defaultValue + "\")"; - } - - private static String typeToValueOfDef(final Class clazz, final String defaultValue) { - return clazz.getName() + ".valueOf(\"" + defaultValue + "\")"; - } - - private static String typeToBooleanDef(final String defaultValue) { - switch (defaultValue) { - case "false": - return "java.lang.Boolean.FALSE"; - case "true": - return "java.lang.Boolean.TRUE"; - default: - return typeToValueOfDef(Boolean.class, defaultValue); - } - } - - private static String binaryToDef(final String defaultValue) { - final StringBuilder sb = new StringBuilder(); - final BaseEncoding en = BaseEncoding.base64(); - final byte[] encoded = en.decode(defaultValue); - sb.append("new byte[] {"); - for (int i = 0; i < encoded.length; i++) { - sb.append(encoded[i]); - if (i != encoded.length - 1) { - sb.append(", "); - } - } - sb.append('}'); - return sb.toString(); - } - - private static final Comparator BIT_NAME_COMPARATOR = (o1, o2) -> o1.getName().compareTo(o2.getName()); - - private static String bitsToDef(final BitsTypeDefinition type, final String className, final String defaultValue, final boolean isExt) { - final List bits = new ArrayList<>(type.getBits()); - Collections.sort(bits, BIT_NAME_COMPARATOR); - final StringBuilder sb = new StringBuilder(); - if (!isExt) { - sb.append("new "); - sb.append(className); - sb.append('('); - } - for (int i = 0; i < bits.size(); i++) { - if (bits.get(i).getName().equals(defaultValue)) { - sb.append(true); - } else { - sb.append(false); - } - if (i != bits.size() - 1) { - sb.append(", "); - } - } - if (!isExt) { - sb.append(')'); - } - return sb.toString(); - } - - private Module getParentModule(final SchemaNode node) { - final QName qname = node.getPath().getPathFromRoot().iterator().next(); - return schemaContext.findModule(qname.getModule()).orElse(null); - } - - private String leafrefToDef(final LeafSchemaNode parentNode, final LeafrefTypeDefinition leafrefType, final String defaultValue) { - Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!"); - Preconditions.checkArgument(leafrefType.getPathStatement() != null, - "The Path Statement for Leafref Type Definition cannot be NULL!"); - - final RevisionAwareXPath xpath = leafrefType.getPathStatement(); - final String strXPath = xpath.toString(); - - if (strXPath != null) { - if (strXPath.indexOf('[') == -1) { - final Module module = findParentModule(schemaContext, parentNode); - if (module != null) { - final SchemaNode dataNode; - if (xpath.isAbsolute()) { - dataNode = findDataSchemaNode(schemaContext, module, xpath); - } else { - dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath); - } - final String result = getTypeDefaultConstruction((LeafSchemaNode) dataNode, defaultValue); - return result; - } - } else { - return "new java.lang.Object()"; - } - } - - return null; - } - - private String unionToDef(final LeafSchemaNode node) { - final TypeDefinition type = CompatUtils.compatLeafType(node); - String parentName; - String className; - - if (type.getBaseType() != null) { - final QName typeQName = type.getQName(); - Module module = null; - final Set modules = schemaContext.findModules(typeQName.getNamespace()); - if (modules.size() > 1) { - for (Module m : modules) { - if (m.getRevision().equals(typeQName.getRevision())) { - module = m; - break; - } - } - if (module == null) { - final List modulesList = new ArrayList<>(modules); - Collections.sort(modulesList, (o1, o2) -> Revision.compare(o1.getRevision(), o2.getRevision())); - module = modulesList.get(0); - } - } else { - module = modules.iterator().next(); - } - - final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule()); - className = basePackageName + "." + BindingMapping.getClassName(typeQName); - } else { - final Iterator path = node.getPath().getPathFromRoot().iterator(); - final QName first = path.next(); - final Module parent = schemaContext.findModule(first.getModule()).orElse(null); - final String basePackageName = BindingMapping.getRootPackageName(parent.getQNameModule()); - if (!path.hasNext()) { - parentName = BindingMapping.getClassName(parent.getName()) + "Data"; - className = basePackageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName()); - } else { - final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, UNION_PATH); - className = packageName + "." + BindingMapping.getClassName(node.getQName()); - } - } - return union(className, (String) node.getType().getDefaultValue().orElse(null), node); - } - - private static String union(final String className, final String defaultValue, final LeafSchemaNode node) { - final StringBuilder sb = new StringBuilder(); - sb.append("new "); - sb.append(className); - sb.append("(\""); - sb.append(defaultValue); - sb.append("\".toCharArray())"); - return sb.toString(); - } - - @Override - public String getConstructorPropertyName(final SchemaNode node) { - return node instanceof TypeDefinition ? "value" : ""; - } - - @Override - public String getParamNameFromType(final TypeDefinition type) { - return BindingMapping.getPropertyName(type.getQName().getLocalName()); - } - } diff --git a/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/generator/impl/TypeProviderIntegrationTest.java b/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/generator/impl/TypeProviderIntegrationTest.java index f5732bc8e0..0c5d04015a 100644 --- a/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/generator/impl/TypeProviderIntegrationTest.java +++ b/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/generator/impl/TypeProviderIntegrationTest.java @@ -14,7 +14,8 @@ import java.util.Set; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.opendaylight.mdsal.binding.yang.types.TypeProviderImpl; +import org.opendaylight.mdsal.binding.yang.types.AbstractTypeProvider; +import org.opendaylight.mdsal.binding.yang.types.CodegenTypeProvider; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; @@ -27,7 +28,7 @@ import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils; public class TypeProviderIntegrationTest { private final String PKG = "org.opendaylight.yang.gen.v1.urn.opendaylight.test.rev131008."; private static SchemaContext context; - private TypeProviderImpl provider; + private AbstractTypeProvider provider; private Module m; @BeforeClass @@ -39,7 +40,7 @@ public class TypeProviderIntegrationTest { @Before public void init() { - provider = new TypeProviderImpl(context); + provider = new CodegenTypeProvider(context); m = context.findModule("test", Revision.of("2013-10-08")).get(); } diff --git a/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/yang/types/Bug4621.java b/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/yang/types/Bug4621.java index f4bd782a19..278e33a0c1 100644 --- a/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/yang/types/Bug4621.java +++ b/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/yang/types/Bug4621.java @@ -13,6 +13,7 @@ import java.net.URI; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.opendaylight.mdsal.binding.generator.spi.TypeProvider; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; @@ -31,7 +32,7 @@ public class Bug4621 { public void bug4621test() { final SchemaContext schemaContext = YangParserTestUtils.parseYangResource("/bug-4621/foo.yang"); final Module moduleValid = schemaContext.findModules(URI.create("foo")).iterator().next(); - final TypeProviderImpl typeProvider = new TypeProviderImpl(schemaContext); + final TypeProvider typeProvider = new RuntimeTypeProvider(schemaContext); expectedEx.expect(IllegalArgumentException.class); diff --git a/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/yang/types/TypeProviderImplTest.java b/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/yang/types/TypeProviderImplTest.java index a9aeef6e59..00dd021e4f 100644 --- a/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/yang/types/TypeProviderImplTest.java +++ b/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/yang/types/TypeProviderImplTest.java @@ -48,7 +48,7 @@ public class TypeProviderImplTest { final SchemaContext schemaContext = YangParserTestUtils.parseYangResource( "/leafref/leafref-relative-invalid.yang"); final Module moduleRelative = schemaContext.findModules(URI.create("urn:xml:ns:yang:lrr")).iterator().next(); - final TypeProviderImpl typeProvider = new TypeProviderImpl(schemaContext); + final AbstractTypeProvider typeProvider = new RuntimeTypeProvider(schemaContext); final QName listNode = QName.create(moduleRelative.getQNameModule(), "neighbor"); final QName leafNode = QName.create(moduleRelative.getQNameModule(), "neighbor-id"); @@ -56,8 +56,7 @@ public class TypeProviderImplTest { .getDataChildByName(leafNode); LeafSchemaNode leaf = (LeafSchemaNode) leafref; TypeDefinition leafType = leaf.getType(); - Type leafrefResolvedType = typeProvider.javaTypeForSchemaDefinitionType(leafType, leaf); - assertNotNull(leafrefResolvedType); + typeProvider.javaTypeForSchemaDefinitionType(leafType, leaf); } @Test(expected = IllegalArgumentException.class) @@ -65,7 +64,7 @@ public class TypeProviderImplTest { final SchemaContext schemaContext = YangParserTestUtils.parseYangResource( "/leafref/leafref-absolute-invalid.yang"); final Module moduleRelative = schemaContext.findModules(URI.create("urn:xml:ns:yang:lra")).iterator().next(); - final TypeProviderImpl typeProvider = new TypeProviderImpl(schemaContext); + final AbstractTypeProvider typeProvider = new RuntimeTypeProvider(schemaContext); final QName listNode = QName.create(moduleRelative.getQNameModule(), "neighbor"); final QName leafNode = QName.create(moduleRelative.getQNameModule(), "neighbor-id"); @@ -81,7 +80,7 @@ public class TypeProviderImplTest { public void testLeafRefRelativeAndAbsoluteValidReference() { final SchemaContext schemaContext = YangParserTestUtils.parseYangResource("/leafref/leafref-valid.yang"); final Module moduleValid = schemaContext.findModules(URI.create("urn:xml:ns:yang:lrv")).iterator().next(); - final TypeProviderImpl typeProvider = new TypeProviderImpl(schemaContext); + final AbstractTypeProvider typeProvider = new RuntimeTypeProvider(schemaContext); final QName listNode = QName.create(moduleValid.getQNameModule(), "neighbor"); final QName leaf1Node = QName.create(moduleValid.getQNameModule(), "neighbor-id"); @@ -105,7 +104,7 @@ public class TypeProviderImplTest { public void testMethodsOfTypeProviderImpl() { final SchemaContext schemaContext = YangParserTestUtils.parseYangResource("/base-yang-types.yang"); - final TypeProviderImpl typeProvider = new TypeProviderImpl(schemaContext); + final AbstractTypeProvider typeProvider = new RuntimeTypeProvider(schemaContext); final SchemaPath refTypePath = SchemaPath.create(true, QName.create("", "cont1"), QName.create("", "list1")); final GeneratedTypeBuilderImpl refType = new GeneratedTypeBuilderImpl("org.opendaylight.yangtools.test", diff --git a/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/yang/types/TypeProviderTest.java b/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/yang/types/TypeProviderTest.java index 13143e7b49..a1a0b3a0ea 100644 --- a/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/yang/types/TypeProviderTest.java +++ b/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/yang/types/TypeProviderTest.java @@ -95,41 +95,41 @@ public class TypeProviderTest { @Test(expected = IllegalArgumentException.class) public void typeProviderInstanceWithNullSchemaContextTest() { - final TypeProvider provider = new TypeProviderImpl(null); + new RuntimeTypeProvider(null); } @Test(expected = IllegalArgumentException.class) public void putReferencedTypeWithNullSchemaPathParamTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); - ((TypeProviderImpl) provider).putReferencedType(null, null); - ((TypeProviderImpl) provider).putReferencedType(this.schemaPath, null); + provider.putReferencedType(null, null); + provider.putReferencedType(this.schemaPath, null); } @Test(expected = IllegalArgumentException.class) public void putReferencedTypeWithNullRefTypeParamTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); - ((TypeProviderImpl) provider).putReferencedType(this.schemaPath, null); + provider.putReferencedType(this.schemaPath, null); } @Test public void getAdditionalTypesTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); - assertNotNull(((TypeProviderImpl) provider).getAdditionalTypes()); + assertNotNull(provider.getAdditionalTypes()); } @Test(expected = IllegalArgumentException.class) public void javaTypeForSchemaDefinitionTypeNullTypedefTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final TypeProvider provider = new RuntimeTypeProvider(this.schemaContext); provider.javaTypeForSchemaDefinitionType(null, null, null); } @Test(expected = IllegalArgumentException.class) public void javaTypeForSchemaDefinitionTypeTypedefNullQNameTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final TypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final TestIntegerTypeDefinition testTypedef = new TestIntegerTypeDefinition(); provider.javaTypeForSchemaDefinitionType(testTypedef, null, null); @@ -165,7 +165,7 @@ public class TypeProviderTest { @Test public void javaTypeForSchemaDefinitionExtTypeTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final TypeProvider provider = new CodegenTypeProvider(this.schemaContext); final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "foo", "yang-int8-type"); final TypeDefinition leafType = leaf.getType(); @@ -182,7 +182,7 @@ public class TypeProviderTest { @Test public void javaTypeForSchemaDefinitionRestrictedExtTypeTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final TypeProvider provider = new CodegenTypeProvider(this.schemaContext); final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "foo", "restricted-int8-type"); final TypeDefinition leafType = leaf.getType(); @@ -206,7 +206,7 @@ public class TypeProviderTest { @Test public void javaTypeForSchemaDefinitionEmptyStringPatternTypeTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final Module testTypeProvider = resolveModule("test-type-provider"); final TypeDefinition emptyPatternString = resolveTypeDefinitionFromModule(testTypeProvider, "empty-pattern-string"); @@ -240,8 +240,9 @@ public class TypeProviderTest { @Ignore @Test public void bug1862RestrictedTypedefTransformationTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); - final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "foo", "bug-1862-restricted-typedef"); + final TypeProvider provider = new CodegenTypeProvider(this.schemaContext); + final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "foo", + "bug-1862-restricted-typedef"); final TypeDefinition leafType = leaf.getType(); final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(leafType); @@ -253,8 +254,9 @@ public class TypeProviderTest { @Test public void javaTypeForSchemaDefinitionEnumExtTypeTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); - LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "foo", "resolve-enum-leaf"); + final TypeProvider provider = new CodegenTypeProvider(this.schemaContext); + LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "foo", + "resolve-enum-leaf"); TypeDefinition leafType = leaf.getType(); Type result = provider.javaTypeForSchemaDefinitionType(leafType, leaf); assertNotNull(result); @@ -280,7 +282,7 @@ public class TypeProviderTest { @Test public void javaTypeForSchemaDefinitionLeafrefExtTypeTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final TypeProvider provider = new CodegenTypeProvider(this.schemaContext); LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "bar", "leafref-value"); TypeDefinition leafType = leaf.getType(); final Type leafrefResolvedType1 = provider.javaTypeForSchemaDefinitionType(leafType, leaf); @@ -302,7 +304,7 @@ public class TypeProviderTest { @Test public void javaTypeForSchemaDefinitionLeafrefToEnumTypeTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new CodegenTypeProvider(this.schemaContext); setReferencedTypeForTypeProvider(provider); @@ -331,14 +333,14 @@ public class TypeProviderTest { assertTrue(leafrefResolvedType2 instanceof ParameterizedType); } - private void setReferencedTypeForTypeProvider(final TypeProvider provider) { + private void setReferencedTypeForTypeProvider(final AbstractTypeProvider provider) { final LeafSchemaNode enumLeafNode = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "foo", "resolve-direct-use-of-enum"); final TypeDefinition enumLeafTypedef = enumLeafNode.getType(); Type enumType = provider.javaTypeForSchemaDefinitionType(enumLeafTypedef, enumLeafNode); Type refType = new ReferencedTypeImpl(enumType.getPackageName(), enumType.getName()); - ((TypeProviderImpl) provider).putReferencedType(enumLeafNode.getPath(), refType); + provider.putReferencedType(enumLeafNode.getPath(), refType); final LeafListSchemaNode enumListNode = provideLeafListNodeFromTopLevelContainer(this.testTypeProviderModule, "foo", "list-of-enums"); @@ -346,12 +348,12 @@ public class TypeProviderTest { enumType = provider.javaTypeForSchemaDefinitionType(enumLeafListTypedef, enumListNode); refType = new ReferencedTypeImpl(enumType.getPackageName(), enumType.getPackageName()); - ((TypeProviderImpl) provider).putReferencedType(enumListNode.getPath(), refType); + provider.putReferencedType(enumListNode.getPath(), refType); } @Test public void javaTypeForSchemaDefinitionConditionalLeafrefTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final TypeProvider provider = new CodegenTypeProvider(this.schemaContext); final Module module = resolveModule("test-type-provider-b"); final QName leafrefNode = QName.create(module.getQNameModule(), "conditional-leafref"); @@ -370,7 +372,7 @@ public class TypeProviderTest { @Test(expected = IllegalArgumentException.class) public void javaTypeForSchemaDefinitionInvalidLeafrefPathTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final TypeProvider provider = new CodegenTypeProvider(this.schemaContext); final Module module = resolveModule("test-type-provider-b"); final QName leafrefNode = QName.create(module.getQNameModule(), "unreslovable-leafref"); @@ -385,14 +387,14 @@ public class TypeProviderTest { @Test(expected = IllegalArgumentException.class) public void provideTypeForLeafrefWithNullLeafrefTypeTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); provider.provideTypeForLeafref(null, null); } @Test(expected = IllegalArgumentException.class) public void provideTypeForLeafrefWithNullLeafrefTypePathStatementTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final LeafrefTypeWithNullXpath leafrePath = new LeafrefTypeWithNullXpath(); provider.provideTypeForLeafref(leafrePath, this.schemaNode); @@ -400,8 +402,9 @@ public class TypeProviderTest { @Test(expected = IllegalStateException.class) public void provideTypeForLeafrefWithNullParentModuleTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); - final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "bar", "leafref-value"); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); + final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "bar", + "leafref-value"); final TypeDefinition leafType = leaf.getType(); assertTrue(leafType instanceof LeafrefTypeDefinition); doReturn(null).when(this.schemaNode).getPath(); @@ -410,7 +413,7 @@ public class TypeProviderTest { @Test public void javaTypeForSchemaDefinitionIdentityrefExtTypeTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final TypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "foo", "crypto"); final TypeDefinition leafType = leaf.getType(); @@ -421,7 +424,7 @@ public class TypeProviderTest { @Test public void javaTypeForSchemaDefinitionForExtUnionWithSimpleTypesTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final TypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "use-of-unions", "simple-int-types-union"); final TypeDefinition leafType = leaf.getType(); @@ -434,7 +437,7 @@ public class TypeProviderTest { @Test public void javaTypeForSchemaDefinitionForExtComplexUnionWithInnerUnionTypesTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final TypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "use-of-unions", "complex-union"); final TypeDefinition leafType = leaf.getType(); @@ -447,7 +450,7 @@ public class TypeProviderTest { @Test public void javaTypeForSchemaDefinitionForExtUnionWithInnerUnionAndSimpleTypeTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final TypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "use-of-unions", "complex-string-int-union"); final TypeDefinition leafType = leaf.getType(); @@ -460,7 +463,7 @@ public class TypeProviderTest { @Test public void provideGeneratedTOBuilderForUnionTypeDefWithInnerUnionTypesTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final Module testTypeProvider = resolveModule("test-type-provider"); final TypeDefinition unionTypeDef = resolveTypeDefinitionFromModule(testTypeProvider, "complex-union"); @@ -494,15 +497,17 @@ public class TypeProviderTest { @Test public void provideGeneratedTOBuilderForUnionTypeDefWithInnerUnionAndSimpleTypeTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final Module testTypeProvider = resolveModule("test-type-provider"); - final TypeDefinition unionTypeDef = resolveTypeDefinitionFromModule(testTypeProvider, "complex-string-int-union"); + final TypeDefinition unionTypeDef = resolveTypeDefinitionFromModule(testTypeProvider, + "complex-string-int-union"); assertNotNull(unionTypeDef); assertTrue(unionTypeDef.getBaseType() instanceof UnionTypeDefinition); - final GeneratedTOBuilder unionTypeBuilder = provider.provideGeneratedTOBuilderForUnionTypeDef("test.package.name", - (UnionTypeDefinition)unionTypeDef.getBaseType(), "ComplexStringIntUnionType", unionTypeDef); + final GeneratedTOBuilder unionTypeBuilder = provider.provideGeneratedTOBuilderForUnionTypeDef( + "test.package.name",(UnionTypeDefinition)unionTypeDef.getBaseType(), "ComplexStringIntUnionType", + unionTypeDef); assertNotNull(unionTypeBuilder); @@ -512,7 +517,7 @@ public class TypeProviderTest { @Test public void generatedTypeForExtendedDefinitionTypeTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new CodegenTypeProvider(this.schemaContext); final Module baseYangTypes = resolveModule("base-yang-types"); final Set> typeDefs = baseYangTypes.getTypeDefinitions(); @@ -603,23 +608,24 @@ public class TypeProviderTest { @Test(expected = IllegalArgumentException.class) public void generatedTypeForExtendedDefinitionTypeWithTypedefNullTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); provider.generatedTypeForExtendedDefinitionType(null, null); } @Test(expected = IllegalArgumentException.class) public void generatedTypeForExtendedDefinitionTypeWithTypedefQNameNullTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final TestIntegerTypeDefinition testInt = new TestIntegerTypeDefinition(); provider.generatedTypeForExtendedDefinitionType(testInt, testInt); } @Test public void generatedTypeForExtendedDefinitionTypeWithInnerExtendedTypeTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final Module baseYangTypes = resolveModule("test-type-provider"); - final TypeDefinition extYangInt8Typedef = resolveTypeDefinitionFromModule(baseYangTypes, "extended-yang-int8"); + final TypeDefinition extYangInt8Typedef = resolveTypeDefinitionFromModule(baseYangTypes, + "extended-yang-int8"); assertNotNull(extYangInt8Typedef); final Type extType = provider.generatedTypeForExtendedDefinitionType(extYangInt8Typedef, extYangInt8Typedef); assertNotNull(extType); @@ -628,7 +634,7 @@ public class TypeProviderTest { @Test public void generatedTypeForExtendedDefinitionTypeWithLeafrefBaseTypeTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final Module baseYangTypes = resolveModule("test-type-provider"); final TypeDefinition barItemLeafrefId = resolveTypeDefinitionFromModule(baseYangTypes, "bar-item-leafref-id"); @@ -639,7 +645,7 @@ public class TypeProviderTest { @Test public void generatedTypeForExtendedDefinitionTypeWithIdentityrefBaseTypeTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final Module baseYangTypes = resolveModule("test-type-provider"); @@ -652,13 +658,13 @@ public class TypeProviderTest { @Test(expected = IllegalArgumentException.class) public void provideGeneratedTOBuilderForBitsTypeDefinitionWithNullTypedefTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); provider.provideGeneratedTOBuilderForBitsTypeDefinition("", null, "", ""); } @Test(expected = IllegalArgumentException.class) public void provideGeneratedTOBuilderForBitsTypeDefinitionWithBasePackageNullTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "foo", "yang-int8-type"); final TypeDefinition leafType = leaf.getType(); provider.provideGeneratedTOBuilderForBitsTypeDefinition(null, leafType, "", ""); @@ -666,7 +672,7 @@ public class TypeProviderTest { @Test public void provideGeneratedTOBuilderForBitsTypeDefinitionWithNonBitsTypedefTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "foo", "yang-int8-type"); final TypeDefinition leafType = leaf.getType(); @@ -677,7 +683,7 @@ public class TypeProviderTest { @Test public void getConstructorPropertyNameTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final TypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "foo", "yang-int8-type"); final TypeDefinition leafType = leaf.getType(); @@ -691,7 +697,7 @@ public class TypeProviderTest { @Test public void getParamNameFromTypeTest() { - final TypeProvider provider = new TypeProviderImpl(this.schemaContext); + final TypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final LeafSchemaNode leaf = provideLeafNodeFromTopLevelContainer(this.testTypeProviderModule, "foo", "yang-int8-type"); final TypeDefinition leafType = leaf.getType(); @@ -702,19 +708,17 @@ public class TypeProviderTest { @Test public void addUnitsToGenTOTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); - final GeneratedTOBuilder builder = new GeneratedTOBuilderImpl("test.package", "TestBuilder"); - TypeProviderImpl.addUnitsToGenTO(builder, null); + CodegenTypeProvider.addUnitsToGenTO(builder, null); GeneratedTransferObject genTO = builder.toInstance(); assertTrue(genTO.getConstantDefinitions().isEmpty()); - TypeProviderImpl.addUnitsToGenTO(builder, ""); + CodegenTypeProvider.addUnitsToGenTO(builder, ""); genTO = builder.toInstance(); assertTrue(genTO.getConstantDefinitions().isEmpty()); - TypeProviderImpl.addUnitsToGenTO(builder, "125"); + CodegenTypeProvider.addUnitsToGenTO(builder, "125"); genTO = builder.toInstance(); assertTrue(!genTO.getConstantDefinitions().isEmpty()); assertEquals(1, genTO.getConstantDefinitions().size()); @@ -724,14 +728,14 @@ public class TypeProviderTest { @Test(expected = NullPointerException.class) public void getTypeDefaultConstructionLeafTypeNullTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final TestLeafSchemaNode leafSchemaNode = new TestLeafSchemaNode(); provider.getTypeDefaultConstruction(leafSchemaNode, null); } @Test(expected = NullPointerException.class) public void getTypeDefaultConstructionDefaultValueNullTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final LeafSchemaNode leaf = provideLeafForGetDefaultConstructionTestCase("yang-boolean"); provider.getTypeDefaultConstruction(leaf, null); } @@ -743,21 +747,21 @@ public class TypeProviderTest { @Test(expected = UnsupportedOperationException.class) public void getTypeDefaultConstructionDefaultValueForInstanceIdentifierTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final LeafSchemaNode leaf = provideLeafForGetDefaultConstructionTestCase("foo-container-id"); provider.getTypeDefaultConstruction(leaf, "NAN"); } @Test(expected = UnsupportedOperationException.class) public void getTypeDefaultConstructionDefaultValueForIdentityrefTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); final LeafSchemaNode leaf = provideLeafForGetDefaultConstructionTestCase("aes-identityref-type"); provider.getTypeDefaultConstruction(leaf, "NAN"); } @Test public void getTypeDefaultConstructionDefaultValueTest() { - final TypeProviderImpl provider = new TypeProviderImpl(this.schemaContext); + final AbstractTypeProvider provider = new RuntimeTypeProvider(this.schemaContext); LeafSchemaNode leaf = provideLeafForGetDefaultConstructionTestCase("yang-boolean"); String result = provider.getTypeDefaultConstruction(leaf, "true"); -- 2.36.6