You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2015/02/11 11:27:09 UTC

cxf git commit: [CXF-6132] More changes to JaxrsServletContainerInitializer

Repository: cxf
Updated Branches:
  refs/heads/3.0.x-fixes 8a06e66a3 -> 94fd3cfdf


[CXF-6132] More changes to JaxrsServletContainerInitializer


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

Branch: refs/heads/3.0.x-fixes
Commit: 94fd3cfdf6c6896482ae48a8e90006f214967fa3
Parents: 8a06e66
Author: Sergey Beryozkin <sb...@talend.com>
Authored: Wed Jan 28 13:32:51 2015 +0000
Committer: Sergey Beryozkin <sb...@talend.com>
Committed: Wed Feb 11 10:26:55 2015 +0000

----------------------------------------------------------------------
 .../JaxrsServletContainerInitializer.java       | 125 +++++++++++++++----
 1 file changed, 99 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/94fd3cfd/rt/rs/http-sci/src/main/java/org/apache/cxf/jaxrs/servlet/JaxrsServletContainerInitializer.java
----------------------------------------------------------------------
diff --git a/rt/rs/http-sci/src/main/java/org/apache/cxf/jaxrs/servlet/JaxrsServletContainerInitializer.java b/rt/rs/http-sci/src/main/java/org/apache/cxf/jaxrs/servlet/JaxrsServletContainerInitializer.java
index 4eb3575..4f7f42b 100644
--- a/rt/rs/http-sci/src/main/java/org/apache/cxf/jaxrs/servlet/JaxrsServletContainerInitializer.java
+++ b/rt/rs/http-sci/src/main/java/org/apache/cxf/jaxrs/servlet/JaxrsServletContainerInitializer.java
@@ -22,6 +22,7 @@ import java.lang.annotation.Annotation;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.logging.Logger;
@@ -29,8 +30,10 @@ import java.util.logging.Logger;
 import javax.servlet.ServletContainerInitializer;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
 import javax.servlet.ServletRegistration.Dynamic;
 import javax.servlet.annotation.HandlesTypes;
+import javax.ws.rs.ApplicationPath;
 import javax.ws.rs.Path;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.ext.Provider;
@@ -42,29 +45,111 @@ public class JaxrsServletContainerInitializer implements ServletContainerInitial
     private static final Logger LOG = LogUtils.getL7dLogger(JaxrsServletContainerInitializer.class);
     private static final String IGNORE_PACKAGE = "org.apache.cxf";
     
-    private static final String IGNORE_APP_PATH_PARAM = "jaxrs.application.address.ignore";
-    private static final String SERVICE_CLASSES_PARAM = "jaxrs.serviceClasses";
-    private static final String PROVIDERS_PARAM = "jaxrs.providers";
     private static final String JAXRS_APPLICATION_PARAM = "javax.ws.rs.Application";
