Enable checkstyle in yang-model-util
[yangtools.git] / yang / yang-model-util / src / main / java / org / opendaylight / yangtools / yang / model / util / type / RestrictedTypes.java
1 /*
2  * Copyright (c) 2015 Pantheon Technologies s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.model.util.type;
9
10 import static com.google.common.base.Preconditions.checkNotNull;
11
12 import com.google.common.annotations.Beta;
13 import java.util.List;
14 import javax.annotation.Nonnull;
15 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
16 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
17 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
18 import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
19 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
20 import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
21 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
22 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
23 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
24 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
25 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
26 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
27 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
28 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
29 import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
30
31 /**
32  * Restricted types are a refinement of the restrictions applied to a particular type. YANG defines restrictions only
33  * on a subset of the base types, but conceptually any such definition can hold unknown nodes.
34  *
35  * <p>
36  * 1) Restrictable
37  *    binary (length)
38  *    int{8,16,32,64} (range)
39  *    string (length, patterns)
40  *    uint{8,16,32,64} (range)
41  *    decimal64 (range)
42  *    instance-identifier (require-instance)
43  *
44  * <p>
45  * 2) Non-restrictable
46  *    boolean
47  *    bits
48  *    empty (ignores default on derivation)
49  *    enumeration
50  *    identityref
51  *    leafref
52  *    union
53  *
54  * <p>
55  * This class holds methods which allow creation of restricted types using {@link TypeBuilder} and its subclasses. Each
56  * restricted type is logically anchored at a {@link SchemaPath}, but can be substituted by its base type if it does
57  * not contribute any additional restrictions. TypeBuilder instances take this into account, and result in the base type
58  * being returned from the builder when the base type and restricted type are semantically equal.
59  *
60  * <p>
61  * Restricted types inherit the default value, description, reference, status and units from the base type, if that type
62  * defines them.
63  */
64 @Beta
65 public final class RestrictedTypes {
66     private RestrictedTypes() {
67         throw new UnsupportedOperationException();
68     }
69
70     public static LengthRestrictedTypeBuilder<BinaryTypeDefinition> newBinaryBuilder(
71             @Nonnull final BinaryTypeDefinition baseType, @Nonnull final SchemaPath path) {
72         return new LengthRestrictedTypeBuilder<BinaryTypeDefinition>(baseType, path) {
73             @Override
74             BinaryTypeDefinition buildType(final List<LengthConstraint> lengthConstraints) {
75                 return new RestrictedBinaryType(getBaseType(), getPath(), getUnknownSchemaNodes(), lengthConstraints);
76             }
77
78             @Override
79             List<LengthConstraint> typeLengthConstraints() {
80                 /**
81                  * Length constraint imposed on YANG binary type by our implementation. byte[].length is an integer,
82                  * capping our ability to support arbitrary binary data.
83                  */
84                 return JavaLengthConstraints.INTEGER_SIZE_CONSTRAINTS;
85             }
86
87             @Override
88             List<LengthConstraint> getLengthConstraints(final BinaryTypeDefinition type) {
89                 return type.getLengthConstraints();
90             }
91         };
92     }
93
94     public static BitsTypeBuilder newBitsBuilder(final BitsTypeDefinition baseType, final SchemaPath path) {
95         return new BitsTypeBuilder(baseType, path);
96     }
97
98     public static TypeBuilder<BooleanTypeDefinition> newBooleanBuilder(@Nonnull final BooleanTypeDefinition baseType,
99             @Nonnull final SchemaPath path) {
100         return new AbstractRestrictedTypeBuilder<BooleanTypeDefinition>(baseType, path) {
101             @Override
102             BooleanTypeDefinition buildType() {
103                 return new RestrictedBooleanType(getBaseType(), getPath(), getUnknownSchemaNodes());
104             }
105         };
106     }
107
108     public static RangeRestrictedTypeBuilder<DecimalTypeDefinition> newDecima64Builder(
109             final DecimalTypeDefinition baseType, final SchemaPath path) {
110         return new RangeRestrictedTypeBuilder<DecimalTypeDefinition>(checkNotNull(baseType), path) {
111             @Override
112             DecimalTypeDefinition buildType() {
113                 return new RestrictedDecimalType(getBaseType(), getPath(), getUnknownSchemaNodes(),
114                     calculateRangeConstraints(getBaseType().getRangeConstraints()));
115             }
116         };
117     }
118
119     public static TypeBuilder<EmptyTypeDefinition> newEmptyBuilder(final EmptyTypeDefinition baseType,
120             final SchemaPath path) {
121         return new AbstractRestrictedTypeBuilder<EmptyTypeDefinition>(baseType, path) {
122             @Override
123             EmptyTypeDefinition buildType() {
124                 return new RestrictedEmptyType(getBaseType(), getPath(), getUnknownSchemaNodes());
125             }
126         };
127     }
128
129     public static EnumerationTypeBuilder newEnumerationBuilder(final EnumTypeDefinition baseType,
130             final SchemaPath path) {
131         return new EnumerationTypeBuilder(baseType, path);
132     }
133
134     public static TypeBuilder<IdentityrefTypeDefinition> newIdentityrefBuilder(final IdentityrefTypeDefinition baseType,
135             final SchemaPath path) {
136         return new AbstractRestrictedTypeBuilder<IdentityrefTypeDefinition>(baseType, path) {
137             @Override
138             IdentityrefTypeDefinition buildType() {
139                 return new RestrictedIdentityrefType(getBaseType(), getPath(), getUnknownSchemaNodes());
140             }
141         };
142     }
143
144     public static InstanceIdentifierTypeBuilder newInstanceIdentifierBuilder(
145             final InstanceIdentifierTypeDefinition baseType, final SchemaPath path) {
146         return new InstanceIdentifierTypeBuilder(baseType, path);
147     }
148
149     public static RequireInstanceRestrictedTypeBuilder<LeafrefTypeDefinition> newLeafrefBuilder(
150             final LeafrefTypeDefinition baseType, final SchemaPath path) {
151         return new RequireInstanceRestrictedTypeBuilder<LeafrefTypeDefinition>(baseType, path) {
152             @Override
153             LeafrefTypeDefinition buildType() {
154                 if (getRequireInstance() == getBaseType().requireInstance()) {
155                     return getBaseType();
156                 }
157                 return new RestrictedLeafrefType(getBaseType(), getPath(), getUnknownSchemaNodes(),
158                         getRequireInstance());
159             }
160         };
161     }
162
163     public static RangeRestrictedTypeBuilder<IntegerTypeDefinition> newIntegerBuilder(
164             final IntegerTypeDefinition baseType, final SchemaPath path) {
165         return new RangeRestrictedTypeBuilder<IntegerTypeDefinition>(checkNotNull(baseType), path) {
166             @Override
167             IntegerTypeDefinition buildType() {
168                 return new RestrictedIntegerType(getBaseType(), getPath(), getUnknownSchemaNodes(),
169                     calculateRangeConstraints(getBaseType().getRangeConstraints()));
170             }
171         };
172     }
173
174     public static StringTypeBuilder newStringBuilder(final StringTypeDefinition baseType, final SchemaPath path) {
175         return new StringTypeBuilder(baseType, path);
176     }
177
178     public static TypeBuilder<UnionTypeDefinition> newUnionBuilder(final UnionTypeDefinition baseType,
179             final SchemaPath path) {
180         return new AbstractRestrictedTypeBuilder<UnionTypeDefinition>(baseType, path) {
181             @Override
182             UnionTypeDefinition buildType() {
183                 return new RestrictedUnionType(getBaseType(), getPath(), getUnknownSchemaNodes());
184             }
185         };
186     }
187
188     public static RangeRestrictedTypeBuilder<UnsignedIntegerTypeDefinition> newUnsignedBuilder(
189             final UnsignedIntegerTypeDefinition baseType, final SchemaPath path) {
190         return new RangeRestrictedTypeBuilder<UnsignedIntegerTypeDefinition>(checkNotNull(baseType), path) {
191             @Override
192             UnsignedIntegerTypeDefinition buildType() {
193                 return new RestrictedUnsignedType(getBaseType(), getPath(), getUnknownSchemaNodes(),
194                     calculateRangeConstraints(getBaseType().getRangeConstraints()));
195             }
196         };
197     }
198 }