diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000..475ebc6387 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,31 @@ +before_script: + - function setEnv(){ + $env:JAVA_HOME="C:\Runners\OpenRewrite\CO_JDK"; + $env:PATH+= ";$env:JAVA_HOME\bin"; + dir env:; + } + - setEnv + +stages: + - build + - test + - deploy + +build: + stage: build + script: + - ./gradlew clean assemble --no-daemon + +test: + stage: test + script: + - ./gradlew check --no-daemon + rules: + - when: never # Never run the test job + +deploy: + stage: deploy + only: + - add-localdate-mapping-to-joda-recipe + script: + - ./gradlew publishNebulaPublicationToPrimionNexusRepository --no-daemon \ No newline at end of file diff --git a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeScanner.java b/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeScanner.java index e636dc915c..2994ba5dd8 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeScanner.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeScanner.java @@ -29,6 +29,7 @@ import org.openrewrite.java.JavadocVisitor; import org.openrewrite.java.tree.*; import org.openrewrite.java.tree.J.VariableDeclarations.NamedVariable; +import org.openrewrite.marker.SearchResult; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; @@ -95,14 +96,19 @@ public J visitCompilationUnit(J.CompilationUnit cu, ExecutionContext ctx) { @Override public J visitVariable(NamedVariable variable, ExecutionContext ctx) { - if (variable.getType() == null || !variable.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { + if (variable.getType() == null){ + return SearchResult.found(variable, "Variable with no type is found. Please check your code."); // unhandled case + } + if (!variable.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { return super.visitVariable(variable, ctx); } // TODO: handle class variables + // working fine with disabling for safe check in JodaTimeVisitor if (isClassVar(variable)) { acc.getUnsafeVars().add(variable); return variable; } + variable = (NamedVariable) super.visitVariable(variable, ctx); if (!variable.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { @@ -199,13 +205,26 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) if (argPos == -1) { return method; } - String paramName = parentMethod.getMethodType().getParameterNames().get(argPos); - NamedVariable var = acc.getVarTable().getVarByName(parentMethod.getMethodType(), paramName); + + JavaType.Method parentMethodType = parentMethod.getMethodType(); + List parameterTypes = parentMethodType.getParameterTypes(); + int parameterTypesSize = parameterTypes.size(); + //try to process method with variable arguments + if(argPos > parameterTypesSize) + { + //todo find better way to detect (...) in method arguments + if (parameterTypes.get(parameterTypesSize - 1).toString().endsWith("[]")){ + return method; + } + } + + String paramName = parentMethodType.getParameterNames().get(argPos); + NamedVariable var = acc.getVarTable().getVarByName(parentMethodType, paramName); if (var != null) { methodReferencedVars.computeIfAbsent(method.getMethodType(), k -> new HashSet<>()).add(var); } else { methodUnresolvedReferencedVars.computeIfAbsent(method.getMethodType(), k -> new HashSet<>()) - .add(new UnresolvedVar(parentMethod.getMethodType(), paramName)); + .add(new UnresolvedVar(parentMethodType, paramName)); } } return method; diff --git a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeVisitor.java b/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeVisitor.java index f89d45ed4b..482541940d 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeVisitor.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/JodaTimeVisitor.java @@ -18,7 +18,6 @@ import lombok.NonNull; import org.jspecify.annotations.Nullable; import org.openrewrite.ExecutionContext; -import org.openrewrite.java.JavaTemplate; import org.openrewrite.java.JavadocVisitor; import org.openrewrite.java.migrate.joda.templates.AllTemplates; import org.openrewrite.java.migrate.joda.templates.MethodTemplate; @@ -30,18 +29,14 @@ import java.util.LinkedList; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; class JodaTimeVisitor extends ScopeAwareVisitor { - private final boolean safeMigration; - private final JodaTimeRecipe.Accumulator acc; - - public JodaTimeVisitor(JodaTimeRecipe.Accumulator acc, boolean safeMigration, LinkedList scopes) { + public JodaTimeVisitor(JodaTimeRecipe.Accumulator acc, boolean b, LinkedList scopes) { super(scopes); - this.acc = acc; - this.safeMigration = safeMigration; } @Override @@ -65,10 +60,25 @@ public Javadoc visitReference(Javadoc.Reference reference, ExecutionContext ctx) maybeRemoveImport(JODA_DATE_TIME_ZONE); maybeRemoveImport(JODA_TIME_FORMAT); maybeRemoveImport(JODA_DURATION); + maybeRemoveImport(JODA_PERIOD); maybeRemoveImport(JODA_ABSTRACT_INSTANT); maybeRemoveImport(JODA_INSTANT); maybeRemoveImport(JODA_INTERVAL); - maybeRemoveImport("java.util.Locale"); + maybeRemoveImport(JODA_TIME_FORMATTER); + maybeRemoveImport(JAVA_UTIL_LOCALE); + maybeRemoveImport(JODA_LOCAL_DATE_TIME); + maybeRemoveImport(JODA_LOCAL_DATE); + maybeRemoveImport(JODA_LOCAL_TIME); + maybeRemoveImport(JODA_SECONDS); + maybeRemoveImport(JODA_MINUTES); + maybeRemoveImport(JODA_HOURS); + maybeRemoveImport(JODA_DAYS); + maybeRemoveImport(JODA_WEEKS); + maybeRemoveImport(JODA_MONTHS); + maybeRemoveImport(JODA_YEARS); + maybeRemoveImport(JODA_DATE_TIME_UTILS); + maybeRemoveImport(JODA_DATE_MIDNIGHT); + maybeRemoveImport(JODA_GEORGIAN_CHRONOLOGY); maybeAddImport(JAVA_DATE_TIME); maybeAddImport(JAVA_ZONE_OFFSET); @@ -77,13 +87,22 @@ public Javadoc visitReference(Javadoc.Reference reference, ExecutionContext ctx) maybeAddImport(JAVA_TIME_FORMATTER); maybeAddImport(JAVA_TIME_FORMAT_STYLE); maybeAddImport(JAVA_DURATION); + maybeAddImport(JAVA_PERIOD); maybeAddImport(JAVA_LOCAL_DATE); + maybeAddImport(JAVA_LOCAL_DATE_TIME); maybeAddImport(JAVA_LOCAL_TIME); maybeAddImport(JAVA_TEMPORAL_ISO_FIELDS); maybeAddImport(JAVA_CHRONO_FIELD); + maybeAddImport(JAVA_CHRONO_UNIT); maybeAddImport(JAVA_UTIL_DATE); + maybeAddImport(JAVA_ISA_CHRONOLOGY); maybeAddImport(THREE_TEN_EXTRA_INTERVAL); + maybeAddImport(THREE_TEN_EXTRA_DAYS); + maybeAddImport(THREE_TEN_EXTRA_WEEKS); + maybeAddImport(THREE_TEN_EXTRA_MONTHS); + maybeAddImport(THREE_TEN_EXTRA_YEARS); } + return j; } @@ -93,43 +112,66 @@ public Javadoc visitReference(Javadoc.Reference reference, ExecutionContext ctx) if (m.getReturnTypeExpression() == null || !m.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { return m; } - if (safeMigration && !acc.getSafeMethodMap().getOrDefault(m.getMethodType(), false)) { - return m; - } JavaType.Class returnType = TimeClassMap.getJavaTimeType(((JavaType.Class) m.getType()).getFullyQualifiedName()); J.Identifier returnExpr = TypeTree.build(returnType.getClassName()).withType(returnType).withPrefix(Space.format(" ")); - return m.withReturnTypeExpression(returnExpr) - .withMethodType(m.getMethodType().withReturnType(returnType)); + + JavaType.Method methodType = m.getMethodType() + .withReturnType(returnType) + .withParameterTypes(m.getMethodType().getParameterTypes().stream().map(p -> visitTypeParameter(p, ctx)).collect(Collectors.toList())); + + J.MethodDeclaration methodDeclaration = m + .withReturnTypeExpression(returnExpr) + .withMethodType(methodType); + + return methodDeclaration; + } + JavaType visitTypeParameter(JavaType parameter, @NonNull ExecutionContext ctx){ + if (parameter instanceof JavaType.Class) {return visitClassTypeParameter((JavaType.Class)parameter, ctx);} + if (parameter instanceof JavaType.Array) {return ((JavaType.Array)parameter).withElemType(visitClassTypeParameter((JavaType.Class)((JavaType.Array) parameter).getElemType(), ctx));} + return parameter; + } + JavaType visitClassTypeParameter(JavaType.Class classParameter, @NonNull ExecutionContext ctx) { + if (!classParameter.isAssignableFrom(JODA_CLASS_PATTERN)) { + return classParameter; + } + return TimeClassMap.getJavaTimeType(classParameter.getFullyQualifiedName()); } @Override public @NonNull J visitVariableDeclarations(@NonNull J.VariableDeclarations multiVariable, @NonNull ExecutionContext ctx) { - if (multiVariable.getTypeExpression() == null || !multiVariable.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { - return super.visitVariableDeclarations(multiVariable, ctx); + J.VariableDeclarations mv = (J.VariableDeclarations) super.visitVariableDeclarations(multiVariable, ctx); + + if (!mv.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { + return mv; } - if (multiVariable.getVariables().stream().anyMatch(acc.getUnsafeVars()::contains)) { - return multiVariable; + + String fullyQualifiedName = ((JavaType.Class) mv.getType()).getFullyQualifiedName(); + JavaType.Class javaTimeType = TimeClassMap.getJavaTimeType(fullyQualifiedName); + String javaTimeShortName = TimeClassMap.getJavaTimeShortName(fullyQualifiedName); + + J.Identifier typeExpression = (J.Identifier) mv.getTypeExpression(); + + if(javaTimeShortName != null){ + typeExpression = typeExpression.withSimpleName(javaTimeShortName); } - J.VariableDeclarations m = (J.VariableDeclarations) super.visitVariableDeclarations(multiVariable, ctx); - return VarTemplates.getTemplate(multiVariable).map(t -> t.apply( - updateCursor(m), - m.getCoordinates().replace(), - VarTemplates.getTemplateArgs(m))).orElse(multiVariable); + + return autoFormat(mv.withTypeExpression(typeExpression.withType(javaTimeType)), ctx); } @Override public @NonNull J visitVariable(@NonNull J.VariableDeclarations.NamedVariable variable, @NonNull ExecutionContext ctx) { - if (!variable.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { - return super.visitVariable(variable, ctx); + J.VariableDeclarations.NamedVariable v = (J.VariableDeclarations.NamedVariable) super.visitVariable(variable, ctx); + if (v.getType() instanceof JavaType.Array && ((JavaType.Array)v.getType()).getElemType().isAssignableFrom(JODA_CLASS_PATTERN)) { + JavaType.Array type = (JavaType.Array) v.getType(); + JavaType.Class elemType = (JavaType.Class) type.getElemType(); + return v.withType(type.withElemType(TimeClassMap.getJavaTimeType(elemType.getFullyQualifiedName()))); } - if (acc.getUnsafeVars().contains(variable) || !(variable.getType() instanceof JavaType.Class)) { - return variable; + if (v.getType() instanceof JavaType.Class && v.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { + return v.withType(TimeClassMap.getJavaTimeType(((JavaType.Class) variable.getType()).getFullyQualifiedName())); } - JavaType.Class jodaType = (JavaType.Class) variable.getType(); - return variable - .withType(TimeClassMap.getJavaTimeType(jodaType.getFullyQualifiedName())) - .withInitializer((Expression) visit(variable.getInitializer(), ctx)); + + return v; } @Override @@ -143,7 +185,7 @@ public Javadoc visitReference(Javadoc.Reference reference, ExecutionContext ctx) } J.Identifier varName = (J.Identifier) a.getVariable(); Optional mayBeVar = findVarInScope(varName.getSimpleName()); - if (!mayBeVar.isPresent() || acc.getUnsafeVars().contains(mayBeVar.get())) { + if (!mayBeVar.isPresent()) { return assignment; } return VarTemplates.getTemplate(assignment).map(t -> t.apply( @@ -183,34 +225,50 @@ public Javadoc visitReference(Javadoc.Reference reference, ExecutionContext ctx) @Override public @NonNull J visitFieldAccess(@NonNull J.FieldAccess fieldAccess, @NonNull ExecutionContext ctx) { J.FieldAccess f = (J.FieldAccess) super.visitFieldAccess(fieldAccess, ctx); - if (TypeUtils.isOfClassType(f.getType(), JODA_DATE_TIME_ZONE) && "UTC".equals(f.getSimpleName())) { - return JavaTemplate.builder("ZoneOffset.UTC") - .imports(JAVA_ZONE_OFFSET) - .build() - .apply(updateCursor(f), f.getCoordinates().replace()); + if (!isJodaVarRef(fieldAccess)) { + return f; } - return f; + + JavaType.Class fieldType = (JavaType.Class) f.getType(); + JavaType.Class javaTimeType = TimeClassMap.getJavaTimeType(fieldType.getFullyQualifiedName()); + + return f.withType(javaTimeType); } @Override public @NonNull J visitIdentifier(@NonNull J.Identifier ident, @NonNull ExecutionContext ctx) { - if (!isJodaVarRef(ident)) { - return super.visitIdentifier(ident, ctx); - } - if (this.safeMigration) { - Optional mayBeVar = findVarInScope(ident.getSimpleName()); - if (!mayBeVar.isPresent() || acc.getUnsafeVars().contains(mayBeVar.get())) { - return ident; - } - } + J.Identifier i = (J.Identifier) super.visitIdentifier(ident, ctx); + //i.getType().isAssignableFrom(JODA_CLASS_PATTERN) + if (!isJodaVarRef(i)) { + return i; + } + JavaType type = i.getType(); + if(type instanceof JavaType.Array) {return visitArrayIdentifier(i, ctx);} + if(type instanceof JavaType.Class) {return visitClassIdentifier(i, ctx);} - JavaType.FullyQualified jodaType = ((JavaType.Class) ident.getType()); - JavaType.FullyQualified fqType = TimeClassMap.getJavaTimeType(jodaType.getFullyQualifiedName()); - if (fqType == null) { - return ident; + return i; + } + private @NonNull J visitArrayIdentifier(J.Identifier arrayIdentifier, @NonNull ExecutionContext ctx) { + JavaType.Array at = (JavaType.Array)arrayIdentifier.getType(); + JavaType.Array javaTimeType = at.withElemType(TimeClassMap.getJavaTimeType(((JavaType.Class)at.getElemType()).getFullyQualifiedName())); + + return arrayIdentifier.withType(javaTimeType) + .withFieldType(arrayIdentifier.getFieldType().withType(javaTimeType)); + } + private @NonNull J visitClassIdentifier(J.Identifier classIdentifier, @NonNull ExecutionContext ctx) { + JavaType.Class javaTimeType = TimeClassMap.getJavaTimeType(((JavaType.Class)classIdentifier.getType()).getFullyQualifiedName()); + + return classIdentifier.withType(javaTimeType) + .withFieldType(classIdentifier.getFieldType().withType(javaTimeType)); + } + + @Override + public J visitArrayAccess(J.ArrayAccess arrayAccess, @NonNull ExecutionContext ctx){ + J.ArrayAccess a = (J.ArrayAccess) super.visitArrayAccess(arrayAccess, ctx); + if (!a.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { + return a; } - return ident.withType(fqType) - .withFieldType(ident.getFieldType().withType(fqType)); + return a.withType(TimeClassMap.getJavaTimeType(((JavaType.Class)a.getType()).getFullyQualifiedName())); } private J migrateMethodCall(MethodCall original, MethodCall updated) { @@ -219,38 +277,50 @@ private J migrateMethodCall(MethodCall original, MethodCall updated) { } MethodTemplate template = AllTemplates.getTemplate(original); if (template == null) { + System.out.println("Joda usage is found but mapping is missing: " + original); return original; // unhandled case } + if (template.getTemplate().getCode().equals(JODA_MULTIPLE_MAPPING_POSSIBLE)) { + System.out.println(JODA_MULTIPLE_MAPPING_POSSIBLE + ": " + original); + return original; // usage with no automated mapping + } + if (template.getTemplate().getCode().equals(JODA_NO_AUTOMATIC_MAPPING_POSSIBLE)) { + System.out.println(JODA_NO_AUTOMATIC_MAPPING_POSSIBLE + ": " + original); + return original; // usage with no automated mapping + } Optional maybeUpdated = applyTemplate(original, updated, template); if (!maybeUpdated.isPresent()) { + System.out.println("Can not apply template: " + template + " to " + original); return original; // unhandled case } Expression updatedExpr = (Expression) maybeUpdated.get(); - if (!safeMigration || !isArgument(original)) { + if (!isArgument(original)) { return updatedExpr; } // this expression is an argument to a method call MethodCall parentMethod = getCursor().getParentTreeCursor().getValue(); - if (parentMethod.getMethodType().getDeclaringType().isAssignableFrom(JODA_CLASS_PATTERN)) { + JavaType.Method parentMethodType = parentMethod.getMethodType(); + if (parentMethodType.getDeclaringType().isAssignableFrom(JODA_CLASS_PATTERN)) { return updatedExpr; } int argPos = parentMethod.getArguments().indexOf(original); - JavaType paramType = parentMethod.getMethodType().getParameterTypes().get(argPos); - if (TypeUtils.isAssignableTo(paramType, updatedExpr.getType())) { - return updatedExpr; - } - String paramName = parentMethod.getMethodType().getParameterNames().get(argPos); - NamedVariable var = acc.getVarTable().getVarByName(parentMethod.getMethodType(), paramName); - if (var != null && !acc.getUnsafeVars().contains(var)) { - return updatedExpr; + List parameterTypes = parentMethodType.getParameterTypes(); + int parameterTypesSize = parameterTypes.size(); + + //try to process method with variable arguments + if(argPos > parameterTypesSize) + { + //todo find better way to detect (...) in method arguments + if (parameterTypes.get(parameterTypesSize - 1).toString().endsWith("[]")){ + return updatedExpr; + } + return original; } - return original; + + return updatedExpr; } private J.MethodInvocation migrateNonJodaMethod(J.MethodInvocation original, J.MethodInvocation updated) { - if (safeMigration && !acc.getSafeMethodMap().getOrDefault(updated.getMethodType(), false)) { - return original; - } JavaType.Class returnType = (JavaType.Class) updated.getMethodType().getReturnType(); JavaType.Class updatedReturnType = TimeClassMap.getJavaTimeType(returnType.getFullyQualifiedName()); if (updatedReturnType == null) { @@ -282,7 +352,18 @@ private Optional applyTemplate(MethodCall original, MethodCall updated, Metho } private boolean isJodaVarRef(@Nullable Expression expr) { - if (expr == null || expr.getType() == null || !expr.getType().isAssignableFrom(JODA_CLASS_PATTERN)) { + if (expr == null) { + return false; + } + JavaType type = expr.getType(); + if (type == null) { + return false; + } + if(type instanceof JavaType.Array){ + type = ((JavaType.Array) type).getElemType(); + } + + if (!type.isAssignableFrom(JODA_CLASS_PATTERN )) { return false; } if (expr instanceof J.FieldAccess) { diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDateTimeTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDateTimeTemplates.java index f561541776..bc6ab5e0ea 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDateTimeTemplates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDateTimeTemplates.java @@ -22,47 +22,66 @@ import java.util.ArrayList; import java.util.List; -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JAVA_DATE_TIME; -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_ABSTRACT_DATE_TIME; +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; public class AbstractDateTimeTemplates implements Templates { + private final MethodMatcher getYear = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getYear()"); private final MethodMatcher getDayOfMonth = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getDayOfMonth()"); private final MethodMatcher getDayOfWeek = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getDayOfWeek()"); private final MethodMatcher getHourOfDay = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getHourOfDay()"); private final MethodMatcher getMillisOfSecond = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getMillisOfSecond()"); + private final MethodMatcher getMillisOfDay = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getMillisOfDay()"); private final MethodMatcher getMinuteOfDay = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getMinuteOfDay()"); private final MethodMatcher getMinuteOfHour = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getMinuteOfHour()"); private final MethodMatcher getMonthOfYear = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getMonthOfYear()"); private final MethodMatcher getSecondOfDay = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getSecondOfDay()"); private final MethodMatcher getSecondOfMinute = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getSecondOfMinute()"); private final MethodMatcher getWeekOfWeekyear = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getWeekOfWeekyear()"); + private final MethodMatcher getZone = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " getZone()"); + private final MethodMatcher toCalendar = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " toCalendar(java.util.Locale)"); private final MethodMatcher toString = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " toString()"); + private final MethodMatcher toStringWithPattern = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " toString(java.lang.String)"); + private final JavaTemplate getYearTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getYear()").build(); private final JavaTemplate getDayOfMonthTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getDayOfMonth()").build(); private final JavaTemplate getDayOfWeekTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getDayOfWeek().getValue()").build(); private final JavaTemplate getHourOfDayTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getHour()").build(); private final JavaTemplate getMillisOfSecondTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.get(ChronoField.MILLI_OF_SECOND)").imports("java.time.temporal.ChronoField").build(); + private final JavaTemplate getMilliOfDayTemplate = JavaTemplate.builder("#{any(java. time. ZonedDateTime)}.get(ChronoField.MILLI_OF_DAY)") + .imports(JAVA_CHRONO_FIELD) + .build(); private final JavaTemplate getMinuteOfDayTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.get(ChronoField.MINUTE_OF_DAY)").imports("java.time.temporal.ChronoField").build(); private final JavaTemplate getMinuteOfHourTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getMinute()").build(); private final JavaTemplate getMonthOfYearTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getMonthValue()").build(); private final JavaTemplate getSecondOfDayTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.get(ChronoField.SECOND_OF_DAY)").imports("java.time.temporal.ChronoField").build(); private final JavaTemplate getSecondOfMinuteTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getSecond()").build(); private final JavaTemplate getWeekOfWeekyearTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.get(ChronoField.ALIGNED_WEEK_OF_YEAR)").imports("java.time.temporal.ChronoField").build(); + private final JavaTemplate getZoneTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getZone()").build(); + private final JavaTemplate toCalendarTemplate = JavaTemplate.builder("GregorianCalendar.from(#{any(" + JAVA_DATE_TIME + ")})").build(); private final JavaTemplate toStringTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.toString()").build(); + private final JavaTemplate toStringWithPatternTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.format(DateTimeFormatter.ofPattern(#{any(String)})") + .imports(JAVA_TIME_FORMATTER) + .build(); @Getter private final List templates = new ArrayList() { { + add(new MethodTemplate(getYear, getYearTemplate)); add(new MethodTemplate(getDayOfMonth, getDayOfMonthTemplate)); add(new MethodTemplate(getDayOfWeek, getDayOfWeekTemplate)); add(new MethodTemplate(getHourOfDay, getHourOfDayTemplate)); add(new MethodTemplate(getMillisOfSecond, getMillisOfSecondTemplate)); + add(new MethodTemplate(getMillisOfDay, getMilliOfDayTemplate)); add(new MethodTemplate(getMinuteOfDay, getMinuteOfDayTemplate)); add(new MethodTemplate(getMinuteOfHour, getMinuteOfHourTemplate)); add(new MethodTemplate(getMonthOfYear, getMonthOfYearTemplate)); add(new MethodTemplate(getSecondOfDay, getSecondOfDayTemplate)); add(new MethodTemplate(getSecondOfMinute, getSecondOfMinuteTemplate)); add(new MethodTemplate(getWeekOfWeekyear, getWeekOfWeekyearTemplate)); + add(new MethodTemplate(getZone, getZoneTemplate)); + add(new MethodTemplate(toCalendar, toCalendarTemplate)); + + add(new MethodTemplate(toStringWithPattern, toStringWithPatternTemplate)); add(new MethodTemplate(toString, toStringTemplate)); } }; diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDurationTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDurationTemplates.java index eb1422b678..53d38c92a7 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDurationTemplates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractDurationTemplates.java @@ -23,20 +23,31 @@ import java.util.List; import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JAVA_DURATION; -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_DURATION; +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_ABSTRACT_DURATION; public class AbstractDurationTemplates implements Templates { - private final MethodMatcher isLongerThan = new MethodMatcher(JODA_DURATION + " isLongerThan(..)"); - private final MethodMatcher toPeriod = new MethodMatcher(JODA_DURATION + " toPeriod()"); + private final MethodMatcher isLongerThan = new MethodMatcher(JODA_ABSTRACT_DURATION + " isLongerThan(..)"); + private final MethodMatcher toPeriod = new MethodMatcher(JODA_ABSTRACT_DURATION + " toPeriod()"); + private final MethodMatcher toString = new MethodMatcher(JODA_ABSTRACT_DURATION + " toString()"); + private final MethodMatcher compareTo = new MethodMatcher(JODA_ABSTRACT_DURATION + " compareTo(org.joda.time.ReadableDuration)"); + private final MethodMatcher isEquals = new MethodMatcher(JODA_ABSTRACT_DURATION + " isEqual(org.joda.time.ReadableDuration)"); + private final MethodMatcher equals = new MethodMatcher(JODA_ABSTRACT_DURATION + " equals(Object)"); private final JavaTemplate isLongerThanTemplate = JavaTemplate.builder("#{any(" + JAVA_DURATION + ")}.compareTo(#{any(" + JAVA_DURATION + ")}) > 0").build(); private final JavaTemplate toPeriodTemplate = JavaTemplate.builder("#{any(" + JAVA_DURATION + ")}.toPeriod()").build(); + private final JavaTemplate toStringTemplate = JavaTemplate.builder("#{any(" + JAVA_DURATION + ")}.toString()").build(); + private final JavaTemplate compareToTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.compareTo(#{any(java.time.Duration)})").build(); + private final JavaTemplate equalsTemplate = JavaTemplate.builder("#{any(" + JAVA_DURATION + ")}.equals(#{any(Object)})").build(); @Getter private final List templates = new ArrayList() { { add(new MethodTemplate(isLongerThan, isLongerThanTemplate)); add(new MethodTemplate(toPeriod, toPeriodTemplate)); + add(new MethodTemplate(toString, toStringTemplate)); + add(new MethodTemplate(compareTo, compareToTemplate)); + add(new MethodTemplate(isEquals, equalsTemplate)); + add(new MethodTemplate(equals, equalsTemplate)); } }; } diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractInstantTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractInstantTemplates.java index 77a29c3d71..d28bf82c45 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractInstantTemplates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractInstantTemplates.java @@ -34,15 +34,18 @@ public class AbstractInstantTemplates implements Templates { private final MethodMatcher getZone = new MethodMatcher(JODA_ABSTRACT_INSTANT + " getZone()"); private final MethodMatcher isAfterLong = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isAfter(long)"); private final MethodMatcher isAfter = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isAfter(org.joda.time.ReadableInstant)"); + private final MethodMatcher isAfterNow = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isAfterNow()"); private final MethodMatcher isBeforeLong = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isBefore(long)"); private final MethodMatcher isBefore = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isBefore(org.joda.time.ReadableInstant)"); private final MethodMatcher isBeforeNow = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isBeforeNow()"); private final MethodMatcher isEqualLong = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isEqual(long)"); private final MethodMatcher isEqualReadableInstant = new MethodMatcher(JODA_ABSTRACT_INSTANT + " isEqual(org.joda.time.ReadableInstant)"); private final MethodMatcher toDate = new MethodMatcher(JODA_ABSTRACT_INSTANT + " toDate()"); + private final MethodMatcher toDateTime = new MethodMatcher(JODA_ABSTRACT_INSTANT + " toDateTime()"); private final MethodMatcher toInstant = new MethodMatcher(JODA_ABSTRACT_INSTANT + " toInstant()"); private final MethodMatcher toString = new MethodMatcher(JODA_ABSTRACT_INSTANT + " toString()"); private final MethodMatcher toStringFormatter = new MethodMatcher(JODA_ABSTRACT_INSTANT + " toString(org.joda.time.format.DateTimeFormatter)"); + private final MethodMatcher compareTo = new MethodMatcher(JODA_ABSTRACT_INSTANT + " compareTo(org.joda.time.ReadableInstant)"); private final JavaTemplate equalsTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.equals(#{any(java.lang.Object)})").build(); private final JavaTemplate getZoneTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.getZone()").build(); @@ -52,6 +55,7 @@ public class AbstractInstantTemplates implements Templates { .imports(JAVA_INSTANT).build(); private final JavaTemplate isAfterTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.isAfter(#{any(" + JAVA_DATE_TIME + ")})").build(); private final JavaTemplate isAfterTemplateWithInstant = JavaTemplate.builder("#{any(" + JAVA_INSTANT + ")}.isAfter(#{any(" + JAVA_INSTANT + ")})").build(); + private final JavaTemplate isAfterNowTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.isAfter(ZonedDateTime.now())").build(); private final JavaTemplate isBeforeLongTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.isBefore(Instant.ofEpochMilli(#{any(long)}).atZone(ZoneId.systemDefault()))") .imports(JAVA_INSTANT, JAVA_ZONE_ID).build(); private final JavaTemplate isBeforeLongTemplateWithInstant = JavaTemplate.builder("#{any(" + JAVA_INSTANT + ")}.isBefore(Instant.ofEpochMilli(#{any(long)}))") @@ -66,9 +70,11 @@ public class AbstractInstantTemplates implements Templates { private final JavaTemplate toDateTemplate = JavaTemplate.builder("Date.from(#{any(" + JAVA_DATE_TIME + ")}.toInstant())") .imports(JAVA_UTIL_DATE) .build(); + private final JavaTemplate toDateTimeTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}").build(); private final JavaTemplate toInstantTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.toInstant()").build(); private final JavaTemplate toStringTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.toString()").build(); private final JavaTemplate toStringFormatterTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.format(#{any(" + JAVA_TIME_FORMATTER + ")})").build(); + private final JavaTemplate compareToTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.compareTo(#{any(java.time.ZonedDateTime)})").build(); @Getter private final List templates = new ArrayList() { @@ -79,6 +85,7 @@ public class AbstractInstantTemplates implements Templates { add(new MethodTemplate(isAfterLong, isAfterLongTemplateWithInstant)); add(new MethodTemplate(isAfter, isAfterTemplate)); add(new MethodTemplate(isAfter, isAfterTemplateWithInstant)); + add(new MethodTemplate(isAfterNow, isAfterNowTemplate)); add(new MethodTemplate(isBeforeLong, isBeforeLongTemplate)); add(new MethodTemplate(isBeforeLong, isBeforeLongTemplateWithInstant)); add(new MethodTemplate(isBefore, isBeforTemplate)); @@ -87,9 +94,11 @@ public class AbstractInstantTemplates implements Templates { add(new MethodTemplate(isEqualLong, isEqualLongTemplate)); add(new MethodTemplate(isEqualReadableInstant, isEqualReadableInstantTemplate)); add(new MethodTemplate(toDate, toDateTemplate)); + add(new MethodTemplate(toDateTime, toDateTimeTemplate)); add(new MethodTemplate(toInstant, toInstantTemplate)); add(new MethodTemplate(toString, toStringTemplate)); add(new MethodTemplate(toStringFormatter, toStringFormatterTemplate)); + add(new MethodTemplate(compareTo, compareToTemplate)); } }; diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractIntervalTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractIntervalTemplates.java index 9fe69cdf14..47c8c803f1 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractIntervalTemplates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractIntervalTemplates.java @@ -31,34 +31,68 @@ public class AbstractIntervalTemplates implements Templates { private final MethodMatcher toDuration = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " toDuration()"); private final MethodMatcher toDurationMillis = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " toDurationMillis()"); private final MethodMatcher contains = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " contains(long)"); + private final MethodMatcher containsReadableInstant = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " contains(org.joda.time.ReadableInstant)"); + private final MethodMatcher overlaps = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " overlaps(org.joda.time.ReadableInterval)"); + private final MethodMatcher containsInterval = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " contains(org.joda.time.ReadableInterval)"); + private final MethodMatcher equals = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " equals(java.lang.Object)"); + private final MethodMatcher isBeforeReadableInstant = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " isBefore(org.joda.time.ReadableInstant)"); + private final MethodMatcher isAfterReadableInstant = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " isAfter(org.joda.time.ReadableInstant)"); + private final MethodMatcher isBeforeReadableInterval = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " isBefore(org.joda.time.ReadableInterval )"); + private final MethodMatcher isAfterReadableInterval = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " isAfter(org.joda.time.ReadableInterval)"); + private final MethodMatcher containsNow = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " containsNow()"); + private final MethodMatcher isAfterNow = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " isAfterNow()"); + private final MethodMatcher isBeforeNow = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " isBeforeNow()"); + private final MethodMatcher toString = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " toString()"); + //.isAfter( org. joda. time. ReadableInterval ) - private final JavaTemplate getStartTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.getStart().atZone(ZoneId.systemDefault())") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .imports(JAVA_ZONE_ID) - .build(); - private final JavaTemplate getEndTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.getEnd().atZone(ZoneId.systemDefault())") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .imports(JAVA_ZONE_ID) - .build(); - private final JavaTemplate toDurationTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.toDuration()") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .build(); - private final JavaTemplate toDurationMillisTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.toDuration().toMillis()") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .build(); - private final JavaTemplate containsTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.contains(Instant.ofEpochMilli(#{any(long)}))") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .imports(JAVA_INSTANT) - .build(); + + private final JavaTemplate.Builder getStartTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.getStart()") + .imports(JAVA_ZONE_ID); + private final JavaTemplate.Builder getEndTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.getEnd().atZone(ZoneId.systemDefault())") + .imports(JAVA_ZONE_ID); + private final JavaTemplate.Builder toDurationTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.toDuration()"); + private final JavaTemplate.Builder toDurationMillisTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.toDuration().toMillis()"); + private final JavaTemplate.Builder containsTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.contains(Instant.ofEpochMilli(#{any(long)}))") + .imports(JAVA_INSTANT); + private final JavaTemplate.Builder containsInstantTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.contains(#{any(java.time.ZonedDateTime)}.toInstant())"); + private final JavaTemplate.Builder overlapsTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.overlaps(#{any(org.threeten.extra.Interval)})"); + private final JavaTemplate.Builder containsIntervalTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.encloses(#{any(org.threeten.extra.Interval)})"); + private final JavaTemplate.Builder equalsTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.equals(#{any(org.threeten.extra.Interval)})"); + private final JavaTemplate.Builder isBeforeReadableInstantTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.isBefore(#{any(java.time.ZonedDateTime)}.toInstant())"); + private final JavaTemplate.Builder isAfterReadableInstantTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.isAfter(#{any(java.time.ZonedDateTime)}.toInstant())"); + private final JavaTemplate.Builder isBeforeReadableIntervalTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.isBefore(#{any(org.threeten.extra.Interval)}.toInstant())"); + private final JavaTemplate.Builder isAfterReadableIntervalTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.isAfter(#{any(org.threeten.extra.Interval)}.toInstant())"); + private final JavaTemplate.Builder containsNowTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.contains(Instant.now())"); + private final JavaTemplate.Builder isAfterNowTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.isAfter(Instant.now())"); + private final JavaTemplate.Builder isBeforeNowTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.isBefore(Instant.now())"); + private final JavaTemplate.Builder toStringTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.toString()"); @Getter private final List templates = new ArrayList() { { - add(new MethodTemplate(getStart, getStartTemplate)); - add(new MethodTemplate(getEnd, getEndTemplate)); - add(new MethodTemplate(toDuration, toDurationTemplate)); - add(new MethodTemplate(toDurationMillis, toDurationMillisTemplate)); - add(new MethodTemplate(contains, containsTemplate)); + add(new MethodTemplate(getStart, build(getStartTemplate))); + add(new MethodTemplate(getEnd, build(getEndTemplate))); + add(new MethodTemplate(toDuration, build(toDurationTemplate))); + add(new MethodTemplate(toDurationMillis, build(toDurationMillisTemplate))); + add(new MethodTemplate(containsReadableInstant, build(containsInstantTemplate))); + add(new MethodTemplate(contains, build(containsTemplate))); + add(new MethodTemplate(overlaps, build(overlapsTemplate))); + add(new MethodTemplate(containsInterval, build(containsIntervalTemplate))); + add(new MethodTemplate(equals, build(equalsTemplate))); + add(new MethodTemplate(isBeforeReadableInstant, build(isBeforeReadableInstantTemplate))); + add(new MethodTemplate(isAfterReadableInstant, build(isAfterReadableInstantTemplate))); + add(new MethodTemplate(isBeforeReadableInterval, build(isBeforeReadableIntervalTemplate))); + add(new MethodTemplate(isAfterReadableInterval, build(isAfterReadableIntervalTemplate))); + add(new MethodTemplate(containsNow, build(containsNowTemplate))); + add(new MethodTemplate(isAfterNow, build(isAfterNowTemplate))); + add(new MethodTemplate(isBeforeNow, build(isBeforeNowTemplate))); + add(new MethodTemplate(toString, build(toStringTemplate))); } }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return builder + .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) + .build(); + } } diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractPartialTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractPartialTemplates.java new file mode 100644 index 0000000000..82ff2a5caa --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractPartialTemplates.java @@ -0,0 +1,44 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_ABSTRACT_PARTIAL; + +public class AbstractPartialTemplates implements Templates { + private final MethodMatcher isAfter = new MethodMatcher(JODA_ABSTRACT_PARTIAL + " isAfter(org.joda.time.ReadablePartial)"); + private final MethodMatcher isBefore = new MethodMatcher(JODA_ABSTRACT_PARTIAL + " isBefore(org.joda.time.ReadablePartial)"); + private final MethodMatcher isEqual = new MethodMatcher(JODA_ABSTRACT_PARTIAL + " isEqual(org.joda.time.ReadablePartial)"); + + private final JavaTemplate isAfterTemplate = JavaTemplate.builder("#{any(java.time.chrono.ChronoLocalDate)}.isAfter(#{any(java.time.chrono.ChronoLocalDate)})").build(); + private final JavaTemplate isBeforeTemplate = JavaTemplate.builder("#{any(java.time.chrono.ChronoLocalDate)}.isBefore(#{any(java.time.chrono.ChronoLocalDate)})").build(); + private final JavaTemplate isEqualTemplate = JavaTemplate.builder("#{any(java.time.chrono.ChronoLocalDate)}.isEqual(#{any(java.time.chrono.ChronoLocalDate)})").build(); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(isAfter, isAfterTemplate)); + add(new MethodTemplate(isBefore, isBeforeTemplate)); + add(new MethodTemplate(isEqual, isEqualTemplate)); + } + }; +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractPeriodTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractPeriodTemplates.java new file mode 100644 index 0000000000..7fdcbd0314 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/AbstractPeriodTemplates.java @@ -0,0 +1,41 @@ +/* + * Copyright 2025 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_ABSTRACT_PERIOD; +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_PERIOD; + +@NoArgsConstructor +public class AbstractPeriodTemplates implements Templates{ + final MethodMatcher toString = new MethodMatcher(JODA_ABSTRACT_PERIOD + " toString()"); + + final JavaTemplate toStringTemplate = JavaTemplate.builder("#{any(java.time.Period)}.getDays()").build(); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(toString, toStringTemplate)); + } + }; +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/AllTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/AllTemplates.java index 3d79830153..4e6565e5da 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/AllTemplates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/AllTemplates.java @@ -29,11 +29,16 @@ public class AllTemplates { private static final MethodMatcher ANY_BASE_DATETIME = new MethodMatcher(JODA_BASE_DATE_TIME + " *(..)"); private static final MethodMatcher ANY_NEW_DATE_TIME = new MethodMatcher(JODA_DATE_TIME + "(..)"); private static final MethodMatcher ANY_DATE_TIME = new MethodMatcher(JODA_DATE_TIME + " *(..)"); + private static final MethodMatcher ANY_NEW_DATE_MIDNIGHT = new MethodMatcher(JODA_DATE_MIDNIGHT + "(..)"); + private static final MethodMatcher ANY_DATE_MIDNIGHT = new MethodMatcher(JODA_DATE_MIDNIGHT + "*(..)"); private static final MethodMatcher ANY_DATE_TIMEZONE = new MethodMatcher(JODA_DATE_TIME_ZONE + " *(..)"); private static final MethodMatcher ANY_TIME_FORMAT = new MethodMatcher(JODA_TIME_FORMAT + " *(..)"); private static final MethodMatcher ANY_TIME_FORMATTER = new MethodMatcher(JODA_TIME_FORMATTER + " *(..)"); private static final MethodMatcher ANY_NEW_DURATION = new MethodMatcher(JODA_DURATION + "(..)"); private static final MethodMatcher ANY_DURATION = new MethodMatcher(JODA_DURATION + " *(..)"); + private static final MethodMatcher ANY_NEW_PERIOD = new MethodMatcher(JODA_PERIOD + "(..)"); + private static final MethodMatcher ANY_ABSTRACT_PERIOD = new MethodMatcher(JODA_ABSTRACT_PERIOD + " *(..)"); + private static final MethodMatcher ANY_PERIOD = new MethodMatcher(JODA_PERIOD + " *(..)"); private static final MethodMatcher ANY_BASE_DURATION = new MethodMatcher(JODA_BASE_DURATION + " *(..)"); private static final MethodMatcher ANY_ABSTRACT_INSTANT = new MethodMatcher(JODA_ABSTRACT_INSTANT + " *(..)"); private static final MethodMatcher ANY_ABSTRACT_DATE_TIME = new MethodMatcher(JODA_ABSTRACT_DATE_TIME + " *(..)"); @@ -41,8 +46,26 @@ public class AllTemplates { private static final MethodMatcher ANY_INSTANT = new MethodMatcher(JODA_INSTANT + " *(..)"); private static final MethodMatcher ANY_NEW_INSTANT = new MethodMatcher(JODA_INSTANT + "(..)"); private static final MethodMatcher ANY_NEW_INTERVAL = new MethodMatcher(JODA_INTERVAL + "(..)"); + private static final MethodMatcher ANY_INTERVAL = new MethodMatcher(JODA_INTERVAL + "*(..)"); private static final MethodMatcher ANY_ABSTRACT_INTERVAL = new MethodMatcher(JODA_ABSTRACT_INTERVAL + " *(..)"); + private static final MethodMatcher ANY_ABSTRACT_PARTIAL = new MethodMatcher(JODA_ABSTRACT_PARTIAL + " *(..)"); private static final MethodMatcher ANY_BASE_INTERVAL = new MethodMatcher(JODA_BASE_INTERVAL + " *(..)"); + private static final MethodMatcher ANY_NEW_LOCAL_DATE = new MethodMatcher(JODA_LOCAL_DATE + "(..)"); + private static final MethodMatcher ANY_LOCAL_DATE = new MethodMatcher(JODA_LOCAL_DATE + " *(..)"); + private static final MethodMatcher ANY_NEW_LOCAL_DATE_TIME = new MethodMatcher(JODA_LOCAL_DATE_TIME + "(..)"); + private static final MethodMatcher ANY_LOCAL_DATE_TIME = new MethodMatcher(JODA_LOCAL_DATE_TIME + " *(..)"); + private static final MethodMatcher ANY_NEW_LOCAL_TIME = new MethodMatcher(JODA_LOCAL_TIME + "(..)"); + private static final MethodMatcher ANY_LOCAL_TIME = new MethodMatcher(JODA_LOCAL_TIME + " *(..)"); + private static final MethodMatcher ANY_SECONDS = new MethodMatcher(JODA_SECONDS + " *(..)"); + private static final MethodMatcher ANY_MINUTES = new MethodMatcher(JODA_MINUTES + " *(..)"); + private static final MethodMatcher ANY_HOURS = new MethodMatcher(JODA_HOURS + " *(..)"); + private static final MethodMatcher ANY_DAYS = new MethodMatcher(JODA_DAYS + " *(..)"); + private static final MethodMatcher ANY_WEEKS = new MethodMatcher(JODA_WEEKS + " *(..)"); + private static final MethodMatcher ANY_MONTHS = new MethodMatcher(JODA_MONTHS + " *(..)"); + private static final MethodMatcher ANY_YEARS = new MethodMatcher(JODA_YEARS + " *(..)"); + private static final MethodMatcher ANY_JODA_DATE_TIME_UTILS = new MethodMatcher(JODA_DATE_TIME_UTILS + " *(..)"); + private static final MethodMatcher ANY_JODA_BASIC_CHRONOLOGY = new MethodMatcher(JODA_BASIC_CHRONOLOGY + " *(..)"); + private static final MethodMatcher ANY_JODA_GEORGIAN_CHRONOLOGY = new MethodMatcher(JODA_GEORGIAN_CHRONOLOGY + " *(..)"); private static List templates = new ArrayList() { { @@ -54,15 +77,38 @@ public class AllTemplates { add(new MatcherAndTemplates(ANY_TIME_FORMATTER, new DateTimeFormatterTemplates())); add(new MatcherAndTemplates(ANY_NEW_DATE_TIME, new DateTimeTemplates())); add(new MatcherAndTemplates(ANY_DATE_TIME, new DateTimeTemplates())); + add(new MatcherAndTemplates(ANY_NEW_DATE_MIDNIGHT, new DateMidnightTemplates())); + add(new MatcherAndTemplates(ANY_DATE_MIDNIGHT, new DateMidnightTemplates())); add(new MatcherAndTemplates(ANY_NEW_DURATION, new DurationTemplates())); add(new MatcherAndTemplates(ANY_DURATION, new DurationTemplates())); + add(new MatcherAndTemplates(ANY_NEW_PERIOD, new PeriodTemplates())); + add(new MatcherAndTemplates(ANY_ABSTRACT_PERIOD, new AbstractPeriodTemplates())); + add(new MatcherAndTemplates(ANY_PERIOD, new PeriodTemplates())); add(new MatcherAndTemplates(ANY_BASE_DURATION, new BaseDurationTemplates())); - add(new MatcherAndTemplates(ANY_DATE_TIMEZONE, new TimeZoneTemplates())); + add(new MatcherAndTemplates(ANY_DATE_TIMEZONE, new DateTimeZoneTemplates())); add(new MatcherAndTemplates(ANY_INSTANT, new InstantTemplates())); add(new MatcherAndTemplates(ANY_NEW_INSTANT, new InstantTemplates())); add(new MatcherAndTemplates(ANY_NEW_INTERVAL, new IntervalTemplates())); + add(new MatcherAndTemplates(ANY_INTERVAL, new IntervalTemplates())); add(new MatcherAndTemplates(ANY_ABSTRACT_INTERVAL, new AbstractIntervalTemplates())); + add(new MatcherAndTemplates(ANY_ABSTRACT_PARTIAL, new AbstractPartialTemplates())); add(new MatcherAndTemplates(ANY_BASE_INTERVAL, new BaseIntervalTemplates())); + add(new MatcherAndTemplates(ANY_NEW_LOCAL_DATE, new LocatDateTemplates())); + add(new MatcherAndTemplates(ANY_LOCAL_DATE, new LocatDateTemplates())); + add(new MatcherAndTemplates(ANY_NEW_LOCAL_DATE_TIME, new LocatDateTimeTemplates())); + add(new MatcherAndTemplates(ANY_LOCAL_DATE_TIME, new LocatDateTimeTemplates())); + add(new MatcherAndTemplates(ANY_NEW_LOCAL_TIME, new LocatTimeTemplates())); + add(new MatcherAndTemplates(ANY_LOCAL_TIME, new LocatTimeTemplates())); + add(new MatcherAndTemplates(ANY_SECONDS, new SecondsTemplates())); + add(new MatcherAndTemplates(ANY_MINUTES, new MinutesTemplates())); + add(new MatcherAndTemplates(ANY_HOURS, new HoursTemplates())); + add(new MatcherAndTemplates(ANY_DAYS, new DaysTemplates())); + add(new MatcherAndTemplates(ANY_WEEKS, new WeeksTemplates())); + add(new MatcherAndTemplates(ANY_MONTHS, new MonthsTemplates())); + add(new MatcherAndTemplates(ANY_YEARS, new YearsTemplates())); + add(new MatcherAndTemplates(ANY_JODA_DATE_TIME_UTILS, new DateTimeUtilsTemplates())); + add(new MatcherAndTemplates(ANY_JODA_BASIC_CHRONOLOGY, new ChronologyTemplates())); + add(new MatcherAndTemplates(ANY_JODA_GEORGIAN_CHRONOLOGY, new ChronologyTemplates())); } }; diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/BaseDurationTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/BaseDurationTemplates.java index aa23fa6385..e542b3e223 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/BaseDurationTemplates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/BaseDurationTemplates.java @@ -22,11 +22,13 @@ import java.util.ArrayList; import java.util.List; -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JAVA_DURATION; -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_BASE_DURATION; +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; public class BaseDurationTemplates implements Templates { private final MethodMatcher getMillis = new MethodMatcher(JODA_BASE_DURATION + " getMillis()"); + private final MethodMatcher toPeriodDayTime = new MethodMatcher(JODA_BASE_DURATION + " toPeriod(" + JODA_PERIOD_TYPE + ")"); + + //.toPeriod(PeriodType.dayTime()) private final JavaTemplate getMillisTemplate = JavaTemplate.builder("#{any(" + JAVA_DURATION + ")}.toMillis()").build(); @@ -34,6 +36,8 @@ public class BaseDurationTemplates implements Templates { private final List templates = new ArrayList() { { add(new MethodTemplate(getMillis, getMillisTemplate)); + + add(new MethodTemplate(toPeriodDayTime, JODA_NO_AUTOMATIC_MAPPING_POSSIBLE_TEMPLATE)); } }; } diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/ChronologyTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/ChronologyTemplates.java new file mode 100644 index 0000000000..d93f820b16 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/ChronologyTemplates.java @@ -0,0 +1,50 @@ +/* + * Copyright 2025 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; + +//todo mapping is not working +@NoArgsConstructor +public class ChronologyTemplates implements Templates{ + final MethodMatcher getInstanceUTC = new MethodMatcher(JODA_GEORGIAN_CHRONOLOGY + " getInstanceUTC()"); + final MethodMatcher getInstance = new MethodMatcher(JODA_GEORGIAN_CHRONOLOGY + " getInstance()"); + final MethodMatcher getDateTimeMillis = new MethodMatcher(JODA_BASIC_CHRONOLOGY + " getDateTimeMillis(int,int,int,int)"); + + final JavaTemplate.Builder instanceTemplate = JavaTemplate.builder("IsoChronology.INSTANCE"); + final JavaTemplate.Builder epochSecondTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.epochSecond(#{any(int)},#{any(int)},#{any(int)},#{any(int)},0,0,0,ZoneOffset.ofTotalSeconds(0))") + .imports(JAVA_ZONE_OFFSET); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(getInstanceUTC, build(instanceTemplate))); + add(new MethodTemplate(getDateTimeMillis, build(epochSecondTemplate))); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, JAVA_ISA_CHRONOLOGY); + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/DateMidnightTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/DateMidnightTemplates.java new file mode 100644 index 0000000000..392ffdc277 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/DateMidnightTemplates.java @@ -0,0 +1,51 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; +import org.openrewrite.java.tree.Expression; +import org.openrewrite.java.tree.J; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; + +@NoArgsConstructor +public class DateMidnightTemplates implements Templates { + private final MethodMatcher newDateMidnight = new MethodMatcher(JODA_DATE_MIDNIGHT + "()"); + private final MethodMatcher newDateMidnightAtDate = new MethodMatcher(JODA_DATE_MIDNIGHT + "(int, int, int)"); + + private final JavaTemplate.Builder dateTimeTemplate = JavaTemplate.builder("LocalDate.now().atStartOfDay(ZoneId.systemDefault())") + .imports(JAVA_ZONE_ID); + private final JavaTemplate.Builder dateTimeWithYMD = JavaTemplate.builder("LocalDate.of(#{any(int)}, #{any(int)}, #{any(int)}).atStartOfDay(ZoneId.systemDefault())") + .imports(JAVA_ZONE_ID); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(newDateMidnight, build(dateTimeTemplate))); + add(new MethodTemplate(newDateMidnightAtDate, build(dateTimeWithYMD))); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, JAVA_DATE_TIME); + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeFormatterTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeFormatterTemplates.java index 711ec20166..03f25ab0cc 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeFormatterTemplates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeFormatterTemplates.java @@ -31,8 +31,10 @@ public class DateTimeFormatterTemplates implements Templates { private final MethodMatcher parseMillis = new MethodMatcher(JODA_TIME_FORMATTER + " parseMillis(java.lang.String)"); private final MethodMatcher printLong = new MethodMatcher(JODA_TIME_FORMATTER + " print(long)"); private final MethodMatcher printDateTime = new MethodMatcher(JODA_TIME_FORMATTER + " print(org.joda.time.ReadableInstant)"); + private final MethodMatcher printLocalDate = new MethodMatcher(JODA_TIME_FORMATTER + " print(org.joda.time.ReadablePartial)"); private final MethodMatcher withZone = new MethodMatcher(JODA_TIME_FORMATTER + " withZone(org.joda.time.DateTimeZone)"); private final MethodMatcher withZoneUTC = new MethodMatcher(JODA_TIME_FORMATTER + " withZoneUTC()"); + private final MethodMatcher parseLocalDate = new MethodMatcher(JODA_TIME_FORMATTER + " parseLocalDate(java.lang.String)"); private final JavaTemplate parseDateTimeTemplate = JavaTemplate.builder("ZonedDateTime.parse(#{any(java.lang.String)}, #{any(" + JAVA_TIME_FORMATTER + ")})") .imports(JAVA_DATE_TIME).build(); @@ -42,9 +44,11 @@ public class DateTimeFormatterTemplates implements Templates { .imports(JAVA_DATE_TIME, JAVA_INSTANT, JAVA_ZONE_ID) .build(); private final JavaTemplate printDateTimeTemplate = JavaTemplate.builder("#{any(" + JAVA_DATE_TIME + ")}.format(#{any(" + JAVA_TIME_FORMATTER + ")})").build(); + private final JavaTemplate printLocalDateTemplate = JavaTemplate.builder("#{any(" + JAVA_LOCAL_DATE + ")}.format(#{any(" + JAVA_TIME_FORMATTER + ")})").build(); private final JavaTemplate withZoneTemplate = JavaTemplate.builder("#{any(" + JAVA_TIME_FORMATTER + ")}.withZone(#{any(" + JAVA_ZONE_ID + ")})").build(); private final JavaTemplate withZoneUTCTemplate = JavaTemplate.builder("#{any(" + JAVA_TIME_FORMATTER + ")}.withZone(ZoneOffset.UTC)") .imports(JAVA_ZONE_OFFSET).build(); + private final JavaTemplate parseTemplate = JavaTemplate.builder("#{any(" + JAVA_TIME_FORMATTER + ")}.parse(#{any(java.lang.String)})").build(); @Getter private final List templates = new ArrayList() { @@ -65,8 +69,13 @@ public class DateTimeFormatterTemplates implements Templates { J.MethodInvocation mi = (J.MethodInvocation) m; return new Expression[]{mi.getArguments().get(0), mi.getSelect()}; })); + add(new MethodTemplate(printLocalDate, printLocalDateTemplate, m -> { + J.MethodInvocation mi = (J.MethodInvocation) m; + return new Expression[]{mi.getArguments().get(0), mi.getSelect()}; + })); add(new MethodTemplate(withZone, withZoneTemplate)); add(new MethodTemplate(withZoneUTC, withZoneUTCTemplate)); + add(new MethodTemplate(parseLocalDate, parseTemplate)); } }; } diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeTemplates.java index 85ea7b451f..14f5c2c014 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeTemplates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeTemplates.java @@ -30,9 +30,11 @@ @NoArgsConstructor public class DateTimeTemplates implements Templates { private final MethodMatcher newDateTime = new MethodMatcher(JODA_DATE_TIME + "()"); + private final MethodMatcher newDateInstant = new MethodMatcher(JODA_DATE_TIME + "(java.lang.Object)"); private final MethodMatcher newDateTimeWithZone = new MethodMatcher(JODA_DATE_TIME + "(" + JODA_DATE_TIME_ZONE + ")"); private final MethodMatcher newDateTimeWithEpoch = new MethodMatcher(JODA_DATE_TIME + "(long)"); private final MethodMatcher newDateTimeWithEpochAndZone = new MethodMatcher(JODA_DATE_TIME + "(long, " + JODA_DATE_TIME_ZONE + ")"); + private final MethodMatcher newDateTimeWithEpochObjectAndZone = new MethodMatcher(JODA_DATE_TIME + "(java.lang.Object, " + JODA_DATE_TIME_ZONE + ")"); private final MethodMatcher newDateTimeWithMin = new MethodMatcher(JODA_DATE_TIME + "(int, int, int, int, int)"); private final MethodMatcher newDateTimeWithMinAndZone = new MethodMatcher(JODA_DATE_TIME + "(int, int, int, int, int, " + JODA_DATE_TIME_ZONE + ")"); private final MethodMatcher newDateTimeWithSec = new MethodMatcher(JODA_DATE_TIME + "(int, int, int, int, int, int)"); @@ -120,227 +122,170 @@ public class DateTimeTemplates implements Templates { private final MethodMatcher secondOfMinute = new MethodMatcher(JODA_DATE_TIME + " secondOfMinute()"); private final MethodMatcher millisOfDay = new MethodMatcher(JODA_DATE_TIME + " millisOfDay()"); private final MethodMatcher millisOfSecond = new MethodMatcher(JODA_DATE_TIME + " millisOfSecond()"); + private final MethodMatcher dateTimeGetZone = new MethodMatcher(JODA_DATE_TIME + " getZone()"); + //clientTime.getZone().getOffsetFromLocal(clientTime.getMillis()) + //start.plusDays(1) - private final JavaTemplate dateTimeTemplate = JavaTemplate.builder("ZonedDateTime.now()") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate dateTimeWithZoneTemplate = JavaTemplate.builder("ZonedDateTime.now(#{any(java.time.ZoneOffset)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate dateTimeWithEpochTemplate = JavaTemplate.builder("ZonedDateTime.ofInstant(Instant.ofEpochMilli(#{any(long)}), ZoneId.systemDefault())") - .imports(JAVA_DATE_TIME, JAVA_ZONE_ID, JAVA_INSTANT) - .build(); - private final JavaTemplate dateTimeWithEpochAndZoneTemplate = JavaTemplate.builder("ZonedDateTime.ofInstant(Instant.ofEpochMilli(#{any(long)}), #{any(java.time.ZoneId)})") - .imports(JAVA_DATE_TIME, JAVA_ZONE_OFFSET, JAVA_ZONE_ID, JAVA_INSTANT) - .build(); - private final JavaTemplate dateTimeWithMinTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, 0, 0, ZoneId.systemDefault())") - .imports(JAVA_DATE_TIME, JAVA_ZONE_ID) - .build(); - private final JavaTemplate dateTimeWithMinAndZoneTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, 0, 0, #{any(java.time.ZoneId)})") - .imports(JAVA_DATE_TIME, JAVA_ZONE_ID) - .build(); - private final JavaTemplate dateTimeWithSecTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, 0, ZoneId.systemDefault())") - .imports(JAVA_DATE_TIME, JAVA_ZONE_ID) - .build(); - private final JavaTemplate dateTimeWithSecAndZoneTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, 0, #{any(java.time.ZoneId)})") - .imports(JAVA_DATE_TIME, JAVA_ZONE_ID) - .build(); - private final JavaTemplate dateTimeWithMillisTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)} * 1_000_000, ZoneId.systemDefault())") - .imports(JAVA_DATE_TIME, JAVA_ZONE_ID) - .build(); - private final JavaTemplate dateTimeWithMillisAndZoneTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)} * 1_000_000, #{any(java.time.ZoneId)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate dateTimeParseTemplate = JavaTemplate.builder("ZonedDateTime.parse(#{any(String)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate dateTimeParseWithFormatterTemplate = JavaTemplate.builder("ZonedDateTime.parse(#{any(String)}, #{any(java.time.format.DateTimeFormatter)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate toDateTimeTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}") - .build(); - private final JavaTemplate getMillisTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toInstant().toEpochMilli()") - .build(); - private final JavaTemplate withMillisTemplate = JavaTemplate.builder("ZonedDateTime.ofInstant(Instant.ofEpochMilli(#{any(long)}),#{any(java.time.ZonedDateTime)}.getZone())") - .imports(JAVA_DATE_TIME, JAVA_INSTANT) - .build(); - private final JavaTemplate withZoneTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withZoneSameInstant(#{any(java.time.ZoneId)})") - .build(); - private final JavaTemplate withZoneRetainFieldsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withZoneSameLocal(#{any(java.time.ZoneId)})") - .build(); - private final JavaTemplate withEarlierOffsetAtOverlapTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withEarlierOffsetAtOverlap()") - .build(); - private final JavaTemplate withLaterOffsetAtOverlapTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withLaterOffsetAtOverlap()") - .build(); - private final JavaTemplate withDateTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withYear(#{any(int)}).withMonth(#{any(int)}).withDayOfMonth(#{any(int)})") - .build(); - private final JavaTemplate withTemporalAdjusterTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(#{any(java.time.temporal.TemporalAdjuster)})") - .imports(JAVA_TEMPORAL_ADJUSTER) - .build(); - private final JavaTemplate withTimeTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withHour(#{any(int)}).withMinute(#{any(int)}).withSecond(#{any(int)}).withNano(#{any(int)} * 1_000_000)") - .build(); - private final JavaTemplate withTimeAtStartOfDayTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toLocalDate().atStartOfDay(#{any(java.time.ZonedDateTime)}.getZone())") - .build(); - private final JavaTemplate withDurationAddedTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plus(Duration.ofMillis(#{any(long)}).multipliedBy(#{any(int)}))") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate plusReadableDurationTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plus(#{any(java.time.Duration)})") - .build(); - private final JavaTemplate plusYearsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusYears(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate plusMonthsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusMonths(#{any(int)})") - .build(); - private final JavaTemplate plusWeeksTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusWeeks(#{any(int)})") - .build(); - private final JavaTemplate plusDaysTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusDays(#{any(int)})") - .build(); - private final JavaTemplate plusHoursTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusHours(#{any(int)})") - .build(); - private final JavaTemplate plusMinutesTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusMinutes(#{any(int)})") - .build(); - private final JavaTemplate plusSecondsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusSeconds(#{any(int)})") - .build(); - private final JavaTemplate plusMillisTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plus(Duration.ofMillis(#{any(int)}))") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate minusMillisTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minus(Duration.ofMillis(#{any(int)}))") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate minusReadableDurationTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minus(#{any(java.time.Duration)})") - .imports(JAVA_DATE_TIME, JAVA_DURATION) - .build(); - private final JavaTemplate minusYearsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusYears(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate minusMonthsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusMonths(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate minusWeeksTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusWeeks(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate minusDaysTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusDays(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate minusHoursTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusHours(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate minusMinutesTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusMinutes(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate minusSecondsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusSeconds(#{any(int)})") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate toLocalDateTimeTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toLocalDateTime()") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate toLocalDateTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toLocalDate()") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate toLocalTimeTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toLocalTime()") - .imports(JAVA_DATE_TIME) - .build(); - private final JavaTemplate withYearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withYear(#{any(int)})") - .build(); - private final JavaTemplate withWeekyearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(IsoFields.WEEK_BASED_YEAR, #{any(int)})") - .imports(JAVA_TEMPORAL_ISO_FIELDS) - .build(); - private final JavaTemplate withMonthOfYearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withMonth(#{any(int)})") - .build(); - private final JavaTemplate withWeekOfWeekyearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(ChronoField.ALIGNED_WEEK_OF_YEAR, #{any(int)})") - .imports(JAVA_CHRONO_FIELD) - .build(); - private final JavaTemplate withDayOfYearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withDayOfYear(#{any(int)})") - .build(); - private final JavaTemplate withDayOfMonthTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withDayOfMonth(#{any(int)})") - .build(); - private final JavaTemplate withDayOfWeekTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(ChronoField.DAY_OF_WEEK, #{any(int)})") - .imports(JAVA_CHRONO_FIELD) - .build(); - private final JavaTemplate withHourOfDayTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withHour(#{any(int)})") - .build(); - private final JavaTemplate withMinuteOfHourTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withMinute(#{any(int)})") - .build(); - private final JavaTemplate withSecondOfMinuteTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withSecond(#{any(int)})") - .build(); - private final JavaTemplate withMillisOfSecondTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withNano(#{any(int)} * 1_000_000)") - .build(); - private final JavaTemplate withMillisOfDayTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(ChronoField.MILLI_OF_DAY, #{any(int)})") - .imports(JAVA_CHRONO_FIELD) - .build(); + private final JavaTemplate.Builder dateTimeTemplate = JavaTemplate.builder("ZonedDateTime.now()"); + private final JavaTemplate.Builder dateTimeWithZoneTemplate = JavaTemplate.builder("ZonedDateTime.now(#{any(java.time.ZoneOffset)})"); + private final JavaTemplate.Builder dateTimeWithEpochTemplate = JavaTemplate.builder("ZonedDateTime.ofInstant(Instant.ofEpochMilli(#{any(long)}), ZoneId.systemDefault())") + .imports(JAVA_ZONE_ID, JAVA_INSTANT); + private final JavaTemplate.Builder dateTimeWithEpochAndZoneTemplate = JavaTemplate.builder("ZonedDateTime.ofInstant(Instant.ofEpochMilli(#{any(long)}), #{any(java.time.ZoneId)})") + .imports(JAVA_ZONE_ID, JAVA_INSTANT); + private final JavaTemplate.Builder dateTimeWithMinTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, 0, 0, ZoneId.systemDefault())") + .imports(JAVA_ZONE_ID); + private final JavaTemplate.Builder dateTimeWithMinAndZoneTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, 0, 0, #{any(java.time.ZoneId)})") + .imports(JAVA_ZONE_ID); + private final JavaTemplate.Builder dateTimeWithSecTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, 0, ZoneId.systemDefault())") + .imports(JAVA_ZONE_ID); + private final JavaTemplate.Builder dateTimeWithSecAndZoneTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, 0, #{any(java.time.ZoneId)})") + .imports(JAVA_ZONE_ID); + private final JavaTemplate.Builder dateTimeWithMillisTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)} * 1_000_000, ZoneId.systemDefault())") + .imports(JAVA_ZONE_ID); + private final JavaTemplate.Builder dateTimeWithMillisAndZoneTemplate = JavaTemplate.builder("ZonedDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)} * 1_000_000, #{any(java.time.ZoneId)})"); + private final JavaTemplate.Builder dateTimeParseTemplate = JavaTemplate.builder("ZonedDateTime.parse(#{any(String)})"); + private final JavaTemplate.Builder dateTimeParseWithFormatterTemplate = JavaTemplate.builder("ZonedDateTime.parse(#{any(String)}, #{any(java.time.format.DateTimeFormatter)})"); + private final JavaTemplate.Builder toDateTimeTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}"); + private final JavaTemplate.Builder getMillisTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toInstant().toEpochMilli()"); + private final JavaTemplate.Builder withMillisTemplate = JavaTemplate.builder("ZonedDateTime.ofInstant(Instant.ofEpochMilli(#{any(long)}),#{any(java.time.ZonedDateTime)}.getZone())") + .imports(JAVA_DATE_TIME, JAVA_INSTANT); + private final JavaTemplate.Builder withZoneTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withZoneSameInstant(#{any(java.time.ZoneId)})"); + private final JavaTemplate.Builder withZoneRetainFieldsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withZoneSameLocal(#{any(java.time.ZoneId)})"); + private final JavaTemplate.Builder withEarlierOffsetAtOverlapTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withEarlierOffsetAtOverlap()"); + private final JavaTemplate.Builder withLaterOffsetAtOverlapTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withLaterOffsetAtOverlap()"); + private final JavaTemplate.Builder withDateTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withYear(#{any(int)}).withMonth(#{any(int)}).withDayOfMonth(#{any(int)})"); + private final JavaTemplate.Builder withTemporalAdjusterTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(#{any(java.time.temporal.TemporalAdjuster)})") + .imports(JAVA_TEMPORAL_ADJUSTER); + private final JavaTemplate.Builder withTimeTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withHour(#{any(int)}).withMinute(#{any(int)}).withSecond(#{any(int)}).withNano(#{any(int)} * 1_000_000)"); + private final JavaTemplate.Builder withTimeAtStartOfDayTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toLocalDate().atStartOfDay(#{any(java.time.ZonedDateTime)}.getZone())"); + private final JavaTemplate.Builder withDurationAddedTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plus(Duration.ofMillis(#{any(long)}).multipliedBy(#{any(int)}))") + .imports(JAVA_DURATION); + private final JavaTemplate.Builder plusReadableDurationTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plus(#{any(java.time.Duration)})") + .imports(JAVA_DURATION); + private final JavaTemplate.Builder plusYearsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusYears(#{any(int)})"); + private final JavaTemplate.Builder plusMonthsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusMonths(#{any(int)})"); + private final JavaTemplate.Builder plusWeeksTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusWeeks(#{any(int)})"); + private final JavaTemplate.Builder plusDaysTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusDays(#{any(int)})"); + private final JavaTemplate.Builder plusHoursTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusHours(#{any(int)})"); + private final JavaTemplate.Builder plusMinutesTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusMinutes(#{any(int)})"); + private final JavaTemplate.Builder plusSecondsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plusSeconds(#{any(int)})"); + private final JavaTemplate.Builder plusMillisTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.plus(Duration.ofMillis(#{any(int)}))") + .imports(JAVA_DURATION); + private final JavaTemplate.Builder minusMillisTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minus(Duration.ofMillis(#{any(int)}))") + .imports(JAVA_DURATION); + private final JavaTemplate.Builder minusReadableDurationTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minus(#{any(java.time.Duration)})") + .imports(JAVA_DATE_TIME, JAVA_DURATION); + private final JavaTemplate.Builder minusYearsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusYears(#{any(int)})"); + private final JavaTemplate.Builder minusMonthsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusMonths(#{any(int)})"); + private final JavaTemplate.Builder minusWeeksTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusWeeks(#{any(int)})"); + private final JavaTemplate.Builder minusDaysTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusDays(#{any(int)})"); + private final JavaTemplate.Builder minusHoursTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusHours(#{any(int)})"); + private final JavaTemplate.Builder minusMinutesTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusMinutes(#{any(int)})"); + private final JavaTemplate.Builder minusSecondsTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.minusSeconds(#{any(int)})"); + private final JavaTemplate.Builder atStartOfDayTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toLocalDate().atStartOfDay(ZoneId.systemDefault())") + .imports(JAVA_ZONE_ID); + private final JavaTemplate.Builder toLocalDateTimeTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toLocalDateTime()"); + private final JavaTemplate.Builder toLocalDateTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toLocalDate()"); + private final JavaTemplate.Builder toLocalTimeTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.toLocalTime()"); + private final JavaTemplate.Builder withYearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withYear(#{any(int)})"); + private final JavaTemplate.Builder withWeekyearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(IsoFields.WEEK_BASED_YEAR, #{any(int)})") + .imports(JAVA_TEMPORAL_ISO_FIELDS); + private final JavaTemplate.Builder withMonthOfYearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withMonth(#{any(int)})"); + private final JavaTemplate.Builder withWeekOfWeekyearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(ChronoField.ALIGNED_WEEK_OF_YEAR, #{any(int)})") + .imports(JAVA_CHRONO_FIELD); + private final JavaTemplate.Builder withDayOfYearTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withDayOfYear(#{any(int)})"); + private final JavaTemplate.Builder withDayOfMonthTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withDayOfMonth(#{any(int)})"); + private final JavaTemplate.Builder withDayOfWeekTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(ChronoField.DAY_OF_WEEK, #{any(int)})") + .imports(JAVA_CHRONO_FIELD); + private final JavaTemplate.Builder withHourOfDayTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withHour(#{any(int)})"); + private final JavaTemplate.Builder withMinuteOfHourTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withMinute(#{any(int)})"); + private final JavaTemplate.Builder withSecondOfMinuteTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withSecond(#{any(int)})"); + private final JavaTemplate.Builder withMillisOfSecondTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.withNano(#{any(int)} * 1_000_000)"); + private final JavaTemplate.Builder withMillisOfDayTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.with(ChronoField.MILLI_OF_DAY, #{any(int)})") + .imports(JAVA_CHRONO_FIELD); + final JavaTemplate.Builder getZoneTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.getZone()"); @Getter private final List templates = new ArrayList() { { - add(new MethodTemplate(newDateTime, dateTimeTemplate)); - add(new MethodTemplate(newDateTimeWithZone, dateTimeWithZoneTemplate)); - add(new MethodTemplate(newDateTimeWithEpoch, dateTimeWithEpochTemplate)); - add(new MethodTemplate(newDateTimeWithEpochAndZone, dateTimeWithEpochAndZoneTemplate)); - add(new MethodTemplate(newDateTimeWithMin, dateTimeWithMinTemplate)); - add(new MethodTemplate(newDateTimeWithMinAndZone, dateTimeWithMinAndZoneTemplate)); - add(new MethodTemplate(newDateTimeWithSec, dateTimeWithSecTemplate)); - add(new MethodTemplate(newDateTimeWithSecAndZone, dateTimeWithSecAndZoneTemplate)); - add(new MethodTemplate(newDateTimeWithMillis, dateTimeWithMillisTemplate)); - add(new MethodTemplate(newDateTimeWithMillisAndZone, dateTimeWithMillisAndZoneTemplate)); - add(new MethodTemplate(dateTimeNow, dateTimeTemplate)); - add(new MethodTemplate(dateTimeNowWithZone, dateTimeWithZoneTemplate)); - add(new MethodTemplate(dateTimeParse, dateTimeParseTemplate)); - add(new MethodTemplate(dateTimeParseWithFormatter, dateTimeParseWithFormatterTemplate)); - add(new MethodTemplate(toDateTime, toDateTimeTemplate)); - add(new MethodTemplate(toDateTimeWithZone, withZoneTemplate)); - add(new MethodTemplate(withMillis, withMillisTemplate, m -> { + add(new MethodTemplate(newDateTime, build(dateTimeTemplate))); + add(new MethodTemplate(newDateInstant, JODA_MULTIPLE_MAPPING_POSSIBLE_TEMPLATE)); + add(new MethodTemplate(newDateTimeWithZone, build(dateTimeWithZoneTemplate))); + add(new MethodTemplate(newDateTimeWithEpoch, build(dateTimeWithEpochTemplate))); + add(new MethodTemplate(newDateTimeWithEpochAndZone, build(dateTimeWithEpochAndZoneTemplate))); + add(new MethodTemplate(newDateTimeWithEpochObjectAndZone, build(dateTimeWithEpochAndZoneTemplate))); + add(new MethodTemplate(newDateTimeWithMin, build(dateTimeWithMinTemplate))); + add(new MethodTemplate(newDateTimeWithMinAndZone, build(dateTimeWithMinAndZoneTemplate))); + add(new MethodTemplate(newDateTimeWithSec, build(dateTimeWithSecTemplate))); + add(new MethodTemplate(newDateTimeWithSecAndZone, build(dateTimeWithSecAndZoneTemplate))); + add(new MethodTemplate(newDateTimeWithMillis, build(dateTimeWithMillisTemplate))); + add(new MethodTemplate(newDateTimeWithMillisAndZone, build(dateTimeWithMillisAndZoneTemplate))); + + add(new MethodTemplate(dateTimeNow, build(dateTimeTemplate))); + add(new MethodTemplate(dateTimeNowWithZone, build(dateTimeWithZoneTemplate))); + add(new MethodTemplate(dateTimeParse, build(dateTimeParseTemplate))); + add(new MethodTemplate(dateTimeParseWithFormatter, build(dateTimeParseWithFormatterTemplate))); + add(new MethodTemplate(toDateTime, build(toDateTimeTemplate))); + add(new MethodTemplate(toDateTimeWithZone, build(withZoneTemplate))); + add(new MethodTemplate(withMillis, build(withMillisTemplate), m -> { J.MethodInvocation mi = (J.MethodInvocation) m; return new Expression[]{mi.getArguments().get(0), mi.getSelect()}; })); - add(new MethodTemplate(withZone, withZoneTemplate)); - add(new MethodTemplate(withZoneRetainFields, withZoneRetainFieldsTemplate)); - add(new MethodTemplate(withEarlierOffsetAtOverlap, withEarlierOffsetAtOverlapTemplate)); - add(new MethodTemplate(withLaterOffsetAtOverlap, withLaterOffsetAtOverlapTemplate)); - add(new MethodTemplate(withDate, withDateTemplate)); - add(new MethodTemplate(withDateLocalDate, withTemporalAdjusterTemplate)); - add(new MethodTemplate(withTime, withTimeTemplate)); - add(new MethodTemplate(withTimeLocalTime, withTemporalAdjusterTemplate)); - add(new MethodTemplate(withTimeAtStartOfDay, withTimeAtStartOfDayTemplate, m -> { + add(new MethodTemplate(withZone, build(withZoneTemplate))); + add(new MethodTemplate(withZoneRetainFields, build(withZoneRetainFieldsTemplate))); + add(new MethodTemplate(withEarlierOffsetAtOverlap, build(withEarlierOffsetAtOverlapTemplate))); + add(new MethodTemplate(withLaterOffsetAtOverlap, build(withLaterOffsetAtOverlapTemplate))); + add(new MethodTemplate(withDate, build(withDateTemplate))); + add(new MethodTemplate(withDateLocalDate, build(withTemporalAdjusterTemplate))); + add(new MethodTemplate(withTime, build(withTimeTemplate))); + add(new MethodTemplate(withTimeLocalTime, build(withTemporalAdjusterTemplate))); + add(new MethodTemplate(withTimeAtStartOfDay, build(withTimeAtStartOfDayTemplate), m -> { J.MethodInvocation mi = (J.MethodInvocation) m; return new Expression[]{mi.getSelect(), mi.getSelect()}; })); - add(new MethodTemplate(withDurationAdded, withDurationAddedTemplate)); - add(new MethodTemplate(plusLong, plusMillisTemplate)); - add(new MethodTemplate(plusReadableDuration, plusReadableDurationTemplate)); - add(new MethodTemplate(plusYears, plusYearsTemplate)); - add(new MethodTemplate(plusMonths, plusMonthsTemplate)); - add(new MethodTemplate(plusWeeks, plusWeeksTemplate)); - add(new MethodTemplate(plusDays, plusDaysTemplate)); - add(new MethodTemplate(plusHours, plusHoursTemplate)); - add(new MethodTemplate(plusMinutes, plusMinutesTemplate)); - add(new MethodTemplate(plusSeconds, plusSecondsTemplate)); - add(new MethodTemplate(plusMillis, plusMillisTemplate)); - add(new MethodTemplate(minusLong, minusMillisTemplate)); - add(new MethodTemplate(minusReadableDuration, minusReadableDurationTemplate)); - add(new MethodTemplate(minusYears, minusYearsTemplate)); - add(new MethodTemplate(minusMonths, minusMonthsTemplate)); - add(new MethodTemplate(minusWeeks, minusWeeksTemplate)); - add(new MethodTemplate(minusDays, minusDaysTemplate)); - add(new MethodTemplate(minusHours, minusHoursTemplate)); - add(new MethodTemplate(minusMinutes, minusMinutesTemplate)); - add(new MethodTemplate(minusSeconds, minusSecondsTemplate)); - add(new MethodTemplate(minusMillis, minusMillisTemplate)); - add(new MethodTemplate(toLocalDateTime, toLocalDateTimeTemplate)); - add(new MethodTemplate(toLocalDate, toLocalDateTemplate)); - add(new MethodTemplate(toLocalTime, toLocalTimeTemplate)); - add(new MethodTemplate(withYear, withYearTemplate)); - add(new MethodTemplate(withWeekyear, withWeekyearTemplate)); - add(new MethodTemplate(withMonthOfYear, withMonthOfYearTemplate)); - add(new MethodTemplate(withWeekOfWeekyear, withWeekOfWeekyearTemplate)); - add(new MethodTemplate(withDayOfYear, withDayOfYearTemplate)); - add(new MethodTemplate(withDayOfMonth, withDayOfMonthTemplate)); - add(new MethodTemplate(withDayOfWeek, withDayOfWeekTemplate)); - add(new MethodTemplate(withHourOfDay, withHourOfDayTemplate)); - add(new MethodTemplate(withMinuteOfHour, withMinuteOfHourTemplate)); - add(new MethodTemplate(withSecondOfMinute, withSecondOfMinuteTemplate)); - add(new MethodTemplate(withMillisOfSecond, withMillisOfSecondTemplate)); - add(new MethodTemplate(withMillisOfDay, withMillisOfDayTemplate)); + add(new MethodTemplate(withDurationAdded, build(withDurationAddedTemplate))); + add(new MethodTemplate(plusLong, build(plusMillisTemplate))); + add(new MethodTemplate(plusReadableDuration, build(plusReadableDurationTemplate))); + add(new MethodTemplate(plusYears, build(plusYearsTemplate))); + add(new MethodTemplate(plusMonths, build(plusMonthsTemplate))); + add(new MethodTemplate(plusWeeks, build(plusWeeksTemplate))); + add(new MethodTemplate(plusDays, build(plusDaysTemplate))); + add(new MethodTemplate(plusHours, build(plusHoursTemplate))); + add(new MethodTemplate(plusMinutes, build(plusMinutesTemplate))); + add(new MethodTemplate(plusSeconds, build(plusSecondsTemplate))); + add(new MethodTemplate(plusMillis, build(plusMillisTemplate))); + add(new MethodTemplate(minusLong, build(minusMillisTemplate))); + add(new MethodTemplate(minusReadableDuration, build(minusReadableDurationTemplate))); + add(new MethodTemplate(minusYears, build(minusYearsTemplate))); + add(new MethodTemplate(minusMonths, build(minusMonthsTemplate))); + add(new MethodTemplate(minusWeeks, build(minusWeeksTemplate))); + add(new MethodTemplate(minusDays, build(minusDaysTemplate))); + add(new MethodTemplate(minusHours, build(minusHoursTemplate))); + add(new MethodTemplate(minusMinutes, build(minusMinutesTemplate))); + add(new MethodTemplate(minusSeconds, build(minusSecondsTemplate))); + add(new MethodTemplate(minusMillis, build(minusMillisTemplate))); + add(new MethodTemplate(toDateMidnight, build(atStartOfDayTemplate))); + add(new MethodTemplate(toLocalDateTime, build(toLocalDateTimeTemplate))); + add(new MethodTemplate(toLocalDate, build(toLocalDateTemplate))); + add(new MethodTemplate(toLocalTime, build(toLocalTimeTemplate))); + add(new MethodTemplate(withYear, build(withYearTemplate))); + add(new MethodTemplate(withWeekyear, build(withWeekyearTemplate))); + add(new MethodTemplate(withMonthOfYear, build(withMonthOfYearTemplate))); + add(new MethodTemplate(withWeekOfWeekyear, build(withWeekOfWeekyearTemplate))); + add(new MethodTemplate(withDayOfYear, build(withDayOfYearTemplate))); + add(new MethodTemplate(withDayOfMonth, build(withDayOfMonthTemplate))); + add(new MethodTemplate(withDayOfWeek, build(withDayOfWeekTemplate))); + add(new MethodTemplate(withHourOfDay, build(withHourOfDayTemplate))); + add(new MethodTemplate(withMinuteOfHour, build(withMinuteOfHourTemplate))); + add(new MethodTemplate(withSecondOfMinute, build(withSecondOfMinuteTemplate))); + add(new MethodTemplate(withMillisOfSecond, build(withMillisOfSecondTemplate))); + add(new MethodTemplate(withMillisOfDay, build(withMillisOfDayTemplate))); + add(new MethodTemplate(dateTimeGetZone, build(getZoneTemplate))); } }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, JAVA_DATE_TIME); + } } diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeUtilsTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeUtilsTemplates.java new file mode 100644 index 0000000000..f0c003d285 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeUtilsTemplates.java @@ -0,0 +1,44 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JAVA_INSTANT; +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_DATE_TIME_UTILS; + +public class DateTimeUtilsTemplates implements Templates { + private final MethodMatcher currentTimeMillis = new MethodMatcher(JODA_DATE_TIME_UTILS + " currentTimeMillis()"); + + private final JavaTemplate.Builder currentTimeMillisTemplate = JavaTemplate.builder("Instant.now().toEpochMilli();") + .imports(JAVA_INSTANT); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(currentTimeMillis, build(currentTimeMillisTemplate))); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return builder.build(); + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeZoneTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeZoneTemplates.java new file mode 100644 index 0000000000..a899841c3e --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/DateTimeZoneTemplates.java @@ -0,0 +1,87 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; +import org.openrewrite.java.tree.Expression; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; + +public class DateTimeZoneTemplates implements Templates { + private final MethodMatcher zoneForID = new MethodMatcher(JODA_DATE_TIME_ZONE + " forID(String)"); + private final MethodMatcher getDefault = new MethodMatcher(JODA_DATE_TIME_ZONE + " getDefault()"); + private final MethodMatcher zoneForOffsetHours = new MethodMatcher(JODA_DATE_TIME_ZONE + " forOffsetHours(int)"); + private final MethodMatcher zoneForOffsetHoursMinutes = new MethodMatcher(JODA_DATE_TIME_ZONE + " forOffsetHoursMinutes(int, int)"); + private final MethodMatcher zoneForOffsetMillis = new MethodMatcher(JODA_DATE_TIME_ZONE + " forOffsetMillis(int)"); + private final MethodMatcher zoneForTimeZone = new MethodMatcher(JODA_DATE_TIME_ZONE + " forTimeZone(java.util.TimeZone)"); + private final MethodMatcher getOffset = new MethodMatcher(JODA_DATE_TIME_ZONE + " getOffset(org.joda.time.ReadableInstant)"); + private final MethodMatcher getStandardOffset = new MethodMatcher(JODA_DATE_TIME_ZONE + " getStandardOffset(long)"); + private final MethodMatcher toTimeZone = new MethodMatcher(JODA_DATE_TIME_ZONE + " toTimeZone()"); + private final MethodMatcher getId = new MethodMatcher(JODA_DATE_TIME_ZONE + " getID()"); + private final MethodMatcher equals = new MethodMatcher(JODA_DATE_TIME_ZONE + " equals(java.lang.Object)"); + private final MethodMatcher zoneGetOffsetFromLocal = new MethodMatcher(JODA_DATE_TIME_ZONE + " getOffsetFromLocal(long)"); + private final MethodMatcher zoneIsLocalDateTimeGap = new MethodMatcher(JODA_DATE_TIME_ZONE + " isLocalDateTimeGap(org.joda.time.LocalDateTime)"); + + //getOffsetFromLocal(long) + //timezone.isLocalDateTimeGap(endSafe) + + private final JavaTemplate.Builder zoneIdOfTemplate = JavaTemplate.builder("ZoneId.of(#{any(String)})") + .imports(JAVA_ZONE_ID); + private final JavaTemplate.Builder systemDefaultTemplate = JavaTemplate.builder("ZoneId.systemDefault()") + .imports(JAVA_ZONE_ID); + private final JavaTemplate.Builder zoneOffsetHoursTemplate = JavaTemplate.builder("ZoneOffset.ofHours(#{any(int)})"); + private final JavaTemplate.Builder zoneOffsetHoursMinutesTemplate = JavaTemplate.builder("ZoneOffset.ofHoursMinutes(#{any(int)}, #{any(int)})"); + private final JavaTemplate.Builder zoneOffsetMillisTemplate = JavaTemplate.builder("ZoneOffset.ofTotalSeconds(#{any(int)} / 1000)"); + private final JavaTemplate.Builder timeZoneToZoneIdTemplate = JavaTemplate.builder("#{any(java.util.TimeZone)}.toZoneId()"); + private final JavaTemplate.Builder getOffsetInMillisTemplate = JavaTemplate.builder("#{any(java.time.ZonedDateTime)}.getOffset().getTotalSeconds() * 1000"); + private final JavaTemplate.Builder getStandardOffsetTemplate = JavaTemplate.builder("(int)Duration.ofSeconds(#{any(java.time.ZoneId)}.getRules().getStandardOffset(Instant.ofEpochMilli(#{any(long)})).getTotalSeconds()).toMillis()") + .imports(JAVA_ZONE_ID, JAVA_DURATION); + private final JavaTemplate.Builder getTimeZone = JavaTemplate.builder("TimeZone.getTimeZone(#{any(java.time.ZoneId)})"); + private final JavaTemplate.Builder getIdTemplate = JavaTemplate.builder("#{any(java.time.ZoneId)}.getId()") + .imports(JAVA_ZONE_ID); + private final JavaTemplate.Builder equalsTemplate = JavaTemplate.builder("#{any(java.time.ZoneId)}.equals()"); + private final JavaTemplate.Builder getOffsetTemplate = JavaTemplate.builder("#{any(java.time.ZoneId)}.getRules().getOffset(Instant.ofEpochMilli(#{any(long)}))"); + private final JavaTemplate.Builder isGapTemplate = JavaTemplate.builder("#{any(java.time.ZoneId)}.getRules().getValidOffsets(#{any(java.time.LocalDateTime)}).isEmpty()"); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(zoneForID, build(zoneIdOfTemplate))); + add(new MethodTemplate(getDefault, build(systemDefaultTemplate))); + add(new MethodTemplate(zoneForOffsetHours, build(zoneOffsetHoursTemplate))); + add(new MethodTemplate(zoneForOffsetHoursMinutes, build(zoneOffsetHoursMinutesTemplate))); + add(new MethodTemplate(zoneForOffsetMillis, build(zoneOffsetMillisTemplate))); + add(new MethodTemplate(zoneForTimeZone, build(timeZoneToZoneIdTemplate))); + add(new MethodTemplate(getOffset, build(getOffsetInMillisTemplate), + m -> new Expression[]{m.getArguments().get(0)})); + add(new MethodTemplate(getStandardOffset, build(getStandardOffsetTemplate))); + add(new MethodTemplate(toTimeZone, build(getTimeZone))); + add(new MethodTemplate(getId, build(getIdTemplate))); + add(new MethodTemplate(equals, build(equalsTemplate))); + add(new MethodTemplate(zoneGetOffsetFromLocal, build(getOffsetTemplate))); + add(new MethodTemplate(zoneIsLocalDateTimeGap, build(isGapTemplate))); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, JAVA_ZONE_OFFSET); + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/DaysTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/DaysTemplates.java new file mode 100644 index 0000000000..2bf4deace1 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/DaysTemplates.java @@ -0,0 +1,57 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; + +@NoArgsConstructor +public class DaysTemplates implements Templates { + final MethodMatcher daysStaticMethod = new MethodMatcher(JODA_DAYS + " days(int)"); + final MethodMatcher daysBetweenPartial = new MethodMatcher(JODA_DAYS + " daysBetween(org.joda.time.ReadablePartial, org.joda.time.ReadablePartial)"); + final MethodMatcher daysBetweenInstant = new MethodMatcher(JODA_DAYS + " daysBetween(org.joda.time.ReadableInstant, org.joda.time.ReadableInstant)"); + final MethodMatcher getDays = new MethodMatcher(JODA_DAYS + " getDays()"); + final MethodMatcher daysOne = new MethodMatcher(JODA_DAYS + " ONE"); + + final JavaTemplate.Builder daysStaticMethodTemplate = JavaTemplate.builder("Days.of(#{any(int)})"); + final JavaTemplate.Builder daysBetweenLocalTimeTemplate = JavaTemplate.builder("Days.between(#{any(java.time.LocalDate)}, #{any(java.time.LocalDate)})"); + final JavaTemplate.Builder daysBetweenZonedDateTimeTemplate = JavaTemplate.builder("Days.between(#{any(java.time.ZonedDateTime)}, #{any(java.time.ZonedDateTime)})"); + final JavaTemplate.Builder getTemplate = JavaTemplate.builder("(int)#{any(org.threeten.extra.Days)}.get(ChronoUnit.DAYS)") + .imports(JAVA_CHRONO_UNIT); + final JavaTemplate.Builder durationOfOneDayTemplate = JavaTemplate.builder("ONE"); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(daysStaticMethod, build(daysStaticMethodTemplate))); + add(new MethodTemplate(daysBetweenPartial, build(daysBetweenLocalTimeTemplate))); + add(new MethodTemplate(daysBetweenInstant, build(daysBetweenZonedDateTimeTemplate))); + add(new MethodTemplate(getDays, build(getTemplate))); + add(new MethodTemplate(daysOne, build(durationOfOneDayTemplate))); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, THREE_TEN_EXTRA_DAYS); + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/DurationTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/DurationTemplates.java index 96de8caf30..49b0cf7360 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/DurationTemplates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/DurationTemplates.java @@ -28,6 +28,11 @@ @NoArgsConstructor public class DurationTemplates implements Templates { + private final MethodMatcher newDuration = new MethodMatcher(JODA_DURATION + "(long)"); + private final MethodMatcher newDurationWithObject = new MethodMatcher(JODA_DURATION + "(java.lang.Object)"); + private final MethodMatcher newDurationWithInstants = new MethodMatcher(JODA_DURATION + "(long,long)"); + private final MethodMatcher newDurationWithDateTimes = new MethodMatcher(JODA_DURATION + "(org.joda.time.ReadableInstant, org.joda.time.ReadableInstant)"); + private final MethodMatcher parse = new MethodMatcher(JODA_DURATION + " parse(String)"); private final MethodMatcher standardDays = new MethodMatcher(JODA_DURATION + " standardDays(long)"); private final MethodMatcher standardHours = new MethodMatcher(JODA_DURATION + " standardHours(long)"); @@ -35,15 +40,13 @@ public class DurationTemplates implements Templates { private final MethodMatcher standardSeconds = new MethodMatcher(JODA_DURATION + " standardSeconds(long)"); private final MethodMatcher millis = new MethodMatcher(JODA_DURATION + " millis(long)"); - private final MethodMatcher newDuration = new MethodMatcher(JODA_DURATION + "(long)"); - private final MethodMatcher newDurationWithInstants = new MethodMatcher(JODA_DURATION + "(long,long)"); - private final MethodMatcher getStandardDays = new MethodMatcher(JODA_DURATION + " getStandardDays()"); private final MethodMatcher getStandardHours = new MethodMatcher(JODA_DURATION + " getStandardHours()"); private final MethodMatcher getStandardMinutes = new MethodMatcher(JODA_DURATION + " getStandardMinutes()"); private final MethodMatcher getStandardSeconds = new MethodMatcher(JODA_DURATION + " getStandardSeconds()"); private final MethodMatcher toDuration = new MethodMatcher(JODA_DURATION + " toDuration()"); + private final MethodMatcher toPeriod = new MethodMatcher(JODA_DURATION + " toPeriod()"); private final MethodMatcher toStandardDays = new MethodMatcher(JODA_DURATION + " toStandardDays()"); private final MethodMatcher toStandardHours = new MethodMatcher(JODA_DURATION + " toStandardHours()"); @@ -64,105 +67,89 @@ public class DurationTemplates implements Templates { private final MethodMatcher negated = new MethodMatcher(JODA_DURATION + " negated()"); private final MethodMatcher abs = new MethodMatcher(JODA_DURATION + " abs()"); + private final MethodMatcher durationIsShorterThan = new MethodMatcher(JODA_DURATION + " isShorterThan(" + JODA_DURATION + ")"); + + private final JavaTemplate.Builder durationOfMillisTemplate = JavaTemplate.builder("Duration.ofMillis(#{any(long)})"); + private final JavaTemplate.Builder durationBetweenInstantsTemplate = JavaTemplate.builder("Duration.between(Instant.ofEpochMilli(#{any(long)}), Instant.ofEpochMilli(#{any(long)}))") + .imports(JAVA_INSTANT); + private final JavaTemplate.Builder durationBetweenZonedDateTimesTemplate = JavaTemplate.builder("Duration.between(#{any(java.time.ZonedDateTime)}, #{any(java.time.ZonedDateTime)})") + .imports(JAVA_INSTANT); + + private final JavaTemplate.Builder parseTemplate = JavaTemplate.builder("Duration.parse(#{any(String)})"); + private final JavaTemplate.Builder standardDaysTemplate = JavaTemplate.builder("Duration.ofDays(#{any(long)})"); + private final JavaTemplate.Builder standardHoursTemplate = JavaTemplate.builder("Duration.ofHours(#{any(long)})"); + private final JavaTemplate.Builder standardMinutesTemplate = JavaTemplate.builder("Duration.ofMinutes(#{any(long)})"); + private final JavaTemplate.Builder standardSecondsTemplate = JavaTemplate.builder("Duration.ofSeconds(#{any(long)})"); + private final JavaTemplate.Builder millisTemplate = JavaTemplate.builder("Duration.ofMillis(#{any(long)})"); + + private final JavaTemplate.Builder toDurationTemplate = JavaTemplate.builder("#{any(java.time.Duration)}"); + private final JavaTemplate.Builder toPeriodTemplate = JavaTemplate.builder("Period.from(#{any(java.time.Duration)})") + .imports(JAVA_PERIOD); + + private final JavaTemplate.Builder toDaysTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.toDays()"); + private final JavaTemplate.Builder toHoursTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.toHours()"); + private final JavaTemplate.Builder toMinutesTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.toMinutes()"); + private final JavaTemplate.Builder getSecondsTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.getSeconds()"); + private final JavaTemplate.Builder ofMillisTemplate = JavaTemplate.builder("Duration.ofMillis(#{any(long)})"); + private final JavaTemplate.Builder withDurationAddedTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plusMillis(#{any(long)} * #{any(int)})"); + private final JavaTemplate.Builder withDurationAddedReadableTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plus(#{any(java.time.Duration)}.multipliedBy(#{any(int)}))"); + private final JavaTemplate.Builder plusLongTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plusMillis(#{any(long)})"); + private final JavaTemplate.Builder plusReadableTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plus(#{any(java.time.Duration)})"); + private final JavaTemplate.Builder minusLongTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minusMillis(#{any(long)})"); + private final JavaTemplate.Builder minusReadableTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minus(#{any(java.time.Duration)})"); + private final JavaTemplate.Builder multipliedByTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.multipliedBy(#{any(long)})"); + private final JavaTemplate.Builder dividedByTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.dividedBy(#{any(long)})"); + private final JavaTemplate.Builder negatedTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.negated()"); + private final JavaTemplate.Builder absTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.abs()"); + private final JavaTemplate.Builder durationCompareTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.compareTo(#{any(java.time.Duration)}) < 0"); - private final JavaTemplate parseTemplate = JavaTemplate.builder("Duration.parse(#{any(String)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate standardDaysTemplate = JavaTemplate.builder("Duration.ofDays(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate standardHoursTemplate = JavaTemplate.builder("Duration.ofHours(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate standardMinutesTemplate = JavaTemplate.builder("Duration.ofMinutes(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate standardSecondsTemplate = JavaTemplate.builder("Duration.ofSeconds(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate millisTemplate = JavaTemplate.builder("Duration.ofMillis(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - - private final JavaTemplate newDurationTemplate = JavaTemplate.builder("Duration.ofMillis(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate newDurationWithInstantsTemplate = JavaTemplate.builder("Duration.between(Instant.ofEpochMilli(#{any(long)}), Instant.ofEpochMilli(#{any(long)}))") - .imports(JAVA_DURATION, JAVA_INSTANT) - .build(); - private final JavaTemplate toDurationTemplate = JavaTemplate.builder("#{any(java.time.Duration)}") - .build(); - private final JavaTemplate toDaysTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.toDays()") - .build(); - private final JavaTemplate toHoursTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.toHours()") - .build(); - private final JavaTemplate toMinutesTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.toMinutes()") - .build(); - private final JavaTemplate getSecondsTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.getSeconds()") - .build(); - private final JavaTemplate ofMillisTemplate = JavaTemplate.builder("Duration.ofMillis(#{any(long)})") - .imports(JAVA_DURATION) - .build(); - private final JavaTemplate withDurationAddedTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plusMillis(#{any(long)} * #{any(int)})") - .build(); - private final JavaTemplate withDurationAddedReadableTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plus(#{any(java.time.Duration)}.multipliedBy(#{any(int)}))") - .build(); - private final JavaTemplate plusLongTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plusMillis(#{any(long)})") - .build(); - private final JavaTemplate plusReadableTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plus(#{any(java.time.Duration)})") - .build(); - private final JavaTemplate minusLongTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minusMillis(#{any(long)})") - .build(); - private final JavaTemplate minusReadableTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minus(#{any(java.time.Duration)})") - .build(); - private final JavaTemplate multipliedByTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.multipliedBy(#{any(long)})") - .build(); - private final JavaTemplate dividedByTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.dividedBy(#{any(long)})") - .build(); - private final JavaTemplate negatedTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.negated()") - .build(); - private final JavaTemplate absTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.abs()") - .build(); @Getter private final List templates = new ArrayList() { { - add(new MethodTemplate(parse, parseTemplate)); - add(new MethodTemplate(standardDays, standardDaysTemplate)); - add(new MethodTemplate(standardHours, standardHoursTemplate)); - add(new MethodTemplate(standardMinutes, standardMinutesTemplate)); - add(new MethodTemplate(standardSeconds, standardSecondsTemplate)); - add(new MethodTemplate(millis, millisTemplate)); - - add(new MethodTemplate(newDuration, newDurationTemplate)); - add(new MethodTemplate(newDurationWithInstants, newDurationWithInstantsTemplate)); - - add(new MethodTemplate(getStandardDays, toDaysTemplate)); - add(new MethodTemplate(getStandardHours, toHoursTemplate)); - add(new MethodTemplate(getStandardMinutes, toMinutesTemplate)); - add(new MethodTemplate(getStandardSeconds, getSecondsTemplate)); - - add(new MethodTemplate(toDuration, toDurationTemplate)); - - add(new MethodTemplate(toStandardDays, toDaysTemplate)); - add(new MethodTemplate(toStandardHours, toHoursTemplate)); - add(new MethodTemplate(toStandardMinutes, toMinutesTemplate)); - add(new MethodTemplate(toStandardSeconds, getSecondsTemplate)); - - add(new MethodTemplate(withMillis, ofMillisTemplate, m -> new Expression[]{m.getArguments().get(0)})); - add(new MethodTemplate(withDurationAdded, withDurationAddedTemplate)); - add(new MethodTemplate(withDurationAddedReadable, withDurationAddedReadableTemplate)); - - add(new MethodTemplate(plusLong, plusLongTemplate)); - add(new MethodTemplate(plusReadable, plusReadableTemplate)); - add(new MethodTemplate(minusLong, minusLongTemplate)); - add(new MethodTemplate(minusReadable, minusReadableTemplate)); - - add(new MethodTemplate(multipliedBy, multipliedByTemplate)); - add(new MethodTemplate(dividedBy, dividedByTemplate)); - - add(new MethodTemplate(negated, negatedTemplate)); - add(new MethodTemplate(abs, absTemplate)); + add(new MethodTemplate(newDuration, build(durationOfMillisTemplate))); + add(new MethodTemplate(newDurationWithObject, build(parseTemplate))); + add(new MethodTemplate(newDurationWithInstants, build(durationBetweenInstantsTemplate))); + add(new MethodTemplate(newDurationWithDateTimes, build(durationBetweenZonedDateTimesTemplate))); + + add(new MethodTemplate(parse, build(parseTemplate))); + add(new MethodTemplate(standardDays, build(standardDaysTemplate))); + add(new MethodTemplate(standardHours, build(standardHoursTemplate))); + add(new MethodTemplate(standardMinutes, build(standardMinutesTemplate))); + add(new MethodTemplate(standardSeconds, build(standardSecondsTemplate))); + add(new MethodTemplate(millis, build(millisTemplate))); + + add(new MethodTemplate(getStandardDays, build(toDaysTemplate))); + add(new MethodTemplate(getStandardHours, build(toHoursTemplate))); + add(new MethodTemplate(getStandardMinutes, build(toMinutesTemplate))); + add(new MethodTemplate(getStandardSeconds, build(getSecondsTemplate))); + + add(new MethodTemplate(toDuration, build(toDurationTemplate))); + add(new MethodTemplate(toPeriod, build(toPeriodTemplate))); + + add(new MethodTemplate(toStandardDays, build(toDaysTemplate))); + add(new MethodTemplate(toStandardHours, build(toHoursTemplate))); + add(new MethodTemplate(toStandardMinutes, build(toMinutesTemplate))); + add(new MethodTemplate(toStandardSeconds, build(getSecondsTemplate))); + + add(new MethodTemplate(withMillis, build(ofMillisTemplate), m -> new Expression[]{m.getArguments().get(0)})); + add(new MethodTemplate(withDurationAdded, build(withDurationAddedTemplate))); + add(new MethodTemplate(withDurationAddedReadable, build(withDurationAddedReadableTemplate))); + + add(new MethodTemplate(plusLong, build(plusLongTemplate))); + add(new MethodTemplate(plusReadable, build(plusReadableTemplate))); + add(new MethodTemplate(minusLong, build(minusLongTemplate))); + add(new MethodTemplate(minusReadable, build(minusReadableTemplate))); + + add(new MethodTemplate(multipliedBy, build(multipliedByTemplate))); + add(new MethodTemplate(dividedBy, build(dividedByTemplate))); + + add(new MethodTemplate(negated, build(negatedTemplate))); + add(new MethodTemplate(abs, build(absTemplate))); } }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, JAVA_DURATION); + } } diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/HoursTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/HoursTemplates.java new file mode 100644 index 0000000000..05ed0756f4 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/HoursTemplates.java @@ -0,0 +1,81 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JAVA_DURATION; +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_HOURS; + +@NoArgsConstructor +public class HoursTemplates implements Templates { + final MethodMatcher staticHoursMethod = new MethodMatcher(JODA_HOURS + " hours(int)"); + final MethodMatcher plusMethod = new MethodMatcher(JODA_HOURS + " plus(org.joda.time.Hours)"); + final MethodMatcher minusMethod = new MethodMatcher(JODA_HOURS + " minus(org.joda.time.Hours)"); + final MethodMatcher plusInt = new MethodMatcher(JODA_HOURS + " plus(int)"); + final MethodMatcher minusInt = new MethodMatcher(JODA_HOURS + " minus(int)"); + final MethodMatcher multipliedByMethod = new MethodMatcher(JODA_HOURS + " multipliedBy(int)"); + final MethodMatcher dividedByMethod = new MethodMatcher(JODA_HOURS + " dividedBy(int)"); + final MethodMatcher getHoursMethod = new MethodMatcher(JODA_HOURS + " getHours()"); + final MethodMatcher isLessThan = new MethodMatcher(JODA_HOURS + " isLessThan(org.joda.time.Hours)"); + final MethodMatcher isGreaterThan = new MethodMatcher(JODA_HOURS + " isGreaterThan(org.joda.time.Hours)"); + final MethodMatcher toString = new MethodMatcher(JODA_HOURS + " toString()"); + final MethodMatcher equals = new MethodMatcher(JODA_HOURS + " equals(org.joda.time.Hours)"); + final MethodMatcher hoursToStandardSeconds = new MethodMatcher(JODA_HOURS + " toStandardSeconds()"); + + final JavaTemplate.Builder staticHoursTemplate = JavaTemplate.builder("Duration.ofHours(#{any(int)})"); + final JavaTemplate.Builder plusTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plus(#{any(java.time.Duration)})"); + final JavaTemplate.Builder minusTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minus(#{any(java.time.Duration)})"); + final JavaTemplate.Builder plusIntTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plusHours(#{any(int)})"); + final JavaTemplate.Builder minusIntTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plus(#{any(int)})"); + final JavaTemplate.Builder multipliedByTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.multipliedBy(#{any(int)})"); + final JavaTemplate.Builder dividedByTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.dividedBy(#{any(int)})"); + final JavaTemplate.Builder getHoursTemplate = JavaTemplate.builder("((int) #{any(java.time.Duration)}.toHours())"); + final JavaTemplate.Builder minusIsNegativeTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minus(#{any(java.time.Duration)}).isNegative()"); + final JavaTemplate.Builder minusIsPositiveTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minus(#{any(java.time.Duration)}).isPositive()"); + final JavaTemplate.Builder toStringTemplate = JavaTemplate.builder("#{any(java.time.Duration)}"); + final JavaTemplate.Builder equalsTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.equals(#{any(java.time.Duration)})"); + final JavaTemplate.Builder toSecondsTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.toSeconds()"); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(staticHoursMethod, build(staticHoursTemplate))); + add(new MethodTemplate(plusMethod, build(plusTemplate))); + add(new MethodTemplate(minusMethod, build(minusTemplate))); + add(new MethodTemplate(plusInt, build(plusIntTemplate))); + add(new MethodTemplate(minusInt, build(minusIntTemplate))); + add(new MethodTemplate(multipliedByMethod, build(multipliedByTemplate))); + add(new MethodTemplate(dividedByMethod, build(dividedByTemplate))); + add(new MethodTemplate(getHoursMethod, build(getHoursTemplate))); + add(new MethodTemplate(isLessThan, build(minusIsNegativeTemplate))); + add(new MethodTemplate(isGreaterThan, build(minusIsPositiveTemplate))); + add(new MethodTemplate(toString, build(toStringTemplate))); + add(new MethodTemplate(equals, build(equalsTemplate))); + add(new MethodTemplate(hoursToStandardSeconds, build(toSecondsTemplate))); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, JAVA_DURATION); + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/InstantTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/InstantTemplates.java index 49e07b7688..7fefe0c69f 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/InstantTemplates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/InstantTemplates.java @@ -22,17 +22,16 @@ import java.util.ArrayList; import java.util.List; -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JAVA_INSTANT; -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_INSTANT; +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; public class InstantTemplates implements Templates { private final MethodMatcher constructor = new MethodMatcher(JODA_INSTANT + " ()"); + private final MethodMatcher constructorWithInstant = new MethodMatcher(JODA_INSTANT + " (java.lang.Object)"); private final MethodMatcher getMillis = new MethodMatcher(JODA_INSTANT + " getMillis()"); private final MethodMatcher minusDuration = new MethodMatcher(JODA_INSTANT + " minus(org.joda.time.ReadableDuration)"); private final MethodMatcher now = new MethodMatcher(JODA_INSTANT + " now()"); private final MethodMatcher ofEpochMilli = new MethodMatcher(JODA_INSTANT + " ofEpochMilli(long)"); private final MethodMatcher parse = new MethodMatcher(JODA_INSTANT + " parse(java.lang.String)"); - private final MethodMatcher plusDuration = new MethodMatcher(JODA_INSTANT + " plus(org.joda.time.ReadableDuration)"); private final JavaTemplate constructorTemplate = JavaTemplate.builder("Instant.now()") .imports(JAVA_INSTANT).build(); @@ -50,13 +49,14 @@ public class InstantTemplates implements Templates { private final List templates = new ArrayList() { { add(new MethodTemplate(constructor, constructorTemplate)); + add(new MethodTemplate(constructorWithInstant, JODA_MULTIPLE_MAPPING_POSSIBLE_TEMPLATE)); add(new MethodTemplate(getMillis, getMillisTemplate)); add(new MethodTemplate(getMillis, getMillisTemplate)); add(new MethodTemplate(minusDuration, minusDurationTemplate)); add(new MethodTemplate(now, nowTemplate)); add(new MethodTemplate(ofEpochMilli, ofEpochMilliTemplate)); add(new MethodTemplate(parse, parseTemplate)); - add(new MethodTemplate(plusDuration, plusDurationTemplate)); + add(new MethodTemplate(parse, plusDurationTemplate)); } }; } diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/IntervalTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/IntervalTemplates.java index fb139a5de4..95c45407ff 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/IntervalTemplates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/IntervalTemplates.java @@ -31,28 +31,42 @@ public class IntervalTemplates implements Templates { private final MethodMatcher intervalWithTimeZone = new MethodMatcher(JODA_INTERVAL + " (long, long, " + JODA_DATE_TIME_ZONE + ")"); private final MethodMatcher intervalWithDateTime = new MethodMatcher(JODA_INTERVAL + " (" + JODA_READABLE_INSTANT + ", " + JODA_READABLE_INSTANT + ")"); private final MethodMatcher intervalWithDateTimeAndDuration = new MethodMatcher(JODA_INTERVAL + " (" + JODA_READABLE_INSTANT + ", " + JODA_READABLE_DURATION + ")"); + private final MethodMatcher withEnd = new MethodMatcher(JODA_INTERVAL + " withEnd(org.joda.time.ReadableInstant)"); + private final MethodMatcher withEndDateTime = new MethodMatcher(JODA_INTERVAL + " withEnd(org.joda.time.DateTime)"); + private final MethodMatcher withStart = new MethodMatcher(JODA_INTERVAL + " withStart(org.joda.time.ReadableInstant)"); + private final MethodMatcher abuts = new MethodMatcher(JODA_INTERVAL + " abuts(org.joda.time.ReadableInterval)"); + private final MethodMatcher overlap = new MethodMatcher(JODA_INTERVAL + " overlap(org.joda.time.ReadableInterval)"); - private final JavaTemplate intervalTemplate = JavaTemplate.builder("Interval.of(Instant.ofEpochMilli(#{any(long)}), Instant.ofEpochMilli(#{any(long)}))") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .imports(JAVA_INSTANT, THREE_TEN_EXTRA_INTERVAL) - .build(); - private final JavaTemplate intervalWithDateTimeTemplate = JavaTemplate.builder("Interval.of(#{any(" + JAVA_DATE_TIME + ")}.toInstant(), #{any(" + JAVA_DATE_TIME + ")}.toInstant())") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .imports(THREE_TEN_EXTRA_INTERVAL) - .build(); - private final JavaTemplate intervalWithDateTimeAndDurationTemplate = JavaTemplate.builder("Interval.of(#{any(" + JAVA_DATE_TIME + ")}.toInstant(), #{any(" + JAVA_DURATION + ")})") - .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) - .imports(THREE_TEN_EXTRA_INTERVAL) - .build(); + private final JavaTemplate.Builder intervalTemplate = JavaTemplate.builder("Interval.of(Instant.ofEpochMilli(#{any(long)}), Instant.ofEpochMilli(#{any(long)}))") + .imports(JAVA_INSTANT); + private final JavaTemplate.Builder intervalWithDateTimeTemplate = JavaTemplate.builder("Interval.of(#{any(" + JAVA_DATE_TIME + ")}.toInstant(), #{any(" + JAVA_DATE_TIME + ")}.toInstant())"); + private final JavaTemplate.Builder intervalWithDateTimeAndDurationTemplate = JavaTemplate.builder("Interval.of(#{any(" + JAVA_DATE_TIME + ")}.toInstant(), #{any(" + JAVA_DURATION + ")})");; + private final JavaTemplate.Builder withEndTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.withEnd(#{any(java.time.Instant)})"); + private final JavaTemplate.Builder withEndZonedDateTimeTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.withEnd(#{any(java.time.ZonedDateTime)}.toInstant())"); + private final JavaTemplate.Builder withStartTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.withStart(#{any(java.time.Instant)})"); + private final JavaTemplate.Builder abutsTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.abuts(#{any(org.threeten.extra.Interval)})"); + private final JavaTemplate.Builder intersectionTemplate = JavaTemplate.builder("#{any(" + THREE_TEN_EXTRA_INTERVAL + ")}.intersection(#{any(org.threeten.extra.Interval)})"); @Getter private final List templates = new ArrayList() { { - add(new MethodTemplate(interval, intervalTemplate)); - add(new MethodTemplate(intervalWithTimeZone, intervalTemplate, + add(new MethodTemplate(interval, build(intervalTemplate))); + add(new MethodTemplate(intervalWithTimeZone, build(intervalTemplate), m -> new Expression[]{m.getArguments().get(0), m.getArguments().get(1)})); - add(new MethodTemplate(intervalWithDateTime, intervalWithDateTimeTemplate)); - add(new MethodTemplate(intervalWithDateTimeAndDuration, intervalWithDateTimeAndDurationTemplate)); + add(new MethodTemplate(intervalWithDateTime, build(intervalWithDateTimeTemplate))); + add(new MethodTemplate(intervalWithDateTimeAndDuration, build(intervalWithDateTimeAndDurationTemplate))); + add(new MethodTemplate(withEnd, build(withEndTemplate))); + add(new MethodTemplate(withEndDateTime, build(withEndZonedDateTimeTemplate))); + add(new MethodTemplate(withStart, build(withStartTemplate))); + add(new MethodTemplate(abuts, build(abutsTemplate))); + add(new MethodTemplate(overlap, build(intersectionTemplate))); } }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return builder + .javaParser(JavaParser.fromJavaVersion().classpath("threeten-extra")) + .imports(THREE_TEN_EXTRA_INTERVAL) + .build(); + } } diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/LocatDateTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/LocatDateTemplates.java new file mode 100644 index 0000000000..4f938b5df8 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/LocatDateTemplates.java @@ -0,0 +1,161 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; +import org.openrewrite.java.tree.Expression; +import org.openrewrite.java.tree.J; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; + +@NoArgsConstructor +public class LocatDateTemplates implements Templates { + final MethodMatcher newLocalDateNoArgs = new MethodMatcher(JODA_LOCAL_DATE + "()"); + final MethodMatcher newLocalDateEpoch = new MethodMatcher(JODA_LOCAL_DATE + "(long)"); + final MethodMatcher newLocalDateYmd = new MethodMatcher(JODA_LOCAL_DATE + "(int,int,int)"); + final MethodMatcher newLocalDate = new MethodMatcher(JODA_LOCAL_DATE + "(java.lang.Object)"); + final MethodMatcher fromDateFields = new MethodMatcher(JODA_LOCAL_DATE + " fromDateFields(java.util.Date)"); + final MethodMatcher localDateToDateTime = new MethodMatcher(JODA_LOCAL_DATE + " toDateTime(" + JODA_LOCAL_TIME + ")"); + + final MethodMatcher withDayOfMonth = new MethodMatcher(JODA_LOCAL_DATE + " withDayOfMonth(int)"); + final MethodMatcher now = new MethodMatcher(JODA_LOCAL_DATE + " now()"); + final MethodMatcher parse = new MethodMatcher(JODA_LOCAL_DATE + " parse(String)"); + final MethodMatcher parseWithFormatter = new MethodMatcher(JODA_LOCAL_DATE + " parse(String, org.joda.time.format.DateTimeFormatter)"); + + final MethodMatcher toDate = new MethodMatcher(JODA_LOCAL_DATE + " toDate()"); + + final MethodMatcher compareTo = new MethodMatcher(JODA_LOCAL_DATE + " compareTo(org.joda.time.ReadablePartial)"); + final MethodMatcher getYear = new MethodMatcher(JODA_LOCAL_DATE + " getYear()"); + final MethodMatcher getMonthOfYear = new MethodMatcher(JODA_LOCAL_DATE + " getMonthOfYear()"); + final MethodMatcher getDayOfMonth = new MethodMatcher(JODA_LOCAL_DATE + " getDayOfMonth()"); + final MethodMatcher plusDays = new MethodMatcher(JODA_LOCAL_DATE + " plusDays(int)"); + final MethodMatcher plusWeeks = new MethodMatcher(JODA_LOCAL_DATE + " plusWeeks(int)"); + final MethodMatcher plusMonths = new MethodMatcher(JODA_LOCAL_DATE + " plusMonths(int)"); + final MethodMatcher plusYears = new MethodMatcher(JODA_LOCAL_DATE + " plusYears(int)"); + final MethodMatcher minusDays = new MethodMatcher(JODA_LOCAL_DATE + " minusDays(int)"); + final MethodMatcher minusWeeks = new MethodMatcher(JODA_LOCAL_DATE + " minusWeeks(int)"); + final MethodMatcher minusMonths = new MethodMatcher(JODA_LOCAL_DATE + " minusMonths(int)"); + final MethodMatcher minusYears = new MethodMatcher(JODA_LOCAL_DATE + " minusYears(int)"); + final MethodMatcher toDateMidnight = new MethodMatcher(JODA_LOCAL_DATE + " toDateMidnight()"); + final MethodMatcher toDateTimeAtStartOfDay = new MethodMatcher(JODA_LOCAL_DATE + " toDateTimeAtStartOfDay()"); + final MethodMatcher toDateTimeAtStartOfDayWithZone = new MethodMatcher(JODA_LOCAL_DATE + " toDateTimeAtStartOfDay(org.joda.time.DateTimeZone)"); + final MethodMatcher dayOfMonth = new MethodMatcher(JODA_LOCAL_DATE + " dayOfMonth()"); + + final MethodMatcher toFormatedString = new MethodMatcher(JODA_LOCAL_DATE + " toString(java.lang.String)"); + final MethodMatcher toString = new MethodMatcher(JODA_LOCAL_DATE + " toString()"); + + final MethodMatcher hashCode = new MethodMatcher(JODA_LOCAL_DATE + " hashCode()"); + final MethodMatcher equals = new MethodMatcher(JODA_LOCAL_DATE + " equals(java.lang.Object)"); + + final JavaTemplate.Builder localDateNoArgsTemplate = JavaTemplate.builder("LocalDate.now()"); + final JavaTemplate.Builder localDateEpochTemplate = JavaTemplate.builder("LocalDate.ofEpochDay(#{any(long)})"); + final JavaTemplate.Builder localDateYmdTemplate = JavaTemplate.builder("LocalDate.of(#{any(int)}, #{any(int)}, #{any(int)})"); + final JavaTemplate.Builder toInstantTemplate = JavaTemplate.builder("#{any(java.util.Date)}.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()") + .imports(JAVA_ZONE_ID); + + final JavaTemplate.Builder withDayOfMonthTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.withDayOfMonth(#{any(int)})"); + final JavaTemplate.Builder nowTemplate = JavaTemplate.builder("LocalDate.now()"); + final JavaTemplate.Builder parseTemplate = JavaTemplate.builder("LocalDate.parse(#{any(String)})"); + final JavaTemplate.Builder parseWithFormatterTemplate = JavaTemplate.builder("LocalDate.parse(#{any(String)}, #{any(java.time.format.DateTimeFormatter)})") + .imports(JAVA_TIME_FORMATTER); + + final JavaTemplate.Builder toDateTemplate = JavaTemplate.builder("Date.from(#{any(java.time.LocalDate)}.atStartOfDay(ZoneId.systemDefault()).toInstant())") + .imports(JAVA_ZONE_ID); + + final JavaTemplate.Builder compareToTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.compareTo(#{any(java.time.chrono.ChronoLocalDate)})"); + final JavaTemplate.Builder getYearTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.getYear()"); + final JavaTemplate.Builder getMonthValueTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.getMonthValue()"); + final JavaTemplate.Builder getDayOfMonthTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.getDayOfMonth()"); + final JavaTemplate.Builder plusDaysTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.plusDays(#{any(int)})"); + final JavaTemplate.Builder plusWeeksTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.plusWeeks(#{any(int)})"); + final JavaTemplate.Builder plusMonthsTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.plusMonths(#{any(int)})"); + final JavaTemplate.Builder plusYearsTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.plusYears(#{any(int)})"); + final JavaTemplate.Builder minusDaysTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.minusDays(#{any(int)})"); + final JavaTemplate.Builder minusWeeksTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.minusWeeks(#{any(int)})"); + final JavaTemplate.Builder minusMonthsTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.minusMonths(#{any(int)})"); + final JavaTemplate.Builder minusYearsTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.minusYears(#{any(int)})"); + final JavaTemplate.Builder toStartOfDayWithDefaultZoneTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.atStartOfDay(java.time.ZoneId.systemDefault())") + .imports(JAVA_ZONE_ID); + final JavaTemplate.Builder toStartOfDateWithZoneTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.atStartOfDay(#{any(java.time.ZoneId)})") + .imports(JAVA_ZONE_ID); + + final JavaTemplate.Builder toFormatedStringTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.format(DateTimeFormatter.ofPattern(#{any(String)}))") + .imports(JAVA_TIME_FORMATTER); + final JavaTemplate.Builder toStringTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.toString()") + .imports(JAVA_ZONE_ID); + + final JavaTemplate.Builder hashCodeTemplate = JavaTemplate.builder("#{any(java.time.LocalDate)}.hashCode()"); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(newLocalDateNoArgs, build(localDateNoArgsTemplate))); + add(new MethodTemplate(newLocalDateEpoch, build(localDateEpochTemplate))); + add(new MethodTemplate(newLocalDateYmd, build(localDateYmdTemplate))); + add(new MethodTemplate(fromDateFields, build(toInstantTemplate))); + + add(new MethodTemplate(withDayOfMonth, build(withDayOfMonthTemplate))); + add(new MethodTemplate(now, build(nowTemplate))); + add(new MethodTemplate(parse, build(parseTemplate))); + add(new MethodTemplate(parseWithFormatter, build(parseWithFormatterTemplate))); + + add(new MethodTemplate(toDate, build(toDateTemplate))); + + add(new MethodTemplate(compareTo, build(compareToTemplate))); + add(new MethodTemplate(getYear, build(getYearTemplate))); + add(new MethodTemplate(getMonthOfYear, build(getMonthValueTemplate))); + add(new MethodTemplate(getDayOfMonth, build(getDayOfMonthTemplate))); + add(new MethodTemplate(plusDays, build(plusDaysTemplate))); + add(new MethodTemplate(plusWeeks, build(plusWeeksTemplate))); + add(new MethodTemplate(plusMonths, build(plusMonthsTemplate))); + add(new MethodTemplate(plusYears, build(plusYearsTemplate))); + add(new MethodTemplate(minusDays, build(minusDaysTemplate))); + add(new MethodTemplate(minusWeeks, build(minusWeeksTemplate))); + add(new MethodTemplate(minusMonths, build(minusMonthsTemplate))); + add(new MethodTemplate(minusYears, build(minusYearsTemplate))); + add(new MethodTemplate(toDateMidnight, build(toStartOfDayWithDefaultZoneTemplate), + m -> new Expression[]{ ((J.MethodInvocation)m).getSelect() }) + ); + add(new MethodTemplate(toDateTimeAtStartOfDay, build(toStartOfDayWithDefaultZoneTemplate), + m -> new Expression[]{ ((J.MethodInvocation)m).getSelect() }) + ); + add(new MethodTemplate(toDateTimeAtStartOfDayWithZone, build(toStartOfDateWithZoneTemplate), + m -> { + J.MethodInvocation mi = (J.MethodInvocation)m; + return new Expression[]{ mi.getSelect(), mi.getArguments().get(0) }; + })); + + add(new MethodTemplate(toFormatedString, build(toFormatedStringTemplate))); + add(new MethodTemplate(toString, build(toStringTemplate))); + add(new MethodTemplate(hashCode, build(hashCodeTemplate))); + + add(new MethodTemplate(localDateToDateTime, JODA_NO_AUTOMATIC_MAPPING_POSSIBLE_TEMPLATE)); + add(new MethodTemplate(dayOfMonth, JODA_NO_AUTOMATIC_MAPPING_POSSIBLE_TEMPLATE)); + add(new MethodTemplate(newLocalDate, JODA_MULTIPLE_MAPPING_POSSIBLE_TEMPLATE)); + add(new MethodTemplate(equals, JODA_MULTIPLE_MAPPING_POSSIBLE_TEMPLATE)); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, JAVA_LOCAL_DATE); + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/LocatDateTimeTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/LocatDateTimeTemplates.java new file mode 100644 index 0000000000..307f1c6c43 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/LocatDateTimeTemplates.java @@ -0,0 +1,189 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; + +@NoArgsConstructor +public class LocatDateTimeTemplates implements Templates { + final MethodMatcher newLocalDateTimeNoArgs = new MethodMatcher(JODA_LOCAL_DATE_TIME + "()"); + final MethodMatcher newLocalDateTimeEpoch = new MethodMatcher(JODA_LOCAL_DATE_TIME + "(long)"); + final MethodMatcher newLocalDateObject = new MethodMatcher(JODA_LOCAL_DATE_TIME + "(Object)"); + final MethodMatcher newLocalDateTimeYmdHm = new MethodMatcher(JODA_LOCAL_DATE_TIME + "(int,int,int,int,int)"); + final MethodMatcher newLocalDateTimeYmdHms = new MethodMatcher(JODA_LOCAL_DATE_TIME + "(int,int,int,int,int,int)"); + final MethodMatcher newLocalDateTimeYmdHmsM = new MethodMatcher(JODA_LOCAL_DATE_TIME + "(int,int,int,int,int,int,int)"); + + final MethodMatcher now = new MethodMatcher(JODA_LOCAL_DATE_TIME + " now()"); + + final MethodMatcher toDate = new MethodMatcher(JODA_LOCAL_DATE_TIME + " toDate()"); + final MethodMatcher toDateTimeAtDefaultZone = new MethodMatcher(JODA_LOCAL_DATE_TIME + " toDateTime()"); + final MethodMatcher toDateTime = new MethodMatcher(JODA_LOCAL_DATE_TIME + " toDateTime(org.joda.time.DateTimeZone)"); + + final MethodMatcher equals = new MethodMatcher(JODA_LOCAL_DATE_TIME + " equals(java.lang.Object)"); + + final MethodMatcher getYear = new MethodMatcher(JODA_LOCAL_DATE_TIME + " getYear()"); + final MethodMatcher getMonthOfYear = new MethodMatcher(JODA_LOCAL_DATE_TIME + " getMonthOfYear()"); + final MethodMatcher getDayOfMonth = new MethodMatcher(JODA_LOCAL_DATE_TIME + " getDayOfMonth()"); + final MethodMatcher getHourOfDay = new MethodMatcher(JODA_LOCAL_DATE_TIME + " getHourOfDay()"); + final MethodMatcher getMinuteOfHour = new MethodMatcher(JODA_LOCAL_DATE_TIME + " getMinuteOfHour()"); + final MethodMatcher getSecondOfMinute = new MethodMatcher(JODA_LOCAL_DATE_TIME + " getSecondOfMinute()"); + final MethodMatcher getMillisOfDay = new MethodMatcher(JODA_LOCAL_DATE_TIME + " getMillisOfDay()"); + final MethodMatcher getMillisOfSecond = new MethodMatcher(JODA_LOCAL_DATE_TIME + " getMillisOfSecond()"); + + final MethodMatcher parse = new MethodMatcher(JODA_LOCAL_DATE_TIME + " parse(String)"); + final MethodMatcher parseWithFormatter = new MethodMatcher(JODA_LOCAL_DATE_TIME + " parse(String, org.joda.time.format.DateTimeFormatter)"); + final MethodMatcher plusYears = new MethodMatcher(JODA_LOCAL_DATE_TIME + " plusYears(int)"); + final MethodMatcher plusMonths = new MethodMatcher(JODA_LOCAL_DATE_TIME + " plusMonths(int)"); + final MethodMatcher plusDays = new MethodMatcher(JODA_LOCAL_DATE_TIME + " plusDays(int)"); + final MethodMatcher plusHours = new MethodMatcher(JODA_LOCAL_DATE_TIME + " plusHours(int)"); + final MethodMatcher plusMinutes = new MethodMatcher(JODA_LOCAL_DATE_TIME + " plusMinutes(int)"); + final MethodMatcher plusSeconds = new MethodMatcher(JODA_LOCAL_DATE_TIME + " plusSeconds(int)"); + final MethodMatcher plusMillis = new MethodMatcher(JODA_LOCAL_DATE_TIME + " plusMillis(int)"); + final MethodMatcher minusYears = new MethodMatcher(JODA_LOCAL_DATE_TIME + " minusYears(int)"); + final MethodMatcher minusMonths = new MethodMatcher(JODA_LOCAL_DATE_TIME + " minusMonths(int)"); + final MethodMatcher minusDays = new MethodMatcher(JODA_LOCAL_DATE_TIME + " minusDays(int)"); + final MethodMatcher minusHours = new MethodMatcher(JODA_LOCAL_DATE_TIME + " minusHours(int)"); + final MethodMatcher minusMinutes = new MethodMatcher(JODA_LOCAL_DATE_TIME + " minusMinutes(int)"); + final MethodMatcher minusSeconds = new MethodMatcher(JODA_LOCAL_DATE_TIME + " minusSeconds(int)"); + final MethodMatcher minusMillis = new MethodMatcher(JODA_LOCAL_DATE_TIME + " minusMillis(int)"); + final MethodMatcher plus = new MethodMatcher(JODA_LOCAL_DATE_TIME + " plus(org.joda.time.ReadableDuration)"); + final MethodMatcher minus = new MethodMatcher(JODA_LOCAL_DATE_TIME + " minus(org.joda.time.ReadableDuration)"); + final MethodMatcher getDateTimeFieldType = new MethodMatcher(JODA_LOCAL_DATE_TIME + " get(org.joda.time.DateTimeFieldType)"); + final MethodMatcher withMinuteOfHour = new MethodMatcher(JODA_LOCAL_DATE_TIME + " withMinuteOfHour(int)"); + final MethodMatcher withHourOfDay = new MethodMatcher(JODA_LOCAL_DATE_TIME + " withHourOfDay(int)"); + + final MethodMatcher toFormatedString = new MethodMatcher(JODA_LOCAL_DATE_TIME + " toString(java.lang.String)"); + final MethodMatcher toString = new MethodMatcher(JODA_LOCAL_DATE_TIME + " toString()"); + //time.get(DateTimeFieldType.hourOfDay()) + //time.get(DateTimeFieldType.minuteOfHour() + //endTime.withMinuteOfHour(0).withHourOfDay(endTime.getHourOfDay() + 1) + //startTime.withMinuteOfHour(0) + + + final JavaTemplate.Builder newLocalDateTimeNoArgsTemplate = JavaTemplate.builder("LocalDateTime.now()"); + final JavaTemplate.Builder newLocalDateTimeEpochTemplate = JavaTemplate.builder("LocalDateTime.ofInstant(Instant.ofEpochMilli(#{any(long)}), ZoneId.systemDefault())") + .imports(JAVA_INSTANT, JAVA_ZONE_ID); + final JavaTemplate.Builder newLocalDateTimeYmdHmTemplate = JavaTemplate.builder("LocalDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)})"); + final JavaTemplate.Builder newLocalDateTimeYmdHmsTemplate = JavaTemplate.builder("LocalDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)})"); + final JavaTemplate.Builder newLocalDateTimeYmdHmsMTemplate = JavaTemplate.builder("LocalDateTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)}, #{any(int)})"); + + final JavaTemplate.Builder nowTemplate = JavaTemplate.builder("LocalDateTime.now()"); + + final JavaTemplate.Builder toDateTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.atZone(ZoneId.systemDefault()).toInstant()"); + final JavaTemplate.Builder toDateTimeAtSystemDefaultTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.atZone(ZoneId.systemDefault())"); + final JavaTemplate.Builder toDateTimeTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.atZone(#{any(java.time.ZoneOffset)})"); + + final JavaTemplate.Builder getYearTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.getYear()"); + final JavaTemplate.Builder getMonthValueTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.getMonthValue()"); + final JavaTemplate.Builder getDayOfMonthTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.getDayOfMonth()"); + final JavaTemplate.Builder getHourTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.getHour()"); + final JavaTemplate.Builder getMinuteTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.getMinute()"); + final JavaTemplate.Builder getSecondTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.getSecond()"); + final JavaTemplate.Builder getMilliOfDayTemplate = JavaTemplate.builder("#{any(java.time.LocalTime)}.get(ChronoField.MILLI_OF_DAY)") + .imports(JAVA_CHRONO_FIELD); + final JavaTemplate.Builder getMillisOfSecondTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.getSecond() * 1000"); + + final JavaTemplate.Builder parseTemplate = JavaTemplate.builder("LocalDateTime.parse(#{any(String)})"); + final JavaTemplate.Builder parseWithFormatterTemplate = JavaTemplate.builder("LocalDateTime.parse(#{any(String)}, #{any(java.time.format.DateTimeFormatter)})"); + final JavaTemplate.Builder plusYearsTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.plusYears(#{any(int)})"); + final JavaTemplate.Builder plusMonthsTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.plusMonths(#{any(int)})"); + final JavaTemplate.Builder plusDaysTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.plusDays(#{any(int)})"); + final JavaTemplate.Builder plusHoursTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.plusHours(#{any(int)})"); + final JavaTemplate.Builder plusMinutesTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.plusMinutes(#{any(int)})"); + final JavaTemplate.Builder plusSecondsTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.plusSeconds(#{any(int)})"); + final JavaTemplate.Builder plusMillisTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.plusNanos(#{any(int)} * 1_000_000L)"); + final JavaTemplate.Builder minusYearsTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.minusYears(#{any(int)})"); + final JavaTemplate.Builder minusMonthsTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.minusMonths(#{any(int)})"); + final JavaTemplate.Builder minusDaysTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.minusDays(#{any(int)})"); + final JavaTemplate.Builder minusHoursTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.minusHours(#{any(int)})"); + final JavaTemplate.Builder minusMinutesTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.minusMinutes(#{any(int)})"); + final JavaTemplate.Builder minusSecondsTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.minusSeconds(#{any(int)})"); + final JavaTemplate.Builder minusMillisTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.minusNanos(#{any(int)} * 1_000_000L)"); + final JavaTemplate.Builder plusTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.plus(#{any(java.time.Duration)})"); + final JavaTemplate.Builder minusTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.minus(#{any(java.time.Duration)})"); + final JavaTemplate.Builder withMinuteTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.withMinute(#{any(int)})"); + final JavaTemplate.Builder withHourTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.withHour(#{any(int)})"); + + final JavaTemplate.Builder toFormatedStringTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.format(DateTimeFormatter.ofPattern(#{any(String)}))") + .imports(JAVA_TIME_FORMATTER); + final JavaTemplate.Builder toStringTemplate = JavaTemplate.builder("#{any(java.time.LocalDateTime)}.toString()"); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(newLocalDateTimeNoArgs, build(newLocalDateTimeNoArgsTemplate))); + add(new MethodTemplate(newLocalDateTimeEpoch, build(newLocalDateTimeEpochTemplate))); + add(new MethodTemplate(newLocalDateTimeYmdHm, build(newLocalDateTimeYmdHmTemplate))); + add(new MethodTemplate(newLocalDateTimeYmdHms, build(newLocalDateTimeYmdHmsTemplate))); + add(new MethodTemplate(newLocalDateTimeYmdHmsM, build(newLocalDateTimeYmdHmsMTemplate))); + + add(new MethodTemplate(now, build(nowTemplate))); + + add(new MethodTemplate(toDate, build(toDateTemplate))); + add(new MethodTemplate(toDateTimeAtDefaultZone, build(toDateTimeAtSystemDefaultTemplate))); + add(new MethodTemplate(toDateTime, build(toDateTimeTemplate))); + + add(new MethodTemplate(getYear, build(getYearTemplate))); + add(new MethodTemplate(getMonthOfYear, build(getMonthValueTemplate))); + add(new MethodTemplate(getDayOfMonth, build(getDayOfMonthTemplate))); + add(new MethodTemplate(getHourOfDay, build(getHourTemplate))); + add(new MethodTemplate(getMinuteOfHour, build(getMinuteTemplate))); + add(new MethodTemplate(getSecondOfMinute, build(getSecondTemplate))); + add(new MethodTemplate(getMillisOfDay, build(getMilliOfDayTemplate))); + add(new MethodTemplate(getMillisOfSecond, build(getMillisOfSecondTemplate))); + + add(new MethodTemplate(parse, build(parseTemplate))); + add(new MethodTemplate(parseWithFormatter, build(parseWithFormatterTemplate))); + add(new MethodTemplate(plusYears, build(plusYearsTemplate))); + add(new MethodTemplate(plusMonths, build(plusMonthsTemplate))); + add(new MethodTemplate(plusDays, build(plusDaysTemplate))); + add(new MethodTemplate(plusHours, build(plusHoursTemplate))); + add(new MethodTemplate(plusMinutes, build(plusMinutesTemplate))); + add(new MethodTemplate(plusSeconds, build(plusSecondsTemplate))); + add(new MethodTemplate(plusMillis, build(plusMillisTemplate))); + add(new MethodTemplate(minusYears, build(minusYearsTemplate))); + add(new MethodTemplate(minusMonths, build(minusMonthsTemplate))); + add(new MethodTemplate(minusDays, build(minusDaysTemplate))); + add(new MethodTemplate(minusHours, build(minusHoursTemplate))); + add(new MethodTemplate(minusMinutes, build(minusMinutesTemplate))); + add(new MethodTemplate(minusSeconds, build(minusSecondsTemplate))); + add(new MethodTemplate(minusMillis, build(minusMillisTemplate))); + add(new MethodTemplate(plus, build(plusTemplate))); + add(new MethodTemplate(minus, build(minusTemplate))); + add(new MethodTemplate(getDateTimeFieldType, JODA_MULTIPLE_MAPPING_POSSIBLE_TEMPLATE)); + add(new MethodTemplate(withMinuteOfHour, build(withMinuteTemplate))); + add(new MethodTemplate(withHourOfDay, build(withHourTemplate))); + + add(new MethodTemplate(toFormatedString, build(toFormatedStringTemplate))); + add(new MethodTemplate(toString, build(toStringTemplate))); + + add(new MethodTemplate(newLocalDateObject, JODA_MULTIPLE_MAPPING_POSSIBLE_TEMPLATE)); + add(new MethodTemplate(equals, JODA_MULTIPLE_MAPPING_POSSIBLE_TEMPLATE)); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, JODA_LOCAL_DATE_TIME); + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/LocatTimeTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/LocatTimeTemplates.java new file mode 100644 index 0000000000..256fc2e965 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/LocatTimeTemplates.java @@ -0,0 +1,128 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; + +@NoArgsConstructor +public class LocatTimeTemplates implements Templates { + final MethodMatcher newLocalTimeNoArgs = new MethodMatcher(JODA_LOCAL_TIME + "()"); + final MethodMatcher newLocalTimeEpoch = new MethodMatcher(JODA_LOCAL_TIME + "(long)"); + final MethodMatcher newLocalTimeString = new MethodMatcher(JODA_LOCAL_TIME + "(Object)"); + final MethodMatcher newLocalTimeWithInstanceAndTimeZone = new MethodMatcher(JODA_LOCAL_TIME + "(java.lang.Object,org.joda.time.DateTimeZone)"); + final MethodMatcher newLocalTimeHm = new MethodMatcher(JODA_LOCAL_TIME + "(int,int)"); + final MethodMatcher newLocalTimeHms = new MethodMatcher(JODA_LOCAL_TIME + "(int,int,int)"); + final MethodMatcher newLocalTimeHmsM = new MethodMatcher(JODA_LOCAL_TIME + "(int,int,int,int)"); + final MethodMatcher newLocalTimeFromSqlTime = new MethodMatcher(JODA_LOCAL_TIME + "(java.sql.Time)"); + + final MethodMatcher fromMillisOfDay = new MethodMatcher(JODA_LOCAL_TIME + " fromMillisOfDay(long)"); + final MethodMatcher now = new MethodMatcher(JODA_LOCAL_TIME + " now()"); + + final MethodMatcher toDateTimeToday = new MethodMatcher(JODA_LOCAL_TIME + " toDateTimeToday()"); + final MethodMatcher toString = new MethodMatcher(JODA_LOCAL_TIME + " toString()"); + + final MethodMatcher getHourOfDay = new MethodMatcher(JODA_LOCAL_TIME + " getHourOfDay()"); + final MethodMatcher getMinuteOfHour = new MethodMatcher(JODA_LOCAL_TIME + " getMinuteOfHour()"); + final MethodMatcher getSecondOfMinute = new MethodMatcher(JODA_LOCAL_TIME + " getSecondOfMinute()"); + final MethodMatcher getMillisOfDay = new MethodMatcher(JODA_LOCAL_TIME + " getMillisOfDay()"); + + final MethodMatcher parse = new MethodMatcher(JODA_LOCAL_TIME + " parse(String)"); + final MethodMatcher plusMinutes = new MethodMatcher(JODA_LOCAL_TIME + " plusMinutes(int)"); + final MethodMatcher plusSeconds = new MethodMatcher(JODA_LOCAL_TIME + " plusSeconds(int)"); + final MethodMatcher plusMillis = new MethodMatcher(JODA_LOCAL_TIME + " plusMillis(int)"); + final MethodMatcher minusMinutes = new MethodMatcher(JODA_LOCAL_TIME + " minusMinutes(int)"); + final MethodMatcher minusSeconds = new MethodMatcher(JODA_LOCAL_TIME + " minusSeconds(int)"); + final MethodMatcher minusMillis = new MethodMatcher(JODA_LOCAL_TIME + " minusMillis(int)"); + + final MethodMatcher equals = new MethodMatcher(JODA_LOCAL_TIME + " equals(java.lang.Object)"); + + final JavaTemplate.Builder localTimeNoArgsTemplate = JavaTemplate.builder("LocalTime.now()"); + final JavaTemplate.Builder localTimeEpochTemplate = JavaTemplate.builder("LocalDate.ofEpochDay(#{any(long)})"); + final JavaTemplate.Builder localTimeStringTemplate = JavaTemplate.builder("LocalTime.parse(#{any(Object)})"); + final JavaTemplate.Builder localTimeOfInstantTemplate = JavaTemplate.builder("LocalTime.ofInstant(#{any(Object)}, #{any(java.time.ZoneId)})"); + final JavaTemplate.Builder localTimeHmTemplate = JavaTemplate.builder("LocalTime.of(#{any(int)}, #{any(int)})"); + final JavaTemplate.Builder localTimeHmsTemplate = JavaTemplate.builder("LocalTime.of(#{any(int)}, #{any(int)}, #{any(int)})"); + final JavaTemplate.Builder localTimeHmsMTemplate = JavaTemplate.builder("LocalTime.of(#{any(int)}, #{any(int)}, #{any(int)}, #{any(int)})"); + final JavaTemplate.Builder newLocalTimeFromSqlTimeTemplate = JavaTemplate.builder("#{any(java.sql.Time)}.toLocalTime()"); + + final JavaTemplate.Builder ofSecondOfDayTemplate = JavaTemplate.builder("LocalTime.ofSecondOfDay(#{any(long)} / 1000)"); + final JavaTemplate.Builder nowTemplate = JavaTemplate.builder("LocalTime.now()"); + + final JavaTemplate.Builder toLocalDateOfTodayTemplate = JavaTemplate.builder("#{any(java.time.LocalTime)}.atDate(LocalDate.now())") + .imports(JAVA_LOCAL_DATE); + final JavaTemplate.Builder toStringTemplate = JavaTemplate.builder("#{any(java.time.LocalTime)}.toString()"); + + final JavaTemplate.Builder getHourTemplate = JavaTemplate.builder("#{any(java.time.LocalTime)}.getHour()"); + final JavaTemplate.Builder getMinuteTemplate = JavaTemplate.builder("#{any(java.time.LocalTime)}.getMinute()"); + final JavaTemplate.Builder getSecondTemplate = JavaTemplate.builder("#{any(java.time.LocalTime)}.getSecond()"); + final JavaTemplate.Builder getMilliOfDayTemplate = JavaTemplate.builder("#{any(java.time.LocalTime)}.get(ChronoField.MILLI_OF_DAY)") + .imports(JAVA_CHRONO_FIELD); + + final JavaTemplate.Builder parseTemplate = JavaTemplate.builder("LocalTime.parse(#{any(String)})"); + final JavaTemplate.Builder plusMinutesTemplate = JavaTemplate.builder("#{any(java.time.LocalTime)}.plusMinutes(#{any(int)})"); + final JavaTemplate.Builder plusSecondsTemplate = JavaTemplate.builder("#{any(java.time.LocalTime)}.plusSeconds(#{any(int)})"); + final JavaTemplate.Builder plusMillisTemplate = JavaTemplate.builder("#{any(java.time.LocalTime)}.plusNanos(#{any(int)})"); + final JavaTemplate.Builder minusMinutesTemplate = JavaTemplate.builder("#{any(java.time.LocalTime)}.minusMinutes(#{any(int)})"); + final JavaTemplate.Builder minusSecondsTemplate = JavaTemplate.builder("#{any(java.time.LocalTime)}.minusSeconds(#{any(int)})"); + final JavaTemplate.Builder minusMillisTemplate = JavaTemplate.builder("#{any(java.time.LocalTime)}.minusNanos(#{any(int)})"); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(newLocalTimeNoArgs, build(localTimeNoArgsTemplate))); + add(new MethodTemplate(newLocalTimeEpoch, build(localTimeEpochTemplate))); + add(new MethodTemplate(newLocalTimeString, build(localTimeStringTemplate))); + add(new MethodTemplate(newLocalTimeWithInstanceAndTimeZone, build(localTimeOfInstantTemplate))); + add(new MethodTemplate(newLocalTimeHm, build(localTimeHmTemplate))); + add(new MethodTemplate(newLocalTimeHms, build(localTimeHmsTemplate))); + add(new MethodTemplate(newLocalTimeHmsM, build(localTimeHmsMTemplate))); + add(new MethodTemplate(newLocalTimeFromSqlTime, build(newLocalTimeFromSqlTimeTemplate))); + + add(new MethodTemplate(fromMillisOfDay, build(ofSecondOfDayTemplate))); + add(new MethodTemplate(now, build(nowTemplate))); + + add(new MethodTemplate(toDateTimeToday, build(toLocalDateOfTodayTemplate))); + add(new MethodTemplate(toString, build(toStringTemplate))); + + add(new MethodTemplate(getHourOfDay, build(getHourTemplate))); + add(new MethodTemplate(getMinuteOfHour, build(getMinuteTemplate))); + add(new MethodTemplate(getSecondOfMinute, build(getSecondTemplate))); + add(new MethodTemplate(getMillisOfDay, build(getMilliOfDayTemplate))); + + add(new MethodTemplate(parse, build(parseTemplate))); + add(new MethodTemplate(plusMinutes, build(plusMinutesTemplate))); + add(new MethodTemplate(plusSeconds, build(plusSecondsTemplate))); + add(new MethodTemplate(plusMillis, build(plusMillisTemplate))); + add(new MethodTemplate(minusMinutes, build(minusMinutesTemplate))); + add(new MethodTemplate(minusSeconds, build(minusSecondsTemplate))); + add(new MethodTemplate(minusMillis, build(minusMillisTemplate))); + + add(new MethodTemplate(equals, JODA_MULTIPLE_MAPPING_POSSIBLE_TEMPLATE)); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, JAVA_LOCAL_DATE); + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/MethodMatcherBuilder.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/MethodMatcherBuilder.java new file mode 100644 index 0000000000..4d38fa0d06 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/MethodMatcherBuilder.java @@ -0,0 +1,83 @@ +package org.openrewrite.java.migrate.joda.templates; + +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_SECONDS; + +//final MethodMatcher secondsPlus = new MethodMatcher(JODA_SECONDS + " plus(int)"); +// -> +//final MethodMatcherBuilder plusInt = from().method("plus").with("int"); + +/* +private MethodMatcherBuilder from() { + return from(JODA_SECONDS); +} + +//to Templates +private MethodMatcher build(MethodMatcherBuilder builder) { + return builder.build(); +} +private MethodMatcherBuilder from(String className) { + return MethodMatcherBuilder.builder(className); +} +*/ + + +public class MethodMatcherBuilder { + private Optional isConstructor = Optional.empty(); + private String className; + private String methodName; + private List arguments = new ArrayList<>(); + + private MethodMatcherBuilder(String className) { + this.className = className; + }; + + public static MethodMatcherBuilder builder(String className) { + return new MethodMatcherBuilder(className); + } + + public MethodMatcherBuilder contructor() { + if (!isConstructor.isPresent()) {throw new IllegalStateException("Type can be set only once");} + if (isConstructor.get() == Boolean.FALSE) {throw new IllegalStateException("Type already set to method");} + isConstructor = Optional.of(Boolean.TRUE); + return this; + } + public MethodMatcherBuilder method(String methodName) { + if (!isConstructor.isPresent()) {throw new IllegalStateException("Type can be set only once");} + if (isConstructor.get() == Boolean.TRUE) {throw new IllegalStateException("Type already set to method");} + isConstructor = Optional.of(Boolean.FALSE); + this.methodName = methodName; + return this; + } + + public MethodMatcherBuilder with(String argumentType) { + if (!isConstructor.isPresent()) {throw new IllegalStateException("Type is not set");} + arguments.add(argumentType); + return this; + } + + public MethodMatcher build() { + return new MethodMatcher( + className + " " + + getCallType() + + "(" + + getArguments() + + ")" + ); + + } + + private String getArguments() { + return String.join(", ", arguments); + } + + private String getCallType() { + if (!isConstructor.isPresent()) throw new IllegalStateException("Type is not set"); + return isConstructor.get() == Boolean.TRUE ? "" : methodName; + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/MinutesTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/MinutesTemplates.java new file mode 100644 index 0000000000..d8e1abc983 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/MinutesTemplates.java @@ -0,0 +1,78 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JAVA_DURATION; +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.JODA_MINUTES; + +@NoArgsConstructor +public class MinutesTemplates implements Templates { + final MethodMatcher minutesStaticMethod = new MethodMatcher(JODA_MINUTES + " minutes(int)"); + final MethodMatcher plusMethod = new MethodMatcher(JODA_MINUTES + " plus(org.joda.time.Minutes)"); + final MethodMatcher minusMethod = new MethodMatcher(JODA_MINUTES + " minus(org.joda.time.Minutes)"); + final MethodMatcher multipliedByMethod = new MethodMatcher(JODA_MINUTES + " multipliedBy(int)"); + final MethodMatcher dividedByMethod = new MethodMatcher(JODA_MINUTES + " dividedBy(int)"); + final MethodMatcher getMinutesMethod = new MethodMatcher(JODA_MINUTES + " getMinutes()"); + final MethodMatcher isLessThan = new MethodMatcher(JODA_MINUTES + " isLessThan(org.joda.time.Minutes)"); + final MethodMatcher isGreaterThan = new MethodMatcher(JODA_MINUTES + " isGreaterThan(org.joda.time.Minutes)"); + final MethodMatcher toStandardDuration = new MethodMatcher(JODA_MINUTES + " toStandardDuration()"); + final MethodMatcher minutesZero = new MethodMatcher(JODA_MINUTES + " ZERO"); + final MethodMatcher minutesToStandardSeconds = new MethodMatcher(JODA_MINUTES + " toStandardSeconds()"); + + //Minutes.ZERO + //Minutes.minutes(10).toStandardSeconds() + + final JavaTemplate.Builder minutesStaticMethodTemplate = JavaTemplate.builder("Duration.ofMinutes(#{any(int)})"); + final JavaTemplate.Builder plusMethodTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plus(#{any(java.time.Duration)})"); + final JavaTemplate.Builder minusMethodTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minus(#{any(java.time.Duration)})"); + final JavaTemplate.Builder multipliedByMethodTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.multipliedBy(#{any(int)})"); + final JavaTemplate.Builder dividedByMethodTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.dividedBy(#{any(int)})"); + final JavaTemplate.Builder getMinutesMethodTemplate = JavaTemplate.builder("(int)#{any(java.time.Duration)}.toMinutes()"); + final JavaTemplate.Builder minusIsNegativeTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minus(#{any(java.time.Duration)}).isNegative()"); + final JavaTemplate.Builder minusIsPositiveTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minus(#{any(java.time.Duration)}).isPositive()"); + final JavaTemplate.Builder asDurationTemplate = JavaTemplate.builder("#{any(java.time.Duration)}"); + final JavaTemplate.Builder durationZeroTemplate = JavaTemplate.builder("Duration.ZERO"); + final JavaTemplate.Builder toSecondsTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.toSeconds()"); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(minutesStaticMethod, build(minutesStaticMethodTemplate))); + add(new MethodTemplate(plusMethod, build(plusMethodTemplate))); + add(new MethodTemplate(minusMethod, build(minusMethodTemplate))); + add(new MethodTemplate(multipliedByMethod, build(multipliedByMethodTemplate))); + add(new MethodTemplate(dividedByMethod, build(dividedByMethodTemplate))); + add(new MethodTemplate(getMinutesMethod, build(getMinutesMethodTemplate))); + add(new MethodTemplate(isLessThan, build(minusIsNegativeTemplate))); + add(new MethodTemplate(isGreaterThan, build(minusIsPositiveTemplate))); + add(new MethodTemplate(toStandardDuration, build(asDurationTemplate))); + add(new MethodTemplate(minutesZero, build(durationZeroTemplate))); + add(new MethodTemplate(minutesToStandardSeconds, build(toSecondsTemplate))); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, JAVA_DURATION); + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/MonthsTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/MonthsTemplates.java new file mode 100644 index 0000000000..aaf4c56e56 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/MonthsTemplates.java @@ -0,0 +1,54 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; + +@NoArgsConstructor +public class MonthsTemplates implements Templates { + final MethodMatcher monthsStaticMethod = new MethodMatcher(JODA_MONTHS + " months(int)"); + final MethodMatcher monthsBetweenPartial = new MethodMatcher(JODA_MONTHS + " monthsBetween(org.joda.time.ReadablePartial, org.joda.time.ReadablePartial)"); + final MethodMatcher monthsBetweenInstant = new MethodMatcher(JODA_MONTHS + " monthsBetween(org.joda.time.ReadableInstant, org.joda.time.ReadableInstant)"); + final MethodMatcher getMonths = new MethodMatcher(JODA_MONTHS + " getMonths()"); + + final JavaTemplate.Builder monthsStaticMethodTemplate = JavaTemplate.builder("Months.of(#{any(int)})"); + final JavaTemplate.Builder monthsBetweenLocalTemplate = JavaTemplate.builder("Months.between(#{any(java.time.LocalDate)}, #{any(java.time.LocalDate)})"); + final JavaTemplate.Builder monthsBetweenZonedDateTimeTemplate = JavaTemplate.builder("Months.between(#{any(java.time.ZonedDateTime)}, #{any(java.time.ZonedDateTime)})"); + final JavaTemplate.Builder getTemplate = JavaTemplate.builder("(int)#{any(org.threeten.extra.Months)}.get(ChronoUnit.MONTHS)") + .imports(JAVA_CHRONO_UNIT); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(monthsStaticMethod, build(monthsStaticMethodTemplate))); + add(new MethodTemplate(monthsBetweenPartial, build(monthsBetweenLocalTemplate))); + add(new MethodTemplate(monthsBetweenInstant, build(monthsBetweenZonedDateTimeTemplate))); + add(new MethodTemplate(getMonths, build(getTemplate))); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, THREE_TEN_EXTRA_MONTHS); + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/PeriodTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/PeriodTemplates.java new file mode 100644 index 0000000000..609be7aa64 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/PeriodTemplates.java @@ -0,0 +1,62 @@ +/* + * Copyright 2025 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; + +@NoArgsConstructor +public class PeriodTemplates implements Templates{ + final MethodMatcher newPeriod = new MethodMatcher(JODA_PERIOD + "()"); + final MethodMatcher newPeriodFromObject = new MethodMatcher(JODA_PERIOD + "(Object)"); + final MethodMatcher newPeriodOfHmSMillis = new MethodMatcher(JODA_PERIOD + "(int,int,int,int)"); + final MethodMatcher newPeriodOfYMDHySMillis = new MethodMatcher(JODA_PERIOD + "(int,int,int,int,int,int,int,int)"); + final MethodMatcher minus = new MethodMatcher(JODA_PERIOD + " minus(org.joda.time.ReadablePeriod)"); + final MethodMatcher plus = new MethodMatcher(JODA_PERIOD + " plus(org.joda.time.ReadablePeriod)"); + final MethodMatcher getDays = new MethodMatcher(JODA_PERIOD + " getDays()"); + + final JavaTemplate.Builder zeroPeriodTemplate = JavaTemplate.builder("Period.ZERO"); + final JavaTemplate.Builder getDaysTemplate = JavaTemplate.builder("#{any(java.time.Period)}.getDays()"); + final JavaTemplate.Builder minusTemplate = JavaTemplate.builder("#{any(java.time.Period)}.minus(#{any(java.time.Period)})"); + final JavaTemplate.Builder plusTemplate = JavaTemplate.builder("#{any(java.time.Period)}.plus(#{any(java.time.Period)})"); + final JavaTemplate.Builder periodOfHMSMillisTemplate = JavaTemplate.builder("Duration.ofHours(#{any(int)}).plusMinutes(#{any(int)}).plusSeconds(#{any(int)}).plusMillis(#{any(int)})"); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(newPeriod, build(zeroPeriodTemplate))); + add(new MethodTemplate(newPeriodOfHmSMillis, build(periodOfHMSMillisTemplate))); + add(new MethodTemplate(minus, build(minusTemplate))); + add(new MethodTemplate(plus, build(plusTemplate))); + add(new MethodTemplate(getDays, build(getDaysTemplate))); + + add(new MethodTemplate(newPeriodOfYMDHySMillis, JODA_NO_AUTOMATIC_MAPPING_POSSIBLE_TEMPLATE)); + add(new MethodTemplate(newPeriodFromObject, JODA_MULTIPLE_MAPPING_POSSIBLE_TEMPLATE)); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, JAVA_PERIOD); + } + +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/SecondsTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/SecondsTemplates.java new file mode 100644 index 0000000000..cd2d210441 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/SecondsTemplates.java @@ -0,0 +1,86 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; + +@NoArgsConstructor +public class SecondsTemplates implements Templates { + final MethodMatcher secondsStaticMethod = new MethodMatcher(JODA_SECONDS + " seconds(int)"); + final MethodMatcher plusMethod = new MethodMatcher(JODA_SECONDS + " plus(org.joda.time.Seconds)"); + final MethodMatcher minusMethod = new MethodMatcher(JODA_SECONDS + " minus(org.joda.time.Seconds)"); + final MethodMatcher multipliedByMethod = new MethodMatcher(JODA_SECONDS + " multipliedBy(int)"); + final MethodMatcher dividedByMethod = new MethodMatcher(JODA_SECONDS + " dividedBy(int)"); + final MethodMatcher getSecondsMethod = new MethodMatcher(JODA_SECONDS + " getSeconds()"); + final MethodMatcher isLessThan = new MethodMatcher(JODA_SECONDS + " isLessThan(org.joda.time.Seconds)"); + final MethodMatcher isGreaterThan = new MethodMatcher(JODA_SECONDS + " isGreaterThan(org.joda.time.Seconds)"); + final MethodMatcher toStandardDuration = new MethodMatcher(JODA_SECONDS + " toStandardDuration()"); + final MethodMatcher secondsPlus = new MethodMatcher(JODA_SECONDS + " plus(int)"); + final MethodMatcher secondsMinus = new MethodMatcher(JODA_SECONDS + " minus(int)"); + final MethodMatcher secondsNegated = new MethodMatcher(JODA_SECONDS + " negated()"); + final MethodMatcher secondsCompareTo = new MethodMatcher(JODA_SECONDS + " compareTo(" + JODA_SECONDS + ")"); + final MethodMatcher secondsToStandardMinutes = new MethodMatcher(JODA_SECONDS + " toStandardMinutes()"); + final MethodMatcher secondsToString = new MethodMatcher(JODA_SECONDS + " toString()"); + + final JavaTemplate.Builder secondsStaticMethodTemplate = JavaTemplate.builder("Duration.ofSeconds(#{any(int)})"); + final JavaTemplate.Builder plusMethodTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plus(#{any(java.time.Duration)})"); + final JavaTemplate.Builder minusMethodTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minus(#{any(java.time.Duration)})"); + final JavaTemplate.Builder multipliedByMethodTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.multipliedBy(#{any(int)})"); + final JavaTemplate.Builder dividedByMethodTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.dividedBy(#{any(int)})"); + final JavaTemplate.Builder getSecondsMethodTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.getSeconds()"); + final JavaTemplate.Builder minusIsNegativeTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minus(#{any(java.time.Duration)}).isNegative()"); + final JavaTemplate.Builder minusIsPositiveTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minus(#{any(java.time.Duration)}).isPositive()"); + final JavaTemplate.Builder asDurationTemplate = JavaTemplate.builder("#{any(java.time.Duration)}"); + final JavaTemplate.Builder plusSecondsTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.plusSeconds(#{any(int)})"); + final JavaTemplate.Builder minusSecondsTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.minusSeconds(#{any(int)})"); + final JavaTemplate.Builder toMinutesTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.toMinutes()"); + final JavaTemplate.Builder toMinutesNegatedTemplate = JavaTemplate.builder("#{any(java.time.Duration)}.toMinutes() * -1"); + final JavaTemplate.Builder compareLongTemplate = JavaTemplate.builder("Long.compare(#{any(long)}, #{any(long)})"); + + final JavaTemplate.Builder plusIntTemplate = JavaTemplate.builder("#{any(java.time.Duration)}"); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(secondsStaticMethod, build(secondsStaticMethodTemplate))); + add(new MethodTemplate(plusMethod, build(plusMethodTemplate))); + add(new MethodTemplate(minusMethod, build(minusMethodTemplate))); + add(new MethodTemplate(multipliedByMethod, build(multipliedByMethodTemplate))); + add(new MethodTemplate(dividedByMethod, build(dividedByMethodTemplate))); + add(new MethodTemplate(getSecondsMethod, build(getSecondsMethodTemplate))); + add(new MethodTemplate(isLessThan, build(minusIsNegativeTemplate))); + add(new MethodTemplate(isGreaterThan, build(minusIsPositiveTemplate))); + add(new MethodTemplate(toStandardDuration, build(asDurationTemplate))); + add(new MethodTemplate(secondsPlus, build(plusSecondsTemplate))); + add(new MethodTemplate(secondsMinus, build(minusSecondsTemplate))); + add(new MethodTemplate(secondsToStandardMinutes, build(toMinutesTemplate))); + add(new MethodTemplate(secondsNegated, build(toMinutesNegatedTemplate))); + add(new MethodTemplate(secondsCompareTo, build(compareLongTemplate))); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, JAVA_DURATION); + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/Templates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/Templates.java index aa2cf39d0a..fcabf7e11f 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/Templates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/Templates.java @@ -15,6 +15,7 @@ */ package org.openrewrite.java.migrate.joda.templates; +import org.openrewrite.java.JavaTemplate; import org.openrewrite.java.tree.MethodCall; import java.util.List; @@ -29,4 +30,8 @@ public interface Templates { default boolean matchesMethodCall(MethodCall method, MethodTemplate template) { return true; } + + default JavaTemplate buildWithImport(JavaTemplate.Builder builder, String imports) { + return builder.imports(imports).build() ; + } } diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassMap.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassMap.java index 06437dea14..87679922c5 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassMap.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassMap.java @@ -31,17 +31,43 @@ public class TimeClassMap { { put(JODA_DATE_TIME, javaTypeClass(JAVA_DATE_TIME, object)); put(JODA_BASE_DATE_TIME, javaTypeClass(JAVA_DATE_TIME, object)); + put(JODA_DATE_MIDNIGHT, javaTypeClass(JAVA_DATE_TIME, object)); put(JODA_DATE_TIME_ZONE, javaTypeClass(JAVA_ZONE_ID, object)); put(JODA_TIME_FORMATTER, javaTypeClass(JAVA_TIME_FORMATTER, object)); put(JODA_DURATION, javaTypeClass(JAVA_DURATION, object)); + put(JODA_PERIOD, javaTypeClass(JAVA_PERIOD, object)); put(JODA_READABLE_DURATION, javaTypeClass(JAVA_DURATION, object)); put(JODA_INTERVAL, javaTypeClass(THREE_TEN_EXTRA_INTERVAL, object)); + put(JODA_LOCAL_DATE, javaTypeClass(JAVA_LOCAL_DATE, object)); + put(JODA_LOCAL_DATE_TIME, javaTypeClass(JAVA_LOCAL_DATE_TIME, object)); + put(JODA_LOCAL_TIME, javaTypeClass(JAVA_LOCAL_TIME, object)); + put(JODA_SECONDS, javaTypeClass(JAVA_DURATION, object)); + put(JODA_MINUTES, javaTypeClass(JAVA_DURATION, object)); + put(JODA_HOURS, javaTypeClass(JAVA_DURATION, object)); + put(JODA_GEORGIAN_CHRONOLOGY, javaTypeClass(JAVA_ISA_CHRONOLOGY, object)); + put(JODA_DAYS, javaTypeClass(THREE_TEN_EXTRA_DAYS, object)); + put(JODA_WEEKS, javaTypeClass(THREE_TEN_EXTRA_WEEKS, object)); + put(JODA_MONTHS, javaTypeClass(THREE_TEN_EXTRA_MONTHS, object)); + put(JODA_YEARS, javaTypeClass(THREE_TEN_EXTRA_YEARS, object)); } }; private final Map jodaToJavaTimeShortName = new HashMap() { { put(JODA_DATE_TIME, "ZonedDateTime"); + put(JODA_DATE_MIDNIGHT, "ZonedDateTime"); + put(JODA_LOCAL_DATE, "LocalDate"); + put(JODA_LOCAL_DATE_TIME, "LocalDateTime"); + put(JODA_LOCAL_TIME, "LocalTime"); + put(JODA_SECONDS, "Duration"); + put(JODA_MINUTES, "Duration"); + put(JODA_HOURS, "Duration"); + put(JODA_DAYS, "Period"); + put(JODA_WEEKS, "Period"); + put(JODA_MONTHS, "Period"); + put(JODA_YEARS, "Period"); + put(JODA_DATE_TIME_ZONE, "ZoneId"); + put(JODA_GEORGIAN_CHRONOLOGY, "IsoChronology"); } }; diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassNames.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassNames.java index 4cb88c0554..688e0ba6af 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassNames.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeClassNames.java @@ -15,29 +15,43 @@ */ package org.openrewrite.java.migrate.joda.templates; +import org.openrewrite.java.JavaTemplate; + import java.util.regex.Pattern; public class TimeClassNames { public static final Pattern JODA_CLASS_PATTERN = Pattern.compile("org\\.joda\\.time\\..*"); + public static final String JODA_MULTIPLE_MAPPING_POSSIBLE = "Multiple mapping is possible.Update manually"; + public static final String JODA_NO_AUTOMATIC_MAPPING_POSSIBLE = "Not possible to migrate with recipe.Update manually"; + public static final JavaTemplate JODA_MULTIPLE_MAPPING_POSSIBLE_TEMPLATE = JavaTemplate.builder(JODA_MULTIPLE_MAPPING_POSSIBLE).build(); + public static final JavaTemplate JODA_NO_AUTOMATIC_MAPPING_POSSIBLE_TEMPLATE = JavaTemplate.builder(JODA_NO_AUTOMATIC_MAPPING_POSSIBLE).build(); // java util public static final String JAVA_UTIL_DATE = "java.util.Date"; + public static final String JAVA_UTIL_LOCALE = "java.util.Locale"; // Joda-Time classes public static final String JODA_TIME_PKG = "org.joda.time"; public static final String JODA_ABSTRACT_DATE_TIME = JODA_TIME_PKG + ".base.AbstractDateTime"; public static final String JODA_ABSTRACT_DURATION = JODA_TIME_PKG + ".base.AbstractDuration"; public static final String JODA_ABSTRACT_INTERVAL = JODA_TIME_PKG + ".base.AbstractInterval"; + public static final String JODA_ABSTRACT_PARTIAL = JODA_TIME_PKG + ".base.AbstractPartial"; public static final String JODA_BASE_DATE_TIME = JODA_TIME_PKG + ".base.BaseDateTime"; public static final String JODA_DATE_TIME = JODA_TIME_PKG + ".DateTime"; + public static final String JODA_DATE_MIDNIGHT = JODA_TIME_PKG + ".DateMidnight"; public static final String JODA_DATE_TIME_ZONE = JODA_TIME_PKG + ".DateTimeZone"; public static final String JODA_TIME_FORMAT = JODA_TIME_PKG + ".format.DateTimeFormat"; public static final String JODA_TIME_FORMATTER = JODA_TIME_PKG + ".format.DateTimeFormatter"; public static final String JODA_LOCAL_DATE = JODA_TIME_PKG + ".LocalDate"; + public static final String JODA_LOCAL_DATE_PROPERTY = JODA_TIME_PKG + ".LocalDate.Property"; public static final String JODA_LOCAL_TIME = JODA_TIME_PKG + ".LocalTime"; + public static final String JODA_LOCAL_DATE_TIME = JODA_TIME_PKG + ".LocalDateTime"; public static final String JODA_DATE_TIME_FIELD_TYPE = JODA_TIME_PKG + ".DateTimeFieldType"; public static final String JODA_DURATION_FIELD_TYPE = JODA_TIME_PKG + ".DurationFieldType"; public static final String JODA_DURATION = JODA_TIME_PKG + ".Duration"; + public static final String JODA_ABSTRACT_PERIOD = JODA_TIME_PKG + ".base.AbstractPeriod"; + public static final String JODA_PERIOD = JODA_TIME_PKG + ".Period"; + public static final String JODA_PERIOD_TYPE = JODA_TIME_PKG + "PeriodType"; public static final String JODA_READABLE_DURATION = JODA_TIME_PKG + ".ReadableDuration"; public static final String JODA_BASE_DURATION = JODA_TIME_PKG + ".base.BaseDuration"; public static final String JODA_ABSTRACT_INSTANT = JODA_TIME_PKG + ".base.AbstractInstant"; @@ -45,11 +59,22 @@ public class TimeClassNames { public static final String JODA_INSTANT = JODA_TIME_PKG + ".Instant"; public static final String JODA_INTERVAL = JODA_TIME_PKG + ".Interval"; public static final String JODA_BASE_INTERVAL = JODA_TIME_PKG + ".base.BaseInterval"; + public static final String JODA_SECONDS = JODA_TIME_PKG + ".Seconds"; + public static final String JODA_MINUTES = JODA_TIME_PKG + ".Minutes"; + public static final String JODA_HOURS = JODA_TIME_PKG + ".Hours"; + public static final String JODA_DAYS = JODA_TIME_PKG + ".Days"; + public static final String JODA_WEEKS = JODA_TIME_PKG + ".Weeks"; + public static final String JODA_MONTHS = JODA_TIME_PKG + ".Months"; + public static final String JODA_YEARS = JODA_TIME_PKG + ".Years"; + public static final String JODA_DATE_TIME_UTILS = JODA_TIME_PKG + ".DateTimeUtils"; + public static final String JODA_BASIC_CHRONOLOGY = JODA_TIME_PKG + ".chrono.BasicChronology"; + public static final String JODA_GEORGIAN_CHRONOLOGY = JODA_TIME_PKG + ".chrono.GregorianChronology"; // Java Time classes public static final String JAVA_TIME_PKG = "java.time"; public static final String JAVA_DATE_TIME = JAVA_TIME_PKG + ".ZonedDateTime"; public static final String JAVA_DURATION = JAVA_TIME_PKG + ".Duration"; + public static final String JAVA_PERIOD = JAVA_TIME_PKG + ".Period"; public static final String JAVA_ZONE_OFFSET = JAVA_TIME_PKG + ".ZoneOffset"; public static final String JAVA_ZONE_ID = JAVA_TIME_PKG + ".ZoneId"; public static final String JAVA_INSTANT = JAVA_TIME_PKG + ".Instant"; @@ -58,10 +83,17 @@ public class TimeClassNames { public static final String JAVA_TEMPORAL_ADJUSTER = JAVA_TIME_PKG + ".temporal.TemporalAdjuster"; public static final String JAVA_LOCAL_DATE = JAVA_TIME_PKG + ".LocalDate"; public static final String JAVA_LOCAL_TIME = JAVA_TIME_PKG + ".LocalTime"; + public static final String JAVA_LOCAL_DATE_TIME = JAVA_TIME_PKG + ".LocalDateTime"; public static final String JAVA_TEMPORAL_ISO_FIELDS = JAVA_TIME_PKG + ".temporal.IsoFields"; public static final String JAVA_CHRONO_FIELD = JAVA_TIME_PKG + ".temporal.ChronoField"; + public static final String JAVA_CHRONO_UNIT = JAVA_TIME_PKG + ".temporal.ChronoUnit"; + public static final String JAVA_ISA_CHRONOLOGY = JAVA_TIME_PKG + ".chrono.IsoChronology"; // ThreeTen-Extra classes public static final String THREE_TEN_EXTRA_PKG = "org.threeten.extra"; public static final String THREE_TEN_EXTRA_INTERVAL = THREE_TEN_EXTRA_PKG + ".Interval"; + public static final String THREE_TEN_EXTRA_DAYS = THREE_TEN_EXTRA_PKG + ".Days"; + public static final String THREE_TEN_EXTRA_WEEKS = THREE_TEN_EXTRA_PKG + ".Weeks"; + public static final String THREE_TEN_EXTRA_MONTHS = THREE_TEN_EXTRA_PKG + ".Months"; + public static final String THREE_TEN_EXTRA_YEARS = THREE_TEN_EXTRA_PKG + ".Years"; } diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeZoneTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeZoneTemplates.java deleted file mode 100644 index b5ba559e66..0000000000 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/TimeZoneTemplates.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2024 the original author or authors. - *