-    
+    private static final String CXF_JAXRS_APPLICATION_PARAM = "jaxrs.application";
+    private static final String CXF_JAXRS_CLASSES_PARAM = "jaxrs.classes";
+        
     @Override
     public void onStartup(final Set< Class< ? > > classes, final ServletContext ctx) throws ServletException {        
-        final Dynamic servlet =  ctx.addServlet("CXFServlet", CXFNonSpringJaxrsServlet.class);
-        servlet.addMapping("/*");
+        Application app = null;
+        String servletName = null;
+        String servletMapping = null;
         
-        final Class< ? > application = findCandidate(classes);
-        if (application != null) {
-            servlet.setInitParameter(JAXRS_APPLICATION_PARAM, application.getName());
-            servlet.setInitParameter(IGNORE_APP_PATH_PARAM, "false");
-        } else {
+        final Class< ? > appClass = findCandidate(classes);
+        if (appClass != null) {
+            // The best effort at detecting a CXFNonSpringJaxrsServlet handling this application.
+            // Custom servlets using non-standard mechanisms to create Application will not be detected
+            if (isApplicationServletAvailable(ctx, appClass)) {
+                return;
+            }
+            try {
+                app = (Application)appClass.newInstance();
+            } catch (Throwable t) {
+                throw new ServletException(t);
+            }
+            // Servlet name is the application class name
+            servletName = appClass.getName();
+            ApplicationPath appPath = appClass.getAnnotation(ApplicationPath.class);
+            // If ApplicationPath is available - use its value as a mapping otherwise get it from 
+            // a servlet registration with an application implementation class name 
+            if (appPath != null) {
+                servletMapping = appPath.value() + "/*";
+            } else {
+                servletMapping = getServletMapping(ctx, servletName);
+            }
+        } 
+        // If application is null or empty then try to create a new application from available
+        // resource and provider classes
+        if (app == null
+            || app.getClasses().isEmpty() && app.getSingletons().isEmpty()) {
+            // The best effort at detecting a CXFNonSpringJaxrsServlet
+            // Custom servlets using non-standard mechanisms to create Application will not be detected
+            if (isCxfServletAvailable(ctx)) {
+                return;
+            }
             final Map< Class< ? extends Annotation >, Collection< Class< ? > > > providersAndResources = 
                 groupByAnnotations(classes);
-            
-            servlet.setInitParameter(PROVIDERS_PARAM, getClassNames(providersAndResources.get(Provider.class)));
-            servlet.setInitParameter(SERVICE_CLASSES_PARAM, getClassNames(providersAndResources.get(Path.class)));
+            if (!providersAndResources.get(Path.class).isEmpty()
+                || !providersAndResources.get(Provider.class).isEmpty()) {
+                if (app == null) {
+                    // Servlet name is a JAX-RS Application class name
+                    servletName = JAXRS_APPLICATION_PARAM;
+                    // Servlet mapping is obtained from a servlet registration 
+                    // with a JAX-RS Application class name
+                    servletMapping = getServletMapping(ctx, JAXRS_APPLICATION_PARAM);
+                }
+                app = new Application() {
+                    @Override
+                    public Set<Class<?>> getClasses() {
+                        Set<Class<?>> set = new HashSet<Class<?>>();
+                        set.addAll(providersAndResources.get(Path.class));
+                        set.addAll(providersAndResources.get(Provider.class));
+                        return set;
+                    }
+                };
+            }
+        }
+        
+        if (app == null) {
+            return;
         }
+        CXFNonSpringJaxrsServlet cxfServlet = new CXFNonSpringJaxrsServlet(app);
+        final Dynamic servlet =  ctx.addServlet(servletName, cxfServlet);
+        servlet.addMapping(servletMapping);
     }
     
+    private boolean isCxfServletAvailable(ServletContext ctx) {
+        for (Map.Entry<String, ? extends ServletRegistration> entry : ctx.getServletRegistrations().entrySet()) {
+            if (entry.getValue().getInitParameter(CXF_JAXRS_CLASSES_PARAM) != null) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private String getServletMapping(final ServletContext ctx, final String name) throws ServletException {
+        ServletRegistration sr = ctx.getServletRegistration(name);
+        if (sr != null) {
+            return sr.getMappings().iterator().next();
+        } else {
+            final String error = "Servlet with a name " + name + " is not available";
+            throw new ServletException(error); 
+        }
+    }
+
+    private boolean isApplicationServletAvailable(final ServletContext ctx, final Class<?> appClass) {
+        for (Map.Entry<String, ? extends ServletRegistration> entry : ctx.getServletRegistrations().entrySet()) {
+            String appParam = entry.getValue().getInitParameter(JAXRS_APPLICATION_PARAM);
+            if (appParam == null) {
+                appParam = entry.getValue().getInitParameter(CXF_JAXRS_APPLICATION_PARAM);
+            }
+            if (appParam != null && appParam.equals(appClass.getName())) { 
+                return true;
+            }
+        }
+        return false;
+    }
+
     private Map< Class< ? extends Annotation >, Collection< Class< ? > > > groupByAnnotations(
         final Set< Class< ? > > classes) {
         
@@ -91,18 +176,6 @@ public class JaxrsServletContainerInitializer implements ServletContainerInitial
         return clazz.getPackage().getName().startsWith(IGNORE_PACKAGE);
     }
 
-    private static String getClassNames(final Collection< Class< ? > > classes) {
-        final StringBuilder classNames = new StringBuilder();
-        
-        for (final Class< ? > clazz: classes) {
-            classNames
-                .append((classNames.length() > 0) ? "," : "")
-                .append(clazz.getName());
-        }
-        
-        return classNames.toString();
-    }
-    
     private static Class< ? > findCandidate(final Set< Class< ? > > classes) {
         for (final Class< ? > clazz: classes) {
             if (Application.class.isAssignableFrom(clazz) && !classShouldBeIgnored(clazz)) {