Skip to content

Instantly share code, notes, and snippets.

@ben-manes
Last active August 11, 2017 07:13
Show Gist options
  • Save ben-manes/af6ab5e857f29f55d990 to your computer and use it in GitHub Desktop.
Save ben-manes/af6ab5e857f29f55d990 to your computer and use it in GitHub Desktop.

Revisions

  1. ben-manes revised this gist May 2, 2015. 1 changed file with 2 additions and 4 deletions.
    6 changes: 2 additions & 4 deletions SwaggerServletContextListener.java
    Original file line number Diff line number Diff line change
    @@ -62,10 +62,8 @@ private String getConfigString(String path) {

    /** Returns a comma separated list of resource packages. */
    private String resourcePackages() {
    return injector.getBindings().values().stream()
    .map(binding -> binding.getKey().getTypeLiteral().getType())
    .filter(type -> type instanceof Class<?>)
    .map(type -> (Class<?>) type)
    return injector.getBindings().keySet().stream()
    .map(key -> key.getTypeLiteral().getRawType())
    .filter(GetRestful::isRootResource)
    .map(clazz -> clazz.getPackage().getName())
    .distinct()
  2. ben-manes revised this gist May 2, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ApiOriginFilter.java
    Original file line number Diff line number Diff line change
    @@ -23,8 +23,8 @@ public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain chain) throws IOException, ServletException {
    HttpServletResponse res = (HttpServletResponse) response;
    res.addHeader("Access-Control-Allow-Origin", "*");
    res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
    res.addHeader("Access-Control-Allow-Headers", "Content-Type");
    res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
    chain.doFilter(request, response);
    }

  3. ben-manes revised this gist May 1, 2015. 2 changed files with 41 additions and 2 deletions.
    36 changes: 36 additions & 0 deletions ApiOriginFilter.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    import java.io.IOException;

    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletResponse;

    import com.google.inject.Singleton;

    /**
    * Allow CORS for Swagger specification api.
    *
    * @author [email protected] (Ben Manes)
    */
    @Singleton
    final class ApiOriginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain chain) throws IOException, ServletException {
    HttpServletResponse res = (HttpServletResponse) response;
    res.addHeader("Access-Control-Allow-Origin", "*");
    res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
    res.addHeader("Access-Control-Allow-Headers", "Content-Type");
    chain.doFilter(request, response);
    }

    @Override
    public void destroy() {}

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}
    }
    7 changes: 5 additions & 2 deletions SwaggerModule.java
    Original file line number Diff line number Diff line change
    @@ -16,9 +16,12 @@ public final class SwaggerModule extends ServletModule {
    protected void configureServlets() {
    Multibinder.newSetBinder(binder(), ServletContextListener.class)
    .addBinding().to(SwaggerServletContextListener.class);
    bind(ApiListingResource.class);
    bind(SwaggerApiListingResource.class);
    bind(SwaggerSerializers.class);

    filter("/*").through(ApiOriginFilter.class);
    filter("/api/*").through(ApiOriginFilter.class);
    }

    @Path("/api")
    static final class SwaggerApiListingResource extends ApiListingResourceJSON {}
    }
  4. ben-manes revised this gist May 1, 2015. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions SwaggerModule.java
    Original file line number Diff line number Diff line change
    @@ -10,13 +10,15 @@
    *
    * @author [email protected] (Ben Manes)
    */
    public final class SwaggerModule extends AbstractModule {
    public final class SwaggerModule extends ServletModule {

    @Override
    protected void configure() {
    protected void configureServlets() {
    Multibinder.newSetBinder(binder(), ServletContextListener.class)
    .addBinding().to(SwaggerServletContextListener.class);
    bind(ApiListingResource.class);
    bind(SwaggerSerializers.class);

    filter("/*").through(ApiOriginFilter.class);
    }
    }
  5. ben-manes revised this gist May 1, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion SwaggerServletContextListener.java
    Original file line number Diff line number Diff line change
    @@ -73,5 +73,5 @@ private String resourcePackages() {
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {}
    public void contextDestroyed(ServletContextEvent event) {}
    }
  6. ben-manes revised this gist May 1, 2015. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions SwaggerServletContextListener.java
    Original file line number Diff line number Diff line change
    @@ -19,8 +19,8 @@
    * @author [email protected] (Ben Manes)
    */
    final class SwaggerServletContextListener implements ServletContextListener {
    final Config config = ConfigFactory.load().getConfig(getClass().getPackage().getName());
    final Injector injector;
    private final Config config = ConfigFactory.load().getConfig(getClass().getPackage().getName());
    private final Injector injector;

    @Inject
    SwaggerServletContextListener(Injector injector) {
  7. ben-manes revised this gist May 1, 2015. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions SwaggerModule.java
    Original file line number Diff line number Diff line change
    @@ -10,10 +10,10 @@
    *
    * @author [email protected] (Ben Manes)
    */
    public final class SwaggerModule extends ServletModule {
    public final class SwaggerModule extends AbstractModule {

    @Override
    protected void configureServlets() {
    protected void configure() {
    Multibinder.newSetBinder(binder(), ServletContextListener.class)
    .addBinding().to(SwaggerServletContextListener.class);
    bind(ApiListingResource.class);
  8. ben-manes created this gist May 1, 2015.
    66 changes: 66 additions & 0 deletions ResourceConfig.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,66 @@
    import java.util.HashSet;
    import java.util.Set;

    import org.reflections.Reflections;
    import org.reflections.scanners.ResourcesScanner;
    import org.reflections.scanners.SubTypesScanner;
    import org.reflections.scanners.TypeAnnotationsScanner;
    import org.reflections.util.ClasspathHelper;
    import org.reflections.util.ConfigurationBuilder;

    import com.wordnik.swagger.annotations.Api;
    import com.wordnik.swagger.jaxrs.config.BeanConfig;
    import com.wordnik.swagger.models.Contact;
    import com.wordnik.swagger.models.Info;
    import com.wordnik.swagger.models.License;

    /**
    * A {@link BeanConfig} that supports multiple resource packages. This can be removed in Swagger M2
    * where this enhancement is supported (and directly ported from).
    *
    * @author [email protected] (Ben Manes)
    */
    final class ResourceConfig extends BeanConfig {

    @Override
    public Set<Class<?>> classes() {
    ConfigurationBuilder config = new ConfigurationBuilder();
    Set<String> acceptablePackages = new HashSet<String>();

    if (getResourcePackage() != "") {
    String[] parts = getResourcePackage().split(",");
    for (String pkg : parts) {
    if (!"".equals(pkg)) {
    acceptablePackages.add(pkg);
    config.addUrls(ClasspathHelper.forPackage(pkg));
    }
    }
    }

    config.setScanners(new ResourcesScanner(),
    new TypeAnnotationsScanner(), new SubTypesScanner());

    setInfo(new Info()
    .title(getTitle())
    .version(getVersion())
    .description(getDescription())
    .termsOfService(getTermsOfServiceUrl()));

    if (getContact() != null) {
    getInfo().contact(new Contact().name(getContact()));
    }
    if ((getLicense() != null) && (getLicenseUrl() != null)) {
    getInfo().license(new License().name(getLicense()).url(getLicenseUrl()));
    }

    getSwagger().setInfo(getInfo());
    Set<Class<?>> classes = new Reflections(config).getTypesAnnotatedWith(Api.class);
    Set<Class<?>> output = new HashSet<Class<?>>();
    for (Class<?> cls : classes) {
    if (acceptablePackages.contains(cls.getPackage().getName())) {
    output.add(cls);
    }
    }
    return output;
    }
    }
    22 changes: 22 additions & 0 deletions SwaggerModule.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,22 @@
    import javax.servlet.ServletContextListener;

    import com.google.inject.multibindings.Multibinder;
    import com.google.inject.servlet.ServletModule;
    import com.wordnik.swagger.jaxrs.listing.ApiListingResource;
    import com.wordnik.swagger.jaxrs.listing.SwaggerSerializers;

    /**
    * A module to install <a href="http://swagger.io">Swagger</a> with JAX-RS scanning.
    *
    * @author [email protected] (Ben Manes)
    */
    public final class SwaggerModule extends ServletModule {

    @Override
    protected void configureServlets() {
    Multibinder.newSetBinder(binder(), ServletContextListener.class)
    .addBinding().to(SwaggerServletContextListener.class);
    bind(ApiListingResource.class);
    bind(SwaggerSerializers.class);
    }
    }
    77 changes: 77 additions & 0 deletions SwaggerServletContextListener.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,77 @@
    import java.util.stream.Collectors;

    import javax.annotation.Nullable;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;

    import org.jboss.resteasy.util.GetRestful;

    import com.google.inject.Inject;
    import com.google.inject.Injector;
    import com.typesafe.config.Config;
    import com.typesafe.config.ConfigFactory;
    import com.wordnik.swagger.config.ScannerFactory;
    import com.wordnik.swagger.jaxrs.config.BeanConfig;

    /**
    * A context listener that scans for APIs and configures Swagger.
    *
    * @author [email protected] (Ben Manes)
    */
    final class SwaggerServletContextListener implements ServletContextListener {
    final Config config = ConfigFactory.load().getConfig(getClass().getPackage().getName());
    final Injector injector;

    @Inject
    SwaggerServletContextListener(Injector injector) {
    this.injector = injector;
    }

    @Override
    public void contextInitialized(ServletContextEvent event) {
    BeanConfig beanConfig = getBeanConfig();
    event.getServletContext().setAttribute("reader", beanConfig);
    event.getServletContext().setAttribute("swagger", beanConfig.getSwagger());
    event.getServletContext().setAttribute("scanner", ScannerFactory.getScanner());
    }

    private BeanConfig getBeanConfig() {
    BeanConfig beanConfig = new ResourceConfig();
    beanConfig.setHost(getConfigString("host"));
    beanConfig.setTitle(getConfigString("title"));
    beanConfig.setVersion(getConfigString("version"));
    beanConfig.setContact(getConfigString("contact"));
    beanConfig.setLicense(getConfigString("license"));
    beanConfig.setBasePath(getConfigString("base_path"));
    beanConfig.setLicenseUrl(getConfigString("licenseUrl"));
    beanConfig.setDescription(getConfigString("description"));
    beanConfig.setPrettyPrint(getConfigString("pretty_print"));
    beanConfig.setTermsOfServiceUrl(getConfigString("terms_of_service_url"));

    // Must be called last
    beanConfig.setResourcePackage(resourcePackages());
    beanConfig.setScan(true);

    return beanConfig;
    }

    @Nullable
    private String getConfigString(String path) {
    return config.hasPath(path) ? config.getString(path) : null;
    }

    /** Returns a comma separated list of resource packages. */
    private String resourcePackages() {
    return injector.getBindings().values().stream()
    .map(binding -> binding.getKey().getTypeLiteral().getType())
    .filter(type -> type instanceof Class<?>)
    .map(type -> (Class<?>) type)
    .filter(GetRestful::isRootResource)
    .map(clazz -> clazz.getPackage().getName())
    .distinct()
    .collect(Collectors.joining(","));
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {}
    }
    6 changes: 6 additions & 0 deletions build.gradle
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,6 @@
    dependencies {
    compile dependencies.create('com.wordnik:swagger-jersey2-jaxrs:1.5.1-M1') {
    exclude group: 'org.glassfish.jersey.containers'
    exclude group: 'org.glassfish.jersey.media'
    }
    }