1515import java .util .function .Function ;
1616import java .util .function .Predicate ;
1717import java .util .function .Supplier ;
18+ import java .util .function .ToDoubleFunction ;
1819import java .util .function .ToIntFunction ;
1920import java .util .function .ToLongFunction ;
2021
@@ -46,20 +47,19 @@ final class ConfigInstanceBuilderImpl<I> implements ConfigInstanceBuilder<I> {
4647 private static final ClassValue <Supplier <?>> builderFactories = new ClassValue <>() {
4748 protected Supplier <?> computeValue (final Class <?> type ) {
4849 assert type .isInterface ();
49- String interfaceName = type . getName ();
50+ // TODO - Should we cache this eagerly in io.smallrye.config.ConfigMappingLoader.ConfigMappingImplementation?
5051 MethodHandles .Lookup lookup ;
5152 try {
5253 lookup = MethodHandles .privateLookupIn (type , myLookup );
5354 } catch (IllegalAccessException e ) {
5455 throw msg .accessDenied (getClass (), type );
5556 }
56- String implInternalName = interfaceName .replace ('.' , '/' ) + "$$SC_BuilderImpl" ;
5757 Class <?> impl ;
5858 try {
59- impl = lookup .findClass (implInternalName );
59+ ConfigMappingLoader .ensureLoaded (type );
60+ impl = lookup .findClass (ConfigMappingInterface .ConfigMappingBuilder .getBuilderClassName (type ));
6061 } catch (ClassNotFoundException e ) {
61- // generate the impl instead
62- throw new UnsupportedOperationException ("Todo" );
62+ throw new IllegalStateException (e );
6363 } catch (IllegalAccessException e ) {
6464 throw msg .accessDenied (getClass (), type );
6565 }
@@ -74,7 +74,7 @@ protected Supplier<?> computeValue(final Class<?> type) {
7474 // capture the constructor as a Supplier
7575 return () -> {
7676 try {
77- return ( ConfigInstanceBuilderImpl <?>) mh .invokeExact ();
77+ return mh .invoke ();
7878 } catch (RuntimeException | Error e ) {
7979 throw e ;
8080 } catch (Throwable e ) {
@@ -83,33 +83,33 @@ protected Supplier<?> computeValue(final Class<?> type) {
8383 };
8484 }
8585 };
86+
8687 /**
8788 * Class value which holds the cached config class instance constructors.
8889 */
8990 private static final ClassValue <Function <Object , ?>> configFactories = new ClassValue <>() {
91+ // TODO - This is to load the mapping class implementation, which we already have, just missing the right constructor in the ConfigMappingLoader, so we can probably remove this one
9092 protected Function <Object , ?> computeValue (final Class <?> type ) {
9193 assert type .isInterface ();
92- String interfaceName = type . getName ();
94+ // TODO - Should we cache this eagerly in io.smallrye.config.ConfigMappingLoader.ConfigMappingImplementation?
9395 MethodHandles .Lookup lookup ;
9496 try {
9597 lookup = MethodHandles .privateLookupIn (type , myLookup );
9698 } catch (IllegalAccessException e ) {
9799 throw msg .accessDenied (getClass (), type );
98100 }
99- String implInternalName = interfaceName .replace ('.' , '/' ) + "$$SC_BuilderImpl" ;
100101 Class <?> impl ;
102+ Class <?> builderClass ;
101103 try {
102- impl = lookup .findClass (implInternalName );
104+ impl = ConfigMappingLoader .ensureLoaded (type ).implementation ();
105+ builderClass = lookup .findClass (ConfigMappingInterface .ConfigMappingBuilder .getBuilderClassName (type ));
103106 } catch (ClassNotFoundException e ) {
104- // generate the impl instead
105- throw new UnsupportedOperationException ("Todo" );
107+ throw new IllegalStateException (e );
106108 } catch (IllegalAccessException e ) {
107109 throw msg .accessDenied (getClass (), type );
108110 }
109111 MethodHandle mh ;
110- Class <?> builderClass = null ;
111- if (true )
112- throw new UnsupportedOperationException ("Not finished yet..." );
112+
113113 try {
114114 mh = lookup .findConstructor (impl , MethodType .methodType (void .class , builderClass ));
115115 } catch (NoSuchMethodException e ) {
@@ -120,7 +120,7 @@ protected Supplier<?> computeValue(final Class<?> type) {
120120 // capture the constructor as a Function
121121 return builder -> {
122122 try {
123- return type . cast ( mh .invokeExact (builder ) );
123+ return mh .invoke (builder );
124124 } catch (RuntimeException | Error e ) {
125125 throw e ;
126126 } catch (Throwable e ) {
@@ -143,7 +143,7 @@ protected Map<Object, BiConsumer<Object, Object>> computeValue(final Class<?> ty
143143
144144 static <I > ConfigInstanceBuilderImpl <I > forInterface (Class <I > configurationInterface )
145145 throws IllegalArgumentException , SecurityException {
146- return new ConfigInstanceBuilderImpl <I >(configurationInterface , builderFactories .get (configurationInterface ).get ());
146+ return new ConfigInstanceBuilderImpl <>(configurationInterface , builderFactories .get (configurationInterface ).get ());
147147 }
148148
149149 // =====================================
@@ -196,7 +196,7 @@ public <F extends ToLongFunction<? super I> & Serializable> ConfigInstanceBuilde
196196 return this ;
197197 }
198198
199- public <F extends ToLongFunction <? super I > & Serializable > ConfigInstanceBuilder <I > with (final F getter ,
199+ public <F extends ToDoubleFunction <? super I > & Serializable > ConfigInstanceBuilder <I > with (final F getter ,
200200 final double value ) {
201201 Assert .checkNotNullParam ("getter" , getter );
202202 Class <?> callerClass = sw .getCallerClass ();
@@ -293,6 +293,14 @@ public I build() {
293293
294294 // =====================================
295295
296+ public static <T > T convertValue (final String value , final Class <T > type ) {
297+ Converter <T > converter = Converters .getConverter (type );
298+ if (converter == null ) {
299+ throw new IllegalArgumentException ("No converter found for type " + type );
300+ }
301+ return converter .convert (value );
302+ }
303+
296304 private Converter <?> getConverter (final Object getter , final Class <?> callerClass ) {
297305 throw new UnsupportedOperationException ("Need class info registry" );
298306 }
@@ -313,7 +321,7 @@ private BiConsumer<Object, Object> createSetter(Object lambda) {
313321 }
314322 Object replaced ;
315323 try {
316- replaced = writeReplace .invokeExact (lambda );
324+ replaced = writeReplace .invoke (lambda );
317325 } catch (RuntimeException | Error e ) {
318326 throw e ;
319327 } catch (Throwable e ) {
@@ -326,7 +334,6 @@ private BiConsumer<Object, Object> createSetter(Object lambda) {
326334 if (sl .getCapturedArgCount () != 0 ) {
327335 throw msg .invalidGetter ();
328336 }
329- String implClassName = sl .getImplClass ();
330337 // TODO: check implClassName against the supertype hierarchy of the config interface using shared info mapping
331338 String setterName = sl .getImplMethodName ();
332339 Class <?> type = parseReturnType (sl .getImplMethodSignature ());
@@ -337,7 +344,7 @@ private BiConsumer<Object, Object> createSetterByName(final String setterName, f
337344 Class <?> builderClass = builderObject .getClass ();
338345 MethodHandle setter ;
339346 try {
340- setter = lookup .findVirtual (builderClass , setterName , MethodType .methodType (void .class , builderClass , type ));
347+ setter = lookup .findVirtual (builderClass , setterName , MethodType .methodType (void .class , type ));
341348 } catch (NoSuchMethodException e ) {
342349 throw new RuntimeException (e );
343350 } catch (IllegalAccessException e ) {
@@ -347,7 +354,7 @@ private BiConsumer<Object, Object> createSetterByName(final String setterName, f
347354 MethodHandle castSetter = setter .asType (MethodType .methodType (void .class , builderClass , Object .class ));
348355 return (builder , val ) -> {
349356 try {
350- castSetter .invokeExact (builderObject , builder , val );
357+ castSetter .invoke (builderObject , val );
351358 } catch (RuntimeException | Error e ) {
352359 throw e ;
353360 } catch (Throwable e ) {
@@ -369,46 +376,24 @@ private Class<?> parseReturnType(final String signature) {
369376 }
370377
371378 private Class <?> parseType (String desc , int start , int end ) {
372- switch (desc .charAt (start )) {
373- case 'L' : {
374- return parseClassName (desc , start + 1 , end - 1 );
375- }
376- case '[' : {
377- return parseType (desc , start + 1 , end ).arrayType ();
378- }
379- case 'B' : {
380- return byte .class ;
381- }
382- case 'C' : {
383- return char .class ;
384- }
385- case 'D' : {
386- return double .class ;
387- }
388- case 'F' : {
389- return float .class ;
390- }
391- case 'I' : {
392- return int .class ;
393- }
394- case 'J' : {
395- return long .class ;
396- }
397- case 'S' : {
398- return short .class ;
399- }
400- case 'Z' : {
401- return boolean .class ;
402- }
403- default : {
404- throw msg .invalidGetter ();
405- }
406- }
379+ return switch (desc .charAt (start )) {
380+ case 'L' -> parseClassName (desc , start + 1 , end - 1 );
381+ case '[' -> parseType (desc , start + 1 , end ).arrayType ();
382+ case 'B' -> byte .class ;
383+ case 'C' -> char .class ;
384+ case 'D' -> double .class ;
385+ case 'F' -> float .class ;
386+ case 'I' -> int .class ;
387+ case 'J' -> long .class ;
388+ case 'S' -> short .class ;
389+ case 'Z' -> boolean .class ;
390+ default -> throw msg .invalidGetter ();
391+ };
407392 }
408393
409394 private Class <?> parseClassName (final String signature , final int start , final int end ) {
410395 try {
411- return lookup .findClass (signature .substring (start , end ));
396+ return lookup .findClass (signature .substring (start , end ). replaceAll ( "/" , "." ) );
412397 } catch (ClassNotFoundException e ) {
413398 throw msg .invalidGetter ();
414399 } catch (IllegalAccessException e ) {
0 commit comments