Skip to content

Commit b538522

Browse files
committed
Revert "GH-1312 Backporting type discovery fix"
This reverts commit 76d0bb8.
1 parent 7476e6a commit b538522

File tree

1 file changed

+119
-120
lines changed
  • spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog

1 file changed

+119
-120
lines changed

spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/FunctionTypeUtils.java

Lines changed: 119 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import org.springframework.util.StringUtils;
7474

7575

76+
7677
/**
7778
* Set of utility operations to interrogate function definitions.
7879
*
@@ -94,17 +95,17 @@ private FunctionTypeUtils() {
9495

9596
public static Type functionType(Type input, Type output) {
9697
return ResolvableType.forClassWithGenerics(Function.class,
97-
ResolvableType.forType(input), ResolvableType.forType(output)).getType();
98+
ResolvableType.forType(input), ResolvableType.forType(output)).getType();
9899
}
99100

100101
public static Type consumerType(Type input) {
101102
return ResolvableType.forClassWithGenerics(Consumer.class,
102-
ResolvableType.forType(input)).getType();
103+
ResolvableType.forType(input)).getType();
103104
}
104105

105106
public static Type supplierType(Type output) {
106107
return ResolvableType.forClassWithGenerics(Supplier.class,
107-
ResolvableType.forType(output)).getType();
108+
ResolvableType.forType(output)).getType();
108109
}
109110

110111
/**
@@ -179,7 +180,7 @@ public static Class<?> getRawType(Type type) {
179180
*/
180181
return ObjectUtils.isEmpty(upperbounds) ? Object.class : getRawType(upperbounds[0]);
181182
}
182-
return ResolvableType.forType(type).getRawClass() == null ? Object.class : ResolvableType.forType(type).getRawClass();
183+
return ResolvableType.forType(type).getRawClass();
183184
}
184185

185186
/**
@@ -194,15 +195,15 @@ public static Class<?> getRawType(Type type) {
194195
public static Method discoverFunctionalMethod(Class<?> pojoFunctionClass) {
195196
if (Supplier.class.isAssignableFrom(pojoFunctionClass)) {
196197
return Stream.of(ReflectionUtils.getAllDeclaredMethods(pojoFunctionClass)).filter(m -> !m.isSynthetic()
197-
&& m.getName().equals("get")).findFirst().get();
198+
&& m.getName().equals("get")).findFirst().get();
198199
}
199200
else if (Consumer.class.isAssignableFrom(pojoFunctionClass) || BiConsumer.class.isAssignableFrom(pojoFunctionClass)) {
200201
return Stream.of(ReflectionUtils.getAllDeclaredMethods(pojoFunctionClass)).filter(m -> !m.isSynthetic()
201-
&& m.getName().equals("accept")).findFirst().get();
202+
&& m.getName().equals("accept")).findFirst().get();
202203
}
203204
else if (Function.class.isAssignableFrom(pojoFunctionClass) || BiFunction.class.isAssignableFrom(pojoFunctionClass)) {
204205
return Stream.of(ReflectionUtils.getAllDeclaredMethods(pojoFunctionClass)).filter(m -> !m.isSynthetic()
205-
&& m.getName().equals("apply")).findFirst().get();
206+
&& m.getName().equals("apply")).findFirst().get();
206207
}
207208

208209
List<Method> methods = new ArrayList<>();
@@ -213,7 +214,7 @@ else if (Function.class.isAssignableFrom(pojoFunctionClass) || BiFunction.class.
213214

214215
}, method ->
215216
!method.getDeclaringClass().isAssignableFrom(Object.class)
216-
&& !method.isSynthetic() && !method.isBridge() && !method.isVarArgs());
217+
&& !method.isSynthetic() && !method.isBridge() && !method.isVarArgs());
217218

218219
if (methods.size() > 1) {
219220
for (Method candidadteMethod : methods) {
@@ -228,28 +229,6 @@ else if (Function.class.isAssignableFrom(pojoFunctionClass) || BiFunction.class.
228229
return CollectionUtils.isEmpty(methods) ? null : methods.get(0);
229230
}
230231

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-
253232
public static Type discoverFunctionTypeFromClass(Class<?> functionalClass) {
254233
if (KotlinDetector.isKotlinPresent()) {
255234
if (Function1.class.isAssignableFrom(functionalClass)) {
@@ -270,15 +249,15 @@ else if (Function0.class.isAssignableFrom(functionalClass)) {
270249
}
271250
}
272251
}
273-
ResolvableType functionType = ResolvableType.forType(functionalClass).as(Function.class);
252+
ResolvableType functionType = ResolvableType.forClass(functionalClass).as(Function.class);
274253
typeToReturn = GenericTypeResolver.resolveType(functionType.getType(), functionalClass);
275254
}
276255
else if (Consumer.class.isAssignableFrom(functionalClass)) {
277-
ResolvableType functionType = ResolvableType.forType(functionalClass).as(Consumer.class);
256+
ResolvableType functionType = ResolvableType.forClass(functionalClass).as(Consumer.class);
278257
typeToReturn = GenericTypeResolver.resolveType(functionType.getType(), functionalClass);
279258
}
280259
else if (Supplier.class.isAssignableFrom(functionalClass)) {
281-
ResolvableType functionType = ResolvableType.forType(functionalClass).as(Supplier.class);
260+
ResolvableType functionType = ResolvableType.forClass(functionalClass).as(Supplier.class);
282261
typeToReturn = GenericTypeResolver.resolveType(functionType.getType(), functionalClass);
283262
}
284263
return typeToReturn;
@@ -307,7 +286,6 @@ public static Type discoverFunctionTypeFromFunctionFactoryMethod(Class<?> clazz,
307286
*/
308287
public static Type discoverFunctionTypeFromFunctionFactoryMethod(Method method) {
309288
return method.getGenericReturnType();
310-
// return discoverFunctionTypeFromClass(method.getReturnType());
311289
}
312290