- * Licensed under the Moderne Source Available License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://docs.moderne.io/licensing/moderne-source-available-license - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.openrewrite.java.migrate.joda.templates; - -import lombok.Getter; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.MethodMatcher; - -import java.util.ArrayList; -import java.util.List; - -import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; - -public class TimeZoneTemplates implements Templates { - private final MethodMatcher zoneForID = new MethodMatcher(JODA_DATE_TIME_ZONE + " forID(String)"); - private final MethodMatcher zoneForOffsetHours = new MethodMatcher(JODA_DATE_TIME_ZONE + " forOffsetHours(int)"); - private final MethodMatcher zoneForOffsetHoursMinutes = new MethodMatcher(JODA_DATE_TIME_ZONE + " forOffsetHoursMinutes(int, int)"); - private final MethodMatcher zoneForTimeZone = new MethodMatcher(JODA_DATE_TIME_ZONE + " forTimeZone(java.util.TimeZone)"); - - private final JavaTemplate zoneIdOfTemplate = JavaTemplate.builder("ZoneId.of(#{any(String)})") - .imports(JAVA_ZONE_ID) - .build(); - private final JavaTemplate zoneOffsetHoursTemplate = JavaTemplate.builder("ZoneOffset.ofHours(#{any(int)})") - .imports(JAVA_ZONE_OFFSET) - .build(); - private final JavaTemplate zoneOffsetHoursMinutesTemplate = JavaTemplate.builder("ZoneOffset.ofHoursMinutes(#{any(int)}, #{any(int)})") - .imports(JAVA_ZONE_OFFSET) - .build(); - private final JavaTemplate timeZoneToZoneIdTemplate = JavaTemplate.builder("#{any(java.util.TimeZone)}.toZoneId()") - .build(); - - @Getter - private final List templates = new ArrayList() { - { - add(new MethodTemplate(zoneForID, zoneIdOfTemplate)); - add(new MethodTemplate(zoneForOffsetHours, zoneOffsetHoursTemplate)); - add(new MethodTemplate(zoneForOffsetHoursMinutes, zoneOffsetHoursMinutesTemplate)); - add(new MethodTemplate(zoneForTimeZone, timeZoneToZoneIdTemplate)); - } - }; -} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/VarTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/VarTemplates.java index 0b5968beeb..dc3e733172 100644 --- a/src/main/java/org/openrewrite/java/migrate/joda/templates/VarTemplates.java +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/VarTemplates.java @@ -31,12 +31,22 @@ public class VarTemplates { private static Map JodaToJavaTimeType = new HashMap() { { put(JODA_DATE_TIME, JAVA_DATE_TIME); + put(JODA_DATE_MIDNIGHT, JAVA_DATE_TIME); put(JODA_TIME_FORMATTER, JAVA_TIME_FORMATTER); put(JODA_LOCAL_DATE, JAVA_LOCAL_DATE); + put(JODA_LOCAL_DATE_TIME, JAVA_LOCAL_DATE_TIME); put(JODA_LOCAL_TIME, JAVA_LOCAL_TIME); put(JODA_DATE_TIME_ZONE, JAVA_ZONE_ID); put(JODA_DURATION, JAVA_DURATION); + put(JODA_PERIOD, JAVA_PERIOD); put(JODA_INTERVAL, THREE_TEN_EXTRA_INTERVAL); + put(JODA_SECONDS, JAVA_DURATION); + put(JODA_MINUTES, JAVA_DURATION); + put(JODA_HOURS, JAVA_DURATION); + put(JODA_DAYS, THREE_TEN_EXTRA_DAYS); + put(JODA_WEEKS, THREE_TEN_EXTRA_WEEKS); + put(JODA_MONTHS, THREE_TEN_EXTRA_MONTHS); + put(JODA_YEARS, THREE_TEN_EXTRA_YEARS); } }; @@ -73,6 +83,9 @@ public static Optional getTemplate(J.VariableDeclarations variable } public static Optional getTemplate(J.Assignment assignment) { + if(assignment.getAssignment().getType() instanceof JavaType.Primitive) { + return Optional.empty(); + } JavaType.Class type = (JavaType.Class) assignment.getAssignment().getType(); JavaType.Class varType = (JavaType.Class) assignment.getVariable().getType(); String typeName = JodaToJavaTimeType.get(type.getFullyQualifiedName()); diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/WeeksTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/WeeksTemplates.java new file mode 100644 index 0000000000..879bd7d156 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/WeeksTemplates.java @@ -0,0 +1,54 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; + +@NoArgsConstructor +public class WeeksTemplates implements Templates { + final MethodMatcher weeksStaticMethod = new MethodMatcher(JODA_WEEKS + " weeks(int)"); + final MethodMatcher weeksBetweenPartial = new MethodMatcher(JODA_WEEKS + " weeksBetween(org.joda.time.ReadablePartial, org.joda.time.ReadablePartial)"); + final MethodMatcher weeksBetweenInstant = new MethodMatcher(JODA_WEEKS + " weeksBetween(org.joda.time.ReadableInstant, org.joda.time.ReadableInstant)"); + final MethodMatcher getWeeks = new MethodMatcher(JODA_WEEKS + " getWeeks()"); + + final JavaTemplate.Builder weeksStaticMethodTemplate = JavaTemplate.builder("Weeks.of(#{any(int)})"); + final JavaTemplate.Builder weeksBetweenLocalTemplate = JavaTemplate.builder("Weeks.between(#{any(java.time.LocalDate)}, #{any(java.time.LocalDate)})"); + final JavaTemplate.Builder weeksBetweenZonedDateTimeTemplate = JavaTemplate.builder("Weeks.between(#{any(java.time.ZonedDateTime)}, #{any(java.time.ZonedDateTime)})"); + final JavaTemplate.Builder getTemplate = JavaTemplate.builder("(int)#{any(org.threeten.extra.Weeks)}.get(ChronoUnit.WEEKS)") + .imports(JAVA_CHRONO_UNIT); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(weeksStaticMethod, build(weeksStaticMethodTemplate))); + add(new MethodTemplate(weeksBetweenPartial, build(weeksBetweenLocalTemplate))); + add(new MethodTemplate(weeksBetweenInstant, build(weeksBetweenZonedDateTimeTemplate))); + add(new MethodTemplate(getWeeks, build(getTemplate))); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, THREE_TEN_EXTRA_WEEKS); + } +} diff --git a/src/main/java/org/openrewrite/java/migrate/joda/templates/YearsTemplates.java b/src/main/java/org/openrewrite/java/migrate/joda/templates/YearsTemplates.java new file mode 100644 index 0000000000..f25aeaa56f --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/joda/templates/YearsTemplates.java @@ -0,0 +1,54 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate.joda.templates; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.MethodMatcher; + +import java.util.ArrayList; +import java.util.List; + +import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*; + +@NoArgsConstructor +public class YearsTemplates implements Templates { + final MethodMatcher yearsStaticMethod = new MethodMatcher(JODA_YEARS + " years(int)"); + final MethodMatcher yearsBetweenPartial = new MethodMatcher(JODA_YEARS + " yearsBetween(org.joda.time.ReadablePartial, org.joda.time.ReadablePartial)"); + final MethodMatcher yearsBetweenInstant = new MethodMatcher(JODA_YEARS + " yearsBetween(org.joda.time.ReadableInstant, org.joda.time.ReadableInstant)"); + final MethodMatcher getYears = new MethodMatcher(JODA_YEARS + " getYears()"); + + final JavaTemplate.Builder yearsStaticMethodTemplate = JavaTemplate.builder("Years.of(#{any(int)})"); + final JavaTemplate.Builder yearsBetweenLocalTemplate = JavaTemplate.builder("Years.between(#{any(java.time.LocalDate)}, #{any(java.time.LocalDate)})"); + final JavaTemplate.Builder yearsBetweenZonedDateTimeTemplate = JavaTemplate.builder("Years.between(#{any(java.time.ZonedDateTime)}, #{any(java.time.ZonedDateTime)})"); + final JavaTemplate.Builder getTemplate = JavaTemplate.builder("(int)#{any(org.threeten.extra.Years)}.get(ChronoUnit.YEARS)") + .imports(JAVA_CHRONO_UNIT); + + @Getter + private final List templates = new ArrayList() { + { + add(new MethodTemplate(yearsStaticMethod, build(yearsStaticMethodTemplate))); + add(new MethodTemplate(yearsBetweenPartial, build(yearsBetweenLocalTemplate))); + add(new MethodTemplate(yearsBetweenInstant, build(yearsBetweenZonedDateTimeTemplate))); + add(new MethodTemplate(getYears, build(getTemplate))); + } + }; + + private JavaTemplate build(JavaTemplate.Builder builder) { + return buildWithImport(builder, THREE_TEN_EXTRA_YEARS); + } +} diff --git a/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeRecipeTest.java b/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeRecipeTest.java index b5b6504980..8567ee2ab9 100644 --- a/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeRecipeTest.java +++ b/src/test/java/org/openrewrite/java/migrate/joda/JodaTimeRecipeTest.java @@ -65,7 +65,7 @@ public void foo() { } @Test - void dontChangeClassVariable() { + void changeClassVariable() { // not supported yet //language=java rewriteRun( @@ -85,18 +85,17 @@ public static class B { } """, """ - import org.joda.time.DateTime; - import java.time.ZonedDateTime; class A { public void foo() { ZonedDateTime dt = ZonedDateTime.now(); System.out.println(dt); - System.out.println(new B().dateTime.toDateTime()); + System.out.println(new B().dateTime); } + public static class B { - DateTime dateTime = new DateTime(); + ZonedDateTime dateTime = ZonedDateTime.now(); } } """ @@ -105,7 +104,7 @@ public static class B { } @Test - void safeMethodParamMigrationAcrossClassBoundary() { + void methodParamMigrationAcrossClassBoundary() { //language=java rewriteRun( java( @@ -115,7 +114,7 @@ void safeMethodParamMigrationAcrossClassBoundary() { class A { public void foo() { new B().print(new DateTime()); - System.out.println(new B().dateTime); // dateTime is class variable, not handled yet + System.out.println(new B().dateTime); } } @@ -127,19 +126,17 @@ public void print(DateTime dateTime) { } """, """ - import org.joda.time.DateTime; - import java.time.ZonedDateTime; class A { public void foo() { new B().print(ZonedDateTime.now()); - System.out.println(new B().dateTime); // dateTime is class variable, not handled yet + System.out.println(new B().dateTime); } } class B { - DateTime dateTime = new DateTime(); + ZonedDateTime dateTime = ZonedDateTime.now(); public void print(ZonedDateTime dateTime) { System.out.println(dateTime); } @@ -283,6 +280,47 @@ public void bar(ZonedDateTime dt) { ); } + @Test + void migrateMethodWithVariableParams() { + //language=java + rewriteRun( + java( + """ + import org.joda.time.DateTime; + import org.joda.time.Seconds; + + class A { + public void foo() { + DateTime bar = new Bar().bar(0, Seconds.seconds(1), new DateTime(), new DateTime()); + } + + private static class Bar { + public DateTime bar(int index, Seconds seconds, DateTime... dt) { + return dt[index]; + } + } + } + """, + """ + import java.time.Duration; + import java.time.ZonedDateTime; + + class A { + public void foo() { + ZonedDateTime bar = new Bar().bar(0, Duration.ofSeconds(1), ZonedDateTime.now(), ZonedDateTime.now()); + } + + private static class Bar { + public ZonedDateTime bar(int index, Duration seconds, ZonedDateTime... dt) { + return dt[index]; + } + } + } + """ + ) + ); + } + @Test void migrationWithRecord() { //language=java @@ -370,7 +408,7 @@ public void bar(ZonedDateTime dt) { } @Test - void migrateMethodWithSafeReturnExpressionAndUnsafeParam() { + void migrateMethodWithReturnExpressionAndParam() { //language=java rewriteRun( java( @@ -395,15 +433,14 @@ public void bar() { } """, """ - import org.joda.time.DateTime; import org.threeten.extra.Interval; import java.time.ZoneId; import java.time.ZonedDateTime; class A { - public ZonedDateTime foo(DateTime dt) { - DateTime d = dt.toDateMidnight(); + public ZonedDateTime foo(ZonedDateTime dt) { + ZonedDateTime d = dt.toLocalDate().atStartOfDay(ZoneId.systemDefault()); ZonedDateTime d2 = ZonedDateTime.now(); Interval interval = Interval.of(d2.toInstant(), d2.plusDays(1).toInstant()); return interval.getEnd().atZone(ZoneId.systemDefault()); @@ -411,7 +448,7 @@ public ZonedDateTime foo(DateTime dt) { private static class Bar { public void bar() { - ZonedDateTime d = foo(new DateTime()); + ZonedDateTime d = foo(ZonedDateTime.now()); System.out.println(d.toInstant().toEpochMilli()); } } @@ -422,7 +459,7 @@ public void bar() { } @Test - void doNotMigrateUnsafeMethodParam() { + void migrateMethodParam() { //language=java rewriteRun( java( @@ -440,17 +477,33 @@ public void bar(DateTime dt) { } } } - """ - ) - ); - } - - @Test - void dontMigrateMethodInvocationIfSelectExprIsNotMigrated() { - //language=java - rewriteRun( - java( + """, """ + import java.time.ZoneId; + import java.time.ZonedDateTime; + + class A { + public void foo() { + new Bar().bar(ZonedDateTime.now()); + } + + private static class Bar { + public void bar(ZonedDateTime dt) { + dt.toLocalDate().atStartOfDay(ZoneId.systemDefault()); // template doesn't exist for toDateMidnight + } + } + } + """ + ) + ); + } + + @Test + void migrateMethodInvocation() { + //language=java + rewriteRun( + java( + """ import org.joda.time.Interval; class A { @@ -466,17 +519,35 @@ public Interval interval() { } } } - """ - ) - ); - } - - @Test - void migrateWithMethodReferenceInComment() { - //language=java - rewriteRun( - java( + """, + """ + import org.threeten.extra.Interval; + + class A { + private Query query = new Query(); + public void foo() { + query.interval().getEnd().toEpochMilli(); + } + + static class Query { + private Interval interval; + + public Interval interval() { + return interval; + } + } + } """ + ) + ); + } + + @Test + void migrateWithMethodReferenceInComment() { + //language=java + rewriteRun( + java( + """ import org.joda.time.DateTime; class A { diff --git a/src/test/java/org/openrewrite/java/migrate/joda/NoJodaTimeTest.java b/src/test/java/org/openrewrite/java/migrate/joda/NoJodaTimeTest.java index adfdd5123f..1f6cc44c4d 100644 --- a/src/test/java/org/openrewrite/java/migrate/joda/NoJodaTimeTest.java +++ b/src/test/java/org/openrewrite/java/migrate/joda/NoJodaTimeTest.java @@ -43,12 +43,24 @@ void migrateJodaTime() { java( """ import org.joda.time.DateTime; + import org.joda.time.LocalDate; + import org.joda.time.LocalDateTime; + import org.joda.time.LocalTime; + import org.joda.time.Seconds; + import org.joda.time.Hours; + import org.joda.time.Days; import org.joda.time.Interval; class A { void foo() { DateTime dt = new DateTime(); DateTime dt1 = new DateTime().plusDays(1); + LocalDate ld = new LocalDate(); + LocalDateTime ldt = new LocalDateTime(); + LocalTime lt = new LocalTime(); + Seconds s1 = Seconds.seconds(30); + Hours h1 = Hours.hours(8); + Days d1 = Days.days(3); Interval i = new Interval(dt, dt1); System.out.println(i.toDuration()); } @@ -58,11 +70,22 @@ void foo() { import org.threeten.extra.Interval; import java.time.ZonedDateTime; + import java.time.LocalDate; + import java.time.LocalDateTime; + import java.time.LocalTime; + import java.time.Duration; + import java.time.Period; class A { void foo() { ZonedDateTime dt = ZonedDateTime.now(); ZonedDateTime dt1 = ZonedDateTime.now().plusDays(1); + LocalDate ld = LocalDate.now(); + LocalDateTime ldt = LocalDateTime.now(); + LocalTime lt = LocalTime.now(); + Duration s1 = Duration.ofSeconds(30); + Duration h1 = Duration.ofHours(8); + Period d1 = Period.ofDays(3); Interval i = Interval.of(dt.toInstant(), dt1.toInstant()); System.out.println(i.toDuration()); }