+ List<TypeDefinition<?>> resolvedTypes = new ArrayList<TypeDefinition<?>>();
+ List<TypeDefinition<?>> typesToRemove = new ArrayList<TypeDefinition<?>>();
+
+ for (TypeDefinition<?> td : unionTypeBuilderToResolve.getTypes()) {
+ if (td instanceof UnknownType) {
+ TypeDefinition<?> resolvedType = findTargetType(
+ (UnknownType) td, modules, builder);
+ resolvedTypes.add(resolvedType);
+ typesToRemove.add(td);
+ }
+ }
+
+ List<TypeDefinition<?>> unionTypeBuilderTypes = unionTypeBuilderToResolve
+ .getTypes();
+ unionTypeBuilderTypes.addAll(resolvedTypes);
+ unionTypeBuilderTypes.removeAll(typesToRemove);
+
+ return unionTypeBuilderToResolve;
+ }
+
+ private TypeDefinition<?> findTargetType(UnknownType ut,
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ ModuleBuilder builder) {
+
+ Map<TypeDefinitionBuilder, TypeConstraints> foundedTypeDefinitionBuilder = findTypeDefinitionBuilderWithConstraints(
+ modules, ut, builder);
+ TypeDefinitionBuilder targetType = foundedTypeDefinitionBuilder
+ .entrySet().iterator().next().getKey();
+ TypeConstraints constraints = foundedTypeDefinitionBuilder.entrySet()
+ .iterator().next().getValue();
+
+ TypeDefinition<?> targetTypeBaseType = targetType.getBaseType();
+ String targetTypeBaseTypeName = targetTypeBaseType.getQName()
+ .getLocalName();
+
+ // RANGE
+ List<RangeConstraint> ranges = ut.getRangeStatements();
+ resolveRanges(ranges, targetType, modules, builder);
+
+ // LENGTH
+ List<LengthConstraint> lengths = ut.getLengthStatements();
+ resolveLengths(lengths, targetType, modules, builder);
+
+ // PATTERN
+ List<PatternConstraint> patterns = ut.getPatterns();
+
+ // Fraction Digits
+ Integer fractionDigits = ut.getFractionDigits();
+
+ // MERGE CONSTRAINTS (enumeration and leafref omitted
+ // because
+ // they have no restrictions)
+ if (targetTypeBaseType instanceof DecimalTypeDefinition) {
+ List<RangeConstraint> fullRanges = new ArrayList<RangeConstraint>();
+ fullRanges.addAll(constraints.getRanges());
+ fullRanges.addAll(ranges);
+ Integer fd = fractionDigits == null ? constraints
+ .getFractionDigits() : fractionDigits;
+ targetTypeBaseType = YangTypesConverter
+ .javaTypeForBaseYangDecimal64Type(fullRanges, fd);
+ } else if (targetTypeBaseType instanceof IntegerTypeDefinition) {
+ List<RangeConstraint> fullRanges = new ArrayList<RangeConstraint>();
+ fullRanges.addAll(constraints.getRanges());
+ fullRanges.addAll(ranges);
+ if (targetTypeBaseTypeName.startsWith("int")) {
+ targetTypeBaseType = YangTypesConverter
+ .javaTypeForBaseYangSignedIntegerType(
+ targetTypeBaseTypeName, fullRanges);
+ } else {
+ targetTypeBaseType = YangTypesConverter
+ .javaTypeForBaseYangUnsignedIntegerType(
+ targetTypeBaseTypeName, fullRanges);
+ }
+ } else if (targetTypeBaseType instanceof StringTypeDefinition) {
+ List<LengthConstraint> fullLengths = new ArrayList<LengthConstraint>();
+ fullLengths.addAll(constraints.getLengths());
+ fullLengths.addAll(lengths);
+ List<PatternConstraint> fullPatterns = new ArrayList<PatternConstraint>();
+ fullPatterns.addAll(constraints.getPatterns());
+ fullPatterns.addAll(patterns);
+ targetTypeBaseType = new StringType(fullLengths, fullPatterns);
+ } else if (targetTypeBaseType instanceof BitsTypeDefinition) {
+ BitsTypeDefinition bitsType = (BitsTypeDefinition) targetTypeBaseType;
+ List<Bit> bits = bitsType.getBits();
+ targetTypeBaseType = new BitsType(bits);
+ } else if (targetTypeBaseType instanceof BinaryTypeDefinition) {
+ targetTypeBaseType = new BinaryType(null, lengths, null);
+ } else if (targetTypeBaseTypeName.equals("instance-identifier")) {
+ // TODO: instance-identifier
+ /*
+ * boolean requireInstance = isRequireInstance(typeBody); type = new
+ * InstanceIdentifier(null, requireInstance);
+ */
+ }
+
+ return targetTypeBaseType;
+ }
+
+ private TypeDefinitionBuilder findTypeDefinitionBuilder(
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ UnknownType unknownType, ModuleBuilder builder) {
+ Map<TypeDefinitionBuilder, TypeConstraints> result = findTypeDefinitionBuilderWithConstraints(
+ modules, unknownType, builder);
+ return result.entrySet().iterator().next().getKey();
+ }
+
+ private Map<TypeDefinitionBuilder, TypeConstraints> findTypeDefinitionBuilderWithConstraints(
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ UnknownType unknownType, ModuleBuilder builder) {
+ return findTypeDefinitionBuilderWithConstraints(new TypeConstraints(),
+ modules, unknownType, builder);
+ }
+
+ /**
+ * Traverse through all referenced types chain until base YANG type is
+ * founded.
+ *
+ * @param constraints current type constraints
+ * @param modules all available modules
+ * @param unknownType unknown type
+ * @param builder current module
+ * @return map, where key is type referenced and value is its constraints
+ */
+ private Map<TypeDefinitionBuilder, TypeConstraints> findTypeDefinitionBuilderWithConstraints(
+ TypeConstraints constraints,
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ UnknownType unknownType, ModuleBuilder builder) {
+ Map<TypeDefinitionBuilder, TypeConstraints> result = new HashMap<TypeDefinitionBuilder, TypeConstraints>();
+
+ // TypeDefinition<?> unknownType = typeBuilder.getType();
+ QName unknownTypeQName = unknownType.getQName();
+ String unknownTypeName = unknownTypeQName.getLocalName();
+ String unknownTypePrefix = unknownTypeQName.getPrefix();
+
+ // search for module which contains referenced typedef