From 43b699d23cd4f7fe12aa7a41b68987efe0e400f8 Mon Sep 17 00:00:00 2001 From: Thomas Wilson Date: Mon, 20 Jul 2015 11:05:56 -0400 Subject: [PATCH] Fixes #59. Permit scanning of Dropwizard environment for resources when resource package property is null or empty --- .../swagger/EnvironmentScanner.java | 91 +++++++++++++++++++ .../dropwizard/swagger/SwaggerBundle.java | 14 ++- ...leServerWithoutResourcePackageSetTest.java | 33 +++++++ .../test-simple-without-resource-package.yaml | 9 ++ 4 files changed, 139 insertions(+), 8 deletions(-) create mode 100644 src/main/java/io/federecio/dropwizard/swagger/EnvironmentScanner.java create mode 100644 src/test/java/io/federecio/dropwizard/swagger/SimpleServerWithoutResourcePackageSetTest.java create mode 100644 src/test/resources/test-simple-without-resource-package.yaml diff --git a/src/main/java/io/federecio/dropwizard/swagger/EnvironmentScanner.java b/src/main/java/io/federecio/dropwizard/swagger/EnvironmentScanner.java new file mode 100644 index 00000000..648c03bc --- /dev/null +++ b/src/main/java/io/federecio/dropwizard/swagger/EnvironmentScanner.java @@ -0,0 +1,91 @@ +/** + * Copyright (C) 2014 Federico Recio + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 io.federecio.dropwizard.swagger; + +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.config.ScannerFactory; +import com.wordnik.swagger.jaxrs.config.BeanConfig; +import io.dropwizard.setup.Environment; +import java.util.HashSet; +import java.util.Set; +import org.glassfish.jersey.server.model.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A {@link com.wordnik.swagger.jaxrs.config.JaxrsScanner} that allows Swagger + * to scan only those resources which are registered in Dropwizard's Jersey + * environment. This scanner avoids documenting resources which may have fallen + * out of use or have not yet been implemented. + * + * @author Thomas Wilson + */ +public class EnvironmentScanner extends BeanConfig { + + private final Set> classes = new HashSet<>(); + private final Environment environment; + + public EnvironmentScanner(Environment environment) { + this.environment = environment; + } + + @Override + public Set> classes() { + if (!classes.isEmpty()) { + return classes; + } + if (getResourcePackage() == null) { + setResourcePackage(""); + } + super.classes(); + + + Set resources = environment.jersey().getResourceConfig().getResources(); + for (Resource resource : resources) { + scan(resource.getHandlerClasses()); + } + Set> registered = environment.jersey().getResourceConfig().getClasses(); + scan(registered); + Set instances = environment.jersey().getResourceConfig().getInstances(); + for (Object obj : instances) { + scan(obj.getClass()); + } + Set singletons = environment.jersey().getResourceConfig().getSingletons(); + for (Object obj : singletons) { + scan(obj.getClass()); + } + return classes; + } + + @Override + public void setScan(boolean shouldScan) { + if (getResourcePackage() != null && !getResourcePackage().isEmpty()) { + super.setScan(shouldScan); + } + ScannerFactory.setScanner(this); + } + + protected void scan(final Set> input) { + for (Class cls : input) { + scan(cls); + } + } + protected void scan(final Class cls) { + if (cls.isAnnotationPresent(Api.class)) { + classes.add(cls); + } + } +} diff --git a/src/main/java/io/federecio/dropwizard/swagger/SwaggerBundle.java b/src/main/java/io/federecio/dropwizard/swagger/SwaggerBundle.java index 80e32dc2..1173e149 100644 --- a/src/main/java/io/federecio/dropwizard/swagger/SwaggerBundle.java +++ b/src/main/java/io/federecio/dropwizard/swagger/SwaggerBundle.java @@ -59,16 +59,15 @@ public void run(T configuration, Environment environment) throws Exception { environment.jersey().register(new SwaggerResource(configurationHelper.getUrlPattern())); environment.getObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL); - setUpSwagger(swaggerBundleConfiguration, configurationHelper.getUrlPattern()); + setUpSwagger(swaggerBundleConfiguration, configurationHelper.getUrlPattern(), environment); environment.jersey().register(new ApiListingResource()); } @SuppressWarnings("unused") protected abstract SwaggerBundleConfiguration getSwaggerBundleConfiguration(T configuration); - private void setUpSwagger(SwaggerBundleConfiguration swaggerBundleConfiguration, String urlPattern) { - BeanConfig config = new BeanConfig(); - + private void setUpSwagger(SwaggerBundleConfiguration swaggerBundleConfiguration, String urlPattern, Environment environment) { + BeanConfig config = new EnvironmentScanner(environment); if (swaggerBundleConfiguration.getTitle() != null) { config.setTitle(swaggerBundleConfiguration.getTitle()); } @@ -99,12 +98,11 @@ private void setUpSwagger(SwaggerBundleConfiguration swaggerBundleConfiguration, config.setBasePath(urlPattern); - if (swaggerBundleConfiguration.getResourcePackage() != null) { + if (swaggerBundleConfiguration.getResourcePackage() != null + && !swaggerBundleConfiguration.getResourcePackage().isEmpty()) { config.setResourcePackage(swaggerBundleConfiguration.getResourcePackage()); - } else { - throw new IllegalStateException("Resource package needs to be specified for Swagger to correctly detect annotated resources"); } - + environment.getApplicationContext().setAttribute("swagger", config.getSwagger()); config.setScan(true); } diff --git a/src/test/java/io/federecio/dropwizard/swagger/SimpleServerWithoutResourcePackageSetTest.java b/src/test/java/io/federecio/dropwizard/swagger/SimpleServerWithoutResourcePackageSetTest.java new file mode 100644 index 00000000..6ee678a5 --- /dev/null +++ b/src/test/java/io/federecio/dropwizard/swagger/SimpleServerWithoutResourcePackageSetTest.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2014 Federico Recio + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 io.federecio.dropwizard.swagger; + +import io.federecio.dropwizard.junitrunner.DropwizardJunitRunner; +import io.federecio.dropwizard.junitrunner.DropwizardTestConfig; +import org.junit.runner.RunWith; + +/** + * @author Thomas Wilson + */ +@RunWith(DropwizardJunitRunner.class) +@DropwizardTestConfig(applicationClass = TestApplication.class, yamlFile = "/test-simple-without-resource-package.yaml") +public class SimpleServerWithoutResourcePackageSetTest extends DropwizardTest { + + public SimpleServerWithoutResourcePackageSetTest() { + super(51481, "/api"); + } + +} diff --git a/src/test/resources/test-simple-without-resource-package.yaml b/src/test/resources/test-simple-without-resource-package.yaml new file mode 100644 index 00000000..7557fcca --- /dev/null +++ b/src/test/resources/test-simple-without-resource-package.yaml @@ -0,0 +1,9 @@ +server: + type: simple + applicationContextPath: / + rootPath: /api/* + connector: + type: http + port: 51481 +swagger: + resourcePackage: "" \ No newline at end of file