You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by il...@apache.org on 2015/12/02 15:59:18 UTC

[4/6] cxf git commit: Support multiple URLs for javadocs

Support multiple URLs for javadocs


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/e915cfd7
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/e915cfd7
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/e915cfd7

Branch: refs/heads/master
Commit: e915cfd794504a9b1522275b3052d0a3b3ff3876
Parents: dcaaabf
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Dec 2 15:38:13 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Dec 2 15:42:58 2015 +0100

----------------------------------------------------------------------
 .../cxf/jaxrs/model/doc/JavaDocProvider.java    |  49 ++++---
 .../cxf/jaxrs/model/wadl/WadlGenerator.java     | 138 ++++++++++---------
 .../cxf/jaxrs/swagger/Swagger2Feature.java      |  12 +-
 .../cxf/jaxrs/swagger/Swagger2Serializers.java  |  12 +-
 4 files changed, 119 insertions(+), 92 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/e915cfd7/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/doc/JavaDocProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/doc/JavaDocProvider.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/doc/JavaDocProvider.java
index ae81234..5e702fe 100644
--- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/doc/JavaDocProvider.java
+++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/doc/JavaDocProvider.java
@@ -44,22 +44,35 @@ public class JavaDocProvider implements DocumentationProvider {
     public static final double JAVA_VERSION_18 = 1.8D;
 
     private ClassLoader javaDocLoader;
-    private ConcurrentHashMap<String, ClassDocs> docs = new ConcurrentHashMap<String, ClassDocs>();
+    private final ConcurrentHashMap<String, ClassDocs> docs = new ConcurrentHashMap<>();
     private double javaDocsBuiltByVersion = JAVA_VERSION;
     
-    public JavaDocProvider(URL javaDocUrl) {
-        if (javaDocUrl == null) {
-            throw new IllegalArgumentException("URL is null");
+    public JavaDocProvider(URL... javaDocUrls) {
+        if (javaDocUrls == null) {
+            throw new IllegalArgumentException("URL are null");
         }
-        javaDocLoader = new URLClassLoader(new URL[]{javaDocUrl});
+        
+        javaDocLoader = new URLClassLoader(javaDocUrls);
     }
     
     public JavaDocProvider(String path) throws Exception {
         this(BusFactory.getDefaultBus(), path);
     }
     
-    public JavaDocProvider(Bus bus, String path) throws Exception {
-        this(ResourceUtils.getResourceURL(path, bus));
+    public JavaDocProvider(String... paths) throws Exception {
+        this(BusFactory.getDefaultBus(), paths == null ? null : paths);
+    }
+    
+    public JavaDocProvider(Bus bus, String... paths) throws Exception {
+        if (paths == null) {
+            throw new IllegalArgumentException("paths are null");
+        }
+
+        URL[] javaDocUrls = new URL[paths.length];
+        for (int i = 0; i < paths.length; i++) {
+            javaDocUrls[i] = ResourceUtils.getResourceURL(paths[i], bus);
+        }
+        javaDocLoader = new URLClassLoader(javaDocUrls);
     }
     
     private static double getVersion() {
@@ -71,6 +84,7 @@ public class JavaDocProvider implements DocumentationProvider {
         }
     }
     
+    @Override
     public String getClassDoc(ClassResourceInfo cri) {
         try {
             ClassDocs doc = getClassDocInternal(cri.getServiceClass());
@@ -84,6 +98,7 @@ public class JavaDocProvider implements DocumentationProvider {
         return null;
     }
     
+    @Override
     public String getMethodDoc(OperationResourceInfo ori) {
         try {
             MethodDocs doc = getOperationDocInternal(ori);
@@ -97,6 +112,7 @@ public class JavaDocProvider implements DocumentationProvider {
         return null;
     }
     
+    @Override
     public String getMethodResponseDoc(OperationResourceInfo ori) {
         try {
             MethodDocs doc = getOperationDocInternal(ori);
@@ -110,6 +126,7 @@ public class JavaDocProvider implements DocumentationProvider {
         return null;
     }
     
+    @Override
     public String getMethodParameterDoc(OperationResourceInfo ori, int paramIndex) {
         try {
             MethodDocs doc = getOperationDocInternal(ori);
@@ -211,7 +228,7 @@ public class JavaDocProvider implements DocumentationProvider {
             String operInfoTag = getOperInfoTag();
             String operInfo = getJavaDocText(operDoc, operInfoTag, operLink, 0);
             String responseInfo = null;
-            List<String> paramDocs = new LinkedList<String>();
+            List<String> paramDocs = new LinkedList<>();
             if (!StringUtils.isEmpty(operInfo)) {
                 int returnsIndex = operDoc.indexOf("Returns:", operLink.length());
                 int nextOpIndex = operDoc.indexOf(operLink);
@@ -228,7 +245,7 @@ public class JavaDocProvider implements DocumentationProvider {
                     
                     int codeIndex = paramString.indexOf(codeTag);
                     while (codeIndex != -1) {
-                        int next = paramString.indexOf("<", codeIndex + 7);
+                        int next = paramString.indexOf('<', codeIndex + 7);
                         if (next == -1) {
                             next = paramString.length();
                         }
@@ -261,7 +278,7 @@ public class JavaDocProvider implements DocumentationProvider {
         if (tagIndex != -1) {
             int notAfterIndex = doc.indexOf(notAfterTag, index);
             if (notAfterIndex == -1 || notAfterIndex > tagIndex) {
-                int nextIndex = doc.indexOf("<", tagIndex + tag.length());
+                int nextIndex = doc.indexOf('<', tagIndex + tag.length());
                 if (nextIndex != -1) {
                     return doc.substring(tagIndex + tag.length(), nextIndex).trim();
                 }
@@ -313,9 +330,9 @@ public class JavaDocProvider implements DocumentationProvider {
     }
     
     private static class ClassDocs {
-        private String classDoc;
-        private String classInfo;
-        private ConcurrentHashMap<Method, MethodDocs> mdocs = new ConcurrentHashMap<Method, MethodDocs>(); 
+        private final String classDoc;
+        private final String classInfo;
+        private final ConcurrentHashMap<Method, MethodDocs> mdocs = new ConcurrentHashMap<>(); 
         ClassDocs(String classDoc, String classInfo) {
             this.classDoc = classDoc;
             this.classInfo = classInfo;
@@ -339,9 +356,9 @@ public class JavaDocProvider implements DocumentationProvider {
     }
     
     private static class MethodDocs {
-        private String methodInfo;
-        private List<String> paramInfo = new LinkedList<String>();
-        private String responseInfo;
+        private final String methodInfo;
+        private final List<String> paramInfo;
+        private final String responseInfo;
         MethodDocs(String methodInfo, List<String> paramInfo, String responseInfo) {
             this.methodInfo = methodInfo;
             this.paramInfo = paramInfo;

http://git-wip-us.apache.org/repos/asf/cxf/blob/e915cfd7/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
----------------------------------------------------------------------
diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
index dd044fe..29b4467 100644
--- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
+++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
@@ -30,6 +30,7 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
 import java.net.URI;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -146,7 +147,7 @@ public class WadlGenerator implements ContainerRequestFilter {
     private static final String DEFAULT_NS_PREFIX = "prefix";
     private static final Map<ParameterType, Class<? extends Annotation>> PARAMETER_TYPE_MAP;
     static {
-        PARAMETER_TYPE_MAP = new HashMap<ParameterType, Class<? extends Annotation>>();
+        PARAMETER_TYPE_MAP = new HashMap<>();
         PARAMETER_TYPE_MAP.put(ParameterType.FORM, FormParam.class);
         PARAMETER_TYPE_MAP.put(ParameterType.QUERY, QueryParam.class);
         PARAMETER_TYPE_MAP.put(ParameterType.HEADER, HeaderParam.class);
@@ -168,8 +169,7 @@ public class WadlGenerator implements ContainerRequestFilter {
     private boolean checkAbsolutePathSlash;
     private boolean keepRelativeDocLinks;
     private boolean usePathParamsToCompareOperations = true;
-    
-    
+        
     private boolean ignoreMessageWriters = true;
     private boolean ignoreRequests;
     private boolean convertResourcesToDOM = true;
@@ -178,21 +178,19 @@ public class WadlGenerator implements ContainerRequestFilter {
     private List<URI> externalSchemaLinks;
     private Map<String, List<String>> externalQnamesMap;
 
-    private ConcurrentHashMap<String, String> docLocationMap = new ConcurrentHashMap<String, String>();
+    private final ConcurrentHashMap<String, String> docLocationMap = new ConcurrentHashMap<>();
 
     private ElementQNameResolver resolver;
     private List<String> privateAddresses;
     private String applicationTitle;
     private String nsPrefix = DEFAULT_NS_PREFIX;
     private MediaType defaultWadlResponseMediaType = MediaType.APPLICATION_XML_TYPE;
-    private MediaType defaultRepMediaType = MediaType.WILDCARD_TYPE;
+    private final MediaType defaultRepMediaType = MediaType.WILDCARD_TYPE;
     private String stylesheetReference;
     private boolean applyStylesheetLocally;
     private Bus bus;
-    private List<DocumentationProvider> docProviders = new LinkedList<DocumentationProvider>();
-    private ResourceIdGenerator idGenerator;     
-    
-    
+    private final List<DocumentationProvider> docProviders = new LinkedList<DocumentationProvider>();
+    private ResourceIdGenerator idGenerator;             
     
     public WadlGenerator() {
     }
@@ -201,8 +199,8 @@ public class WadlGenerator implements ContainerRequestFilter {
         this.bus = bus;
     }
 
+    @Override
     public void filter(ContainerRequestContext context) {
-
         Message m = JAXRSUtils.getCurrentMessage();
         doFilter(context, m);
     }
@@ -270,7 +268,7 @@ public class WadlGenerator implements ContainerRequestFilter {
                                        UriInfo ui) {
         StringBuilder sbMain = new StringBuilder();
         if (!isJson && stylesheetReference != null && !applyStylesheetLocally) {
-            sbMain.append("<?xml-stylesheet " + getStylesheetInstructionData(baseURI) + "?>");
+            sbMain.append("<?xml-stylesheet ").append(getStylesheetInstructionData(baseURI)).append("?>");
         }
         sbMain.append("<application");
         if (!isJson) {
@@ -295,7 +293,7 @@ public class WadlGenerator implements ContainerRequestFilter {
         
         JAXBContext jaxbContext = null;
         if (useJaxbContextForQnames && !allTypes.isEmpty()) { 
-            jaxbContext = ResourceUtils.createJaxbContext(new HashSet<Class<?>>(allTypes), null, null);
+            jaxbContext = ResourceUtils.createJaxbContext(new HashSet<>(allTypes), null, null);
             if (jaxbContext == null) {
                 LOG.warning("JAXB Context is null: possibly due to one of input classes being not accepted");
             }
@@ -305,8 +303,8 @@ public class WadlGenerator implements ContainerRequestFilter {
         ElementQNameResolver qnameResolver = schemaWriter == null
             ? null : createElementQNameResolver(jaxbContext);
 
-        Map<Class<?>, QName> clsMap = new IdentityHashMap<Class<?>, QName>();
-        Set<ClassResourceInfo> visitedResources = new LinkedHashSet<ClassResourceInfo>();
+        Map<Class<?>, QName> clsMap = new IdentityHashMap<>();
+        Set<ClassResourceInfo> visitedResources = new LinkedHashSet<>();
         for (ClassResourceInfo cri : cris) {
             startResourceTag(sbResources, cri, cri.getURITemplate().getValue());
             
@@ -366,7 +364,7 @@ public class WadlGenerator implements ContainerRequestFilter {
             return;
         }
 
-        Map<String, String> map = new HashMap<String, String>();
+        Map<String, String> map = new HashMap<>();
         for (QName qname : clsMap.values()) {
             map.put(qname.getPrefix(), qname.getNamespaceURI());
         }
@@ -424,7 +422,7 @@ public class WadlGenerator implements ContainerRequestFilter {
     }
 
     private Map<Parameter, Object> getClassParameters(ClassResourceInfo cri) {
-        Map<Parameter, Object> classParams = new LinkedHashMap<Parameter, Object>();
+        Map<Parameter, Object> classParams = new LinkedHashMap<>();
         List<Method> paramMethods = cri.getParameterMethods();
         for (Method m : paramMethods) {
             classParams.put(ResourceUtils.getParameter(0, m.getAnnotations(), m.getParameterTypes()[0]), m);
@@ -446,7 +444,7 @@ public class WadlGenerator implements ContainerRequestFilter {
     }
 
     protected String getPath(String path) {
-        String thePath = null;
+        String thePath;
         if (ignoreForwardSlash && path.startsWith("/") && path.length() > 0) {
             thePath = path.substring(1);
         } else {
@@ -460,7 +458,7 @@ public class WadlGenerator implements ContainerRequestFilter {
         if (!this.useJaxbContextForQnames) {
             return;
         }
-        List<Class<?>> extraClasses = new LinkedList<Class<?>>();
+        List<Class<?>> extraClasses = new LinkedList<>();
         for (Class<?> cls : resourceTypes.getAllTypes().keySet()) {
             if (!isXmlRoot(cls) || Modifier.isAbstract(cls.getModifiers())) {
                 XmlSeeAlso seeAlsoAnn = cls.getAnnotation(XmlSeeAlso.class);
@@ -579,7 +577,7 @@ public class WadlGenerator implements ContainerRequestFilter {
         if (!handleDocs(anns, sb, DocTarget.METHOD, true, isJson)) {
             handleOperJavaDocs(ori, sb);
         }
-        if (getMethod(ori).getParameterTypes().length != 0 || classParams.size() != 0) {
+        if (getMethod(ori).getParameterTypes().length != 0 || !classParams.isEmpty()) {
             startMethodRequestTag(sb, ori);
             handleDocs(anns, sb, DocTarget.REQUEST, false, isJson);
 
@@ -708,7 +706,7 @@ public class WadlGenerator implements ContainerRequestFilter {
                                        Map<Parameter, Object> params, 
                                        boolean isJson,
                                        ParameterType... pType) {
-        Set<ParameterType> pTypes = new LinkedHashSet<ParameterType>(Arrays.asList(pType));
+        Set<ParameterType> pTypes = new LinkedHashSet<>(Arrays.asList(pType));
         for (Map.Entry<Parameter, Object> entry : params.entrySet()) {
             Parameter pm = entry.getKey();
             Object obj = entry.getValue();
@@ -803,7 +801,7 @@ public class WadlGenerator implements ContainerRequestFilter {
                          method.getParameterAnnotations()[pm.getIndex()], 
                          isJson);
         } else {
-            List<Class<?>> parentBeanClasses = new LinkedList<Class<?>>();
+            List<Class<?>> parentBeanClasses = new LinkedList<>();
             parentBeanClasses.add(type);
             doWriteBeanParam(ori, sb, type, pm, null, parentBeanClasses, isJson);
             parentBeanClasses.remove(type);
@@ -940,12 +938,12 @@ public class WadlGenerator implements ContainerRequestFilter {
 
     private void setEnumOptions(StringBuilder sb, Class<?> enumClass) {
         try {
-            Method m = enumClass.getMethod("values", new Class[] {});
+            Method m = enumClass.getMethod("values", new Class<?>[] {});
             Object[] values = (Object[])m.invoke(null, new Object[] {});
-            m = enumClass.getMethod("toString", new Class[] {});
+            m = enumClass.getMethod("toString", new Class<?>[] {});
             for (Object o : values) {
                 String str = (String)m.invoke(o, new Object[] {});
-                sb.append("<option value=\"" + str + "\"/>");
+                sb.append("<option value=\"").append(str).append("\"/>");
             }
 
         } catch (Throwable ex) {
@@ -967,12 +965,12 @@ public class WadlGenerator implements ContainerRequestFilter {
             sb.append(">");
             if (docAnnAvailable) {
                 handleDocs(anns, sb, category, allowDefault, isJson);
-            } else if (category == DocTarget.RETURN) {
+            } else if (DocTarget.RETURN.equals(category)) {
                 handleOperResponseJavaDocs(ori, sb);
-            } else if (category == DocTarget.PARAM) {
+            } else if (DocTarget.PARAM.equals(category)) {
                 handleOperParamJavaDocs(ori, paramIndex, sb);
             }
-            sb.append("</" + elementName + ">");
+            sb.append("</").append(elementName).append(">");
         } else {
             sb.append("/>");
         }
@@ -1012,7 +1010,7 @@ public class WadlGenerator implements ContainerRequestFilter {
             String docCategory;
             Annotation[] anns;
             int inParamIndex = -1;
-            Type genericType = null;
+            Type genericType;
             if (inbound) {
                 inParamIndex = getRequestBodyParam(ori).getIndex();
                 anns = opMethod.getParameterAnnotations()[inParamIndex];
@@ -1035,7 +1033,7 @@ public class WadlGenerator implements ContainerRequestFilter {
                 sb.append("</representation>");
             } else {
                 boolean isCollection = InjectionUtils.isSupportedCollectionOrArray(type);
-                Class<?> theActualType = null;
+                Class<?> theActualType;
                 if (isCollection) {
                     theActualType = InjectionUtils.getActualType(genericType);
                 } else {
@@ -1102,9 +1100,10 @@ public class WadlGenerator implements ContainerRequestFilter {
     }
 
     protected List<OperationResourceInfo> sortOperationsByPath(Set<OperationResourceInfo> ops) {
-        List<OperationResourceInfo> opsWithSamePath = new LinkedList<OperationResourceInfo>(ops);
+        List<OperationResourceInfo> opsWithSamePath = new LinkedList<>(ops);
         Collections.sort(opsWithSamePath, new Comparator<OperationResourceInfo>() {
 
+            @Override
             public int compare(OperationResourceInfo op1, OperationResourceInfo op2) {
                 boolean sub1 = op1.getHttpMethod() == null;
                 boolean sub2 = op2.getHttpMethod() == null;
@@ -1144,9 +1143,9 @@ public class WadlGenerator implements ContainerRequestFilter {
         if (slash.equals(path) && !absolutePathSlashOn) {
             return all;
         }
-        List<ClassResourceInfo> cris = new LinkedList<ClassResourceInfo>();
+        List<ClassResourceInfo> cris = new LinkedList<>();
         for (ClassResourceInfo cri : all) {
-            MultivaluedMap<String, String> map = new MetadataMap<String, String>();
+            MultivaluedMap<String, String> map = new MetadataMap<>();
             if (cri.getURITemplate().match(path, map)
                 && slash.equals(map.getFirst(URITemplate.FINAL_MATCH_GROUP))) {
                 cris.add(cri);
@@ -1205,7 +1204,7 @@ public class WadlGenerator implements ContainerRequestFilter {
     }
     private Response finalizeExistingWadlResponse(Document wadlDoc, Message m, UriInfo ui, MediaType mt) 
         throws Exception {
-        Object entity = null;
+        Object entity;
         if (stylesheetReference != null) {
             if (!applyStylesheetLocally) {
                 ProcessingInstruction pi = wadlDoc.createProcessingInstruction("xml-stylesheet", 
@@ -1245,7 +1244,7 @@ public class WadlGenerator implements ContainerRequestFilter {
         try {
             String loc = docLocationMap.get(href);
             if (loc != null) {
-                int fragmentIndex = loc.lastIndexOf("#");
+                int fragmentIndex = loc.lastIndexOf('#');
                 if (fragmentIndex != -1) {
                     loc = loc.substring(0, fragmentIndex);
                 }
@@ -1306,7 +1305,7 @@ public class WadlGenerator implements ContainerRequestFilter {
             String href = element.getAttribute(attrName);
             String originalRef = href;
             if (!StringUtils.isEmpty(href) && !href.startsWith("#")) {
-                int fragmentIndex = href.lastIndexOf("#");
+                int fragmentIndex = href.lastIndexOf('#');
                 String fragment = null;
                 if (fragmentIndex != -1) {
                     fragment = href.substring(fragmentIndex + 1);
@@ -1341,7 +1340,7 @@ public class WadlGenerator implements ContainerRequestFilter {
                 clsMap.put(type, qname);
             } else {
                 XMLName name = AnnotationUtils.getAnnotation(annotations, XMLName.class);
-                String localPart = null;
+                String localPart;
                 if (name != null) {
                     localPart = JAXRSUtils.convertStringToQName(name.value()).getLocalPart();
                 } else {
@@ -1354,8 +1353,7 @@ public class WadlGenerator implements ContainerRequestFilter {
     }
 
     private void writeQName(StringBuilder sb, QName qname) {
-        sb.append(" element=\"").append(qname.getPrefix()).append(':').append(qname.getLocalPart())
-            .append("\"");
+        sb.append(" element=\"").append(qname.getPrefix()).append(':').append(qname.getLocalPart()).append("\"");
     }
 
     private boolean isXmlRoot(Class<?> cls) {
@@ -1367,8 +1365,8 @@ public class WadlGenerator implements ContainerRequestFilter {
             return null;
         }
         SchemaCollection xmlSchemaCollection = new SchemaCollection();
-        Collection<DOMSource> schemas = new HashSet<DOMSource>();
-        List<String> targetNamespaces = new ArrayList<String>();
+        Collection<DOMSource> schemas = new HashSet<>();
+        List<String> targetNamespaces = new ArrayList<>();
         try {
             for (DOMResult r : JAXBUtils.generateJaxbSchemas(context, CastUtils.cast(Collections.emptyMap(),
                                                                                      String.class,
@@ -1493,7 +1491,6 @@ public class WadlGenerator implements ContainerRequestFilter {
     }
 
     private QName getJaxbQName(String name, String namespace, Class<?> type, Map<Class<?>, QName> clsMap) {
-
         QName qname = getQNameFromParts(name, namespace, type, clsMap);
         if (qname != null) {
             return qname;
@@ -1508,7 +1505,6 @@ public class WadlGenerator implements ContainerRequestFilter {
     }
     
     private QName getJaxbQName(JAXBContextProxy jaxbProxy, Class<?> type, Map<Class<?>, QName> clsMap) {
-
         XmlRootElement root = type.getAnnotation(XmlRootElement.class);
         if (root != null) {
             return getJaxbQName(root.name(), root.namespace(), type, clsMap);
@@ -1537,7 +1533,7 @@ public class WadlGenerator implements ContainerRequestFilter {
             }
         }
         if (prefix == null) {
-            int size = new HashSet<QName>(clsMap.values()).size();
+            int size = new HashSet<>(clsMap.values()).size();
             prefix = nsPrefix + (size + 1);
         }
         return prefix;
@@ -1642,9 +1638,7 @@ public class WadlGenerator implements ContainerRequestFilter {
     private Document copy(Document doc) {
         try {
             return StaxUtils.copy(doc);
-        } catch (XMLStreamException e) {
-            // ignore
-        } catch (ParserConfigurationException e) {
+        } catch (XMLStreamException | ParserConfigurationException e) {
             // ignore
         }
         return doc;
@@ -1670,7 +1664,7 @@ public class WadlGenerator implements ContainerRequestFilter {
 
     private void handleApplicationDocs(StringBuilder sbApp) {
         if (applicationTitle != null) {
-            sbApp.append("<doc title=\"" + xmlEncodeIfNeeded(applicationTitle) + "\"/>");
+            sbApp.append("<doc title=\"").append(xmlEncodeIfNeeded(applicationTitle)).append("\"/>");
         }
     }
 
@@ -1727,16 +1721,16 @@ public class WadlGenerator implements ContainerRequestFilter {
 
                 sb.append("<doc");
                 if (!isJson && d.lang().length() > 0) {
-                    sb.append(" xml:lang=\"" + d.lang() + "\"");
+                    sb.append(" xml:lang=\"").append(d.lang()).append("\"");
                 }
                 if (d.title().length() > 0) {
-                    sb.append(" title=\"" + xmlEncodeIfNeeded(d.title()) + "\"");
+                    sb.append(" title=\"").append(xmlEncodeIfNeeded(d.title())).append("\"");
                 }
                 sb.append(">");
                 if (d.value().length() > 0) {
                     sb.append(xmlEncodeIfNeeded(d.value()));
                 } else if (d.docuri().length() > 0) {
-                    InputStream is = null;
+                    InputStream is;
                     if (d.docuri().startsWith(CLASSPATH_PREFIX)) {
                         String path = d.docuri().substring(CLASSPATH_PREFIX.length());
                         is = ResourceUtils.getClasspathResourceStream(path, SchemaHandler.class,
@@ -1782,9 +1776,8 @@ public class WadlGenerator implements ContainerRequestFilter {
     }
 
     public void setSchemaLocations(List<String> locations) {
-
-        externalQnamesMap = new HashMap<String, List<String>>();
-        externalSchemasCache = new ArrayList<String>(locations.size());
+        externalQnamesMap = new HashMap<>();
+        externalSchemasCache = new ArrayList<>(locations.size());
         for (int i = 0; i < locations.size(); i++) {
             String loc = locations.get(i);
             try {
@@ -1855,7 +1848,7 @@ public class WadlGenerator implements ContainerRequestFilter {
     }
 
     public void setExternalLinks(List<String> externalLinks) {
-        externalSchemaLinks = new LinkedList<URI>();
+        externalSchemaLinks = new LinkedList<>();
         for (String s : externalLinks) {
             try {
                 String href = s;
@@ -1879,11 +1872,10 @@ public class WadlGenerator implements ContainerRequestFilter {
 
     private class StringSchemaWriter implements SchemaWriter {
 
-        private List<String> theSchemas;
+        private final List<String> theSchemas;
 
         StringSchemaWriter(List<String> schemas, List<URI> links, UriInfo ui) {
-
-            this.theSchemas = new LinkedList<String>();
+            this.theSchemas = new LinkedList<>();
             // we'll need to do the proper schema caching eventually
             for (String s : schemas) {
                 XMLSource source = new XMLSource(new ByteArrayInputStream(s.getBytes()));
@@ -1900,7 +1892,7 @@ public class WadlGenerator implements ContainerRequestFilter {
             Map<String, String> nsMap = Collections.singletonMap("xs", Constants.URI_2001_SCHEMA_XSD);
             String[] locations = source.getValues("/*/xs:" + elementName + "/@schemaLocation", nsMap);
             
-            Map<String, String> locs = new HashMap<String, String>();
+            Map<String, String> locs = new HashMap<>();
             if (locations == null) {
                 return locs;
             }
@@ -1947,6 +1939,7 @@ public class WadlGenerator implements ContainerRequestFilter {
 
         }
 
+        @Override
         public void write(StringBuilder sb) {
             for (String s : theSchemas) {
                 sb.append(s);
@@ -1956,12 +1949,13 @@ public class WadlGenerator implements ContainerRequestFilter {
 
     private class SchemaCollectionWriter implements SchemaWriter {
 
-        private SchemaCollection coll;
+        private final SchemaCollection coll;
 
         SchemaCollectionWriter(SchemaCollection coll) {
             this.coll = coll;
         }
 
+        @Override
         public void write(StringBuilder sb) {
             for (XmlSchema xs : coll.getXmlSchemas()) {
                 if (xs.getItems().isEmpty() || Constants.URI_2001_SCHEMA_XSD.equals(xs.getTargetNamespace())) {
@@ -1976,19 +1970,19 @@ public class WadlGenerator implements ContainerRequestFilter {
 
     private class ExternalSchemaWriter implements SchemaWriter {
 
-        private List<URI> links;
-        private UriInfo uriInfo;
+        private final List<URI> links;
+        private final UriInfo uriInfo;
 
         ExternalSchemaWriter(List<URI> links, UriInfo ui) {
             this.links = links;
             this.uriInfo = ui;
         }
 
+        @Override
         public void write(StringBuilder sb) {
             for (URI link : links) {
                 try {
-                    URI value = link.isAbsolute() ? link : uriInfo.getBaseUriBuilder().path(link.toString())
-                        .build();
+                    URI value = link.isAbsolute() ? link : uriInfo.getBaseUriBuilder().path(link.toString()).build();
                     sb.append("<include href=\"").append(value.toString()).append("\"/>");
                 } catch (Exception ex) {
                     LOG.warning("WADL grammar section will be incomplete, this link is not a valid URI : "
@@ -2000,12 +1994,13 @@ public class WadlGenerator implements ContainerRequestFilter {
 
     private class JaxbContextQNameResolver implements ElementQNameResolver {
 
-        private JAXBContextProxy proxy;
+        private final JAXBContextProxy proxy;
         
         JaxbContextQNameResolver(JAXBContextProxy proxy) {
             this.proxy = proxy;
         }
 
+        @Override
         public QName resolve(Class<?> type, Annotation[] annotations, Map<Class<?>, QName> clsMap) {
             QName qname = WadlGenerator.this.getJaxbQName(proxy, type, clsMap);
             if (qname == null && supportJaxbXmlType) {
@@ -2029,6 +2024,7 @@ public class WadlGenerator implements ContainerRequestFilter {
 
     private class XMLNameQNameResolver implements ElementQNameResolver {
 
+        @Override
         public QName resolve(Class<?> type, Annotation[] annotations, Map<Class<?>, QName> clsMap) {
             XMLName name = AnnotationUtils.getAnnotation(annotations, XMLName.class);
             if (name == null) {
@@ -2048,12 +2044,13 @@ public class WadlGenerator implements ContainerRequestFilter {
     }
 
     private class SchemaQNameResolver implements ElementQNameResolver {
-        private Map<String, List<String>> map;
+        private final Map<String, List<String>> map;
 
         SchemaQNameResolver(Map<String, List<String>> map) {
             this.map = map;
         }
 
+        @Override
         public QName resolve(Class<?> type, Annotation[] annotations, Map<Class<?>, QName> clsMap) {
             String name = type.getSimpleName();
             for (Map.Entry<String, List<String>> entry : map.entrySet()) {
@@ -2155,6 +2152,14 @@ public class WadlGenerator implements ContainerRequestFilter {
         setDocumentationProvider(new JavaDocProvider(bus == null ? BusFactory.getDefaultBus() : bus, path));
     }
     
+    public void setJavaDocPaths(String... paths) throws Exception {
+        setDocumentationProvider(new JavaDocProvider(bus == null ? BusFactory.getDefaultBus() : bus, paths));
+    }
+
+    public void setJavaDocURLs(final URL[] javaDocURLs) {
+        setDocumentationProvider(new JavaDocProvider(javaDocURLs));
+    }
+
     public void setDocumentationProvider(DocumentationProvider p) {
         docProviders.add(p);
     }
@@ -2195,13 +2200,14 @@ public class WadlGenerator implements ContainerRequestFilter {
 
     private static class SchemaConverter extends DelegatingXMLStreamWriter {
         private static final String SCHEMA_LOCATION = "schemaLocation";
-        private Map<String, String> locsMap;
+        private final Map<String, String> locsMap;
 
         SchemaConverter(XMLStreamWriter writer, Map<String, String> locsMap) {
             super(writer);
             this.locsMap = locsMap;
         }
 
+        @Override
         public void writeAttribute(String local, String value) throws XMLStreamException {
             if (SCHEMA_LOCATION.equals(local) && locsMap.containsKey(value)) {
                 value = locsMap.get(value);

http://git-wip-us.apache.org/repos/asf/cxf/blob/e915cfd7/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java
----------------------------------------------------------------------
diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java
index f335eec..da84457 100644
--- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java
+++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java
@@ -20,6 +20,7 @@ package org.apache.cxf.jaxrs.swagger;
 
 import java.io.IOException;
 import java.net.URI;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedHashSet;
@@ -34,7 +35,6 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 
-import org.apache.cxf.BusFactory;
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.endpoint.Server;
 import org.apache.cxf.jaxrs.JAXRSServiceFactoryBean;
@@ -160,7 +160,15 @@ public class Swagger2Feature extends AbstractSwaggerFeature {
     }
 
     public void setJavaDocPath(final String javaDocPath) throws Exception {
-        this.javadocProvider = new JavaDocProvider(BusFactory.getDefaultBus(), javaDocPath);
+        this.javadocProvider = new JavaDocProvider(javaDocPath);
+    }
+
+    public void setJavaDocPaths(final String... javaDocPaths) throws Exception {
+        this.javadocProvider = new JavaDocProvider(javaDocPaths);
+    }
+
+    public void setJavaDocURLs(final URL[] javaDocURLs) {
+        this.javadocProvider = new JavaDocProvider(javaDocURLs);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cxf/blob/e915cfd7/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Serializers.java
----------------------------------------------------------------------
diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Serializers.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Serializers.java
index c80cf4d..187ea96 100644
--- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Serializers.java
+++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Serializers.java
@@ -91,8 +91,8 @@ public class Swagger2Serializers extends SwaggerSerializers {
             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());
+                    String normalizedPath = getNormalizedPath(
+                            cri.getURITemplate().getValue(), ori.getURITemplate().getValue());
 
                     operations.put(normalizedPath, cri);
                     methods.put(ImmutablePair.of(ori.getHttpMethod(), normalizedPath), ori);
@@ -146,13 +146,9 @@ public class Swagger2Serializers extends SwaggerSerializers {
     }
 
     private String getNormalizedPath(String classResourcePath, String operationResourcePath) {
-        StringBuilder path = new StringBuilder().
-            append(classResourcePath).
-            append(operationResourcePath);
-
         StringBuilder normalizedPath = new StringBuilder();
 
-        String[] segments = StringUtils.split(path.toString(), "/");
+        String[] segments = StringUtils.split(classResourcePath + operationResourcePath, "/");
         for (String segment : segments) {
             if (!StringUtils.isEmpty(segment)) {
                 normalizedPath.append("/").append(segment);
@@ -163,6 +159,6 @@ public class Swagger2Serializers extends SwaggerSerializers {
             normalizedPath.setLength(normalizedPath.length() - 4);
             normalizedPath.append('}');
         }
-        return normalizedPath.toString();
+        return StringUtils.EMPTY.equals(normalizedPath.toString()) ? "/" : normalizedPath.toString();
     }
 }