Skip to content

Commit

Permalink
fix(spring): update setters for properties of type Duration (#1093)
Browse files Browse the repository at this point in the history
* Updates setters for Spring properties of type org.threeten.bp.Duration to accept argument of type java.time.Duration instead, and parse to org.threeten.bp.Duration in the setter body.

* Converting between the two types: parse() and toString() methods for both will accept or return ISO-8601 seconds based representation, such as PT8H6M12.345S.

* This addresses the issue that properties of type org.threeten.bp.Duration cannot be set from strings (e.g. specified in Spring property files) because the implicit conversion is unsupported. Spring boot has dedicated support for properties of type java.time.Duration.
  • Loading branch information
emmileaf authored Nov 16, 2022
1 parent c79dab2 commit b873b60
Show file tree
Hide file tree
Showing 4 changed files with 256 additions and 227 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.google.api.generator.engine.ast.Expr;
import com.google.api.generator.engine.ast.ExprStatement;
import com.google.api.generator.engine.ast.MethodDefinition;
import com.google.api.generator.engine.ast.MethodInvocationExpr;
import com.google.api.generator.engine.ast.NewObjectExpr;
import com.google.api.generator.engine.ast.PrimitiveValue;
import com.google.api.generator.engine.ast.ScopeNode;
Expand Down Expand Up @@ -291,8 +292,36 @@ private static MethodDefinition createGetterMethod(

private static MethodDefinition createSetterMethod(
TypeNode thisClassType, String propertyName, TypeNode returnType) {

// Common building blocks
Variable propertyVar = Variable.builder().setName(propertyName).setType(returnType).build();
Expr thisExpr = ValueExpr.withValue(ThisObjectValue.withType(thisClassType));
TypeNode threetenBpDurationType = staticTypes.get("org.threeten.bp.Duration");
TypeNode javaTimeDurationType = staticTypes.get("java.time.Duration");

// Default building blocks - may be updated in Duration condition below
Variable argumentVar = propertyVar;
Expr propertyValueExpr = VariableExpr.withVariable(argumentVar);

// Setter logic for Duration accepts different type and handles conversion
if (returnType.equals(threetenBpDurationType)) {
argumentVar = Variable.builder().setName(propertyName).setType(javaTimeDurationType).build();

MethodInvocationExpr durationToStringExpr =
MethodInvocationExpr.builder()
.setExprReferenceExpr(VariableExpr.withVariable(argumentVar))
.setMethodName("toString")
.setReturnType(TypeNode.STRING)
.build();

propertyValueExpr =
MethodInvocationExpr.builder()
.setStaticReferenceType(threetenBpDurationType)
.setMethodName("parse")
.setArguments(durationToStringExpr)
.setReturnType(threetenBpDurationType)
.build();
}

AssignmentExpr propertyVarExpr =
AssignmentExpr.builder()
Expand All @@ -301,7 +330,7 @@ private static MethodDefinition createSetterMethod(
.toBuilder()
.setExprReferenceExpr(thisExpr)
.build())
.setValueExpr(VariableExpr.withVariable(propertyVar))
.setValueExpr(propertyValueExpr)
.build();

String methodName = "set" + CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, propertyName);
Expand All @@ -310,7 +339,7 @@ private static MethodDefinition createSetterMethod(
.setName(methodName)
.setScope(ScopeNode.PUBLIC)
.setReturnType(TypeNode.VOID)
.setArguments(VariableExpr.builder().setVariable(propertyVar).setIsDecl(true).build())
.setArguments(VariableExpr.builder().setVariable(argumentVar).setIsDecl(true).build())
.setBody(Arrays.asList(ExprStatement.withExpr(propertyVarExpr)))
.build();
}
Expand Down Expand Up @@ -365,14 +394,8 @@ private static Map<String, TypeNode> createDynamicTypes(Service service, String
.setPakkage("org.springframework.boot.context.properties")
.build());

// import org.threeten.bp.Duration;
TypeNode duration =
TypeNode.withReference(
VaporReference.builder().setName("Duration").setPakkage("org.threeten.bp").build());

typeMap.put(service.name() + "Properties", clientProperties);
typeMap.put("Credentials", credentials);
typeMap.put("Duration", duration);
typeMap.put("CredentialsSupplier", credentialsSupplier);
typeMap.put("ConfigurationProperties", configurationProperties);
typeMap.put("NestedConfigurationProperty", nestedConfigurationProperty);
Expand All @@ -382,11 +405,11 @@ private static Map<String, TypeNode> createDynamicTypes(Service service, String

private static Map<String, TypeNode> createStaticTypes() {
List<Class> concreteClazzes =
Arrays.asList(RetrySettings.class, org.threeten.bp.Duration.class);
Arrays.asList(
RetrySettings.class, org.threeten.bp.Duration.class, java.time.Duration.class);
return concreteClazzes.stream()
.collect(
Collectors.toMap(
c -> c.getSimpleName(),
c -> TypeNode.withReference(ConcreteReference.withClazz(c))));
Class::getName, c -> TypeNode.withReference(ConcreteReference.withClazz(c))));
}
}
Loading

0 comments on commit b873b60

Please sign in to comment.