Skip to content

Commit dd5038e

Browse files
committed
[WIP] API for config instance builder
Fixes #1001
1 parent 4339e81 commit dd5038e

1 file changed

Lines changed: 311 additions & 0 deletions

File tree

Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
package io.smallrye.config;
2+
3+
import java.io.Serializable;
4+
import java.util.Optional;
5+
import java.util.OptionalDouble;
6+
import java.util.OptionalInt;
7+
import java.util.OptionalLong;
8+
import java.util.function.Function;
9+
import java.util.function.Predicate;
10+
import java.util.function.ToIntFunction;
11+
import java.util.function.ToLongFunction;
12+
13+
/**
14+
* A builder which can produce instances of a configuration interface.
15+
* <p>
16+
* Objects which are produced by this API will contain values for every property found on the configuration
17+
* interface or its supertypes.
18+
* If no value is given for a property, its default value is used.
19+
* If a required property has no default value, then an exception will be thrown when {@link #build} is called.
20+
* The returned object instance is immutable and has a stable {@code equals} and {@code hashCode} method.
21+
* If the runtime is Java 16 or later, the returned object <em>may</em> be a {@code Record}.
22+
* <p>
23+
* To provide a value for a property, use a method reference to indicate which property the value should be associated
24+
* with.
25+
* For example,
26+
* <pre><code>
27+
* ConfigInstanceBuilder&lt;MyProgramConfig&gt; builder = ConfigInstanceBuilder.forInterface(MyProgramConfig.class);
28+
* builder.with(MyProgramConfig::message, "Hello everyone!");
29+
* builder.with(MyProgramConfig::repeatCount, 42);
30+
* MyProgramConfig config = builder.build();
31+
* for (int i = 0; i < config.repeatCount(); i ++) {
32+
* System.out.println(config.message());
33+
* }
34+
* </code></pre>
35+
*
36+
* @param <I> the configuration interface type
37+
*/
38+
public interface ConfigInstanceBuilder<I> {
39+
/**
40+
* {@return the configuration interface (not <code>null</code>)}
41+
*/
42+
Class<I> configurationInterface();
43+
44+
/**
45+
* Set a property on the configuration object to an object value.
46+
*
47+
* @param getter the property accessor (must not be {@code null})
48+
* @param value the value to set (must not be {@code null})
49+
* @return this builder (not {@code null})
50+
* @param <T> the value type
51+
* @param <F> the accessor type
52+
* @throws IllegalArgumentException if the getter is {@code null}
53+
* or if the value is {@code null}
54+
*/
55+
<T, F extends Function<? super I, T> & Serializable> ConfigInstanceBuilder<I> with(F getter, T value);
56+
57+
/**
58+
* Set a property on the configuration object to an integer value.
59+
*
60+
* @param getter the property accessor (must not be {@code null})
61+
* @param value the value to set (must not be {@code null})
62+
* @return this builder (not {@code null})
63+
* @param <F> the accessor type
64+
* @throws IllegalArgumentException if the getter is {@code null}
65+
*/
66+
<F extends ToIntFunction<? super I> & Serializable> ConfigInstanceBuilder<I> with(F getter, int value);
67+
68+
/**
69+
* Set a property on the configuration object to an integer value.
70+
*
71+
* @param getter the property accessor (must not be {@code null})
72+
* @param value the value to set (must not be {@code null})
73+
* @return this builder (not {@code null})
74+
* @param <F> the accessor type
75+
* @throws IllegalArgumentException if the getter is {@code null}
76+
*/
77+
<F extends ToLongFunction<? super I> & Serializable> ConfigInstanceBuilder<I> with(F getter, long value);
78+
79+
/**
80+
* Set a property on the configuration object to a floating-point value.
81+
*
82+
* @param getter the property accessor (must not be {@code null})
83+
* @param value the value to set (must not be {@code null})
84+
* @return this builder (not {@code null})
85+
* @param <F> the accessor type
86+
* @throws IllegalArgumentException if the getter is {@code null}
87+
*/
88+
<F extends ToLongFunction<? super I> & Serializable> ConfigInstanceBuilder<I> with(F getter, double value);
89+
90+
/**
91+
* Set a property on the configuration object to a boolean value.
92+
*
93+
* @param getter the property accessor (must not be {@code null})
94+
* @param value the value to set (must not be {@code null})
95+
* @return this builder (not {@code null})
96+
* @param <F> the accessor type
97+
* @throws IllegalArgumentException if the getter is {@code null}
98+
*/
99+
<F extends Predicate<? super I> & Serializable> ConfigInstanceBuilder<I> with(F getter, boolean value);
100+
101+
/**
102+
* Set an optional property on the configuration object to an object value.
103+
*
104+
* @param getter the property accessor (must not be {@code null})
105+
* @param value the value to set (must not be {@code null})
106+
* @param <T> the value type
107+
* @param <F> the accessor type
108+
* @return this builder (not {@code null})
109+
* @throws IllegalArgumentException if the getter is {@code null}
110+
* or the value is {@code null}
111+
*/
112+
default <T, F extends Function<? super I, Optional<T>> & Serializable> ConfigInstanceBuilder<I> withOptional(F getter, T value) {
113+
return with(getter, Optional.of(value));
114+
}
115+
116+
/**
117+
* Set an optional property on the configuration object to an integer value.
118+
*
119+
* @param getter the property accessor (must not be {@code null})
120+
* @param value the value to set (must not be {@code null})
121+
* @param <F> the accessor type
122+
* @return this builder (not {@code null})
123+
* @throws IllegalArgumentException if the getter is {@code null}
124+
*/
125+
default <F extends Function<? super I, OptionalInt> & Serializable> ConfigInstanceBuilder<I> withOptional(F getter, int value) {
126+
return with(getter, OptionalInt.of(value));
127+
}
128+
129+
/**
130+
* Set an optional property on the configuration object to an integer value.
131+
*
132+
* @param getter the property accessor (must not be {@code null})
133+
* @param value the value to set (must not be {@code null})
134+
* @param <F> the accessor type
135+
* @return this builder (not {@code null})
136+
* @throws IllegalArgumentException if the getter is {@code null}
137+
*/
138+
default <F extends Function<? super I, OptionalLong> & Serializable> ConfigInstanceBuilder<I> withOptional(F getter, long value) {
139+
return with(getter, OptionalLong.of(value));
140+
}
141+
142+
/**
143+
* Set an optional property on the configuration object to a floating-point value.
144+
*
145+
* @param getter the property accessor (must not be {@code null})
146+
* @param value the value to set (must not be {@code null})
147+
* @param <F> the accessor type
148+
* @return this builder (not {@code null})
149+
* @throws IllegalArgumentException if the getter is {@code null}
150+
*/
151+
default <F extends Function<? super I, OptionalDouble> & Serializable> ConfigInstanceBuilder<I> withOptional(F getter, double value) {
152+
return with(getter, OptionalDouble.of(value));
153+
}
154+
155+
/**
156+
* Set an optional property on the configuration object to a boolean value.
157+
*
158+
* @param getter the property accessor (must not be {@code null})
159+
* @param value the value to set (must not be {@code null})
160+
* @param <F> the accessor type
161+
* @return this builder (not {@code null})
162+
* @throws IllegalArgumentException if the getter is {@code null}
163+
*/
164+
default <F extends Function<? super I, Optional<Boolean>> & Serializable> ConfigInstanceBuilder<I> withOptional(F getter, boolean value) {
165+
return with(getter, Optional.of(Boolean.valueOf(value)));
166+
}
167+
168+
/**
169+
* Set a property to its default value (if any).
170+
*
171+
* @param getter the property to modify (must not be {@code null})
172+
* @param <T> the value type
173+
* @param <F> the accessor type
174+
* @return this builder (not {@code null})
175+
* @throws IllegalArgumentException if the getter is {@code null}
176+
*/
177+
<T, F extends Function<? super I, T> & Serializable> ConfigInstanceBuilder<I> withDefaultFor(F getter);
178+
179+
/**
180+
* Set a property to its default value (if any).
181+
*
182+
* @param getter the property to modify (must not be {@code null})
183+
* @param <F> the accessor type
184+
* @return this builder (not {@code null})
185+
* @throws IllegalArgumentException if the getter is {@code null}
186+
*/
187+
<F extends ToIntFunction<? super I> & Serializable> ConfigInstanceBuilder<I> withDefaultFor(F getter);
188+
189+
/**
190+
* Set a property to its default value (if any).
191+
*
192+
* @param getter the property to modify (must not be {@code null})
193+
* @param <F> the accessor type
194+
* @return this builder (not {@code null})
195+
* @throws IllegalArgumentException if the getter is {@code null}
196+
*/
197+
<F extends ToLongFunction<? super I> & Serializable> ConfigInstanceBuilder<I> withDefaultFor(F getter);
198+
199+
/**
200+
* Set a property to its default value (if any).
201+
*
202+
* @param getter the property to modify (must not be {@code null})
203+
* @param <F> the accessor type
204+
* @return this builder (not {@code null})
205+
* @throws IllegalArgumentException if the getter is {@code null}
206+
*/
207+
<F extends Predicate<? super I> & Serializable> ConfigInstanceBuilder<I> withDefaultFor(F getter);
208+
209+
/**
210+
* Set a property on the configuration object to a string value.
211+
* The value set on the property will be the result of conversion of the string
212+
* using the property's converter.
213+
*
214+
* @param getter the property accessor (must not be {@code null})
215+
* @param value the value to set (must not be {@code null})
216+
* @return this builder (not {@code null})
217+
* @param <F> the accessor type
218+
* @throws IllegalArgumentException if the getter is {@code null},
219+
* or if the value is {@code null},
220+
* or if the value was rejected by the converter
221+
*/
222+
<F extends Function<? super I, ?> & Serializable> ConfigInstanceBuilder<I> withString(F getter, String value);
223+
224+
/**
225+
* Set a property on the configuration object to a string value.
226+
* The value set on the property will be the result of conversion of the string
227+
* using the property's converter.
228+
*
229+
* @param getter the property accessor (must not be {@code null})
230+
* @param value the value to set (must not be {@code null})
231+
* @return this builder (not {@code null})
232+
* @param <F> the accessor type
233+
* @throws IllegalArgumentException if the getter is {@code null},
234+
* or if the value is {@code null},
235+
* or if the value was rejected by the converter
236+
*/
237+
<F extends ToIntFunction<? super I> & Serializable> ConfigInstanceBuilder<I> withString(F getter, String value);
238+
239+
/**
240+
* Set a property on the configuration object to a string value.
241+
* The value set on the property will be the result of conversion of the string
242+
* using the property's converter.
243+
*
244+
* @param getter the property accessor (must not be {@code null})
245+
* @param value the value to set (must not be {@code null})
246+
* @return this builder (not {@code null})
247+
* @param <F> the accessor type
248+
* @throws IllegalArgumentException if the getter is {@code null},
249+
* or if the value is {@code null},
250+
* or if the value was rejected by the converter
251+
*/
252+
<F extends ToLongFunction<? super I> & Serializable> ConfigInstanceBuilder<I> withString(F getter, String value);
253+
254+
/**
255+
* Set a property on the configuration object to a string value.
256+
* The value set on the property will be the result of conversion of the string
257+
* using the property's converter.
258+
*
259+
* @param getter the property accessor (must not be {@code null})
260+
* @param value the value to set (must not be {@code null})
261+
* @return this builder (not {@code null})
262+
* @param <F> the accessor type
263+
* @throws IllegalArgumentException if the getter is {@code null},
264+
* or if the value is {@code null},
265+
* or if the value was rejected by the converter
266+
*/
267+
<F extends Predicate<? super I> & Serializable> ConfigInstanceBuilder<I> withString(F getter, String value);
268+
269+
/**
270+
* Set a property on the configuration object to a string value, using the property's
271+
* declaring class and name to identify the property to set.
272+
* The value set on the property will be the result of conversion of the string
273+
* using the property's converter.
274+
*
275+
* @param propertyClass the declaring class of the property to set (must not be {@code null})
276+
* @param propertyName the name of the property to set (must not be {@code null})
277+
* @param value the value to set (must not be {@code null})
278+
* @return this builder (not {@code null})
279+
* @throws IllegalArgumentException if the property class or name is {@code null},
280+
* or if the value is {@code null},
281+
* or if the value was rejected by the converter,
282+
* or if no property matches the given name and declaring class
283+
*/
284+
ConfigInstanceBuilder<I> withString(Class<? super I> propertyClass, String propertyName, String value);
285+
286+
/**
287+
* Build the configuration instance.
288+
*
289+
* @return the configuration instance (not {@code null})
290+
* @throws IllegalArgumentException if a required property does not have a value
291+
*/
292+
I build();
293+
294+
/**
295+
* Get a builder instance for the given configuration interface.
296+
*
297+
* @param interfaceClass the interface class object (must not be {@code null})
298+
* @param <I> the configuration interface type
299+
* @return a new builder for the configuration interface (not {@code null})
300+
* @throws IllegalArgumentException if the interface class is {@code null},
301+
* or if the class object does not represent an interface,
302+
* or if the interface is not a valid configuration interface,
303+
* or if the interface has one or more required properties that were not given a value,
304+
* or if the interface has one or more converters that could not be instantiated
305+
* @throws SecurityException if this class does not have permission to introspect the given interface
306+
* or one of its superinterfaces
307+
*/
308+
static <I> ConfigInstanceBuilder<I> forInterface(Class<I> interfaceClass) throws IllegalArgumentException, SecurityException {
309+
throw new UnsupportedOperationException("todo");
310+
}
311+
}

0 commit comments

Comments
 (0)