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