7d65c96043488a822b114c200b1a04ce0a9b5474
[yangtools.git] / yang / yang-model-util / src / main / java / org / opendaylight / yangtools / yang / model / util / Decimal64.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. 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;
9
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.collect.ImmutableList;
13 import com.google.common.collect.ImmutableList.Builder;
14 import java.math.BigDecimal;
15 import java.util.Collections;
16 import java.util.List;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
19 import org.opendaylight.yangtools.yang.model.api.Status;
20 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
21 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
22 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
23
24 /**
25  * The <code>default</code> implementation of Decimal Type Definition interface.
26  *
27  * @see DecimalTypeDefinition
28  */
29 public final class Decimal64 implements DecimalTypeDefinition {
30     private static final String DESCRIPTION = "The decimal64 type represents a subset of the real numbers, which can "
31             + "be represented by decimal numerals. The value space of decimal64 is the set of numbers that can "
32             + "be obtained by multiplying a 64-bit signed integer by a negative power of ten, i.e., expressible as "
33             + "'i x 10^-n' where i is an integer64 and n is an integer between 1 and 18, inclusively.";
34     private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.3";
35     private static final List<List<RangeConstraint>> IMPLICIT_RANGE_STATEMENTS;
36     static {
37         final Builder<List<RangeConstraint>> b = ImmutableList.builder();
38         b.add(createRangeConstraint("-922337203685477580.8", "922337203685477580.7"));
39         b.add(createRangeConstraint("-92233720368547758.08", "92233720368547758.07"));
40         b.add(createRangeConstraint("-9223372036854775.808", "9223372036854775.807"));
41         b.add(createRangeConstraint("-922337203685477.5808", "922337203685477.5807"));
42         b.add(createRangeConstraint("-92233720368547.75808", "92233720368547.75807"));
43         b.add(createRangeConstraint("-9223372036854.775808", "9223372036854.775807"));
44         b.add(createRangeConstraint("-922337203685.4775808", "922337203685.4775807"));
45         b.add(createRangeConstraint("-92233720368.54775808", "92233720368.54775807"));
46         b.add(createRangeConstraint("-9223372036.854775808", "9223372036.854775807"));
47         b.add(createRangeConstraint("-922337203.6854775808", "922337203.6854775807"));
48         b.add(createRangeConstraint("-9223372.036854775808", "92233720.36854775807"));
49         b.add(createRangeConstraint("-922337.2036854775808", "9223372.036854775807"));
50         b.add(createRangeConstraint("-92233.72036854775808", "922337.2036854775807"));
51         b.add(createRangeConstraint("-9223.372036854775808", "9223.372036854775807"));
52         b.add(createRangeConstraint("-922.3372036854775808", "922.3372036854775807"));
53         b.add(createRangeConstraint("-92.23372036854775808", "92.23372036854775807"));
54         b.add(createRangeConstraint("-9.223372036854775808", "9.223372036854775807"));
55         IMPLICIT_RANGE_STATEMENTS = b.build();
56     }
57
58     private static List<RangeConstraint> createRangeConstraint(final String min, final String max) {
59         final String description = "Decimal values between " + min + " and " + max +", inclusively";
60
61         return ImmutableList.of(BaseConstraints.newRangeConstraint(new BigDecimal(min), new BigDecimal(max),
62             Optional.of(description), Optional.of("https://tools.ietf.org/html/rfc6020#section-9.3.4")));
63     }
64
65     private final List<RangeConstraint> rangeStatements;
66     private final int fractionDigits;
67     private final SchemaPath path;
68
69     /**
70      * Default Decimal64 Type Constructor. <br>
71      * <br>
72      * The initial range statements are set to implicit ranges for Decimal64 implied by the number of fraction
73      * digits. Fraction digits MUST be defined as integer between 1 and 18 inclusively as defined interface
74      * {@link DecimalTypeDefinition}<br>
75      * If the fraction digits are not defined inner the definition boundaries
76      * the constructor will throw {@link IllegalArgumentException}
77      *
78      * @param path
79      * @param fractionDigits integer between 1 and 18 inclusively
80      * @throws IllegalArgumentException
81      *
82      * @see DecimalTypeDefinition
83      */
84     private Decimal64(final SchemaPath path, final int fractionDigits) {
85         Preconditions.checkArgument(fractionDigits >= 1 && fractionDigits <= 18,
86                 "The number of fraction digits %s is outside of allowed range [1, 18]", fractionDigits);
87
88         this.path = Preconditions.checkNotNull(path);
89         this.fractionDigits = fractionDigits;
90         this.rangeStatements = IMPLICIT_RANGE_STATEMENTS.get(fractionDigits - 1);
91     }
92
93     public static Decimal64 create(final SchemaPath path, final Integer fractionDigits) {
94         return new Decimal64(path, fractionDigits);
95     }
96
97     @Override
98     public DecimalTypeDefinition getBaseType() {
99         return null;
100     }
101
102     @Override
103     public String getUnits() {
104         return "";
105     }
106
107     @Override
108     public Object getDefaultValue() {
109         return null;
110     }
111
112     @Override
113     public QName getQName() {
114         return BaseTypes.DECIMAL64_QNAME;
115     }
116
117     @Override
118     public SchemaPath getPath() {
119         return path;
120     }
121
122     @Override
123     public String getDescription() {
124         return DESCRIPTION;
125     }
126
127     @Override
128     public String getReference() {
129         return REFERENCE;
130     }
131
132     @Override
133     public Status getStatus() {
134         return Status.CURRENT;
135     }
136
137     @Override
138     public List<UnknownSchemaNode> getUnknownSchemaNodes() {
139         return Collections.emptyList();
140     }
141
142     @Override
143     public List<RangeConstraint> getRangeConstraints() {
144         return rangeStatements;
145     }
146
147     @Override
148     public Integer getFractionDigits() {
149         return fractionDigits;
150     }
151
152     @Override
153     public int hashCode() {
154         final int prime = 31;
155         int result = 1;
156         result = prime * result + BaseTypes.DECIMAL64_QNAME.hashCode();
157         result = prime * result + path.hashCode();
158         return result;
159     }
160
161     @Override
162     public boolean equals(final Object obj) {
163         if (this == obj) {
164             return true;
165         }
166         if (obj == null) {
167             return false;
168         }
169         if (getClass() != obj.getClass()) {
170             return false;
171         }
172         Decimal64 other = (Decimal64) obj;
173         return path.equals(other.path);
174     }
175
176     @Override
177     public String toString() {
178         return Decimal64.class.getSimpleName() + "[qname=" + BaseTypes.DECIMAL64_QNAME + ", fractionDigits="
179                 + fractionDigits + "]";
180     }
181 }