Repository: cxf Updated Branches: refs/heads/3.0.x-fixes 877b5a7a4 -> f9e4a4cad refs/heads/master 27a511a9c -> 4ddbf53b1
Feature implemented Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/4ddbf53b Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/4ddbf53b Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/4ddbf53b Branch: refs/heads/master Commit: 4ddbf53b105a0a4155f4589f254cdef25065704d Parents: 27a511a Author: Francesco Chicchiriccò <ilgro...@apache.org> Authored: Wed Aug 24 14:33:51 2016 +0200 Committer: Francesco Chicchiriccò <ilgro...@apache.org> Committed: Wed Aug 24 14:42:09 2016 +0200 ---------------------------------------------------------------------- .../swagger/DefaultSwagger2Serializers.java | 197 +++++++++++++++++++ .../cxf/jaxrs/swagger/Swagger2Feature.java | 59 +++--- .../cxf/jaxrs/swagger/Swagger2Serializers.java | 148 +------------- 3 files changed, 232 insertions(+), 172 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/4ddbf53b/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/DefaultSwagger2Serializers.java ---------------------------------------------------------------------- diff --git a/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/DefaultSwagger2Serializers.java b/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/DefaultSwagger2Serializers.java new file mode 100644 index 0000000..d6f0bb7 --- /dev/null +++ b/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/DefaultSwagger2Serializers.java @@ -0,0 +1,197 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.cxf.jaxrs.swagger; + +import java.io.IOException; +import java.io.OutputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.net.URL; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.cxf.jaxrs.ext.MessageContext; +import org.apache.cxf.jaxrs.model.ClassResourceInfo; +import org.apache.cxf.jaxrs.model.OperationResourceInfo; +import org.apache.cxf.jaxrs.model.doc.DocumentationProvider; +import org.apache.cxf.jaxrs.model.doc.JavaDocProvider; +import org.apache.cxf.jaxrs.utils.JAXRSUtils; + +import io.swagger.jaxrs.listing.SwaggerSerializers; +import io.swagger.models.HttpMethod; +import io.swagger.models.Operation; +import io.swagger.models.Path; +import io.swagger.models.Swagger; +import io.swagger.models.Tag; + +public class DefaultSwagger2Serializers extends SwaggerSerializers implements Swagger2Serializers { + + protected boolean dynamicBasePath; + + protected boolean replaceTags; + + protected DocumentationProvider javadocProvider; + + protected List<ClassResourceInfo> cris; + + @Override + public void writeTo( + final Swagger data, + final Class<?> type, + final Type genericType, + final Annotation[] annotations, + final MediaType mediaType, + final MultivaluedMap<String, Object> headers, + final OutputStream out) throws IOException { + + if (dynamicBasePath) { + MessageContext ctx = JAXRSUtils.createContextValue( + JAXRSUtils.getCurrentMessage(), null, MessageContext.class); + data.setBasePath(StringUtils.substringBeforeLast(ctx.getHttpServletRequest().getRequestURI(), "/")); + } + + if (replaceTags || javadocProvider != null) { + Map<String, ClassResourceInfo> operations = new HashMap<>(); + Map<Pair<String, String>, OperationResourceInfo> methods = new HashMap<>(); + for (ClassResourceInfo cri : cris) { + for (OperationResourceInfo ori : cri.getMethodDispatcher().getOperationResourceInfos()) { + String normalizedPath = getNormalizedPath( + cri.getURITemplate().getValue(), ori.getURITemplate().getValue()); + + operations.put(normalizedPath, cri); + methods.put(ImmutablePair.of(ori.getHttpMethod(), normalizedPath), ori); + } + } + + if (replaceTags && data.getTags() != null) { + data.getTags().clear(); + } + for (final Map.Entry<String, Path> entry : data.getPaths().entrySet()) { + Tag tag = null; + if (replaceTags && operations.containsKey(entry.getKey())) { + ClassResourceInfo cri = operations.get(entry.getKey()); + + tag = new Tag(); + tag.setName(cri.getURITemplate().getValue()); + if (javadocProvider != null) { + tag.setDescription(javadocProvider.getClassDoc(cri)); + } + + data.addTag(tag); + } + + for (Map.Entry<HttpMethod, Operation> subentry : entry.getValue().getOperationMap().entrySet()) { + if (replaceTags && tag != null) { + subentry.getValue().setTags(Collections.singletonList(tag.getName())); + } + + Pair<String, String> key = ImmutablePair.of(subentry.getKey().name(), entry.getKey()); + if (methods.containsKey(key) && javadocProvider != null) { + OperationResourceInfo ori = methods.get(key); + + subentry.getValue().setSummary(javadocProvider.getMethodDoc(ori)); + for (int i = 0; i < subentry.getValue().getParameters().size(); i++) { + subentry.getValue().getParameters().get(i). + setDescription(javadocProvider.getMethodParameterDoc(ori, i)); + } + + if (subentry.getValue().getResponses() != null + && !subentry.getValue().getResponses().isEmpty()) { + + subentry.getValue().getResponses().entrySet().iterator().next().getValue(). + setDescription(javadocProvider.getMethodResponseDoc(ori)); + } + } + } + } + } + if (replaceTags && data.getTags() != null) { + Collections.sort(data.getTags(), new Comparator<Tag>() { + + @Override + public int compare(final Tag tag1, final Tag tag2) { + return tag1.getName().compareTo(tag2.getName()); + } + }); + } + + super.writeTo(data, type, genericType, annotations, mediaType, headers, out); + } + + protected String getNormalizedPath(String classResourcePath, String operationResourcePath) { + StringBuilder normalizedPath = new StringBuilder(); + + String[] segments = StringUtils.split(classResourcePath + operationResourcePath, "/"); + for (String segment : segments) { + if (!StringUtils.isEmpty(segment)) { + normalizedPath.append("/").append(segment); + } + } + // Adapt to Swagger's path expression + if (normalizedPath.toString().endsWith(":.*}")) { + normalizedPath.setLength(normalizedPath.length() - 4); + normalizedPath.append('}'); + } + return StringUtils.EMPTY.equals(normalizedPath.toString()) ? "/" : normalizedPath.toString(); + } + + @Override + public void setDynamicBasePath(final boolean dynamicBasePath) { + this.dynamicBasePath = dynamicBasePath; + } + + @Override + public void setReplaceTags(final boolean replaceTags) { + this.replaceTags = replaceTags; + } + + @Override + public void setJavadocProvider(final DocumentationProvider javadocProvider) { + this.javadocProvider = javadocProvider; + } + + @Override + public void setClassResourceInfos(final List<ClassResourceInfo> classResourceInfos) { + this.cris = classResourceInfos; + } + + @Override + public void setJavaDocPath(final String javaDocPath) throws Exception { + this.javadocProvider = new JavaDocProvider(javaDocPath); + } + + @Override + public void setJavaDocPaths(final String... javaDocPaths) throws Exception { + this.javadocProvider = new JavaDocProvider(javaDocPaths); + } + + @Override + public void setJavaDocURLs(final URL[] javaDocURLs) { + this.javadocProvider = new JavaDocProvider(javaDocURLs); + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/4ddbf53b/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java ---------------------------------------------------------------------- diff --git a/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java b/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java index 7b757fc..5b813c3 100644 --- a/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java +++ b/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java @@ -61,8 +61,6 @@ import org.apache.cxf.jaxrs.ext.ContextProvider; import org.apache.cxf.jaxrs.ext.MessageContext; import org.apache.cxf.jaxrs.model.ApplicationInfo; import org.apache.cxf.jaxrs.model.ClassResourceInfo; -import org.apache.cxf.jaxrs.model.doc.DocumentationProvider; -import org.apache.cxf.jaxrs.model.doc.JavaDocProvider; import org.apache.cxf.jaxrs.provider.ServerProviderFactory; import org.apache.cxf.jaxrs.utils.InjectionUtils; import org.apache.cxf.jaxrs.utils.JAXRSUtils; @@ -86,18 +84,16 @@ public class Swagger2Feature extends AbstractSwaggerFeature { private String ignoreRoutes; + private Swagger2Serializers swagger2Serializers; + private boolean supportSwaggerUi = true; + private String swaggerUiVersion; - private Map<String, String> swaggerUiMediaTypes; - - private boolean dynamicBasePath; - private boolean replaceTags; + private Map<String, String> swaggerUiMediaTypes; private boolean usePathBasedConfig; - private DocumentationProvider javadocProvider; - @Override protected void addSwaggerResource(Server server, Bus bus) { JAXRSServiceFactoryBean sfb = @@ -109,7 +105,7 @@ public class Swagger2Feature extends AbstractSwaggerFeature { (ServerProviderFactory)server.getEndpoint().get(ServerProviderFactory.class.getName()); appInfo = factory.getApplicationProvider(); if (appInfo == null) { - Set<Class<?>> serviceClasses = new HashSet<Class<?>>(); + Set<Class<?>> serviceClasses = new HashSet<>(); for (ClassResourceInfo cri : sfb.getClassResourceInfo()) { serviceClasses.add(cri.getServiceClass()); } @@ -118,7 +114,7 @@ public class Swagger2Feature extends AbstractSwaggerFeature { } } - List<Object> swaggerResources = new LinkedList<Object>(); + List<Object> swaggerResources = new LinkedList<>(); ApiListingResource apiListingResource = new ApiListingResource(); swaggerResources.add(apiListingResource); @@ -149,7 +145,13 @@ public class Swagger2Feature extends AbstractSwaggerFeature { if (swaggerUiService != null) { providers.add(new SwaggerUIFilter()); } - providers.add(new Swagger2Serializers(dynamicBasePath, replaceTags, javadocProvider, cris)); + + if (swagger2Serializers == null) { + swagger2Serializers = new DefaultSwagger2Serializers(); + } + swagger2Serializers.setClassResourceInfos(cris); + providers.add(swagger2Serializers); + providers.add(new ReaderConfigFilter()); if (usePathBasedConfig) { @@ -227,26 +229,10 @@ public class Swagger2Feature extends AbstractSwaggerFeature { this.ignoreRoutes = ignoreRoutes; } - public void setDynamicBasePath(final boolean dynamicBasePath) { - this.dynamicBasePath = dynamicBasePath; - } - - public void setReplaceTags(final boolean replaceTags) { - this.replaceTags = replaceTags; - } - - public void setJavaDocPath(final String javaDocPath) throws Exception { - this.javadocProvider = new JavaDocProvider(javaDocPath); - } - - public void setJavaDocPaths(final String... javaDocPaths) throws Exception { - this.javadocProvider = new JavaDocProvider(javaDocPaths); + public void setSwagger2Serializers(final Swagger2Serializers swagger2Serializers) { + this.swagger2Serializers = swagger2Serializers; } - - public void setJavaDocURLs(final URL[] javaDocURLs) { - this.javadocProvider = new JavaDocProvider(javaDocURLs); - } - + @Override protected void setBasePathByAddress(String address) { if (!address.startsWith("/")) { @@ -273,6 +259,8 @@ public class Swagger2Feature extends AbstractSwaggerFeature { @javax.ws.rs.ext.Provider private class ServletConfigProvider implements ContextProvider<ServletConfig> { + + @Override public ServletConfig createContext(Message message) { final ServletConfig sc = (ServletConfig)message.get("HTTP.CONFIG"); @@ -386,7 +374,7 @@ public class Swagger2Feature extends AbstractSwaggerFeature { private static final Map<String, String> DEFAULT_MEDIA_TYPES; static { - DEFAULT_MEDIA_TYPES = new HashMap<String, String>(); + DEFAULT_MEDIA_TYPES = new HashMap<>(); DEFAULT_MEDIA_TYPES.put("html", "text/html"); DEFAULT_MEDIA_TYPES.put("png", "image/png"); DEFAULT_MEDIA_TYPES.put("gif", "image/gif"); @@ -398,8 +386,11 @@ public class Swagger2Feature extends AbstractSwaggerFeature { DEFAULT_MEDIA_TYPES.put("woff", "application/font-woff"); DEFAULT_MEDIA_TYPES.put("woff2", "application/font-woff2"); } - private String swaggerUiRoot; - private Map<String, String> mediaTypes; + + private final String swaggerUiRoot; + + private final Map<String, String> mediaTypes; + public SwaggerUIService(String swaggerUiRoot, Map<String, String> mediaTypes) { this.swaggerUiRoot = swaggerUiRoot; this.mediaTypes = mediaTypes; @@ -422,7 +413,7 @@ public class Swagger2Feature extends AbstractSwaggerFeature { URL resourceURL = URI.create(swaggerUiRoot + resourcePath).toURL(); String mediaType = null; - int ind = resourcePath.lastIndexOf("."); + int ind = resourcePath.lastIndexOf('.'); if (ind != -1 && ind < resourcePath.length()) { String resourceExt = resourcePath.substring(ind + 1); if (mediaTypes != null && mediaTypes.containsKey(resourceExt)) { http://git-wip-us.apache.org/repos/asf/cxf/blob/4ddbf53b/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Serializers.java ---------------------------------------------------------------------- diff --git a/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Serializers.java b/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Serializers.java index ae6dc27..6b26552 100644 --- a/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Serializers.java +++ b/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Serializers.java @@ -18,157 +18,29 @@ */ package org.apache.cxf.jaxrs.swagger; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; +import java.net.URL; import java.util.List; -import java.util.Map; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyWriter; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.cxf.jaxrs.ext.MessageContext; import org.apache.cxf.jaxrs.model.ClassResourceInfo; -import org.apache.cxf.jaxrs.model.OperationResourceInfo; import org.apache.cxf.jaxrs.model.doc.DocumentationProvider; -import org.apache.cxf.jaxrs.utils.JAXRSUtils; -import io.swagger.jaxrs.listing.SwaggerSerializers; -import io.swagger.models.HttpMethod; -import io.swagger.models.Operation; -import io.swagger.models.Path; import io.swagger.models.Swagger; -import io.swagger.models.Tag; -public class Swagger2Serializers extends SwaggerSerializers { +public interface Swagger2Serializers extends MessageBodyWriter<Swagger> { - protected final boolean dynamicBasePath; + void setDynamicBasePath(boolean dynamicBasePath); - protected final boolean replaceTags; + void setReplaceTags(boolean replaceTags); - protected final DocumentationProvider javadocProvider; + void setJavadocProvider(DocumentationProvider javadocProvider); - protected final List<ClassResourceInfo> cris; + void setClassResourceInfos(List<ClassResourceInfo> classResourceInfos); - public Swagger2Serializers( - final boolean dynamicBasePath, - final boolean replaceTags, - final DocumentationProvider javadocProvider, - final List<ClassResourceInfo> cris) { + void setJavaDocPath(String javaDocPath) throws Exception; - super(); + void setJavaDocPaths(String... javaDocPaths) throws Exception; - this.dynamicBasePath = dynamicBasePath; - this.replaceTags = replaceTags; - this.javadocProvider = javadocProvider; - this.cris = cris; - } - - @Override - public void writeTo( - final Swagger data, - final Class<?> type, - final Type genericType, - final Annotation[] annotations, - final MediaType mediaType, - final MultivaluedMap<String, Object> headers, - final OutputStream out) throws IOException { - - if (dynamicBasePath) { - MessageContext ctx = JAXRSUtils.createContextValue( - JAXRSUtils.getCurrentMessage(), null, MessageContext.class); - data.setBasePath(StringUtils.substringBeforeLast(ctx.getHttpServletRequest().getRequestURI(), "/")); - } - - if (replaceTags || javadocProvider != null) { - Map<String, ClassResourceInfo> operations = new HashMap<>(); - Map<Pair<String, String>, OperationResourceInfo> methods = new HashMap<>(); - for (ClassResourceInfo cri : cris) { - for (OperationResourceInfo ori : cri.getMethodDispatcher().getOperationResourceInfos()) { - String normalizedPath = getNormalizedPath( - cri.getURITemplate().getValue(), ori.getURITemplate().getValue()); - - operations.put(normalizedPath, cri); - methods.put(ImmutablePair.of(ori.getHttpMethod(), normalizedPath), ori); - } - } - - if (replaceTags && data.getTags() != null) { - data.getTags().clear(); - } - for (final Map.Entry<String, Path> entry : data.getPaths().entrySet()) { - Tag tag = null; - if (replaceTags && operations.containsKey(entry.getKey())) { - ClassResourceInfo cri = operations.get(entry.getKey()); - - tag = new Tag(); - tag.setName(cri.getURITemplate().getValue()); - if (javadocProvider != null) { - tag.setDescription(javadocProvider.getClassDoc(cri)); - } - - data.addTag(tag); - } - - for (Map.Entry<HttpMethod, Operation> subentry : entry.getValue().getOperationMap().entrySet()) { - if (replaceTags && tag != null) { - subentry.getValue().setTags(Collections.singletonList(tag.getName())); - } - - Pair<String, String> key = ImmutablePair.of(subentry.getKey().name(), entry.getKey()); - if (methods.containsKey(key) && javadocProvider != null) { - OperationResourceInfo ori = methods.get(key); - - subentry.getValue().setSummary(javadocProvider.getMethodDoc(ori)); - for (int i = 0; i < subentry.getValue().getParameters().size(); i++) { - subentry.getValue().getParameters().get(i). - setDescription(javadocProvider.getMethodParameterDoc(ori, i)); - } - - if (subentry.getValue().getResponses() != null - && !subentry.getValue().getResponses().isEmpty()) { - - subentry.getValue().getResponses().entrySet().iterator().next().getValue(). - setDescription(javadocProvider.getMethodResponseDoc(ori)); - } - } - } - } - } - if (replaceTags && data.getTags() != null) { - Collections.sort(data.getTags(), new Comparator<Tag>() { - - @Override - public int compare(final Tag tag1, final Tag tag2) { - return tag1.getName().compareTo(tag2.getName()); - } - }); - } - - super.writeTo(data, type, genericType, annotations, mediaType, headers, out); - } - - protected String getNormalizedPath(String classResourcePath, String operationResourcePath) { - StringBuilder normalizedPath = new StringBuilder(); - - String[] segments = StringUtils.split(classResourcePath + operationResourcePath, "/"); - for (String segment : segments) { - if (!StringUtils.isEmpty(segment)) { - normalizedPath.append("/").append(segment); - } - } - // Adapt to Swagger's path expression - if (normalizedPath.toString().endsWith(":.*}")) { - normalizedPath.setLength(normalizedPath.length() - 4); - normalizedPath.append('}'); - } - return StringUtils.EMPTY.equals(normalizedPath.toString()) ? "/" : normalizedPath.toString(); - } + void setJavaDocURLs(URL[] javaDocURLs); }