2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.model.util.type;
10 import com.google.common.base.Preconditions;
11 import java.util.List;
12 import java.util.Optional;
13 import javax.annotation.Nonnull;
14 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
15 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
16 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
17 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
18 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
19 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
20 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
21 import org.opendaylight.yangtools.yang.model.api.type.LengthRestrictedTypeDefinition;
22 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
23 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
24 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
27 * Compatibility utilities for dealing with differences between the old parser's ExtendedType-driven type
28 * representation versus the representation this package models.
30 * @deprecated This class is provided strictly for compatibility only. No new users should be introduced, as this class
31 * is scheduled for removal when its two OpenDaylight users, Java Binding v1 and YANG JMX Bindings are
35 public final class CompatUtils {
36 private CompatUtils() {
37 throw new UnsupportedOperationException();
41 * This package's type hierarchy model generates a type which encapsulates the default value and units for leaves.
42 * Java Binding specification is implemented in a way, where it needs to revert this process if the internal
43 * declaration has not restricted the type further -- which is not something available via
44 * {@link TypeDefinition#getBaseType()}.
47 * Here are the possible scenarios:
56 * The leaf type's schema path does not match the schema path of the leaf. We do NOT want to strip it, as
57 * we need to generate an inner class to hold the restrictions.
67 * The leaf type's schema path will match the schema path of the leaf. We do NOT want to strip it, as we need
68 * to generate an inner class to hold the restrictions.
76 * The leaf type's schema path will match the schema path of the leaf. We DO want to strip it, as we will deal
77 * with the default value ourselves.
84 * The leaf type's schema path will not match the schema path of the leaf. We do NOT want to strip it.
87 * The situation is different for types which do not have a default instantiation in YANG: leafref, enumeration,
88 * identityref, decimal64, bits and union. If these types are defined within this leaf's statement, a base type
89 * will be instantiated. If the leaf defines a default statement, this base type will be visible via getBaseType().
98 * The leaf type's schema path will not match the schema path of the leaf, and we do not want to strip it, as it
99 * needs to be generated.
109 * The leaf type's schema path will match the schema path of the leaf, and we DO want to strip it.
111 * @param leaf Leaf for which we are acquiring the type
112 * @return Potentially base type of the leaf type.
114 @Nonnull public static TypeDefinition<?> compatLeafType(@Nonnull final LeafSchemaNode leaf) {
115 final TypeDefinition<?> leafType = leaf.getType();
116 Preconditions.checkNotNull(leafType);
118 if (!leaf.getPath().equals(leafType.getPath())) {
119 // Old parser semantics, or no new default/units defined for this leaf
123 // We are dealing with a type generated for the leaf itself
124 final TypeDefinition<?> baseType = leafType.getBaseType();
125 Preconditions.checkArgument(baseType != null, "Leaf %s has type for leaf, but no base type", leaf);
127 if (leaf.getPath().equals(baseType.getPath().getParent())) {
128 // Internal instantiation of a base YANG type (decimal64 and similar)
132 // At this point we have dealt with the easy cases. Now we need to perform per-type checking if there are no
133 // new constraints introduced by this type. If there were not, we will return the base type.
134 if (leafType instanceof BinaryTypeDefinition) {
135 return baseTypeIfNotConstrained((BinaryTypeDefinition) leafType);
136 } else if (leafType instanceof DecimalTypeDefinition) {
137 return baseTypeIfNotConstrained((DecimalTypeDefinition) leafType);
138 } else if (leafType instanceof InstanceIdentifierTypeDefinition) {
139 return baseTypeIfNotConstrained((InstanceIdentifierTypeDefinition) leafType);
140 } else if (leafType instanceof IntegerTypeDefinition) {
141 return baseTypeIfNotConstrained((IntegerTypeDefinition) leafType);
142 } else if (leafType instanceof StringTypeDefinition) {
143 return baseTypeIfNotConstrained((StringTypeDefinition) leafType);
144 } else if (leafType instanceof UnsignedIntegerTypeDefinition) {
145 return baseTypeIfNotConstrained((UnsignedIntegerTypeDefinition) leafType);
147 // Other types cannot be constrained, return the base type
152 private static BinaryTypeDefinition baseTypeIfNotConstrained(final BinaryTypeDefinition type) {
153 return baseTypeIfNotConstrained(type, type.getBaseType());
156 private static TypeDefinition<?> baseTypeIfNotConstrained(final DecimalTypeDefinition type) {
157 final DecimalTypeDefinition base = type.getBaseType();
158 return baseTypeIfNotConstrained(type, type.getRangeConstraints(), base, base.getRangeConstraints());
161 private static TypeDefinition<?> baseTypeIfNotConstrained(final InstanceIdentifierTypeDefinition type) {
162 final InstanceIdentifierTypeDefinition base = type.getBaseType();
163 return type.requireInstance() == base.requireInstance() ? base : type;
166 private static TypeDefinition<?> baseTypeIfNotConstrained(final IntegerTypeDefinition type) {
167 final IntegerTypeDefinition base = type.getBaseType();
168 return baseTypeIfNotConstrained(type, type.getRangeConstraints(), base, base.getRangeConstraints());
171 private static TypeDefinition<?> baseTypeIfNotConstrained(final StringTypeDefinition type) {
172 final StringTypeDefinition base = type.getBaseType();
173 final List<PatternConstraint> patterns = type.getPatternConstraints();
174 final Optional<LengthConstraint> optLengths = type.getLengthConstraint();
176 if ((patterns.isEmpty() || patterns.equals(base.getPatternConstraints()))
177 && (!optLengths.isPresent() || optLengths.equals(base.getLengthConstraint()))) {
184 private static TypeDefinition<?> baseTypeIfNotConstrained(final UnsignedIntegerTypeDefinition type) {
185 final UnsignedIntegerTypeDefinition base = type.getBaseType();
186 return baseTypeIfNotConstrained(type, type.getRangeConstraints(), base, base.getRangeConstraints());
189 private static TypeDefinition<?> baseTypeIfNotConstrained(final TypeDefinition<?> type,
190 final List<?> typeConstraints, final TypeDefinition<?> base, final List<?> baseConstraints) {
191 return typeConstraints.isEmpty() || typeConstraints.equals(baseConstraints) ? base : type;
194 private static <T extends LengthRestrictedTypeDefinition<T>> T baseTypeIfNotConstrained(final T type,
196 final Optional<LengthConstraint> optConstraint = type.getLengthConstraint();
197 if (!optConstraint.isPresent()) {
200 return optConstraint.equals(base.getLengthConstraint()) ? base : type;