@@ -179,7 +179,7 @@ public static Class<?> getRawType(Type type) {
179179 */
180180 return ObjectUtils .isEmpty (upperbounds ) ? Object .class : getRawType (upperbounds [0 ]);
181181 }
182- return ResolvableType .forType (type ).getRawClass ();
182+ return ResolvableType .forType (type ).getRawClass () == null ? Object . class : ResolvableType . forType ( type ). getRawClass () ;
183183 }
184184
185185 /**
@@ -228,6 +228,28 @@ else if (Function.class.isAssignableFrom(pojoFunctionClass) || BiFunction.class.
228228 return CollectionUtils .isEmpty (methods ) ? null : methods .get (0 );
229229 }
230230
231+ public static Type discoverFunctionTypeFromType (Type functionalType ) {
232+ Type typeToReturn = null ;
233+ if (Function .class .isAssignableFrom (getRawType (functionalType ))) {
234+ ResolvableType functionType = ResolvableType .forType (functionalType ).as (Function .class );
235+ typeToReturn = GenericTypeResolver .resolveType (functionType .getType (), getRawType (functionalType ));
236+ }
237+ else if (Consumer .class .isAssignableFrom (getRawType (functionalType ))) {
238+ ResolvableType functionType = ResolvableType .forType (functionalType ).as (Consumer .class );
239+
240+ ResolvableType t = ResolvableType .forClassWithGenerics (getRawType (functionalType ), functionType .getGeneric (0 ));
241+ Type t2 = t .getType ();
242+ //Type t = ResolvableType.
243+
244+ typeToReturn = GenericTypeResolver .resolveType (functionType .getType (), functionType .getRawClass ());
245+ }
246+ else {
247+ ResolvableType functionType = ResolvableType .forType (functionalType ).as (Supplier .class );
248+ typeToReturn = GenericTypeResolver .resolveType (functionType .getType (), getRawType (functionalType ));
249+ }
250+ return typeToReturn ;
251+ }
252+
231253 public static Type discoverFunctionTypeFromClass (Class <?> functionalClass ) {
232254 if (KotlinDetector .isKotlinPresent ()) {
233255 if (Function1 .class .isAssignableFrom (functionalClass )) {
@@ -248,15 +270,15 @@ else if (Function0.class.isAssignableFrom(functionalClass)) {
248270 }
249271 }
250272 }
251- ResolvableType functionType = ResolvableType .forClass (functionalClass ).as (Function .class );
273+ ResolvableType functionType = ResolvableType .forType (functionalClass ).as (Function .class );
252274 typeToReturn = GenericTypeResolver .resolveType (functionType .getType (), functionalClass );
253275 }
254276 else if (Consumer .class .isAssignableFrom (functionalClass )) {
255- ResolvableType functionType = ResolvableType .forClass (functionalClass ).as (Consumer .class );
277+ ResolvableType functionType = ResolvableType .forType (functionalClass ).as (Consumer .class );
256278 typeToReturn = GenericTypeResolver .resolveType (functionType .getType (), functionalClass );
257279 }
258280 else if (Supplier .class .isAssignableFrom (functionalClass )) {
259- ResolvableType functionType = ResolvableType .forClass (functionalClass ).as (Supplier .class );
281+ ResolvableType functionType = ResolvableType .forType (functionalClass ).as (Supplier .class );
260282 typeToReturn = GenericTypeResolver .resolveType (functionType .getType (), functionalClass );
261283 }
262284 return typeToReturn ;
@@ -285,6 +307,7 @@ public static Type discoverFunctionTypeFromFunctionFactoryMethod(Class<?> clazz,
285307 */
286308 public static Type discoverFunctionTypeFromFunctionFactoryMethod (Method method ) {
287309 return method .getGenericReturnType ();
310+ // return discoverFunctionTypeFromClass(method.getReturnType());
288311 }
289312
290313 /**
@@ -375,6 +398,49 @@ public static Type getComponentTypeOfOutputType(Type functionType) {
375398 return getImmediateGenericType (inputType , 0 );
376399 }
377400
401+ /**
402+ * Will resolve @{@link ResolvableType} to {@link Type} preserving all the resolved generics.
403+ * @param typeWithGenerics - instance of {@link ResolvableType}.
404+ * @return - {@link Type} representation of the provided {@link ResolvableType}.
405+ */
406+ public static Type resolveType (ResolvableType typeWithGenerics ) {
407+ if (typeWithGenerics .hasResolvableGenerics ()) {
408+ ResolvableType [] generics = typeWithGenerics .getGenerics ();
409+ List <ResolvableType > resolvedGenerics = new ArrayList <>();
410+ for (int i = 0 ; i < generics .length ; i ++) {
411+ ResolvableType genericType = typeWithGenerics .getGenerics ()[i ];
412+ resolvedGenerics .add (ResolvableType .forType (resolveType (genericType )));
413+ }
414+ return ResolvableType .forClassWithGenerics (typeWithGenerics .getRawClass (),
415+ resolvedGenerics .toArray (new ResolvableType [0 ])).getType ();
416+ }
417+ else {
418+ return typeWithGenerics .resolve ();
419+ }
420+ }
421+
422+ public static Type getOutputType (Type functionType ) {
423+ assertSupportedTypes (functionType );
424+ if (isConsumer (functionType )) {
425+ logger .debug ("Consumer does not have output type, returning null as output type." );
426+ return null ;
427+ }
428+
429+ if (KotlinDetector .isKotlinPresent () && Function1 .class .isAssignableFrom (getRawType (functionType ))) { // Kotlin
430+ return ResolvableType .forType (getImmediateGenericType (functionType , 1 )).getType ();
431+ }
432+ else {
433+ ResolvableType resolvableFunctionType = isSupplier (functionType )
434+ ? ResolvableType .forType (functionType ).as (Supplier .class )
435+ : ResolvableType .forType (functionType ).as (Function .class );
436+ ResolvableType generics = isSupplier (functionType )
437+ ? resolvableFunctionType .getGenerics ()[0 ]
438+ : resolvableFunctionType .getGenerics ()[1 ];
439+ Type outputType = FunctionTypeUtils .resolveType (generics );
440+ return outputType == null || outputType instanceof TypeVariable <?> ? Object .class : outputType ;
441+ }
442+ }
443+
378444 /**
379445 * Returns input type of function type that represents Function or Consumer.
380446 * @param functionType the Type of Function or Consumer
@@ -387,32 +453,16 @@ public static Type getInputType(Type functionType) {
387453 return null ;
388454 }
389455
390- ResolvableType resolvableFunctionType = ResolvableType .forType (functionType );
391-
392- ResolvableType resolvableInputType = resolvableFunctionType .as (resolvableFunctionType .getRawClass ());
393-
394- if (resolvableInputType .getType () instanceof ParameterizedType ) {
395- return resolvableInputType .getGeneric (0 ).getType ();
456+ if (KotlinDetector .isKotlinPresent () && Function1 .class .isAssignableFrom (getRawType (functionType ))) { // Kotlin
457+ return ResolvableType .forType (getImmediateGenericType (functionType , 1 )).getType ();
396458 }
397459 else {
398- // will try another way. See GH-1251
399- if (FunctionTypeUtils .isFunction (functionType )) {
400- resolvableInputType = resolvableFunctionType .as (Function .class );
401- }
402- else {
403- if (KotlinDetector .isKotlinPresent () && Function1 .class .isAssignableFrom (getRawType (functionType ))) { // Kotlin
404- return ResolvableType .forType (getImmediateGenericType (functionType , 1 )).getType ();
405- }
406- else {
407- resolvableInputType = resolvableFunctionType .as (Consumer .class );
408- }
409- }
410- if (resolvableInputType .getType () instanceof ParameterizedType ) {
411- return resolvableInputType .getGeneric (0 ).getType ();
412- }
413- else {
414- return Object .class ;
415- }
460+ ResolvableType resolvableFunctionType = isConsumer (functionType )
461+ ? ResolvableType .forType (functionType ).as (Consumer .class )
462+ : ResolvableType .forType (functionType ).as (Function .class );
463+ ResolvableType generics = resolvableFunctionType .getGenerics ()[0 ];
464+ Type inputType = FunctionTypeUtils .resolveType (generics );
465+ return inputType == null || inputType instanceof TypeVariable <?> ? Object .class : inputType ;
416466 }
417467 }
418468
@@ -475,52 +525,6 @@ public static String discoverBeanDefinitionNameByQualifier(ListableBeanFactory b
475525 }
476526 return null ;
477527 }
478-
479- public static Type getOutputType (Type functionType ) {
480- assertSupportedTypes (functionType );
481- if (isConsumer (functionType )) {
482- logger .debug ("Consumer does not have output type, returning null as output type." );
483- return null ;
484- }
485-
486- ResolvableType resolvableFunctionType = ResolvableType .forType (functionType );
487-
488- ResolvableType resolvableOutputType ;
489- if (FunctionTypeUtils .isFunction (functionType )) {
490- resolvableOutputType = resolvableFunctionType .as (Function .class );
491- }
492- else {
493- if (KotlinDetector .isKotlinPresent () && Function1 .class .isAssignableFrom (getRawType (functionType ))) { // Kotlin
494- return ResolvableType .forType (getImmediateGenericType (functionType , 1 )).getType ();
495- }
496- else {
497- resolvableOutputType = resolvableFunctionType .as (Supplier .class );
498- }
499- }
500-
501- Type outputType ;
502- if (functionType instanceof Class functionTypeClass ) {
503- if (FunctionTypeUtils .isFunction (functionType )) {
504- ResolvableType genericClass1 = resolvableOutputType .getGeneric (1 );
505- outputType = genericClass1 .getType ();
506- outputType = (outputType instanceof TypeVariable ) ? Object .class : GenericTypeResolver .resolveType (outputType , functionTypeClass );
507- }
508- else {
509- ResolvableType genericClass0 = resolvableOutputType .getGeneric (0 );
510- outputType = genericClass0 .getType ();
511- outputType = (outputType instanceof TypeVariable ) ? Object .class : GenericTypeResolver .resolveType (outputType , functionTypeClass );
512- }
513- }
514- else if (functionType instanceof ParameterizedType ) {
515- Type genericType = isSupplier (functionType ) ? resolvableOutputType .getGeneric (0 ).getType () : resolvableOutputType .getGeneric (1 ).getType ();
516- outputType = GenericTypeResolver .resolveType (genericType , getRawType (functionType ));
517- }
518- else {
519- outputType = resolvableOutputType .getType ();
520- }
521- return outputType instanceof TypeVariable ? Object .class : outputType ;
522- }
523-
524528 public static Type getImmediateGenericType (Type type , int index ) {
525529 if (type instanceof ParameterizedType ) {
526530 return ((ParameterizedType ) type ).getActualTypeArguments ()[index ];
0 commit comments