in mapper-processor/src/main/java/com/datastax/oss/driver/internal/mapper/processor/dao/DefaultDaoReturnTypeParser.java [143:250]
public DaoReturnType parse(
@NonNull TypeMirror returnTypeMirror, @NonNull Map<Name, TypeElement> typeParameters) {
// void or a primitive?
DaoReturnType match = typeKindMatches.get(returnTypeMirror.getKind());
if (match != null) {
return match;
}
if (returnTypeMirror.getKind() == TypeKind.DECLARED) {
// entity class? e.g. Product
TypeElement entityElement;
if ((entityElement = EntityUtils.asEntityElement(returnTypeMirror, typeParameters)) != null) {
return new DaoReturnType(DefaultDaoReturnTypeKind.ENTITY, entityElement);
}
// simple class? e.g. Boolean
DeclaredType declaredReturnType = (DeclaredType) returnTypeMirror;
for (Map.Entry<Class<?>, DaoReturnType> entry : classMatches.entrySet()) {
Class<?> simpleClass = entry.getKey();
if (context.getClassUtils().isSame(declaredReturnType, simpleClass)) {
return entry.getValue();
}
}
// entity container? e.g. Optional<Product>
if (declaredReturnType.getTypeArguments().size() == 1
&& (entityElement =
EntityUtils.typeArgumentAsEntityElement(returnTypeMirror, typeParameters))
!= null) {
Element returnElement = declaredReturnType.asElement();
for (Map.Entry<Class<?>, DaoReturnTypeKind> entry : entityContainerMatches.entrySet()) {
Class<?> containerClass = entry.getKey();
if (context.getClassUtils().isSame(returnElement, containerClass)) {
return new DaoReturnType(entry.getValue(), entityElement);
}
}
}
if (context.getClassUtils().isFuture(declaredReturnType)) {
TypeMirror typeArgumentMirror = declaredReturnType.getTypeArguments().get(0);
// future of a simple class? e.g. CompletableFuture<Boolean>
for (Map.Entry<Class<?>, DaoReturnType> entry : futureOfClassMatches.entrySet()) {
Class<?> simpleClassArgument = entry.getKey();
if (context.getClassUtils().isSame(typeArgumentMirror, simpleClassArgument)) {
return entry.getValue();
}
}
// Note that futures of entities (e.g. CompletionStage<Product>) are already covered by the
// "entity container" check above
// future of entity container? e.g. CompletionStage<Optional<Product>>
if (typeArgumentMirror.getKind() == TypeKind.DECLARED) {
DeclaredType declaredTypeArgument = (DeclaredType) typeArgumentMirror;
if (declaredTypeArgument.getTypeArguments().size() == 1
&& (entityElement =
EntityUtils.typeArgumentAsEntityElement(typeArgumentMirror, typeParameters))
!= null) {
Element typeArgumentElement = declaredTypeArgument.asElement();
for (Map.Entry<Class<?>, DaoReturnTypeKind> entry :
futureOfEntityContainerMatches.entrySet()) {
Class<?> containerClass = entry.getKey();
if (context.getClassUtils().isSame(typeArgumentElement, containerClass)) {
return new DaoReturnType(entry.getValue(), entityElement);
}
}
}
}
}
// Otherwise assume a custom type. A MappedResultProducer will be looked up from the
// MapperContext at runtime.
if (context.areCustomResultsEnabled()) {
return new DaoReturnType(
DefaultDaoReturnTypeKind.CUSTOM,
findEntityInCustomType(declaredReturnType, typeParameters, new ArrayList<>()));
}
}
if (returnTypeMirror.getKind() == TypeKind.TYPEVAR) {
// entity class? e.g. Product
TypeElement entityElement;
if ((entityElement = EntityUtils.asEntityElement(returnTypeMirror, typeParameters)) != null) {
return new DaoReturnType(DefaultDaoReturnTypeKind.ENTITY, entityElement);
}
// simple class? e.g. Boolean
TypeVariable typeVariable = ((TypeVariable) returnTypeMirror);
Name name = typeVariable.asElement().getSimpleName();
TypeElement element = typeParameters.get(name);
if (element != null) {
for (Map.Entry<Class<?>, DaoReturnType> entry : classMatches.entrySet()) {
Class<?> simpleClass = entry.getKey();
if (context.getClassUtils().isSame(element, simpleClass)) {
return entry.getValue();
}
}
}
// DAO parameterization by more complex types (futures, containers...) is not supported
}
return DaoReturnType.UNSUPPORTED;
}