2727 *
2828 * @param <Value> The object type to construct when `parse` is called.
2929 */
30- public class ConstructingObjectParser <Value > implements ObjectParser < Value > {
30+ public class ObjectFactory <Value > implements Function < Map < String , Object >, Value > {
3131 private final Map <String , BiConsumer <Value , Object >> parsers = new HashMap <>();
32- private List <Field <?>> constructorFields = null ;
32+ private List <Field <?>> constructorFields ;
3333 private final Function <Map <String , Object >, Value > builder ;
34+
3435 /**
3536 * Zero-argument object constructor (A Supplier)
37+ *
3638 * @param supplier The supplier which produces an object instance.
3739 */
3840 @ SuppressWarnings ("WeakerAccess" ) // Public Interface
39- public ConstructingObjectParser (Supplier <Value > supplier ) {
41+ public ObjectFactory (Supplier <Value > supplier ) {
4042 this (config -> supplier .get ());
4143 constructorFields = Collections .emptyList ();
4244 }
@@ -45,7 +47,7 @@ public ConstructingObjectParser(Supplier<Value> supplier) {
4547 * One-argument object constructor
4648 */
4749 @ SuppressWarnings ("WeakerAccess" ) // Public Interface
48- public <Arg0 > ConstructingObjectParser (Function <Arg0 , Value > function , Field <Arg0 > arg0 ) {
50+ public <Arg0 > ObjectFactory (Function <Arg0 , Value > function , Field <Arg0 > arg0 ) {
4951 this (config -> function .apply (arg0 .apply (config )));
5052 constructorFields = Collections .singletonList (arg0 );
5153 }
@@ -54,7 +56,7 @@ public <Arg0> ConstructingObjectParser(Function<Arg0, Value> function, Field<Arg
5456 * Two-argument object constructor
5557 */
5658 @ SuppressWarnings ("WeakerAccess" ) // Public Interface
57- public <Arg0 , Arg1 > ConstructingObjectParser (BiFunction <Arg0 , Arg1 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 ) {
59+ public <Arg0 , Arg1 > ObjectFactory (BiFunction <Arg0 , Arg1 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 ) {
5860 this (config -> function .apply (arg0 .apply (config ), arg1 .apply (config )));
5961 constructorFields = Arrays .asList (arg0 , arg1 );
6062 }
@@ -63,110 +65,55 @@ public <Arg0, Arg1> ConstructingObjectParser(BiFunction<Arg0, Arg1, Value> funct
6365 * Three-argument object constructor
6466 */
6567 @ SuppressWarnings ("WeakerAccess" ) // Public Interface
66- public <Arg0 , Arg1 , Arg2 > ConstructingObjectParser (Function3 <Arg0 , Arg1 , Arg2 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 ) {
68+ public <Arg0 , Arg1 , Arg2 > ObjectFactory (Function3 <Arg0 , Arg1 , Arg2 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 ) {
6769 this (config -> function .apply (arg0 .apply (config ), arg1 .apply (config ), arg2 .apply (config )));
6870 constructorFields = Arrays .asList (arg0 , arg1 , arg2 );
6971 }
7072
7173
7274 @ SuppressWarnings ("WeakerAccess" ) // Public Interface
73- public <Arg0 , Arg1 , Arg2 , Arg3 > ConstructingObjectParser (Function4 <Arg0 , Arg1 , Arg2 , Arg3 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 , Field <Arg3 > arg3 ) {
75+ public <Arg0 , Arg1 , Arg2 , Arg3 > ObjectFactory (Function4 <Arg0 , Arg1 , Arg2 , Arg3 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 , Field <Arg3 > arg3 ) {
7476 this (config -> function .apply (arg0 .apply (config ), arg1 .apply (config ), arg2 .apply (config ), arg3 .apply (config )));
7577 constructorFields = Arrays .asList (arg0 , arg1 , arg2 , arg3 );
7678 }
7779
7880 @ SuppressWarnings ("WeakerAccess" ) // Public Interface
79- public <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 > ConstructingObjectParser (Function5 <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 , Field <Arg3 > arg3 , Field <Arg4 > arg4 ) {
81+ public <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 > ObjectFactory (Function5 <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 , Field <Arg3 > arg3 , Field <Arg4 > arg4 ) {
8082 this (config -> function .apply (arg0 .apply (config ), arg1 .apply (config ), arg2 .apply (config ), arg3 .apply (config ), arg4 .apply (config )));
8183 constructorFields = Arrays .asList (arg0 , arg1 , arg2 , arg3 , arg4 );
8284 }
8385
8486 @ SuppressWarnings ("WeakerAccess" ) // Public Interface
85- public <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 > ConstructingObjectParser (Function6 <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 , Field <Arg3 > arg3 , Field <Arg4 > arg4 , Field <Arg5 > arg5 ) {
87+ public <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 > ObjectFactory (Function6 <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 , Field <Arg3 > arg3 , Field <Arg4 > arg4 , Field <Arg5 > arg5 ) {
8688 this (config -> function .apply (arg0 .apply (config ), arg1 .apply (config ), arg2 .apply (config ), arg3 .apply (config ), arg4 .apply (config ), arg5 .apply (config )));
8789 constructorFields = Arrays .asList (arg0 , arg1 , arg2 , arg3 , arg4 , arg5 );
8890 }
8991
9092 @ SuppressWarnings ("WeakerAccess" ) // Public Interface
91- public <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 > ConstructingObjectParser (Function7 <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 , Field <Arg3 > arg3 , Field <Arg4 > arg4 , Field <Arg5 > arg5 , Field <Arg6 > arg6 ) {
93+ public <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 > ObjectFactory (Function7 <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 , Field <Arg3 > arg3 , Field <Arg4 > arg4 , Field <Arg5 > arg5 , Field <Arg6 > arg6 ) {
9294 this (config -> function .apply (arg0 .apply (config ), arg1 .apply (config ), arg2 .apply (config ), arg3 .apply (config ), arg4 .apply (config ), arg5 .apply (config ), arg6 .apply (config )));
9395 constructorFields = Arrays .asList (arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 );
9496 }
9597
9698 @ SuppressWarnings ("WeakerAccess" ) // Public Interface
97- public <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Arg7 > ConstructingObjectParser (Function8 <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Arg7 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 , Field <Arg3 > arg3 , Field <Arg4 > arg4 , Field <Arg5 > arg5 , Field <Arg6 > arg6 , Field <Arg7 > arg7 ) {
99+ public <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Arg7 > ObjectFactory (Function8 <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Arg7 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 , Field <Arg3 > arg3 , Field <Arg4 > arg4 , Field <Arg5 > arg5 , Field <Arg6 > arg6 , Field <Arg7 > arg7 ) {
98100 this (config -> function .apply (arg0 .apply (config ), arg1 .apply (config ), arg2 .apply (config ), arg3 .apply (config ), arg4 .apply (config ), arg5 .apply (config ), arg6 .apply (config ), arg7 .apply (config )));
99101 constructorFields = Arrays .asList (arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 );
100102 }
101103
102104 @ SuppressWarnings ("WeakerAccess" ) // Public Interface
103- public <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Arg7 , Arg8 > ConstructingObjectParser (Function9 <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Arg7 , Arg8 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 , Field <Arg3 > arg3 , Field <Arg4 > arg4 , Field <Arg5 > arg5 , Field <Arg6 > arg6 , Field <Arg7 > arg7 , Field <Arg8 > arg8 ) {
105+ public <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Arg7 , Arg8 > ObjectFactory (Function9 <Arg0 , Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Arg7 , Arg8 , Value > function , Field <Arg0 > arg0 , Field <Arg1 > arg1 , Field <Arg2 > arg2 , Field <Arg3 > arg3 , Field <Arg4 > arg4 , Field <Arg5 > arg5 , Field <Arg6 > arg6 , Field <Arg7 > arg7 , Field <Arg8 > arg8 ) {
104106 this (config -> function .apply (arg0 .apply (config ), arg1 .apply (config ), arg2 .apply (config ), arg3 .apply (config ), arg4 .apply (config ), arg5 .apply (config ), arg6 .apply (config ), arg7 .apply (config ), arg8 .apply (config )));
105107 constructorFields = Arrays .asList (arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 );
106108 }
107109
108- private ConstructingObjectParser (Function <Map <String , Object >, Value > builder ) {
110+ private ObjectFactory (Function <Map <String , Object >, Value > builder ) {
109111 this .builder = builder ;
110112 }
111113
112- private static <Value > Value construct (Map <String , Object > config , Function <Object [], Value > builder , Field <?>... constructorFields ) throws IllegalArgumentException {
113- Object [] builderArgs = new Object [constructorFields .length ];
114- int i = 0 ;
115- for (Field <?> field : constructorFields ) {
116- final String name = field .getName ();
117-
118- if (config .containsKey (name )) {
119- builderArgs [i ] = field .apply (config .get (name ));
120- } else {
121- throw new IllegalArgumentException ("Missing required argument '" + name + "'" );
122- }
123-
124- i ++;
125- }
126-
127- return builder .apply (builderArgs );
128- }
129-
130- /**
131- * Declare a field. Field ordering does not matter.
132- * <p>
133- * A field is intended to call a Setter on an Object.
134- * <p>
135- * When calling `apply`, all fields are considered optional and may be absent from the config map.
136- * <p>
137- * <code>{@code
138- * ConstructingObjectParser<SocketServer> c = new ConstructingObjectParser<>(SocketServer::new)
139- * c.declareBoolean("reuseAddress", SocketServer::setReuseAddress);
140- * c.declareInteger("receiveBufferSize", SocketServer::setReceiveBufferSize);
141- * <p>
142- * Map<String, Object> config = new HashMap<>();
143- * config.put("reuseAddress", true);
144- * config.put("receiveBufferSize", 65536);
145- * SocketServer server = c.apply(config);
146- * }</code>
147- *
148- * @param name
149- * @param consumer
150- * @param transform
151- * @param <T>
152- * @return
153- */
154- @ Override
155- @ SuppressWarnings ("WeakerAccess" ) // Public Interface
156- public <T > Field declareField (String name , BiConsumer <Value , T > consumer , Function <Object , T > transform ) {
157- if (isKnownField (name )) {
158- throw new IllegalArgumentException ("Duplicate field defined '" + name + "'" );
159- }
160-
161- BiConsumer <Value , Object > objConsumer = (value , object ) -> consumer .accept (value , transform .apply (object ));
162- FieldDefinition <T > field = new FieldDefinition <>(name , transform );
163- parsers .put (name , (value , input ) -> consumer .accept (value , transform .apply (input )));
164- return field ;
165- }
166-
167114 /**
168115 * Use the given config to produce the Value object.
169- *
116+ * <p>
170117 * Contract:
171118 * 1) All declared constructor arguments are required. If any are missing, an IllegalArgumentException is thrown.
172119 * 2) All declared fields are optional.
@@ -176,6 +123,7 @@ public <T> Field declareField(String name, BiConsumer<Value, T> consumer, Functi
176123 * @param config the configuration
177124 * @return the configured object
178125 */
126+ @ SuppressWarnings ("WeakerAccess" ) // Public Interface
179127 public Value apply (Map <String , Object > config ) {
180128 rejectUnknownFields (config .keySet ());
181129
@@ -219,4 +167,23 @@ private void rejectUnknownFields(Set<String> configNames) throws IllegalArgument
219167 }
220168 }
221169
170+ @ SuppressWarnings ("WeakerAccess" ) // Public Interface
171+ public <T > ObjectFactory <Value > define (Field <T > field , BiConsumer <Value , T > consumer ) {
172+ if (isKnownField (field .getName ())) {
173+ throw new IllegalArgumentException ("Duplicate field defined '" + field .getName () + "'" );
174+ }
175+
176+ parsers .put (field .getName (), (value , input ) -> consumer .accept (value , field .apply (input )));
177+ return this ;
178+ }
179+
180+ @ SuppressWarnings ("WeakerAccess" ) // Public Interface
181+ public <T > ObjectFactory <Value > deprecate (Field <T > field , BiConsumer <Value , T > consumer , String details ) {
182+ return define (new DeprecatedField <>(field .getName (), field , details ), consumer );
183+ }
184+
185+ @ SuppressWarnings ("WeakerAccess" ) // Public Interface
186+ public <T > ObjectFactory <Value > obsolete (Field <T > field , BiConsumer <Value , T > consumer , String details ) {
187+ return define (new ObsoleteField <>(field .getName (), field , details ), consumer );
188+ }
222189}
0 commit comments