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)) {