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