313291
/**
@@ -321,11 +299,11 @@ public static Type discoverFunctionTypeFromFunctionMethod(Method functionMethod)
321299
return null;
322300
}
323301
Assert.isTrue(
324-
functionMethod.getName().equals("apply") ||
302+
functionMethod.getName().equals("apply") ||
325303
functionMethod.getName().equals("accept") ||
326304
functionMethod.getName().equals("get") ||
327305
functionMethod.getName().equals("invoke"),
328-
"Only Supplier, Function or Consumer supported at the moment. Was " + functionMethod.getDeclaringClass());
306+
"Only Supplier, Function or Consumer supported at the moment. Was " + functionMethod.getDeclaringClass());
329307

330308
ResolvableType functionType;
331309
if (functionMethod.getName().equals("apply") || functionMethod.getName().equals("invoke")) {
@@ -398,49 +376,6 @@ public static Type getComponentTypeOfOutputType(Type functionType) {
398376
return getImmediateGenericType(inputType, 0);
399377
}
400378

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-
444379
/**
445380
* Returns input type of function type that represents Function or Consumer.
446381
* @param functionType the Type of Function or Consumer
@@ -453,17 +388,35 @@ public static Type getInputType(Type functionType) {
453388
return null;
454389
}
455390

391+
ResolvableType resolvableFunctionType = ResolvableType.forType(functionType);
392+
393+
if (FunctionTypeUtils.isFunction(functionType)) {
394+
return extractInputType(resolvableFunctionType.as(Function.class).getGeneric(0));
395+
}
396+
if (FunctionTypeUtils.isConsumer(functionType)) {
397+
return extractInputType(resolvableFunctionType.as(Consumer.class).getGeneric(0));
398+
}
456399
if (KotlinDetector.isKotlinPresent() && Function1.class.isAssignableFrom(getRawType(functionType))) { // Kotlin
457400
return ResolvableType.forType(getImmediateGenericType(functionType, 1)).getType();
458401
}
459-
else {
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;
402+
403+
// no consumer or function
404+
// might be one of the other supported types (as asserted in first line of method)
405+
// for example FunctionRegistration or IntConsumer
406+
407+
// unclear what the contract is in such a case
408+
// maybe returning null here might be "more" correct
409+
return Object.class;
410+
}
411+
412+
private static Type extractInputType(ResolvableType resolvableInputType) {
413+
if (resolvableInputType.getType() instanceof TypeVariable) {
414+
// In case the input type is a type variable (e.g. as in GH-1251) we need to resolve the type
415+
// For the case that the type is unbound Object.class is used
416+
return resolvableInputType.resolve(Object.class);
466417
}
418+
419+
return resolvableInputType.getType();
467420
}
468421

469422
@SuppressWarnings("rawtypes")
@@ -476,7 +429,7 @@ else if (function instanceof FunctionRegistration) {
476429
}
477430
if (applicationContext.containsBean(functionName + FunctionRegistration.REGISTRATION_NAME_SUFFIX)) { // for Kotlin primarily
478431
FunctionRegistration fr = applicationContext
479-
.getBean(functionName + FunctionRegistration.REGISTRATION_NAME_SUFFIX, FunctionRegistration.class);
432+
.getBean(functionName + FunctionRegistration.REGISTRATION_NAME_SUFFIX, FunctionRegistration.class);
480433
return fr.getType();
481434
}
482435

@@ -525,6 +478,52 @@ public static String discoverBeanDefinitionNameByQualifier(ListableBeanFactory b
525478
}
526479
return null;
527480
}
481+
482+
public static Type getOutputType(Type functionType) {
483+
assertSupportedTypes(functionType);
484+
if (isConsumer(functionType)) {
485+
logger.debug("Consumer does not have output type, returning null as output type.");
486+
return null;
487+
}
488+
489+
ResolvableType resolvableFunctionType = ResolvableType.forType(functionType);
490+
491+
ResolvableType resolvableOutputType;
492+
if (FunctionTypeUtils.isFunction(functionType)) {
493+
resolvableOutputType = resolvableFunctionType.as(Function.class);
494+
}
495+
else {
496+
if (KotlinDetector.isKotlinPresent() && Function1.class.isAssignableFrom(getRawType(functionType))) { // Kotlin
497+
return ResolvableType.forType(getImmediateGenericType(functionType, 1)).getType();
498+
}
499+
else {
500+
resolvableOutputType = resolvableFunctionType.as(Supplier.class);
501+
}
502+
}
503+
504+
Type outputType;
505+
if (functionType instanceof Class functionTypeClass) {
506+
if (FunctionTypeUtils.isFunction(functionType)) {
507+
ResolvableType genericClass1 = resolvableOutputType.getGeneric(1);
508+
outputType = genericClass1.getType();
509+
outputType = (outputType instanceof TypeVariable) ? Object.class : GenericTypeResolver.resolveType(outputType, functionTypeClass);
510+
}
511+
else {
512+
ResolvableType genericClass0 = resolvableOutputType.getGeneric(0);
513+
outputType = genericClass0.getType();
514+
outputType = (outputType instanceof TypeVariable) ? Object.class : GenericTypeResolver.resolveType(outputType, functionTypeClass);
515+
}
516+
}
517+
else if (functionType instanceof ParameterizedType) {
518+
Type genericType = isSupplier(functionType) ? resolvableOutputType.getGeneric(0).getType() : resolvableOutputType.getGeneric(1).getType();
519+
outputType = GenericTypeResolver.resolveType(genericType, getRawType(functionType));
520+
}
521+
else {
522+
outputType = resolvableOutputType.getType();
523+
}
524+
return outputType instanceof TypeVariable ? Object.class : outputType;
525+
}
526+
528527
public static Type getImmediateGenericType(Type type, int index) {
529528
if (type instanceof ParameterizedType) {
530529
return ((ParameterizedType) type).getActualTypeArguments()[index];
@@ -614,23 +613,23 @@ static Type fromFunctionMethod(Method functionalMethod) {
614613

615614
Type functionType = null;
616615
switch (parameterTypes.length) {
617-
case 0:
618-
functionType = ResolvableType.forClassWithGenerics(Supplier.class,
616+
case 0:
617+
functionType = ResolvableType.forClassWithGenerics(Supplier.class,
619618
ResolvableType.forMethodReturnType(functionalMethod)).getType();
620-
break;
621-
case 1:
622-
if (Void.class.isAssignableFrom(functionalMethod.getReturnType())) {
623-
functionType = ResolvableType.forClassWithGenerics(Consumer.class,
619+
break;
620+
case 1:
621+
if (Void.class.isAssignableFrom(functionalMethod.getReturnType())) {
622+
functionType = ResolvableType.forClassWithGenerics(Consumer.class,
624623
ResolvableType.forMethodParameter(functionalMethod, 0)).getType();
625-
}
626-
else {
627-
functionType = ResolvableType.forClassWithGenerics(Function.class,
624+
}
625+
else {
626+
functionType = ResolvableType.forClassWithGenerics(Function.class,
628627
ResolvableType.forMethodParameter(functionalMethod, 0),
629628
ResolvableType.forMethodReturnType(functionalMethod)).getType();
630-
}
631-
break;
632-
default:
633-
throw new UnsupportedOperationException("Functional method: " + functionalMethod + " is not supported");
629+
}
630+
break;
631+
default:
632+
throw new UnsupportedOperationException("Functional method: " + functionalMethod + " is not supported");
634633
}
635634
return functionType;
636635
}
@@ -653,31 +652,31 @@ private static void assertSupportedTypes(Type type) {
653652
if (type instanceof ParameterizedType) {
654653
type = ((ParameterizedType) type).getRawType();
655654
Assert.isTrue(type instanceof Class<?>, "Must be one of Supplier, Function, Consumer"
656-
+ " or FunctionRegistration. Was " + type);
655+
+ " or FunctionRegistration. Was " + type);
657656
}
658657

659658
Class<?> candidateType = (Class<?>) type;
660659

661660
Assert.isTrue(Supplier.class.isAssignableFrom(candidateType)
662-
|| (KotlinDetector.isKotlinPresent() && (Function0.class.isAssignableFrom(candidateType) || Function1.class.isAssignableFrom(candidateType)))
663-
|| Function.class.isAssignableFrom(candidateType)
664-
|| Consumer.class.isAssignableFrom(candidateType)
665-
|| FunctionRegistration.class.isAssignableFrom(candidateType)
666-
|| IntConsumer.class.isAssignableFrom(candidateType)
667-
|| IntSupplier.class.isAssignableFrom(candidateType)
668-
|| IntFunction.class.isAssignableFrom(candidateType)
669-
|| ToIntFunction.class.isAssignableFrom(candidateType)
670-
|| LongConsumer.class.isAssignableFrom(candidateType)
671-
|| LongSupplier.class.isAssignableFrom(candidateType)
672-
|| LongFunction.class.isAssignableFrom(candidateType)
673-
|| ToLongFunction.class.isAssignableFrom(candidateType)
674-
|| DoubleConsumer.class.isAssignableFrom(candidateType)
675-
|| DoubleSupplier.class.isAssignableFrom(candidateType)
676-
|| DoubleFunction.class.isAssignableFrom(candidateType)
677-
|| ToDoubleFunction.class.isAssignableFrom(candidateType)
678-
|| type.getTypeName().startsWith("org.springframework.context.annotation.ConfigurationClassEnhancer"),
679-
"Must be one of Supplier, Function, Consumer"
680-
+ " or FunctionRegistration. Was " + type);
661+
|| (KotlinDetector.isKotlinPresent() && (Function0.class.isAssignableFrom(candidateType) || Function1.class.isAssignableFrom(candidateType)))
662+
|| Function.class.isAssignableFrom(candidateType)
663+
|| Consumer.class.isAssignableFrom(candidateType)
664+
|| FunctionRegistration.class.isAssignableFrom(candidateType)
665+
|| IntConsumer.class.isAssignableFrom(candidateType)
666+
|| IntSupplier.class.isAssignableFrom(candidateType)
667+
|| IntFunction.class.isAssignableFrom(candidateType)
668+
|| ToIntFunction.class.isAssignableFrom(candidateType)
669+
|| LongConsumer.class.isAssignableFrom(candidateType)
670+
|| LongSupplier.class.isAssignableFrom(candidateType)
671+
|| LongFunction.class.isAssignableFrom(candidateType)
672+
|| ToLongFunction.class.isAssignableFrom(candidateType)
673+
|| DoubleConsumer.class.isAssignableFrom(candidateType)
674+
|| DoubleSupplier.class.isAssignableFrom(candidateType)
675+
|| DoubleFunction.class.isAssignableFrom(candidateType)
676+
|| ToDoubleFunction.class.isAssignableFrom(candidateType)
677+
|| type.getTypeName().startsWith("org.springframework.context.annotation.ConfigurationClassEnhancer"),
678+
"Must be one of Supplier, Function, Consumer"
679+
+ " or FunctionRegistration. Was " + type);
681680
}
682681

683682
private static Type extractReactiveType(Type type) {

0 commit comments

Comments
 (0)