diff --git a/modules/swagger-gradle-plugin/src/main/java/io/swagger/v3/plugins/gradle/SwaggerPlugin.java b/modules/swagger-gradle-plugin/src/main/java/io/swagger/v3/plugins/gradle/SwaggerPlugin.java index 824e56c294..44255580c9 100644 --- a/modules/swagger-gradle-plugin/src/main/java/io/swagger/v3/plugins/gradle/SwaggerPlugin.java +++ b/modules/swagger-gradle-plugin/src/main/java/io/swagger/v3/plugins/gradle/SwaggerPlugin.java @@ -4,9 +4,10 @@ import org.gradle.api.Action; import org.gradle.api.Plugin; import org.gradle.api.Project; -import org.gradle.api.Task; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.DependencySet; +import org.gradle.api.tasks.SourceSetContainer; +import org.gradle.api.tasks.TaskProvider; public class SwaggerPlugin implements Plugin { public void apply(Project project) { @@ -21,24 +22,20 @@ public void execute(DependencySet dependencies) { dependencies.add(project.getDependencies().create("javax.servlet:javax.servlet-api:3.1.0")); } }); - Task task = project.getTasks().create("resolve", ResolveTask.class); - ((ResolveTask)task).setBuildClasspath(config); - - try { - if (project.getTasks().findByPath("classes") != null) { - task.dependsOn("classes"); - } - if (project.getTasks().findByPath("compileJava") != null) { - task.dependsOn("compileJava"); - } - if (project.getTasks().findByPath("compileTestJava") != null) { - task.dependsOn("compileTestJava"); - } - if (project.getTasks().findByPath("testClasses") != null) { - task.dependsOn("testClasses"); - } - } catch (Exception e) { - project.getLogger().warn("Exception in task dependencies: " + e.getMessage(), e); - } + TaskProvider lazyTask = project.getTasks().register("resolve", ResolveTask.class,task -> { + task.buildClasspath.setFrom(config); + task.classpath.setFrom(project.getExtensions().findByType(SourceSetContainer.class).getByName("main").getRuntimeClasspath().getFiles()); + task.prettyPrint.convention(false); + task.readAllResources.convention(true); + task.outputFormat.convention(ResolveTask.Format.JSON); + task.skip.convention(false); + task.encoding.convention("UTF-8"); + task.sortOutput.convention(Boolean.FALSE); + task.alwaysResolveAppPath.convention(Boolean.FALSE); + task.skipResolveAppPath.convention(Boolean.FALSE); + task.openAPI31.convention(false); + task.convertToOpenAPI31.convention(false); + task.outputDir.convention(project.getLayout().getBuildDirectory().dir("swagger")); + }); } } diff --git a/modules/swagger-gradle-plugin/src/main/java/io/swagger/v3/plugins/gradle/tasks/ResolveTask.java b/modules/swagger-gradle-plugin/src/main/java/io/swagger/v3/plugins/gradle/tasks/ResolveTask.java index c885bd593a..af6814e7d5 100644 --- a/modules/swagger-gradle-plugin/src/main/java/io/swagger/v3/plugins/gradle/tasks/ResolveTask.java +++ b/modules/swagger-gradle-plugin/src/main/java/io/swagger/v3/plugins/gradle/tasks/ResolveTask.java @@ -1,20 +1,16 @@ package io.swagger.v3.plugins.gradle.tasks; -import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; -import org.gradle.api.logging.Logging; -import org.gradle.api.tasks.CacheableTask; -import org.gradle.api.tasks.Classpath; -import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.InputFile; -import org.gradle.api.tasks.Optional; -import org.gradle.api.tasks.OutputDirectory; -import org.gradle.api.tasks.PathSensitive; -import org.gradle.api.tasks.PathSensitivity; -import org.gradle.api.tasks.TaskAction; -import org.slf4j.Logger; +import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.provider.Provider; +import org.gradle.api.provider.SetProperty; +import org.gradle.api.tasks.*; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; @@ -26,201 +22,226 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; -import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.StreamSupport; +import java.util.stream.Stream; @CacheableTask public class ResolveTask extends DefaultTask { - private static Logger LOGGER = Logging.getLogger(ResolveTask.class); - - public enum Format {JSON, YAML, JSONANDYAML}; - - private String outputFileName = "openapi"; - - private String outputPath; - private File outputDir; - - private File openApiFile; - - private Format outputFormat = Format.JSON; - - private Set resourcePackages; - private Set resourceClasses; - private String filterClass; - private String readerClass; - private String scannerClass; - private Boolean prettyPrint = false; - private Boolean readAllResources = Boolean.TRUE; - private Collection ignoredRoutes; - private Iterable buildClasspath; - private Iterable classpath; - - private Boolean skip = Boolean.FALSE; - - private String encoding = "UTF-8"; - - private LinkedHashSet modelConverterClasses; - private String objectMapperProcessorClass; - - private Boolean sortOutput = Boolean.FALSE; - private Boolean alwaysResolveAppPath = Boolean.FALSE; - private Boolean skipResolveAppPath = Boolean.FALSE; + public enum Format {JSON, YAML, JSONANDYAML} + @Input + @Optional + public final Property outputFileName = getProject().getObjects().property(String.class); + @OutputDirectory + public final DirectoryProperty outputDir = getProject().getObjects().directoryProperty(); + @InputFile + @Optional + @PathSensitive(PathSensitivity.RELATIVE) + public final RegularFileProperty openApiFile = getProject().getObjects().fileProperty(); + @Input + @Optional + public final Property outputFormat = getProject().getObjects().property(Format.class); + @Input + @Optional + public final SetProperty resourcePackages = getProject().getObjects().setProperty(String.class); + @Input + @Optional + public final SetProperty resourceClasses = getProject().getObjects().setProperty(String.class); + @Input + @Optional + public final Property filterClass = getProject().getObjects().property(String.class); + @Input + @Optional + public final Property readerClass = getProject().getObjects().property(String.class); + @Input + @Optional + public final Property scannerClass = getProject().getObjects().property(String.class); + @Input + @Optional + public final Property prettyPrint = getProject().getObjects().property(Boolean.class); + @Input + @Optional + public final Property readAllResources = getProject().getObjects().property(Boolean.class); + @Input + @Optional + public final SetProperty ignoredRoutes = getProject().getObjects().setProperty(String.class); + @Classpath + @Optional + public final ConfigurableFileCollection buildClasspath = getProject().getObjects().fileCollection(); + @Classpath + public final ConfigurableFileCollection classpath = getProject().getObjects().fileCollection(); + /** + * Completely skips execution of the task. + * + * @deprecated if you want to skip the task do not execute it in the first place or remove the task dependency + * that causes it to run + */ + @Deprecated + @Input + @Optional + public final Property skip = getProject().getObjects().property(Boolean.class); + @Input + @Optional - private String contextId; + public final Property encoding = getProject().getObjects().property(String.class); + /** + * @since 2.0.6 + */ + @Input + @Optional + public final SetProperty modelConverterClasses = getProject().getObjects().setProperty(String.class); + @Input + @Optional + public final Property objectMapperProcessorClass = getProject().getObjects().property(String.class); + @Input + @Optional + public final Property sortOutput = getProject().getObjects().property(Boolean.class); + @Input + @Optional - private Boolean openAPI31 = false; + public final Property alwaysResolveAppPath = getProject().getObjects().property(Boolean.class); + @Input + @Optional - private Boolean convertToOpenAPI31 = false; - private String schemaResolution; + public final Property skipResolveAppPath = getProject().getObjects().property(Boolean.class); + @Input + @Optional + public final Property contextId = getProject().getObjects().property(String.class); + @Input + @Optional + public final Property openAPI31 = getProject().getObjects().property(Boolean.class); - private String defaultResponseCode; + /** + * @since 2.2.12 + */ + @Input + @Optional + public final Property convertToOpenAPI31 = getProject().getObjects().property(Boolean.class); + /** + * @since 2.2.24 + */ + @Input + @Optional + public final Property schemaResolution = getProject().getObjects().property(String.class); @Input @Optional - public String getOutputFileName() { + public final Property defaultResponseCode = getProject().getObjects().property(String.class); + + public Property getOutputFileName() { return outputFileName; } - @InputFile - @Optional - @PathSensitive(PathSensitivity.RELATIVE) - public File getOpenApiFile() { + public RegularFileProperty getOpenApiFile() { return openApiFile; } + public DirectoryProperty getOutputDir() { + return outputDir; + } + + public void setOutputDir(String outputPath) { + this.outputDir.set(getProject().file(outputPath)); + } + + public void setOutputFileName(String outputFileName) { + this.outputFileName.set(outputFileName); + } + public void setOpenApiFile(File openApiFile) { - this.openApiFile = openApiFile; + this.openApiFile.set(openApiFile); } - @Classpath - public Iterable getClasspath() { + public ConfigurableFileCollection getClasspath() { return classpath; } public void setClasspath(Iterable classpath) { - this.classpath = classpath; + this.classpath.setFrom(classpath); } - @Classpath - @Optional - public Iterable getBuildClasspath() { + public ConfigurableFileCollection getBuildClasspath() { return buildClasspath; } public void setBuildClasspath(Iterable buildClasspath) { - this.buildClasspath = buildClasspath; - } - - public void setOutputFileName(String outputFileName) { - this.outputFileName = outputFileName; + this.buildClasspath.setFrom(buildClasspath); } /** - * @deprecated Use {@linkplain #getOutputDir()} instead. + * @deprecated Use {@linkplain #outputDir} instead. */ @Deprecated - @Input - @Optional - public String getOutputPath() { - return outputPath; + @Internal + public Provider getOutputPath() { + return outputDir.map(dir -> dir.getAsFile().getPath()); } /** - * @deprecated Use {@linkplain #setOutputDir(File)} instead. + * @deprecated Use {@linkplain #outputDir} instead. */ @Deprecated public void setOutputPath(String outputPath) { - this.outputPath = outputPath; - outputDir = new File(outputPath); + this.outputDir.set(getProject().file(outputPath)); } - @OutputDirectory - public File getOutputDir() { - return outputDir; - } - - public void setOutputDir(File outputDir) { - this.outputDir = outputDir; + public Property getOutputFormat() { + return outputFormat; } - @Input - @Optional - public Format getOutputFormat() { - return outputFormat; + public void setOutputFormat(String outputFormat) { + this.outputFormat.set(Format.valueOf(outputFormat)); } public void setOutputFormat(Format outputFormat) { - this.outputFormat = outputFormat; + this.outputFormat.set(outputFormat); } - @Input - @Optional - public Set getResourcePackages() { + public SetProperty getResourcePackages() { return resourcePackages; } public void setResourcePackages(Set resourcePackages) { - this.resourcePackages = resourcePackages; + this.resourcePackages.set(resourcePackages); } - /** - * @since 2.0.6 - */ - @Input - @Optional - public LinkedHashSet getModelConverterClasses() { + public SetProperty getModelConverterClasses() { return modelConverterClasses; } - /** - * @since 2.0.6 - */ - public void setModelConverterClasses(LinkedHashSet modelConverterClasses) { - this.modelConverterClasses = modelConverterClasses; + public void setModelConverterClasses(Set modelConverterClasses) { + this.modelConverterClasses.set(modelConverterClasses); } - @Input - @Optional - public Set getResourceClasses() { + public SetProperty getResourceClasses() { return resourceClasses; } public void setResourceClasses(Set resourceClasses) { - this.resourceClasses = resourceClasses; + this.resourceClasses.set(resourceClasses); } - @Input - @Optional - public String getFilterClass() { + public Property getFilterClass() { return filterClass; } public void setFilterClass(String filterClass) { - this.filterClass = filterClass; + this.filterClass.set(filterClass); } - @Input - @Optional - public String getReaderClass() { + public Property getReaderClass() { return readerClass; } public void setReaderClass(String readerClass) { - this.readerClass = readerClass; + this.readerClass.set(readerClass); } - /** - * @since 2.0.6 - */ - @Input - @Optional - public String getObjectMapperProcessorClass() { + public Property getObjectMapperProcessorClass() { return objectMapperProcessorClass; } @@ -228,15 +249,10 @@ public String getObjectMapperProcessorClass() { * @since 2.0.6 */ public void setObjectMapperProcessorClass(String objectMapperProcessorClass) { - this.objectMapperProcessorClass = objectMapperProcessorClass; + this.objectMapperProcessorClass.set(objectMapperProcessorClass); } - /** - * @since 2.2.17 - */ - @Input - @Optional - public String getDefaultResponseCode() { + public Property getDefaultResponseCode() { return defaultResponseCode; } @@ -244,15 +260,10 @@ public String getDefaultResponseCode() { * @since 2.2.17 */ public void setDefaultResponseCode(String defaultResponseCode) { - this.defaultResponseCode = defaultResponseCode; + this.defaultResponseCode.set(defaultResponseCode); } - /** - * @since 2.0.6 - */ - @Input - @Optional - public String getContextId() { + public Property getContextId() { return contextId; } @@ -260,95 +271,87 @@ public String getContextId() { * @since 2.0.6 */ public void setContextId(String contextId) { - this.contextId = contextId; + this.contextId.set(contextId); } - @Input - @Optional - public String getScannerClass() { + public Property getScannerClass() { return scannerClass; } public void setScannerClass(String scannerClass) { - this.scannerClass = scannerClass; + this.scannerClass.set(scannerClass); } - @Input - @Optional - public Boolean getPrettyPrint() { + public Property getPrettyPrint() { return prettyPrint; } - public void setPrettyPrint(Boolean prettyPrint) { - this.prettyPrint = prettyPrint; + public void setPrettyPrint(@Nullable String prettyPrint) { + setPrettyPrint(prettyPrint == null ? null : Boolean.valueOf(prettyPrint)); } - @Input - @Optional - public Boolean getReadAllResources() { + public void setPrettyPrint(@Nullable Boolean prettyPrint) { + this.prettyPrint.set(prettyPrint); + } + + public Property getReadAllResources() { return readAllResources; } public void setReadAllResources(Boolean readAllResources) { - this.readAllResources = readAllResources; + this.readAllResources.set(readAllResources); + ; } - @Input - @Optional - public Collection getIgnoredRoutes() { + public void setReadAllResources(@Nullable String readAllResources) { + setReadAllResources(readAllResources == null ? null : Boolean.valueOf(readAllResources)); + } + + public SetProperty getIgnoredRoutes() { return ignoredRoutes; } public void setIgnoredRoutes(Collection ignoredRoutes) { - this.ignoredRoutes = ignoredRoutes; + this.ignoredRoutes.set(ignoredRoutes); } - @Input - @Optional - public Boolean getSkip() { + public Property getSkip() { return skip; } public void setSkip(Boolean skip) { - this.skip = skip; + this.skip.set(skip); } - @Input - @Optional - public String getEncoding() { + public Property getEncoding() { return encoding; } public void setEncoding(String resourceClasses) { - this.encoding = encoding; + this.encoding.set(encoding); } - @Input - @Optional - public Boolean getSortOutput() { + public Property getSortOutput() { return sortOutput; } public void setSortOutput(Boolean sortOutput) { - this.sortOutput = sortOutput; + this.sortOutput.set(sortOutput); } - @Input - @Optional - public Boolean getAlwaysResolveAppPath() { + public Property getAlwaysResolveAppPath() { return alwaysResolveAppPath; } public void setAlwaysResolveAppPath(Boolean alwaysResolveAppPath) { - this.alwaysResolveAppPath = alwaysResolveAppPath; + this.alwaysResolveAppPath.set(alwaysResolveAppPath); } - /** - * @since 2.2.15 - */ - @Input - @Optional - public Boolean getSkipResolveAppPath() { + public void setAlwaysResolveAppPath(@Nullable String alwaysResolveAppPath) { + setAlwaysResolveAppPath(alwaysResolveAppPath == null ? null : Boolean.valueOf(alwaysResolveAppPath)); + } + + public Property getSkipResolveAppPath() { return skipResolveAppPath; } @@ -356,183 +359,188 @@ public Boolean getSkipResolveAppPath() { * @since 2.2.15 */ public void setSkipResolveAppPath(Boolean skipResolveAppPath) { - this.skipResolveAppPath = skipResolveAppPath; + this.skipResolveAppPath.set(skipResolveAppPath); + ; } - /** - * @since 2.2.0 - */ - @Input - @Optional - public Boolean getOpenAPI31() { + public Property getOpenAPI31() { return openAPI31; } public void setOpenAPI31(Boolean openAPI31) { - this.openAPI31 = openAPI31; + this.openAPI31.set(openAPI31); } - /** - * @since 2.2.12 - */ - @Input - @Optional - public Boolean getConvertToOpenAPI31() { + public void setOpenAPI31(@Nullable String openAPI31) { + setOpenAPI31(openAPI31 == null ? null : Boolean.valueOf(openAPI31)); + } + + public Property getConvertToOpenAPI31() { return convertToOpenAPI31; } public void setConvertToOpenAPI31(Boolean convertToOpenAPI31) { - this.convertToOpenAPI31 = convertToOpenAPI31; + this.convertToOpenAPI31.set(convertToOpenAPI31); if (Boolean.TRUE.equals(convertToOpenAPI31)) { - this.openAPI31 = true; + this.openAPI31.set(Boolean.TRUE); } } - /** - * @since 2.2.24 - */ - @Input - @Optional - public String getSchemaResolution() { + public void setConvertToOpenAPI31(@Nullable String convertToOpenAPI31) { + setConvertToOpenAPI31(convertToOpenAPI31 == null ? null : Boolean.valueOf(convertToOpenAPI31)); + } + + public Property getSchemaResolution() { return schemaResolution; } public void setSchemaResolution(String schemaResolution) { - this.schemaResolution = schemaResolution; + this.schemaResolution.set(schemaResolution); } @TaskAction public void resolve() throws GradleException { - if (skip) { - LOGGER.info( "Skipping OpenAPI specification resolution" ); + if (skip.getOrElse(false)) { + getLogger().warn("You use the deprecated 'skip' property. For better performance prevent the execution instead (for example by calling the `compileJava` task instead)"); + getLogger().info("Skipping OpenAPI specification resolution"); return; } - LOGGER.info( "Resolving OpenAPI specification.." ); - - Stream classpathStream = StreamSupport.stream(getClasspath().spliterator(), false).map(f -> { + getLogger().info("Resolving OpenAPI specification.."); + Stream classpathStream = classpath.getFiles().stream().map(f -> { try { return f.toURI().toURL(); } catch (MalformedURLException e) { throw new GradleException( - String.format("Could not create classpath for annotations task %s.", getName()), e); + String.format("Could not create classpath for annotations task %s.", getName()), e); } }); - Stream buildClasspathStream = StreamSupport.stream(getBuildClasspath().spliterator(), false).map(f -> { + + Stream buildClasspathStream = buildClasspath.getFiles().stream().map(f -> { try { return f.toURI().toURL(); } catch (MalformedURLException e) { throw new GradleException( - String.format("Could not create classpath for annotations task %s.", getName()), e); + String.format("Could not create classpath for annotations task %s.", getName()), e); } }); URL[] urls = Stream.concat(classpathStream, buildClasspathStream) - .distinct() - .toArray(URL[]::new); + .distinct() + .toArray(URL[]::new); //ClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]), Thread.currentThread().getContextClassLoader()); - ClassLoader classLoader = new URLClassLoader(urls); - try { - Class swaggerLoaderClass = classLoader.loadClass("io.swagger.v3.jaxrs2.integration.SwaggerLoader"); + try (URLClassLoader classLoader = new URLClassLoader(urls)) { + Class swaggerLoaderClass = classLoader.loadClass("io.swagger.v3.jaxrs2.integration.SwaggerLoader"); Object swaggerLoader = swaggerLoaderClass.newInstance(); - Method method = null; - method=swaggerLoaderClass.getDeclaredMethod("setOutputFormat",String.class); - method.invoke(swaggerLoader, outputFormat.name()); + Method method = null; + method = swaggerLoaderClass.getDeclaredMethod("setOutputFormat", String.class); + method.invoke(swaggerLoader, outputFormat.get().name()); - if (openApiFile != null) { - if (openApiFile.exists() && openApiFile.isFile()) { - String openapiFileContent = new String(Files.readAllBytes(openApiFile.toPath()), encoding); + if (openApiFile.isPresent()) { + final File openApiFileHandle = openApiFile.get().getAsFile(); + if (openApiFileHandle.exists() && openApiFileHandle.isFile()) { + String openapiFileContent = new String(Files.readAllBytes(openApiFileHandle.toPath()), encoding.get()); if (StringUtils.isNotBlank(openapiFileContent)) { - method=swaggerLoaderClass.getDeclaredMethod("setOpenapiAsString",String.class); + method = swaggerLoaderClass.getDeclaredMethod("setOpenapiAsString", String.class); method.invoke(swaggerLoader, openapiFileContent); } } } - if (resourcePackages != null && !resourcePackages.isEmpty()) { - method=swaggerLoaderClass.getDeclaredMethod("setResourcePackages",String.class); - method.invoke(swaggerLoader, resourcePackages.stream().map(Object::toString).collect(Collectors.joining(","))); + if (resourcePackages.isPresent() && !resourcePackages.get().isEmpty()) { + method = swaggerLoaderClass.getDeclaredMethod("setResourcePackages", String.class); + method.invoke(swaggerLoader, resourcePackages.get().stream().map(Object::toString).collect(Collectors.joining(","))); } - if (resourceClasses != null && !resourceClasses.isEmpty()) { - method=swaggerLoaderClass.getDeclaredMethod("setResourceClasses",String.class); - method.invoke(swaggerLoader, resourceClasses.stream().map(Object::toString).collect(Collectors.joining(","))); + if (resourceClasses.isPresent() && !resourceClasses.get().isEmpty()) { + method = swaggerLoaderClass.getDeclaredMethod("setResourceClasses", String.class); + method.invoke(swaggerLoader, resourceClasses.get().stream().map(Object::toString).collect(Collectors.joining(","))); } - if (modelConverterClasses != null && !modelConverterClasses.isEmpty()) { - method=swaggerLoaderClass.getDeclaredMethod("setModelConverterClasses",String.class); - method.invoke(swaggerLoader, modelConverterClasses.stream().map(Object::toString).collect(Collectors.joining(","))); + if (modelConverterClasses.isPresent() && !modelConverterClasses.get().isEmpty()) { + method = swaggerLoaderClass.getDeclaredMethod("setModelConverterClasses", String.class); + method.invoke(swaggerLoader, modelConverterClasses.get().stream().map(Object::toString).collect(Collectors.joining(","))); } - if (ignoredRoutes != null && !ignoredRoutes.isEmpty()) { - method=swaggerLoaderClass.getDeclaredMethod("setIgnoredRoutes",String.class); - method.invoke(swaggerLoader, ignoredRoutes.stream().map(Object::toString).collect(Collectors.joining(","))); + if (ignoredRoutes.isPresent() && !ignoredRoutes.get().isEmpty()) { + method = swaggerLoaderClass.getDeclaredMethod("setIgnoredRoutes", String.class); + method.invoke(swaggerLoader, ignoredRoutes.get().stream().map(Object::toString).collect(Collectors.joining(","))); } - if (StringUtils.isNotBlank(filterClass)) { - method=swaggerLoaderClass.getDeclaredMethod("setFilterClass",String.class); - method.invoke(swaggerLoader, filterClass); + if (filterClass.isPresent() && StringUtils.isNotBlank(filterClass.get())) { + method = swaggerLoaderClass.getDeclaredMethod("setFilterClass", String.class); + method.invoke(swaggerLoader, filterClass.get()); } - if (StringUtils.isNotBlank(readerClass)) { - method=swaggerLoaderClass.getDeclaredMethod("setReaderClass",String.class); - method.invoke(swaggerLoader, readerClass); + if (readerClass.isPresent() && StringUtils.isNotBlank(readerClass.get())) { + method = swaggerLoaderClass.getDeclaredMethod("setReaderClass", String.class); + method.invoke(swaggerLoader, readerClass.get()); } - if (StringUtils.isNotBlank(scannerClass)) { - method=swaggerLoaderClass.getDeclaredMethod("setScannerClass",String.class); - method.invoke(swaggerLoader, scannerClass); + if (scannerClass.isPresent() && StringUtils.isNotBlank(scannerClass.get())) { + method = swaggerLoaderClass.getDeclaredMethod("setScannerClass", String.class); + method.invoke(swaggerLoader, scannerClass.get()); } - if (StringUtils.isNotBlank(contextId)) { - method=swaggerLoaderClass.getDeclaredMethod("setContextId",String.class); - method.invoke(swaggerLoader, contextId); + if (contextId.isPresent() && StringUtils.isNotBlank(contextId.get())) { + method = swaggerLoaderClass.getDeclaredMethod("setContextId", String.class); + method.invoke(swaggerLoader, contextId.get()); } - if (StringUtils.isNotBlank(objectMapperProcessorClass)) { - method=swaggerLoaderClass.getDeclaredMethod("setObjectMapperProcessorClass",String.class); - method.invoke(swaggerLoader, objectMapperProcessorClass); + if (objectMapperProcessorClass.isPresent() && StringUtils.isNotBlank(objectMapperProcessorClass.get())) { + method = swaggerLoaderClass.getDeclaredMethod("setObjectMapperProcessorClass", String.class); + method.invoke(swaggerLoader, objectMapperProcessorClass.get()); } - if (StringUtils.isNotBlank(defaultResponseCode)) { - method=swaggerLoaderClass.getDeclaredMethod("setDefaultResponseCode",String.class); - method.invoke(swaggerLoader, defaultResponseCode); + if (defaultResponseCode.isPresent() && StringUtils.isNotBlank(defaultResponseCode.get())) { + method = swaggerLoaderClass.getDeclaredMethod("setDefaultResponseCode", String.class); + method.invoke(swaggerLoader, defaultResponseCode.get()); } - method=swaggerLoaderClass.getDeclaredMethod("setPrettyPrint", Boolean.class); - method.invoke(swaggerLoader, prettyPrint); - - method=swaggerLoaderClass.getDeclaredMethod("setSortOutput", Boolean.class); - method.invoke(swaggerLoader, sortOutput); + method = swaggerLoaderClass.getDeclaredMethod("setPrettyPrint", Boolean.class); + method.invoke(swaggerLoader, prettyPrint.get()); - method=swaggerLoaderClass.getDeclaredMethod("setAlwaysResolveAppPath", Boolean.class); - method.invoke(swaggerLoader, alwaysResolveAppPath); + method = swaggerLoaderClass.getDeclaredMethod("setSortOutput", Boolean.class); + method.invoke(swaggerLoader, sortOutput.get()); - method=swaggerLoaderClass.getDeclaredMethod("setSkipResolveAppPath", Boolean.class); - method.invoke(swaggerLoader, skipResolveAppPath); + method = swaggerLoaderClass.getDeclaredMethod("setAlwaysResolveAppPath", Boolean.class); + method.invoke(swaggerLoader, alwaysResolveAppPath.get()); - method=swaggerLoaderClass.getDeclaredMethod("setReadAllResources", Boolean.class); - method.invoke(swaggerLoader, readAllResources); + method = swaggerLoaderClass.getDeclaredMethod("setSkipResolveAppPath", Boolean.class); + method.invoke(swaggerLoader, skipResolveAppPath.get()); - method=swaggerLoaderClass.getDeclaredMethod("setOpenAPI31", Boolean.class); - method.invoke(swaggerLoader, openAPI31); + method = swaggerLoaderClass.getDeclaredMethod("setReadAllResources", Boolean.class); + method.invoke(swaggerLoader, readAllResources.get()); - method=swaggerLoaderClass.getDeclaredMethod("setConvertToOpenAPI31", Boolean.class); - method.invoke(swaggerLoader, convertToOpenAPI31); - - method=swaggerLoaderClass.getDeclaredMethod("setSchemaResolution", String.class); - method.invoke(swaggerLoader, schemaResolution); + if (openAPI31.isPresent() && !openAPI31.get() && convertToOpenAPI31.get()) { + throw new GradleException("`convertToOpenAPI31` can't be enabled when `openAPI31` support is explicity disabled"); + } + if (openAPI31.isPresent()) { + method = swaggerLoaderClass.getDeclaredMethod("setOpenAPI31", Boolean.class); + method.invoke(swaggerLoader, openAPI31.get()); + } - method=swaggerLoaderClass.getDeclaredMethod("resolve"); - Map specs = (Map)method.invoke(swaggerLoader); + if (convertToOpenAPI31.isPresent()) { + method = swaggerLoaderClass.getDeclaredMethod("setConvertToOpenAPI31", Boolean.class); + method.invoke(swaggerLoader, convertToOpenAPI31.get()); + } + if (schemaResolution.isPresent()) { + method = swaggerLoaderClass.getDeclaredMethod("setSchemaResolution", String.class); + method.invoke(swaggerLoader, schemaResolution.get()); + } + method = swaggerLoaderClass.getDeclaredMethod("resolve"); + Map specs = (Map) method.invoke(swaggerLoader); + final Path outputFile = outputDir.getAsFile().get().toPath(); if (specs.get("JSON") != null) { - Path path = outputDir.toPath().resolve(String.format("%s.json", outputFileName)); - Files.write(path, specs.get("JSON").getBytes(Charset.forName(encoding))); + Path path = outputFile.resolve(String.format("%s.json", outputFileName.get())); + Files.write(path, specs.get("JSON").getBytes(Charset.forName(encoding.get()))); + getLogger().debug("Saved openapi to {}", path.toAbsolutePath()); } if (specs.get("YAML") != null) { - Path path = outputDir.toPath().resolve(String.format("%s.yaml", outputFileName)); - Files.write(path, specs.get("YAML").getBytes(Charset.forName(encoding))); + Path path = outputFile.resolve(String.format("%s.yaml", outputFileName.get())); + Files.write(path, specs.get("YAML").getBytes(Charset.forName(encoding.get()))); + getLogger().debug("Saved openapi to {}", path.toAbsolutePath()); } } catch (IOException e) { throw new GradleException("Failed to write API definition: " + e.getMessage(), e);