-
Couldn't load subscription status.
- Fork 107
Convert Spring Fox's ApiInfoBuilder into Swagger's Info
#805
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 18 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
fb1a4c4
prototype recipe for transforming programmatic springfox to springdoc
dsgrieve 42458a8
progress on ApiInfo to Info recipe
dsgrieve 9cf4dae
fix where name and url are added
dsgrieve a0b1321
Add early returns to appease the bot
timtebeek f6c7f96
Move recipe to defaults method
timtebeek 4d7d911
accumulate method calls to reconstruct fluent chain
dsgrieve 95c90c0
remove unused matchers
dsgrieve 03f32a6
Apply suggestions from code review
dsgrieve 5be7c89
Separate the concerns in converting ApiInfoBuilder
timtebeek 54362cc
Autoformat after removing `build()`
timtebeek 6da5c44
Update test type table
timtebeek a65a3b3
Remove unused imports
timtebeek 4e1befc
Update recipe descriptions
timtebeek e5c91b1
Definitely autoformat
timtebeek c3b2856
add test
dsgrieve 27f5ed3
unit test updates
dsgrieve 2c5d911
apply Tim's suggestions for handling license
dsgrieve b5f0ab1
Format input and outputs
timtebeek f0445e8
Merge the template methods into the apply
timtebeek 7ea7948
Rename test class to match declarative recipe
timtebeek ebd8bcd
Delete older approach TransformApiInfo.java
timtebeek 208058a
No need for `mavenProject` here
timtebeek File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
src/main/java/org/openrewrite/java/spring/swagger/RemoveBuild.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| /* | ||
| * Copyright 2025 the original author or authors. | ||
| * <p> | ||
| * 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 | ||
| * <p> | ||
| * https://docs.moderne.io/licensing/moderne-source-available-license | ||
| * <p> | ||
| * 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.spring.swagger; | ||
|
|
||
| import org.openrewrite.ExecutionContext; | ||
| import org.openrewrite.Preconditions; | ||
| import org.openrewrite.Recipe; | ||
| import org.openrewrite.TreeVisitor; | ||
| import org.openrewrite.java.JavaVisitor; | ||
| import org.openrewrite.java.MethodMatcher; | ||
| import org.openrewrite.java.search.UsesMethod; | ||
| import org.openrewrite.java.tree.J; | ||
|
|
||
| public class RemoveBuild extends Recipe { | ||
| private static final MethodMatcher BUILD_MATCHER = new MethodMatcher("springfox.documentation.builders.ApiInfoBuilder build()"); | ||
|
|
||
| @Override | ||
| public String getDisplayName() { | ||
| return "Remove `ApiInfoBuilder.build()`"; | ||
| } | ||
|
|
||
| @Override | ||
| public String getDescription() { | ||
| return "Remove SpringFox's `ApiInfoBuilder.build()` ahead of migration to Swagger's `Info`."; | ||
| } | ||
|
|
||
| @Override | ||
| public TreeVisitor<?, ExecutionContext> getVisitor() { | ||
| return Preconditions.check(new UsesMethod<>(BUILD_MATCHER), new JavaVisitor<ExecutionContext>() { | ||
| @Override | ||
| public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { | ||
| if (BUILD_MATCHER.matches(method)) { | ||
| return autoFormat(method.getSelect().withPrefix(method.getPrefix()), ctx); | ||
| } | ||
| return super.visitMethodInvocation(method, ctx); | ||
| } | ||
| }); | ||
| } | ||
| } |
61 changes: 61 additions & 0 deletions
61
src/main/java/org/openrewrite/java/spring/swagger/ReplaceContact.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| /* | ||
| * Copyright 2025 the original author or authors. | ||
| * <p> | ||
| * 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 | ||
| * <p> | ||
| * https://docs.moderne.io/licensing/moderne-source-available-license | ||
| * <p> | ||
| * 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.spring.swagger; | ||
|
|
||
| import org.openrewrite.ExecutionContext; | ||
| import org.openrewrite.Preconditions; | ||
| import org.openrewrite.Recipe; | ||
| import org.openrewrite.TreeVisitor; | ||
| import org.openrewrite.java.JavaParser; | ||
| import org.openrewrite.java.JavaTemplate; | ||
| import org.openrewrite.java.JavaVisitor; | ||
| import org.openrewrite.java.MethodMatcher; | ||
| import org.openrewrite.java.search.UsesMethod; | ||
| import org.openrewrite.java.tree.J; | ||
|
|
||
| public class ReplaceContact extends Recipe { | ||
| private static final MethodMatcher CONTACT_MATCHER = new MethodMatcher("springfox.documentation.service.Contact <constructor>(String, String, String)"); | ||
|
|
||
| @Override | ||
| public String getDisplayName() { | ||
| return "Replace SpringFox's `Contact` with Swagger's `Contact`"; | ||
| } | ||
|
|
||
| @Override | ||
| public String getDescription() { | ||
| return "Replace three argument constructor with immutable builder."; | ||
| } | ||
|
|
||
| @Override | ||
| public TreeVisitor<?, ExecutionContext> getVisitor() { | ||
| return Preconditions.check(new UsesMethod<>(CONTACT_MATCHER), new JavaVisitor<ExecutionContext>() { | ||
| // Replace `Contact` constructor | ||
| @Override | ||
| public J visitNewClass(J.NewClass newClass, ExecutionContext ctx) { | ||
| if (CONTACT_MATCHER.matches(newClass)) { | ||
| maybeRemoveImport("springfox.documentation.service.Contact"); | ||
| maybeAddImport("io.swagger.v3.oas.models.info.Contact"); | ||
| return JavaTemplate.builder("new Contact().name(#{any(String)}).url(#{any(String)}).email(#{any(String)})") | ||
| .imports("io.swagger.v3.oas.models.info.Contact") | ||
| .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "swagger-models")) | ||
| .build() | ||
| .apply(getCursor(), newClass.getCoordinates().replace(), newClass.getArguments().toArray()); | ||
| } | ||
| return super.visitNewClass(newClass, ctx); | ||
| } | ||
| }); | ||
| } | ||
| } |
127 changes: 127 additions & 0 deletions
127
src/main/java/org/openrewrite/java/spring/swagger/ReplaceLicenseUrl.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| /* | ||
| * Copyright 2025 the original author or authors. | ||
| * <p> | ||
| * 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 | ||
| * <p> | ||
| * https://docs.moderne.io/licensing/moderne-source-available-license | ||
| * <p> | ||
| * 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.spring.swagger; | ||
|
|
||
| import org.jspecify.annotations.Nullable; | ||
| import org.openrewrite.*; | ||
| import org.openrewrite.java.*; | ||
| import org.openrewrite.java.search.UsesMethod; | ||
| import org.openrewrite.java.tree.*; | ||
timtebeek marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| import org.openrewrite.marker.Markers; | ||
|
|
||
| import java.util.UUID; | ||
|
|
||
| public class ReplaceLicenseUrl extends Recipe { | ||
| private static final MethodMatcher LICENSE_MATCHER = new MethodMatcher("springfox.documentation.builders.ApiInfoBuilder license(String)"); | ||
| private static final MethodMatcher LICENSEURL_MATCHER = new MethodMatcher("springfox.documentation.builders.ApiInfoBuilder licenseUrl(String)"); | ||
|
|
||
| @Override | ||
| public String getDisplayName() { | ||
| return "Replace SpringFox's `license` and `licenseUrl`"; | ||
| } | ||
|
|
||
| @Override | ||
| public String getDescription() { | ||
| return "Replace SpringFox's license methods with Swaggers immutable `new License().name(String).url(String)`."; | ||
| } | ||
|
|
||
| @Override | ||
| public TreeVisitor<?, ExecutionContext> getVisitor() { | ||
| TreeVisitor<?, ExecutionContext> preconditions = Preconditions.or(new UsesMethod<>(LICENSE_MATCHER), new UsesMethod<>(LICENSEURL_MATCHER)); | ||
| return Preconditions.check(preconditions, new JavaVisitor<ExecutionContext>() { | ||
| @Override | ||
| public J visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext ctx) { | ||
| // Extract and store values or cursor | ||
| Cursor mdCursor = getCursor(); | ||
| new JavaIsoVisitor<ExecutionContext>() { | ||
| @Override | ||
| public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { | ||
| J.MethodInvocation mi = super.visitMethodInvocation(method, ctx); | ||
| if (LICENSE_MATCHER.matches(mi)) { | ||
| mdCursor.putMessage("LICENSE", mi.getArguments().get(0)); | ||
| } else if (LICENSEURL_MATCHER.matches(mi)) { | ||
| mdCursor.putMessage("LICENSE_URL", mi.getArguments().get(0)); | ||
| } | ||
| return mi; | ||
| } | ||
| }.visit(method, ctx, getCursor().getParentOrThrow()); | ||
|
|
||
| // Now replace any downstream method invocations | ||
| return super.visitMethodDeclaration(method, ctx); | ||
| } | ||
|
|
||
| @Override | ||
| public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { | ||
| J.MethodInvocation mi = (J.MethodInvocation) super.visitMethodInvocation(method, ctx); | ||
|
|
||
| Expression license; | ||
| Expression licenseUrl; | ||
| if (LICENSE_MATCHER.matches(mi)) { | ||
| license = mi.getArguments().get(0); | ||
| licenseUrl = getCursor().pollNearestMessage("LICENSE_URL"); | ||
| if (licenseUrl == null) { | ||
| return replaceLicense(mi, ctx, nameOnyTemplate(), mi.getSelect(), license); | ||
| } | ||
| // Combine license and url | ||
| return replaceLicense(mi, ctx, fullTemplate(), mi.getSelect(), license, licenseUrl); | ||
| } | ||
| if (LICENSEURL_MATCHER.matches(mi)) { | ||
| license = getCursor().pollNearestMessage("LICENSE"); | ||
| licenseUrl = mi.getArguments().get(0); | ||
| if (license == null) { | ||
| return replaceLicense(mi, ctx, urlOnlyTemplate(), mi.getSelect(), licenseUrl); | ||
| } | ||
| // Remove the method itself already | ||
| return mi.getSelect().withPrefix(mi.getPrefix()); | ||
| } | ||
| return mi; | ||
| } | ||
|
|
||
| private String fullTemplate() { | ||
| return makeTemplate(true, true); | ||
| } | ||
|
|
||
| private String nameOnyTemplate() { | ||
| return makeTemplate(true, false); | ||
| } | ||
|
|
||
| private String urlOnlyTemplate() { | ||
| return makeTemplate(false, true); | ||
| } | ||
|
|
||
| private String makeTemplate(boolean withName, boolean withUrl) { | ||
| StringBuilder sb = new StringBuilder("#{any(io.swagger.v3.oas.models.info.Info)}\n.license(new License()"); | ||
| if (withName) { | ||
| sb.append(".name(#{any(String)})"); | ||
| } | ||
| if (withUrl) { | ||
| sb.append(".url(#{any(String)})"); | ||
| } | ||
| sb.append(')'); | ||
| return sb.toString(); | ||
| } | ||
|
|
||
| private J.MethodInvocation replaceLicense(J.MethodInvocation mi, ExecutionContext ctx, String template, Object... args) { | ||
| maybeAddImport("io.swagger.v3.oas.models.info.License"); | ||
| return JavaTemplate.builder(template) | ||
| .imports("io.swagger.v3.oas.models.info.License") | ||
| .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "swagger-models")) | ||
| .build() | ||
| .apply(getCursor(), mi.getCoordinates().replace(), args); | ||
| } | ||
| }); | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.