Skip to content
Closed
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
bce32bb
Add mapping for migration for joda LocalDate
Feb 17, 2025
0ed4bf2
Fix safe migration issue.
Feb 18, 2025
fa80bf7
Merge branch 'main' into add-localdate-mapping-to-joda-recipe
timtebeek Feb 18, 2025
4d2d32f
Add LocalDateTime mapping
Feb 18, 2025
d058821
Add LocalTime mapping
Feb 19, 2025
d5f61bc
Add Seconds mapping
Feb 19, 2025
e16c12d
Add Days mapping
Feb 20, 2025
ccbc050
Add tests
Feb 20, 2025
37eb88c
Disable safe check in Visitor
Feb 21, 2025
53f40df
add additional mappings
Mar 4, 2025
86e5b1d
add additional mappings
Mar 6, 2025
8b466aa
add additional mappings
Mar 19, 2025
3fc49b1
Update .gitlab-ci.yml file
Mar 24, 2025
6a6008b
fix assignment to primitive
Mar 26, 2025
60c7759
add mappings
Mar 28, 2025
015df71
Fix mappings
Mar 29, 2025
6036bb2
Add mappings
Apr 2, 2025
214b137
Merge remote-tracking branch 'refs/remotes/origin/add-localdate-mappi…
Apr 2, 2025
c8b70f8
Merge branch 'refs/heads/main' into add-localdate-mapping-to-joda-recipe
Apr 7, 2025
bf618b5
Add mappings
Apr 7, 2025
dc0f687
Merge branch 'openrewrite:main' into add-localdate-mapping-to-joda-re…
YarochkinMichael Apr 10, 2025
26b04fe
Merge pull request #1 from YarochkinMichael/main
YarochkinMichael Apr 22, 2025
272cab9
Merge branch 'main' into add-localdate-mapping-to-joda-recipe
timtebeek May 6, 2025
a0dedc0
Apply suggestions from code review
timtebeek May 6, 2025
3774163
Update build.gradle.kts
timtebeek May 6, 2025
a08d224
Merge branch 'openrewrite:main' into add-localdate-mapping-to-joda-re…
YarochkinMichael Jun 10, 2025
890ff0f
Merge branch 'openrewrite:main' into add-localdate-mapping-to-joda-re…
YarochkinMichael Jun 14, 2025
d757bf8
Add mappings
Jun 16, 2025
f2bdd45
Fix tests
Aug 1, 2025
27c79d7
Merge branch 'refs/heads/main' into add-localdate-mapping-to-joda-recipe
Aug 1, 2025
f841f60
Merge branch 'main' into add-localdate-mapping-to-joda-recipe
Aug 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -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
16 changes: 16 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ plugins {

group = "org.openrewrite.recipe"
description = "Migrate to later Java versions. Automatically."
version = "3.3.0-SNAPSHOT"

recipeDependencies {
parserClasspath("javax.persistence:javax.persistence-api:2.2")
Expand Down Expand Up @@ -88,3 +89,18 @@ tasks.withType(Javadoc::class.java) {
tasks.test {
maxHeapSize = "2g" // Set max heap size to 2GB or adjust as necessary
}

publishing {
publications {
repositories {
maven {
name = "PrimionNexus"
url = uri("https://nexus.primion.eu/repository/maven-snapshots/")
credentials {
username = System.getenv("NEXUS_USER")
password = System.getenv("NEXUS_PASSWORD")
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -93,14 +94,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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,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);
Expand All @@ -77,12 +92,20 @@ 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;
}
Expand All @@ -108,22 +131,26 @@ public Javadoc visitReference(Javadoc.Reference reference, ExecutionContext ctx)
if (multiVariable.getTypeExpression() == null || !multiVariable.getType().isAssignableFrom(JODA_CLASS_PATTERN)) {
return super.visitVariableDeclarations(multiVariable, ctx);
}
/*
if (multiVariable.getVariables().stream().anyMatch(acc.getUnsafeVars()::contains)) {
return multiVariable;
}
*/
J.VariableDeclarations m = (J.VariableDeclarations) super.visitVariableDeclarations(multiVariable, ctx);
return VarTemplates.getTemplate(multiVariable).<J>map(t -> t.apply(
J.VariableDeclarations j = VarTemplates.getTemplate(multiVariable).<J.VariableDeclarations>map(t -> t.apply(
updateCursor(m),
m.getCoordinates().replace(),
VarTemplates.getTemplateArgs(m))).orElse(multiVariable);

return autoFormat(j.withModifiers(m.getModifiers()), 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);
}
if (acc.getUnsafeVars().contains(variable) || !(variable.getType() instanceof JavaType.Class)) {
if (/*acc.getUnsafeVars().contains(variable) || */ !(variable.getType() instanceof JavaType.Class)) {
return variable;
}
JavaType.Class jodaType = (JavaType.Class) variable.getType();
Expand All @@ -143,7 +170,7 @@ public Javadoc visitReference(Javadoc.Reference reference, ExecutionContext ctx)
}
J.Identifier varName = (J.Identifier) a.getVariable();
Optional<NamedVariable> mayBeVar = findVarInScope(varName.getSimpleName());
if (!mayBeVar.isPresent() || acc.getUnsafeVars().contains(mayBeVar.get())) {
if (!mayBeVar.isPresent() /*|| acc.getUnsafeVars().contains(mayBeVar.get())*/) {
return assignment;
}
return VarTemplates.getTemplate(assignment).<J>map(t -> t.apply(
Expand Down Expand Up @@ -199,7 +226,7 @@ public Javadoc visitReference(Javadoc.Reference reference, ExecutionContext ctx)
}
if (this.safeMigration) {
Optional<NamedVariable> mayBeVar = findVarInScope(ident.getSimpleName());
if (!mayBeVar.isPresent() || acc.getUnsafeVars().contains(mayBeVar.get())) {
if (!mayBeVar.isPresent() /* || acc.getUnsafeVars().contains(mayBeVar.get())*/) {
return ident;
}
}
Expand All @@ -219,10 +246,20 @@ 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<J> 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();
Expand All @@ -241,7 +278,7 @@ private J migrateMethodCall(MethodCall original, MethodCall updated) {
}
String paramName = parentMethod.getMethodType().getParameterNames().get(argPos);
NamedVariable var = acc.getVarTable().getVarByName(parentMethod.getMethodType(), paramName);
if (var != null && !acc.getUnsafeVars().contains(var)) {
if (var != null /*&& !acc.getUnsafeVars().contains(var)*/) {
return updatedExpr;
}
return original;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<MethodTemplate> templates = new ArrayList<MethodTemplate>() {
{
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));
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,31 @@
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_DURATION;
import static org.openrewrite.java.migrate.joda.templates.TimeClassNames.*;

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<MethodTemplate> templates = new ArrayList<MethodTemplate>() {
{
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));
}
};
}
Loading
Loading