Skip to content

Commit c43ea2e

Browse files
authored
Merge pull request #3623 from apache/4036-val.digit.constraints
CAUSEWAY-4036: Consistent Decimal Digit constraining API
2 parents 4d00401 + 9902bc1 commit c43ea2e

41 files changed

Lines changed: 1160 additions & 1115 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

api/applib/src/main/java/org/apache/causeway/applib/annotation/ValueSemantics.java

Lines changed: 79 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.lang.annotation.RetentionPolicy;
2525
import java.lang.annotation.Target;
2626
import java.math.BigDecimal;
27+
import java.math.BigInteger;
2728
import java.time.format.FormatStyle;
2829
import java.util.Locale;
2930

@@ -64,42 +65,96 @@
6465
String provider()
6566
default "";
6667

67-
// -- NUMBER CONSTRAINTS
68+
// -- DIGIT CONSTRAINTS
6869

6970
/**
70-
* If associated with a {@link Number}, the maximum number of total digits accepted for
71-
* this number.<br>
72-
* Can be omitted, if {@link Column#precision()} is used.<br>
73-
* default = {@code 65}
71+
* If associated with {@link BigDecimal}, {@link BigInteger},
72+
* or any Java integer type (long, int, short, byte),
73+
* the maximum number of total digits accepted for input (editing).
74+
*
75+
* <p> But input is not constrained for double/float, since those
76+
* types have fixed intrinsic precision and their bit representation does not
77+
* directly correspond to decimal digits. Further more, double/float may support
78+
* scientific notation for input (as well as display), where the notion of 'total digits' is
79+
* no longer viable.
80+
*
81+
* <p> When {@link Column#precision()} {@code >0} is used,
82+
* while {@link ValueSemantics#maxTotalDigits()} is not used (<=0),
83+
* then {@link Column#precision()} is undersood as an alias for this annotation attribute.
84+
*
85+
* <p> default = {@code 0} understood as unlimited
86+
*
7487
* @apiNote SQL's DECIMAL(precision, scale) has max-precision=65 and max-scale=30
7588
* @see Column#precision()
7689
*/
7790
int maxTotalDigits()
78-
default 65;
91+
default 0;
92+
93+
/**
94+
* If associated with any Java number type {@link BigDecimal}, {@link BigInteger},
95+
* long, int, short, byte, double or float,
96+
* the maximum number of integer digits required for
97+
* input (editing).
98+
*
99+
* <p> For double/float specifically, requires their decimal representation, to satisfy this requirement.
100+
* Those types may support scientific notation for input (as well as display), where the notion of 'integer digits'
101+
* is still viable.
102+
*
103+
* <p> {@link Digits#integer()} can be used as a replacement. If both are used, the stronger constraint applies.
104+
*
105+
* <p> default = {@code 0} understood as unlimited
106+
*
107+
* @see Digits#integer()
108+
*/
109+
int maxIntegerDigits()
110+
default 0;
79111

80112
/**
81-
* If associated with a {@link Number}, the minimum number of integer digits required for
82-
* this number.<br>
83-
* default = {@code 1}
113+
* If associated with any Java number type {@link BigDecimal}, {@link BigInteger},
114+
* long, int, short, byte, double or float,
115+
* the minimum number of integer digits required for
116+
* input (editing).
117+
*
118+
* <p> For double/float specifically, requires their decimal representation, to satisfy this requirement.
119+
* Those types may support scientific notation for input (as well as display), where the notion of 'integer digits'
120+
* is still viable.
121+
*
122+
* <p> default = {@code 1}
84123
*/
85124
int minIntegerDigits()
86125
default 1;
87126

88127
/**
89-
* If associated with a {@link BigDecimal}, the maximum number of fractional digits accepted
90-
* for this number.<br>
91-
* Can be omitted, if {@link Column#scale()} is used.<br>
92-
* default = {@code 30}
128+
* If associated with any non-integer {@link Number} type,
129+
* the maximum number of fractional decimal digits displayed.
130+
*
131+
* <p> If associated with a {@link BigDecimal} specifically,
132+
* also governs the maximum number of fractional digits accepted for input (editing).
133+
*
134+
* <p> But input is not constrained for double/float, since those
135+
* types have fixed intrinsic precision and their bit representation does not
136+
* directly correspond to decimal digits.
137+
*
138+
* <p> {@link Digits#fraction()} can be used as a replacement. If both are used, the stronger constraint applies.
139+
*
140+
* <p> When {@link Column#scale()} {@code >0} is used on a {@link BigDecimal},
141+
* while {@link ValueSemantics#maxFractionalDigits()} is not used (<0),
142+
* then {@link Column#scale()} is undersood as an alias for this annotation attribute.
143+
*
144+
* <p> default = {@code -1} understood as unlimited
145+
*
93146
* @apiNote SQL's DECIMAL(precision, scale) has max-precision=65 and max-scale=30
147+
* @see Digits#fraction()
94148
* @see Column#scale()
95149
*/
96150
int maxFractionalDigits()
97-
default 30;
151+
default -1;
98152

99153
/**
100-
* If associated with a {@link BigDecimal}, the minimum number of fractional digits
101-
* required for this number.<br>
102-
* default = {@code 0}
154+
* If associated with any non-integer {@link Number} type,
155+
* the minimum number of fractional digits displayed.
156+
*
157+
* <p> default = {@code 0}
103158
*/
104159
int minFractionalDigits()
105160
default 0;
@@ -133,8 +188,10 @@ TimePrecision timePrecision()
133188
* If associated with a temporal value,
134189
* that has time-zone or time-offset information,
135190
* the rendering mode, as to whether to transform the rendered value
136-
* to the user's local/current time-zone or not.<br>
137-
* default = {@link TimeZoneTranslation#TO_LOCAL_TIMEZONE}
191+
* to the user's local/current time-zone or not.
192+
*
193+
* <p>default = {@link TimeZoneTranslation#TO_LOCAL_TIMEZONE}
194+
*
138195
* @see TimeZoneTranslation
139196
*/
140197
TimeZoneTranslation timeZoneTranslation()
@@ -151,26 +208,20 @@ TimeZoneTranslation timeZoneTranslation()
151208
* after the actually stored date.
152209
* For negative <i>n</i> its days before respectively.
153210
*
154-
* <p>
155-
* This is intended to be used so that an exclusive end date of an interval
211+
* <p>This is intended to be used so that an exclusive end date of an interval
156212
* can be rendered as 1 day before the actual value stored.
157-
* </p>
158213
*
159-
* <p>
160-
* For example:
161-
* </p>
214+
* <p> For example:
162215
* <pre>
163216
* public LocalDate getStartDate() { ... }
164217
*
165218
* &#64;ValueSemantics(dateRenderAdjustDays = ValueSemantics.AS_DAY_BEFORE)
166219
* public LocalDate getEndDate() { ... }
167220
* </pre>
168221
*
169-
* <p>
170-
* Here, the interval of the [1-may-2013,1-jun-2013) would be rendered as the dates
222+
* <p>Here, the interval of the [1-may-2013,1-jun-2013) would be rendered as the dates
171223
* 1-may-2013 for the start date but using 31-may-2013 (the day before) for the end date. What is stored
172224
* In the domain object, itself, however, the value stored is 1-jun-2013.
173-
* </p>
174225
*/
175226
int dateRenderAdjustDays()
176227
default 0;

0 commit comments

Comments
 (0)