Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http')
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/DefaultServletContextHelper.java43
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/DefaultServletContextHelperFactory.java36
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceImpl.java115
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceObjectRegistration.java9
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java354
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java544
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/HttpContextHelperFactory.java154
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/WrappedHttpContext.java76
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextFilterTrackerCustomizer.java20
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextListenerTrackerCustomizer.java20
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextResourceTrackerCustomizer.java22
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextServletTrackerCustomizer.java72
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/RegistrationServiceTrackerCustomizer.java2
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/dto/ExtendedErrorPageDTO.java33
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/dto/ExtendedFailedServletContextDTO.java30
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/RegisteredFilterException.java10
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/EndpointRegistration.java13
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/FilterRegistration.java59
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/MatchableRegistration.java12
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ResourceRegistration.java16
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ServletRegistration.java20
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletRequestWrapperImpl.java19
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpSessionAdaptor.java4
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/Match.java6
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResponseStateHandler.java69
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java3
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java30
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/HttpStatus.java173
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/ServiceProperties.java8
29 files changed, 1298 insertions, 674 deletions
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/DefaultServletContextHelper.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/DefaultServletContextHelper.java
new file mode 100644
index 000000000..04fc3e6db
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/DefaultServletContextHelper.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) Jan. 27, 2019 Liferay, Inc.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Liferay, Inc. - initial API and implementation and/or initial
+ * documentation
+ ******************************************************************************/
+
+package org.eclipse.equinox.http.servlet.internal;
+
+import java.net.URL;
+import org.eclipse.equinox.http.servlet.internal.util.Const;
+import org.osgi.framework.Bundle;
+import org.osgi.service.http.HttpContext;
+import org.osgi.service.http.context.ServletContextHelper;
+
+public class DefaultServletContextHelper extends ServletContextHelper implements HttpContext {
+ private final Bundle bundle;
+ public DefaultServletContextHelper(Bundle bundle) {
+ super(bundle);
+ this.bundle = bundle;
+ }
+
+ @Override
+ public URL getResource(String name) {
+ if (name != null) {
+ if (name.startsWith(Const.SLASH)) {
+ name = name.substring(1);
+ }
+
+ return bundle.getResource(name);
+ }
+ return null;
+ }
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/DefaultServletContextHelperFactory.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/DefaultServletContextHelperFactory.java
new file mode 100644
index 000000000..ba1358b78
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/DefaultServletContextHelperFactory.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) Jan. 27, 2019 Liferay, Inc.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Liferay, Inc. - initial API and implementation and/or initial
+ * documentation
+ ******************************************************************************/
+
+package org.eclipse.equinox.http.servlet.internal;
+
+import org.osgi.framework.*;
+import org.osgi.service.http.context.ServletContextHelper;
+
+public class DefaultServletContextHelperFactory implements ServiceFactory<ServletContextHelper> {
+ @Override
+ public ServletContextHelper getService(
+ Bundle bundle,
+ ServiceRegistration<ServletContextHelper> registration) {
+ return new DefaultServletContextHelper(bundle);
+ }
+
+ @Override
+ public void ungetService(
+ Bundle bundle,
+ ServiceRegistration<ServletContextHelper> registration,
+ ServletContextHelper service) {
+ // do nothing
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceImpl.java
index 0ba942053..296235d45 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceImpl.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2017 Cognos Incorporated, IBM Corporation and others.
+ * Copyright (c) 2005, 2019 Cognos Incorporated, IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -16,59 +16,41 @@
package org.eclipse.equinox.http.servlet.internal;
-import java.io.IOException;
-import java.net.URL;
import java.security.*;
import java.util.Dictionary;
-import javax.servlet.*;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import java.util.Hashtable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicLong;
+import javax.servlet.Filter;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
import org.eclipse.equinox.http.servlet.ExtendedHttpService;
+import org.eclipse.equinox.http.servlet.internal.context.WrappedHttpContext;
+import org.eclipse.equinox.http.servlet.internal.util.Const;
import org.eclipse.equinox.http.servlet.internal.util.Throw;
-import org.osgi.framework.Bundle;
+import org.osgi.framework.*;
import org.osgi.service.http.*;
+import org.osgi.service.http.context.ServletContextHelper;
+import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
public class HttpServiceImpl implements HttpService, ExtendedHttpService {
+ private static AtomicLong legacyIdGenerator = new AtomicLong(0);
+
final Bundle bundle; //The bundle associated with this instance of http service
final HttpServiceRuntimeImpl httpServiceRuntime;
- private boolean shutdown = false; // We prevent use of this instance if HttpServiceFactory.ungetService has called unregisterAliases.
-
- class DefaultHttpContext implements HttpContext {
- /**
- * @throws IOException
- */
- @Override
- public boolean handleSecurity(
- HttpServletRequest request, HttpServletResponse response)
- throws IOException {
- return true;
- }
-
- @Override
- public URL getResource(String name) {
- if (name != null) {
- if (name.startsWith("/")) { //$NON-NLS-1$
- name = name.substring(1);
- }
+ private volatile boolean shutdown = false; // We prevent use of this instance if HttpServiceFactory.ungetService has called unregisterAliases.
- return bundle.getResource(name);
- }
- return null;
- }
-
- @Override
- public String getMimeType(String name) {
- return null;
- }
-
- }
+ private final ConcurrentMap<HttpContext, ServiceReference<DefaultServletContextHelper>> contextMap = new ConcurrentHashMap<HttpContext, ServiceReference<DefaultServletContextHelper>>();
+ private final ServiceReference<DefaultServletContextHelper> defaultHttpContextReference;
public HttpServiceImpl(
Bundle bundle, HttpServiceRuntimeImpl httpServiceRuntime) {
this.bundle = bundle;
this.httpServiceRuntime = httpServiceRuntime;
+ defaultHttpContextReference = this.bundle.getBundleContext().getServiceReference(DefaultServletContextHelper.class);
}
/**
@@ -77,27 +59,31 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService {
public synchronized HttpContext createDefaultHttpContext() {
checkShutdown();
- return new DefaultHttpContext();
+ DefaultServletContextHelper defaultServletContextHelper = bundle.getBundleContext().getService(defaultHttpContextReference);
+
+ contextMap.putIfAbsent(defaultServletContextHelper, defaultHttpContextReference);
+
+ return defaultServletContextHelper;
}
/**
- * @throws ServletException
+ * @throws ServletException
* @see ExtendedHttpService#registerFilter(String, Filter, Dictionary, HttpContext)
*/
public synchronized void registerFilter(
- final String alias, final Filter filter,
+ final String alias, final Filter filter,
final Dictionary<String, String> initparams,
HttpContext httpContext)
throws ServletException {
checkShutdown();
-
- final HttpContext finalHttpContext = httpContext == null ? createDefaultHttpContext() : httpContext;
+ httpContext = httpContext == null ? createDefaultHttpContext() : registerContext(httpContext);
+ final ServiceReference<DefaultServletContextHelper> serviceReference = contextMap.get(httpContext);
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws ServletException {
- httpServiceRuntime.registerHttpServiceFilter(bundle, alias, filter, initparams, finalHttpContext);
+ httpServiceRuntime.registerHttpServiceFilter(bundle, alias, filter, initparams, serviceReference);
return null;
}
});
@@ -109,7 +95,7 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService {
}
/**
- * @throws NamespaceException
+ * @throws NamespaceException
* @see HttpService#registerResources(String, String, HttpContext)
*/
public synchronized void registerResources(
@@ -117,12 +103,13 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService {
throws NamespaceException {
checkShutdown();
- final HttpContext finalHttpContext = httpContext == null ? createDefaultHttpContext() : httpContext;
+ httpContext = httpContext == null ? createDefaultHttpContext() : registerContext(httpContext);
+ final ServiceReference<DefaultServletContextHelper> serviceReference = contextMap.get(httpContext);
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws NamespaceException {
- httpServiceRuntime.registerHttpServiceResources(bundle, alias, name, finalHttpContext);
+ httpServiceRuntime.registerHttpServiceResources(bundle, alias, name, serviceReference);
return null;
}
});
@@ -133,22 +120,23 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService {
}
/**
- * @throws ServletException
- * @throws NamespaceException
+ * @throws ServletException
+ * @throws NamespaceException
* @see HttpService#registerServlet(String, Servlet, Dictionary, HttpContext)
*/
public synchronized void registerServlet(
- final String alias, final Servlet servlet,
+ final String alias, final Servlet servlet,
final Dictionary initparams, HttpContext httpContext)
throws ServletException, NamespaceException {
checkShutdown();
- final HttpContext finalHttpContext = httpContext == null ? createDefaultHttpContext() : httpContext;
+ httpContext = httpContext == null ? createDefaultHttpContext() : registerContext(httpContext);
+ final ServiceReference<DefaultServletContextHelper> serviceReference = contextMap.get(httpContext);
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws NamespaceException, ServletException {
- httpServiceRuntime.registerHttpServiceServlet(bundle, alias, servlet, initparams, finalHttpContext);
+ httpServiceRuntime.registerHttpServiceServlet(bundle, alias, servlet, initparams, serviceReference);
return null;
}
});
@@ -188,4 +176,29 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService {
"Service instance is already shutdown"); //$NON-NLS-1$
}
}
+
+ private long generateLegacyId() {
+ return legacyIdGenerator.getAndIncrement();
+ }
+
+ private HttpContext registerContext(HttpContext httpContext) {
+ ServiceReference<? extends HttpContext> serviceReference = contextMap.get(httpContext);
+
+ if (serviceReference == null) {
+ Dictionary<String, Object> props = new Hashtable<String, Object>();
+ props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, httpContext.getClass().getName().replaceAll("[^a-zA-Z_0-9\\-]", "_") + "-" + generateLegacyId()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/"); //$NON-NLS-1$
+ props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_TARGET, httpServiceRuntime.getTargetFilter());
+ props.put(Const.EQUINOX_LEGACY_CONTEXT_HELPER, Boolean.TRUE);
+ props.put(Const.EQUINOX_LEGACY_HTTP_CONTEXT_INITIATING_ID, bundle.getBundleId());
+
+ @SuppressWarnings("unchecked")
+ ServiceRegistration<DefaultServletContextHelper> registration = (ServiceRegistration<DefaultServletContextHelper>)bundle.getBundleContext().registerService(ServletContextHelper.class.getName(), new WrappedHttpContext(httpContext, bundle), props);
+
+ contextMap.put(httpContext, registration.getReference());
+ }
+
+ return httpContext;
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceObjectRegistration.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceObjectRegistration.java
index 72348f209..c78adbfc9 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceObjectRegistration.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceObjectRegistration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) Dec 1, 2014 Liferay, Inc.
+ * Copyright (c) 2014, 2019 Liferay, Inc.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -9,27 +9,24 @@
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
- * Liferay, Inc. - initial API and implementation and/or initial
+ * Liferay, Inc. - initial API and implementation and/or initial
* documentation
******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
-import org.eclipse.equinox.http.servlet.internal.context.HttpContextHelperFactory;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceRegistration;
public class HttpServiceObjectRegistration {
public final Object serviceKey;
public final ServiceRegistration<?> registration;
- public final HttpContextHelperFactory factory;
public final Bundle bundle;
public HttpServiceObjectRegistration(
Object serviceKey, ServiceRegistration<?> registration,
- HttpContextHelperFactory factory, Bundle bundle) {
+ Bundle bundle) {
this.serviceKey = serviceKey;
this.registration = registration;
- this.factory = factory;
this.bundle = bundle;
}
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java
index 1ad919b95..a69f1117a 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014, 2016 Raymond Augé and others.
+ * Copyright (c) 2014, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -16,9 +16,8 @@ package org.eclipse.equinox.http.servlet.internal;
import java.io.IOException;
import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.Map.Entry;
+import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import javax.servlet.*;
import javax.servlet.Filter;
@@ -26,7 +25,10 @@ import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionListener;
import org.eclipse.equinox.http.servlet.context.ContextPathCustomizer;
import org.eclipse.equinox.http.servlet.dto.ExtendedFailedServletDTO;
-import org.eclipse.equinox.http.servlet.internal.context.*;
+import org.eclipse.equinox.http.servlet.internal.context.ContextController;
+import org.eclipse.equinox.http.servlet.internal.context.DispatchTargets;
+import org.eclipse.equinox.http.servlet.internal.dto.ExtendedErrorPageDTO;
+import org.eclipse.equinox.http.servlet.internal.dto.ExtendedFailedServletContextDTO;
import org.eclipse.equinox.http.servlet.internal.error.*;
import org.eclipse.equinox.http.servlet.internal.servlet.HttpSessionTracker;
import org.eclipse.equinox.http.servlet.internal.servlet.Match;
@@ -34,7 +36,6 @@ import org.eclipse.equinox.http.servlet.internal.util.*;
import org.eclipse.equinox.http.servlet.session.HttpSessionInvalidator;
import org.osgi.framework.*;
import org.osgi.framework.dto.ServiceReferenceDTO;
-import org.osgi.service.http.HttpContext;
import org.osgi.service.http.NamespaceException;
import org.osgi.service.http.context.ServletContextHelper;
import org.osgi.service.http.runtime.HttpServiceRuntime;
@@ -86,7 +87,8 @@ public class HttpServiceRuntimeImpl
defaultContextProps.put(Constants.SERVICE_RANKING, Integer.MIN_VALUE);
defaultContextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, Const.SLASH);
defaultContextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_TARGET, this.targetFilter);
- defaultContextReg = consumingContext.registerService(ServletContextHelper.class, new DefaultServletContextHelperFactory(), defaultContextProps);
+ defaultContextReg = consumingContext.registerService(
+ new String [] {ServletContextHelper.class.getName(), DefaultServletContextHelper.class.getName()}, new DefaultServletContextHelperFactory(), defaultContextProps);
}
@Override
@@ -98,27 +100,9 @@ public class HttpServiceRuntimeImpl
return result;
}
- String contextName = (String)serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME);
- String contextPath = (String)serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH);
-
try {
- if (contextName == null) {
- throw new IllegalContextNameException(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + " is null. Ignoring!", //$NON-NLS-1$
- DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
- }
-
- if (contextPath == null) {
- throw new IllegalContextPathException(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + " is null. Ignoring!", //$NON-NLS-1$
- DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
- }
-
- contextPath = adaptContextPath(contextPath, serviceReference);
-
ContextController contextController = new ContextController(
- trackingContext, consumingContext, serviceReference, new ProxyContext(contextName, parentServletContext),
- this, contextName, contextPath, httpSessionTracker);
+ trackingContext, consumingContext, serviceReference, parentServletContext, this);
controllerMap.put(serviceReference, contextController);
@@ -127,18 +111,18 @@ public class HttpServiceRuntimeImpl
catch (HttpWhiteboardFailureException hwfe) {
parentServletContext.log(hwfe.getMessage(), hwfe);
- recordFailedServletContextDTO(serviceReference, contextName, contextPath, hwfe.getFailureReason());
+ recordFailedServletContextDTO(serviceReference, 0, hwfe.getFailureReason());
}
catch (Exception e) {
parentServletContext.log(e.getMessage(), e);
- recordFailedServletContextDTO(serviceReference, contextName, contextPath, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
+ recordFailedServletContextDTO(serviceReference, 0, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
}
return result;
}
- private String adaptContextPath(String contextPath, ServiceReference<ServletContextHelper> helper) {
+ public String adaptContextPath(String contextPath, ServiceReference<ServletContextHelper> helper) {
ContextPathCustomizer pathAdaptor = contextPathCustomizerHolder.getHighestRanked();
if (pathAdaptor != null) {
String contextPrefix = pathAdaptor.getContextPathPrefix(helper);
@@ -164,8 +148,16 @@ public class HttpServiceRuntimeImpl
return null;
}
+ public boolean isDefaultContext(ContextController contextController) {
+ ServiceReference<?> thisReference = defaultContextReg.getReference();
+ ServiceReference<ServletContextHelper> contextReference = contextController.getServiceReference();
+ if (thisReference == null) throw new NullPointerException("Default Context Service reference is null. " + this); //$NON-NLS-1$
+ if (contextReference == null) throw new NullPointerException("Context Service reference is null. " + contextController); //$NON-NLS-1$
+ return thisReference.equals(contextReference);
+ }
+
@Override
- public RequestInfoDTO calculateRequestInfoDTO(String path) {
+ public synchronized RequestInfoDTO calculateRequestInfoDTO(String path) {
RequestInfoDTO requestInfoDTO = new RequestInfoDTO();
requestInfoDTO.path = path;
@@ -180,7 +172,7 @@ public class HttpServiceRuntimeImpl
return requestInfoDTO;
}
- public void destroy() {
+ public synchronized void destroy() {
invalidatorReg.unregister();
defaultContextReg.unregister();
@@ -197,14 +189,13 @@ public class HttpServiceRuntimeImpl
failedServletDTOs.clear();
httpSessionTracker.clear();
+ registeredObjects.clear();
httpSessionTracker = null;
attributes = null;
trackingContext = null;
consumingContext = null;
- legacyIdGenerator = null;
parentServletContext = null;
- registeredObjects = null;
contextServiceTracker = null;
contextPathCustomizerHolder = null;
}
@@ -229,26 +220,43 @@ public class HttpServiceRuntimeImpl
requestInfoDTO);
}
- if (dispatchTargets == null) {
+ if (dispatchTargets == null && !Const.SLASH.equals(pathString)) {
// regex match
dispatchTargets = getDispatchTargets(
requestURI, null, queryString, Match.REGEX, requestInfoDTO);
}
if (dispatchTargets == null) {
- // handle '/' aliases
+ // handle with servlet mapped to '/'
+ // the servletpath is the requestURI minus the contextpath and the pathinfo is null
dispatchTargets = getDispatchTargets(
requestURI, null, queryString, Match.DEFAULT_SERVLET,
requestInfoDTO);
}
+ if (dispatchTargets == null && Const.SLASH.equals(pathString)) {
+ // handle with servlet mapped to '' (empty string)
+ // the pathinfo is '/' and the servletpath and contextpath are the empty string ("")
+ dispatchTargets = getDispatchTargets(
+ requestURI, null, queryString, Match.CONTEXT_ROOT,
+ requestInfoDTO);
+ }
+
return dispatchTargets;
}
+ public HttpSessionTracker getHttpSessionTracker() {
+ return httpSessionTracker;
+ }
+
public Set<Object> getRegisteredObjects() {
return registeredObjects;
}
+ public String getTargetFilter() {
+ return targetFilter;
+ }
+
public List<String> getHttpServiceEndpoints() {
return StringPlus.from(
attributes.get(
@@ -256,24 +264,33 @@ public class HttpServiceRuntimeImpl
}
@Override
- public RuntimeDTO getRuntimeDTO() {
+ public synchronized RuntimeDTO getRuntimeDTO() {
RuntimeDTO runtimeDTO = new RuntimeDTO();
- runtimeDTO.serviceDTO = getServiceDTO();
-
- // TODO FailedErrorDTOs
-
- runtimeDTO.failedErrorPageDTOs = null;
+ runtimeDTO.failedErrorPageDTOs = getFailedErrorPageDTOs();
runtimeDTO.failedFilterDTOs = getFailedFilterDTOs();
runtimeDTO.failedListenerDTOs = getFailedListenerDTOs();
runtimeDTO.failedResourceDTOs = getFailedResourceDTOs();
runtimeDTO.failedServletContextDTOs = getFailedServletContextDTO();
runtimeDTO.failedServletDTOs = getFailedServletDTOs();
+ runtimeDTO.serviceDTO = getServiceDTO();
runtimeDTO.servletContextDTOs = getServletContextDTOs();
return runtimeDTO;
}
+ private FailedErrorPageDTO[] getFailedErrorPageDTOs() {
+ Collection<FailedErrorPageDTO> fepDTOs = failedErrorPageDTOs.values();
+
+ List<FailedErrorPageDTO> copies = new ArrayList<FailedErrorPageDTO>();
+
+ for (FailedErrorPageDTO failedErrorPageDTO : fepDTOs) {
+ copies.add(DTOUtil.clone(failedErrorPageDTO));
+ }
+
+ return copies.toArray(new FailedErrorPageDTO[0]);
+ }
+
private ServiceReferenceDTO getServiceDTO() {
ServiceReferenceDTO[] services = consumingContext.getBundle().adapt(ServiceReferenceDTO[].class);
for (ServiceReferenceDTO serviceDTO : services) {
@@ -303,22 +320,31 @@ public class HttpServiceRuntimeImpl
return true;
}
- org.osgi.framework.Filter targetFilter;
+ org.osgi.framework.Filter whiteboardTargetFilter;
try {
- targetFilter = FrameworkUtil.createFilter(target);
+ whiteboardTargetFilter = FrameworkUtil.createFilter(target);
}
catch (InvalidSyntaxException ise) {
throw new IllegalArgumentException(ise);
}
- if (targetFilter.matches(attributes)) {
+ if (whiteboardTargetFilter.matches(attributes)) {
return true;
}
return false;
}
+ public boolean matchesAnyContext(ServiceReference<?> serviceReference) {
+ for (ContextController contextController : controllerMap.values()) {
+ if (contextController.matches(serviceReference)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@Override
public synchronized void modifiedService(
ServiceReference<ServletContextHelper> serviceReference,
@@ -336,10 +362,16 @@ public class HttpServiceRuntimeImpl
ContextController contextController = contextControllerRef.get();
if (contextController != null) {
+ Iterator<Entry<ServiceReference<ServletContextHelper>, ExtendedFailedServletContextDTO>> iterator = failedServletContextDTOs.entrySet().iterator();
+ while (iterator.hasNext()) {
+ if (iterator.next().getValue().shadowingServiceId == contextController.getServiceId()) {
+ iterator.remove();
+ }
+ }
contextController.destroy();
}
- controllerMap.remove(serviceReference);
failedServletContextDTOs.remove(serviceReference);
+ controllerMap.remove(serviceReference);
trackingContext.ungetService(serviceReference);
}
@@ -373,8 +405,8 @@ public class HttpServiceRuntimeImpl
return null;
}
- long generateLegacyId() {
- return legacyIdGenerator.getAndIncrement();
+ public Collection<ContextController> getContextControllers() {
+ return controllerMap.values();
}
public DispatchTargets getDispatchTargets(
@@ -398,9 +430,9 @@ public class HttpServiceRuntimeImpl
String servletPath = requestURI;
String pathInfo = null;
- if (match == Match.DEFAULT_SERVLET) {
- pathInfo = servletPath;
- servletPath = Const.SLASH;
+ if (match == Match.CONTEXT_ROOT) {
+ pathInfo = Const.SLASH;
+ servletPath = Const.BLANK;
}
do {
@@ -415,7 +447,7 @@ public class HttpServiceRuntimeImpl
}
}
- if (match == Match.EXACT) {
+ if ((match == Match.EXACT) || (match == Match.CONTEXT_ROOT) || (match == Match.DEFAULT_SERVLET)) {
break;
}
@@ -444,7 +476,7 @@ public class HttpServiceRuntimeImpl
copies.add(DTOUtil.clone(failedFilterDTO));
}
- return copies.toArray(new FailedFilterDTO[copies.size()]);
+ return copies.toArray(new FailedFilterDTO[0]);
}
private FailedListenerDTO[] getFailedListenerDTOs() {
@@ -456,10 +488,10 @@ public class HttpServiceRuntimeImpl
copies.add(DTOUtil.clone(failedListenerDTO));
}
- return copies.toArray(new FailedListenerDTO[copies.size()]);
+ return copies.toArray(new FailedListenerDTO[0]);
}
- private FailedResourceDTO[] getFailedResourceDTOs() {
+ public FailedResourceDTO[] getFailedResourceDTOs() {
Collection<FailedResourceDTO> frDTOs = failedResourceDTOs.values();
List<FailedResourceDTO> copies = new ArrayList<FailedResourceDTO>();
@@ -468,11 +500,11 @@ public class HttpServiceRuntimeImpl
copies.add(DTOUtil.clone(failedResourceDTO));
}
- return copies.toArray(new FailedResourceDTO[copies.size()]);
+ return copies.toArray(new FailedResourceDTO[0]);
}
private FailedServletContextDTO[] getFailedServletContextDTO() {
- Collection<FailedServletContextDTO> fscDTOs = failedServletContextDTOs.values();
+ Collection<ExtendedFailedServletContextDTO> fscDTOs = failedServletContextDTOs.values();
List<FailedServletContextDTO> copies = new ArrayList<FailedServletContextDTO>();
@@ -480,7 +512,7 @@ public class HttpServiceRuntimeImpl
copies.add(DTOUtil.clone(failedServletContextDTO));
}
- return copies.toArray(new FailedServletContextDTO[copies.size()]);
+ return copies.toArray(new FailedServletContextDTO[0]);
}
private FailedServletDTO[] getFailedServletDTOs() {
@@ -492,28 +524,27 @@ public class HttpServiceRuntimeImpl
copies.add(DTOUtil.clone(failedServletDTO));
}
- return copies.toArray(new FailedServletDTO[copies.size()]);
+ return copies.toArray(new FailedServletDTO[0]);
}
- private ServletContextDTO[] getServletContextDTOs() {
+ public ServletContextDTO[] getServletContextDTOs() {
List<ServletContextDTO> servletContextDTOs = new ArrayList<ServletContextDTO>();
for (ContextController contextController : controllerMap.values()) {
servletContextDTOs.add(contextController.getServletContextDTO());
}
- return servletContextDTOs.toArray(
- new ServletContextDTO[servletContextDTOs.size()]);
+ return servletContextDTOs.toArray(new ServletContextDTO[0]);
}
public void registerHttpServiceFilter(
- Bundle bundle, String alias, Filter filter, Dictionary<String, String> initparams, HttpContext httpContext) throws ServletException {
+ Bundle bundle, String alias, Filter filter, Dictionary<String, String> initparams, ServiceReference<? extends ServletContextHelper> serviceReference) {
if (alias == null) {
- throw new IllegalArgumentException("Alias cannot be null");
+ throw new IllegalArgumentException("Alias cannot be null"); //$NON-NLS-1$
}
if (filter == null) {
- throw new IllegalArgumentException("Filter cannot be null");
+ throw new IllegalArgumentException("Filter cannot be null"); //$NON-NLS-1$
}
ContextController.checkPattern(alias);
@@ -539,7 +570,6 @@ public class HttpServiceRuntimeImpl
if ((initparams != null) && (initparams.get(Const.FILTER_NAME) != null)) {
filterName = initparams.get(Const.FILTER_NAME);
}
- HttpContextHelperFactory factory = getOrRegisterHttpContextHelperFactory(bundle, httpContext);
HttpServiceObjectRegistration objectRegistration = null;
ServiceRegistration<Filter> registration = null;
@@ -548,8 +578,7 @@ public class HttpServiceRuntimeImpl
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_TARGET, targetFilter);
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, alias);
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_NAME, filterName);
- props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + Const.EQUINOX_LEGACY_CONTEXT_HELPER + "=true)"); //$NON-NLS-1$ //$NON-NLS-2$
- props.put(Const.EQUINOX_LEGACY_CONTEXT_SELECT, factory.getFilter());
+ props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, getFilter(serviceReference));
props.put(Const.EQUINOX_LEGACY_TCCL_PROP, Thread.currentThread().getContextClassLoader());
props.put(Constants.SERVICE_RANKING, findFilterPriority(initparams));
fillInitParams(props, initparams, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_INIT_PARAM_PREFIX);
@@ -560,7 +589,7 @@ public class HttpServiceRuntimeImpl
// check that init got called and did not throw an exception
filterFactory.checkForError();
- objectRegistration = new HttpServiceObjectRegistration(filter, registration, factory, bundle);
+ objectRegistration = new HttpServiceObjectRegistration(filter, registration, bundle);
Set<HttpServiceObjectRegistration> objectRegistrations = bundleRegistrations.get(bundle);
if (objectRegistrations == null) {
objectRegistrations = new HashSet<HttpServiceObjectRegistration>();
@@ -571,8 +600,6 @@ public class HttpServiceRuntimeImpl
} finally {
if (objectRegistration == null || !legacyMappings.containsKey(objectRegistration.serviceKey)) {
// something bad happened above (likely going to throw a runtime exception)
- // need to clean up the factory reference
- decrementFactoryUseCount(factory);
if (registration != null) {
registration.unregister();
}
@@ -617,17 +644,17 @@ public class HttpServiceRuntimeImpl
}
throw new IllegalArgumentException(
- "filter-priority must be an integer between -1000 and 1000 but " +
- "was: " + filterPriority);
+ "filter-priority must be an integer between -1000 and 1000 but " + //$NON-NLS-1$
+ "was: " + filterPriority); //$NON-NLS-1$
}
public void registerHttpServiceResources(
- Bundle bundle, String alias, String name, HttpContext httpContext) throws NamespaceException {
+ Bundle bundle, String alias, String name, ServiceReference<? extends ServletContextHelper> serviceReference) throws NamespaceException {
if (alias == null) {
- throw new IllegalArgumentException("Alias cannot be null");
+ throw new IllegalArgumentException("Alias cannot be null"); //$NON-NLS-1$
}
if (name == null) {
- throw new IllegalArgumentException("Name cannot be null");
+ throw new IllegalArgumentException("Name cannot be null"); //$NON-NLS-1$
}
String pattern = alias;
if (pattern.startsWith("/*.")) { //$NON-NLS-1$
@@ -643,9 +670,9 @@ public class HttpServiceRuntimeImpl
synchronized (legacyMappings) {
HttpServiceObjectRegistration objectRegistration = null;
- HttpContextHelperFactory factory = getOrRegisterHttpContextHelperFactory(bundle, httpContext);
+ ServiceRegistration<?> registration = null;
try {
- String fullAlias = getFullAlias(alias, factory);
+ String fullAlias = getFullAlias(alias, serviceReference);
HttpServiceObjectRegistration existing = legacyMappings.get(fullAlias);
if (existing != null) {
throw new PatternInUseException(alias);
@@ -654,11 +681,11 @@ public class HttpServiceRuntimeImpl
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_TARGET, targetFilter);
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PATTERN, pattern);
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PREFIX, name);
- props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, factory.getFilter());
+ props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, getFilter(serviceReference));
props.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE);
props.put(Const.EQUINOX_LEGACY_TCCL_PROP, Thread.currentThread().getContextClassLoader());
- ServiceRegistration<?> registration = bundle.getBundleContext().registerService(String.class, "resource", props); //$NON-NLS-1$
- objectRegistration = new HttpServiceObjectRegistration(fullAlias, registration, factory, bundle);
+ registration = bundle.getBundleContext().registerService(String.class, "resource", props); //$NON-NLS-1$
+ objectRegistration = new HttpServiceObjectRegistration(fullAlias, registration, bundle);
Set<HttpServiceObjectRegistration> objectRegistrations = bundleRegistrations.get(bundle);
if (objectRegistrations == null) {
@@ -678,19 +705,26 @@ public class HttpServiceRuntimeImpl
if (objectRegistration == null || !legacyMappings.containsKey(objectRegistration.serviceKey)) {
// something bad happened above (likely going to throw a runtime exception)
// need to clean up the factory reference
- decrementFactoryUseCount(factory);
+ if (registration != null) {
+ registration.unregister();
+ }
}
}
}
}
+ private Object getFilter(ServiceReference<? extends ServletContextHelper> serviceReference) {
+ String ctxName = (String)serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME);
+ return String.format("(%s=%s)", HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, ctxName); //$NON-NLS-1$
+ }
+
public void registerHttpServiceServlet(
- Bundle bundle, String alias, Servlet servlet, Dictionary<String, String> initparams, HttpContext httpContext) throws NamespaceException, ServletException{
+ Bundle bundle, String alias, Servlet servlet, Dictionary<String, String> initparams, ServiceReference<? extends ServletContextHelper> serviceReference) throws NamespaceException, ServletException{
if (alias == null) {
- throw new IllegalArgumentException("Alias cannot be null");
+ throw new IllegalArgumentException("Alias cannot be null"); //$NON-NLS-1$
}
if (servlet == null) {
- throw new IllegalArgumentException("Servlet cannot be null");
+ throw new IllegalArgumentException("Servlet cannot be null"); //$NON-NLS-1$
}
// check the pattern against the original input
@@ -713,9 +747,8 @@ public class HttpServiceRuntimeImpl
}
HttpServiceObjectRegistration objectRegistration = null;
ServiceRegistration<Servlet> registration = null;
- HttpContextHelperFactory factory = getOrRegisterHttpContextHelperFactory(bundle, httpContext);
try {
- String fullAlias = getFullAlias(alias, factory);
+ String fullAlias = getFullAlias(alias, serviceReference);
HttpServiceObjectRegistration existing = legacyMappings.get(fullAlias);
if (existing != null) {
throw new PatternInUseException(alias);
@@ -729,7 +762,7 @@ public class HttpServiceRuntimeImpl
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_TARGET, targetFilter);
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, pattern);
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, servletName);
- props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, factory.getFilter());
+ props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, getFilter(serviceReference));
props.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE);
props.put(Const.EQUINOX_LEGACY_TCCL_PROP, Thread.currentThread().getContextClassLoader());
fillInitParams(props, initparams, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX);
@@ -739,7 +772,7 @@ public class HttpServiceRuntimeImpl
// check that init got called and did not throw an exception
legacyServlet.checkForError();
- objectRegistration = new HttpServiceObjectRegistration(fullAlias, registration, factory, bundle);
+ objectRegistration = new HttpServiceObjectRegistration(fullAlias, registration, bundle);
Set<HttpServiceObjectRegistration> objectRegistrations = bundleRegistrations.get(bundle);
if (objectRegistrations == null) {
@@ -760,7 +793,6 @@ public class HttpServiceRuntimeImpl
if (objectRegistration == null || !legacyMappings.containsKey(objectRegistration.serviceKey)) {
// something bad happened above (likely going to throw a runtime exception)
// need to clean up the factory reference
- decrementFactoryUseCount(factory);
if (registration != null) {
registration.unregister();
}
@@ -769,8 +801,9 @@ public class HttpServiceRuntimeImpl
}
}
- private String getFullAlias(String alias, HttpContextHelperFactory factory) {
- AtomicReference<ContextController> controllerRef = contextServiceTracker.getService(factory.getServiceReference());
+ private String getFullAlias(String alias, ServiceReference<? extends ServletContextHelper> serviceReference) {
+ @SuppressWarnings("unchecked")
+ AtomicReference<ContextController> controllerRef = contextServiceTracker.getService((ServiceReference<ServletContextHelper>)serviceReference);
if (controllerRef != null) {
ContextController controller = controllerRef.get();
if (controller != null) {
@@ -802,7 +835,6 @@ public class HttpServiceRuntimeImpl
} catch (IllegalStateException e) {
// ignore; already unregistered
}
- decrementFactoryUseCount(objectRegistration.factory);
legacyMappings.remove(aliasCustomization);
}
@@ -824,7 +856,6 @@ public class HttpServiceRuntimeImpl
} catch (IllegalStateException e) {
// ignore; already unregistered
}
- decrementFactoryUseCount(objectRegistration.factory);
legacyMappings.remove(filter);
}
}
@@ -840,43 +871,12 @@ public class HttpServiceRuntimeImpl
} catch (IllegalStateException e) {
// ignore; already unregistered
}
- decrementFactoryUseCount(objectRegistration.factory);
legacyMappings.remove(objectRegistration.serviceKey);
}
}
}
}
- private HttpContextHelperFactory getOrRegisterHttpContextHelperFactory(Bundle initiatingBundle, HttpContext httpContext) {
- if (httpContext == null) {
- throw new NullPointerException("A null HttpContext is not allowed."); //$NON-NLS-1$
- }
- synchronized (httpContextHelperFactories) {
- HttpContextHelperFactory factory = httpContextHelperFactories.get(httpContext);
- if (factory == null) {
- factory = new HttpContextHelperFactory(httpContext);
- Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, httpContext.getClass().getName().replaceAll("[^a-zA-Z_0-9\\-]", "_") + "-" + generateLegacyId()); //$NON-NLS-1$
- props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/"); //$NON-NLS-1$
- props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_TARGET, targetFilter);
- props.put(Const.EQUINOX_LEGACY_CONTEXT_HELPER, Boolean.TRUE);
- props.put(Const.EQUINOX_LEGACY_HTTP_CONTEXT_INITIATING_ID, initiatingBundle.getBundleId());
- factory.setRegistration(consumingContext.registerService(ServletContextHelper.class, factory, props));
- httpContextHelperFactories.put(httpContext, factory);
- }
- factory.incrementUseCount();
- return factory;
- }
- }
-
- private void decrementFactoryUseCount(HttpContextHelperFactory factory) {
- synchronized (httpContextHelperFactories) {
- if (factory.decrementUseCount() == 0) {
- httpContextHelperFactories.remove(factory.getHttpContext());
- }
- }
- }
-
private static org.osgi.framework.Filter createResourceFilter(BundleContext context) {
StringBuilder sb = new StringBuilder();
@@ -980,6 +980,17 @@ public class HttpServiceRuntimeImpl
return resourceServiceFilter;
}
+ public void recordFailedErrorPageDTO(
+ ServiceReference<?> serviceReference,
+ FailedErrorPageDTO failedErrorPageDTO) {
+
+ if (failedErrorPageDTOs.containsKey(serviceReference)) {
+ return;
+ }
+
+ failedErrorPageDTOs.put(serviceReference, failedErrorPageDTO);
+ }
+
public void recordFailedFilterDTO(
ServiceReference<Filter> serviceReference,
FailedFilterDTO failedFilterDTO) {
@@ -1003,7 +1014,7 @@ public class HttpServiceRuntimeImpl
}
public void recordFailedResourceDTO(
- ServiceReference<Object> serviceReference, FailedResourceDTO failedResourceDTO) {
+ ServiceReference<?> serviceReference, FailedResourceDTO failedResourceDTO) {
if (failedResourceDTOs.containsKey(serviceReference)) {
return;
@@ -1012,30 +1023,30 @@ public class HttpServiceRuntimeImpl
failedResourceDTOs.put(serviceReference, failedResourceDTO);
}
- private void recordFailedServletContextDTO(
- ServiceReference<ServletContextHelper> serviceReference, String contextName,
- String contextPath, int failureReason) {
+ public void recordFailedServletContextDTO(
+ ServiceReference<ServletContextHelper> serviceReference, long shadowingServiceId, int failureReason) {
- FailedServletContextDTO failedServletContextDTO = new FailedServletContextDTO();
+ ExtendedFailedServletContextDTO failedServletContextDTO = new ExtendedFailedServletContextDTO();
failedServletContextDTO.attributes = Collections.emptyMap();
- failedServletContextDTO.contextPath = contextPath;
- failedServletContextDTO.errorPageDTOs = new ErrorPageDTO[0];
+ failedServletContextDTO.contextPath = String.valueOf(serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH));
+ failedServletContextDTO.errorPageDTOs = new ExtendedErrorPageDTO[0];
failedServletContextDTO.failureReason = failureReason;
failedServletContextDTO.filterDTOs = new FilterDTO[0];
failedServletContextDTO.initParams = ServiceProperties.parseInitParams(
serviceReference, HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_INIT_PARAM_PREFIX);
failedServletContextDTO.listenerDTOs = new ListenerDTO[0];
- failedServletContextDTO.name = contextName;
+ failedServletContextDTO.name = String.valueOf(serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME));
failedServletContextDTO.resourceDTOs = new ResourceDTO[0];
failedServletContextDTO.serviceId = (Long)serviceReference.getProperty(Constants.SERVICE_ID);
failedServletContextDTO.servletDTOs = new ServletDTO[0];
+ failedServletContextDTO.shadowingServiceId = shadowingServiceId;
failedServletContextDTOs.put(serviceReference, failedServletContextDTO);
}
public void recordFailedServletDTO(
- ServiceReference<Servlet> serviceReference,
+ ServiceReference<?> serviceReference,
ExtendedFailedServletDTO failedServletDTO) {
if (failedServletDTOs.containsKey(serviceReference)) {
@@ -1045,6 +1056,12 @@ public class HttpServiceRuntimeImpl
failedServletDTOs.put(serviceReference, failedServletDTO);
}
+ public void removeFailedErrorPageDTO(
+ ServiceReference<Servlet> serviceReference) {
+
+ failedErrorPageDTOs.remove(serviceReference);
+ }
+
public void removeFailedFilterDTO(
ServiceReference<Filter> serviceReference) {
@@ -1063,13 +1080,13 @@ public class HttpServiceRuntimeImpl
failedResourceDTOs.remove(serviceReference);
}
- public void removeFailedServletDTOs(
+ public void removeFailedServletDTO(
ServiceReference<Servlet> serviceReference) {
failedServletDTOs.remove(serviceReference);
}
- public void fireSessionIdChanged(String oldSessionId) {
+ public synchronized void fireSessionIdChanged(String oldSessionId) {
for (ContextController contextController : controllerMap.values()) {
contextController.fireSessionIdChanged(oldSessionId);
}
@@ -1081,7 +1098,7 @@ public class HttpServiceRuntimeImpl
private Map<String, Object> attributes;
private final String targetFilter;
- private final ServiceRegistration<ServletContextHelper> defaultContextReg;
+ private final ServiceRegistration<?> defaultContextReg;
private ServletContext parentServletContext;
private BundleContext trackingContext;
@@ -1093,32 +1110,30 @@ public class HttpServiceRuntimeImpl
private final org.osgi.framework.Filter listenerServiceFilter;
// BEGIN of old HttpService support
- private Map<HttpContext, HttpContextHelperFactory> httpContextHelperFactories =
- Collections.synchronizedMap(new HashMap<HttpContext, HttpContextHelperFactory>());
- private Map<Object, HttpServiceObjectRegistration> legacyMappings =
+ private final Map<Object, HttpServiceObjectRegistration> legacyMappings =
Collections.synchronizedMap(new HashMap<Object, HttpServiceObjectRegistration>());
- private Map<Bundle, Set<HttpServiceObjectRegistration>> bundleRegistrations =
+ private final Map<Bundle, Set<HttpServiceObjectRegistration>> bundleRegistrations =
new HashMap<Bundle, Set<HttpServiceObjectRegistration>>();
- private Map<Bundle, Map<String, String>> bundleAliasCustomizations = new HashMap<Bundle, Map<String,String>>();
+ private final Map<Bundle, Map<String, String>> bundleAliasCustomizations = new HashMap<Bundle, Map<String,String>>();
// END of old HttpService support
- private ConcurrentMap<ServiceReference<ServletContextHelper>, ContextController> controllerMap =
- new ConcurrentHashMap<ServiceReference<ServletContextHelper>, ContextController>();
+ private final ConcurrentMap<ServiceReference<ServletContextHelper>, ContextController> controllerMap =
+ new ConcurrentSkipListMap<ServiceReference<ServletContextHelper>, ContextController>(Collections.reverseOrder());
+ private final ConcurrentMap<ServiceReference<?>, FailedErrorPageDTO> failedErrorPageDTOs =
+ new ConcurrentHashMap<ServiceReference<?>, FailedErrorPageDTO>();
private final ConcurrentMap<ServiceReference<Filter>, FailedFilterDTO> failedFilterDTOs =
new ConcurrentHashMap<ServiceReference<Filter>, FailedFilterDTO>();
private final ConcurrentMap<ServiceReference<EventListener>, FailedListenerDTO> failedListenerDTOs =
new ConcurrentHashMap<ServiceReference<EventListener>, FailedListenerDTO>();
- private final ConcurrentMap<ServiceReference<Object>, FailedResourceDTO> failedResourceDTOs =
- new ConcurrentHashMap<ServiceReference<Object>, FailedResourceDTO>();
- private final ConcurrentMap<ServiceReference<ServletContextHelper>, FailedServletContextDTO> failedServletContextDTOs =
- new ConcurrentHashMap<ServiceReference<ServletContextHelper>, FailedServletContextDTO>();
- private final ConcurrentMap<ServiceReference<Servlet>, ExtendedFailedServletDTO> failedServletDTOs =
- new ConcurrentHashMap<ServiceReference<Servlet>, ExtendedFailedServletDTO>();
-
- private AtomicLong legacyIdGenerator = new AtomicLong(0);
+ private final ConcurrentMap<ServiceReference<?>, FailedResourceDTO> failedResourceDTOs =
+ new ConcurrentHashMap<ServiceReference<?>, FailedResourceDTO>();
+ private final ConcurrentMap<ServiceReference<ServletContextHelper>, ExtendedFailedServletContextDTO> failedServletContextDTOs =
+ new ConcurrentHashMap<ServiceReference<ServletContextHelper>, ExtendedFailedServletContextDTO>();
+ private final ConcurrentMap<ServiceReference<?>, ExtendedFailedServletDTO> failedServletDTOs =
+ new ConcurrentHashMap<ServiceReference<?>, ExtendedFailedServletDTO>();
- private Set<Object> registeredObjects = Collections.newSetFromMap(new ConcurrentHashMap<Object, Boolean>());
+ private final Set<Object> registeredObjects = Collections.newSetFromMap(new ConcurrentHashMap<Object, Boolean>());
private ServiceTracker<ServletContextHelper, AtomicReference<ContextController>> contextServiceTracker;
private ServiceTracker<ContextPathCustomizer, ContextPathCustomizer> contextPathAdaptorTracker;
@@ -1126,29 +1141,6 @@ public class HttpServiceRuntimeImpl
private HttpSessionTracker httpSessionTracker;
private final ServiceRegistration<HttpSessionInvalidator> invalidatorReg;
- static class DefaultServletContextHelperFactory implements ServiceFactory<ServletContextHelper> {
- @Override
- public ServletContextHelper getService(
- Bundle bundle,
- ServiceRegistration<ServletContextHelper> registration) {
- return new DefaultServletContextHelper(bundle);
- }
-
- @Override
- public void ungetService(
- Bundle bundle,
- ServiceRegistration<ServletContextHelper> registration,
- ServletContextHelper service) {
- // do nothing
- }
- }
-
- static class DefaultServletContextHelper extends ServletContextHelper {
- public DefaultServletContextHelper(Bundle b) {
- super(b);
- }
- }
-
static class LegacyServiceObject {
final AtomicReference<Exception> error = new AtomicReference<Exception>(new ServletException("The init() method was never called.")); //$NON-NLS-1$
public void checkForError() {
@@ -1333,4 +1325,16 @@ public class HttpServiceRuntimeImpl
}
}
+ public boolean failedResourceDTO(ServiceReference<?> serviceReference) {
+ return failedResourceDTOs.containsKey(serviceReference);
+ }
+
+ public boolean failedServletDTO(ServiceReference<?> serviceReference) {
+ return failedServletDTOs.containsKey(serviceReference);
+ }
+
+ public boolean failedErrorPageDTO(ServiceReference<?> serviceReference) {
+ return failedErrorPageDTOs.containsKey(serviceReference);
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java
index 6d87145aa..16f115b5f 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016 Raymond Augé and others.
+ * Copyright (c) 2016, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -21,12 +21,16 @@ import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
import javax.servlet.*;
import javax.servlet.Filter;
import javax.servlet.http.*;
+import org.eclipse.equinox.http.servlet.dto.ExtendedFailedServletDTO;
import org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO;
import org.eclipse.equinox.http.servlet.internal.HttpServiceRuntimeImpl;
import org.eclipse.equinox.http.servlet.internal.customizer.*;
+import org.eclipse.equinox.http.servlet.internal.dto.ExtendedErrorPageDTO;
+import org.eclipse.equinox.http.servlet.internal.dto.ExtendedErrorPageDTO.ErrorCodeType;
import org.eclipse.equinox.http.servlet.internal.error.*;
import org.eclipse.equinox.http.servlet.internal.registration.*;
import org.eclipse.equinox.http.servlet.internal.registration.FilterRegistration;
@@ -50,20 +54,28 @@ public class ContextController {
final Bundle bundle;
final long serviceId;
final int serviceRanking;
+ final ClassLoader legacyTCCL;
public ServiceHolder(ServiceObjects<S> serviceObjects) {
this.serviceObjects = serviceObjects;
this.bundle = serviceObjects.getServiceReference().getBundle();
this.service = serviceObjects.getService();
- this.serviceId = (Long) serviceObjects.getServiceReference().getProperty(Constants.SERVICE_ID);
+ this.legacyTCCL = (ClassLoader)serviceObjects.getServiceReference().getProperty(Const.EQUINOX_LEGACY_TCCL_PROP);
+ Long serviceIdProp = (Long)serviceObjects.getServiceReference().getProperty(Constants.SERVICE_ID);
+ if (legacyTCCL != null) {
+ // this is a legacy registration; use a negative id for the DTO
+ serviceIdProp = -serviceIdProp;
+ }
+ this.serviceId = serviceIdProp;
Integer rankProp = (Integer) serviceObjects.getServiceReference().getProperty(Constants.SERVICE_RANKING);
this.serviceRanking = rankProp == null ? 0 : rankProp.intValue();
}
- public ServiceHolder(S service, Bundle bundle, long serviceId, int serviceRanking) {
+ public ServiceHolder(S service, Bundle bundle, long serviceId, int serviceRanking, ClassLoader legacyTCCL) {
this.service = service;
this.bundle = bundle;
this.serviceObjects = null;
this.serviceId = serviceId;
this.serviceRanking = serviceRanking;
+ this.legacyTCCL = legacyTCCL;
}
public S get() {
return service;
@@ -72,6 +84,11 @@ public class ContextController {
public Bundle getBundle() {
return bundle;
}
+
+ public ClassLoader getLegacyTCCL() {
+ return legacyTCCL;
+ }
+
public void release() {
if (serviceObjects != null && service != null) {
try {
@@ -111,40 +128,21 @@ public class ContextController {
public ContextController(
BundleContext trackingContextParam, BundleContext consumingContext,
- ServiceReference<ServletContextHelper> servletContextHelperRef,
- ProxyContext proxyContext, HttpServiceRuntimeImpl httpServiceRuntime,
- String contextName, String contextPath, HttpSessionTracker httpSessionTracker) {
-
- validate(contextName, contextPath);
+ ServiceReference<ServletContextHelper> serviceReference,
+ ServletContext parentServletContext, HttpServiceRuntimeImpl httpServiceRuntime) {
- this.servletContextHelperRef = servletContextHelperRef;
-
- long serviceId = (Long)servletContextHelperRef.getProperty(Constants.SERVICE_ID);
-
- StringBuilder filterBuilder = new StringBuilder();
- filterBuilder.append('(');
- filterBuilder.append(Constants.SERVICE_ID);
- filterBuilder.append('=');
- filterBuilder.append(serviceId);
- filterBuilder.append(')');
- this.servletContextHelperRefFilter = filterBuilder.toString();
- this.proxyContext = proxyContext;
+ this.trackingContext = trackingContextParam;
+ this.consumingContext = consumingContext;
+ this.serviceReference = serviceReference;
this.httpServiceRuntime = httpServiceRuntime;
- this.contextName = contextName;
-
- if (contextPath.equals(Const.SLASH)) {
- contextPath = Const.BLANK;
- }
-
- this.contextPath = contextPath;
- this.contextServiceId = serviceId;
+ this.contextName = validateName();
+ this.contextPath = validatePath();
+ this.proxyContext = new ProxyContext(contextName, parentServletContext);
+ this.contextServiceId = (Long)serviceReference.getProperty(Constants.SERVICE_ID);
+ this.servletContextHelperRefFilter = createFilter(contextServiceId);
this.initParams = ServiceProperties.parseInitParams(
- servletContextHelperRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_INIT_PARAM_PREFIX, proxyContext.getServletContext());
-
- this.trackingContext = trackingContextParam;
- this.consumingContext = consumingContext;
- this.httpSessionTracker = httpSessionTracker;
+ serviceReference, HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_INIT_PARAM_PREFIX, parentServletContext);
listenerServiceTracker = new ServiceTracker<EventListener, AtomicReference<ListenerRegistration>>(
trackingContext, httpServiceRuntime.getListenerFilter(),
@@ -184,12 +182,13 @@ public class ContextController {
boolean addedRegisteredObject = false;
try {
if (filter == null) {
- throw new IllegalArgumentException("Filter cannot be null");
+ throw new IllegalArgumentException("Filter cannot be null"); //$NON-NLS-1$
}
addedRegisteredObject = httpServiceRuntime.getRegisteredObjects().add(filter);
- if (addedRegisteredObject) {
- registration = doAddFilterRegistration(filterHolder, filterRef);
+ if (!addedRegisteredObject) {
+ throw new HttpWhiteboardFailureException("Multiple registration of instance detected. Prototype scope is recommended: " + filterRef, DTOConstants.FAILURE_REASON_SERVICE_IN_USE); //$NON-NLS-1$
}
+ registration = doAddFilterRegistration(filterHolder, filterRef);
} finally {
if (registration == null) {
filterHolder.release();
@@ -203,21 +202,13 @@ public class ContextController {
private FilterRegistration doAddFilterRegistration(ServiceHolder<Filter> filterHolder, ServiceReference<Filter> filterRef) throws ServletException {
- ClassLoader legacyTCCL = (ClassLoader)filterRef.getProperty(Const.EQUINOX_LEGACY_TCCL_PROP);
boolean asyncSupported = ServiceProperties.parseBoolean(
filterRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_ASYNC_SUPPORTED);
List<String> dispatcherList = StringPlus.from(
filterRef.getProperty(
HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_DISPATCHER));
- String[] dispatchers = dispatcherList.toArray(
- new String[dispatcherList.size()]);
- Long serviceId = (Long)filterRef.getProperty(
- Constants.SERVICE_ID);
- if (legacyTCCL != null) {
- // this is a legacy registration; use a negative id for the DTO
- serviceId = -serviceId;
- }
+ String[] dispatchers = dispatcherList.toArray(new String[0]);
Integer filterPriority = (Integer)filterRef.getProperty(
Constants.SERVICE_RANKING);
if (filterPriority == null) {
@@ -228,15 +219,15 @@ public class ContextController {
List<String> patternList = StringPlus.from(
filterRef.getProperty(
HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN));
- String[] patterns = patternList.toArray(new String[patternList.size()]);
+ String[] patterns = patternList.toArray(new String[0]);
List<String> regexList = StringPlus.from(
filterRef.getProperty(
HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_REGEX));
- String[] regexs = regexList.toArray(new String[regexList.size()]);
+ String[] regexs = regexList.toArray(new String[0]);
List<String> servletList = StringPlus.from(
filterRef.getProperty(
HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_SERVLET));
- String[] servletNames = servletList.toArray(new String[servletList.size()]);
+ String[] servletNames = servletList.toArray(new String[0]);
String name = ServiceProperties.parseName(filterRef.getProperty(
HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_NAME), filterHolder.get());
@@ -247,8 +238,8 @@ public class ContextController {
((regexs == null) || (regexs.length == 0)) &&
((servletNames == null) || (servletNames.length == 0))) {
- throw new IllegalArgumentException(
- "Patterns, regex or servletNames must contain a value.");
+ throw new HttpWhiteboardFailureException(
+ "Patterns, regex or servletNames must contain a value.", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
}
if (patterns != null) {
@@ -257,8 +248,14 @@ public class ContextController {
}
}
+ if (regexs != null) {
+ for (String regex : regexs) {
+ checkRegex(regex);
+ }
+ }
+
if (filter == null) {
- throw new IllegalArgumentException("Filter cannot be null");
+ throw new HttpWhiteboardFailureException("Filter cannot be null", DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE); //$NON-NLS-1$
}
if (name == null) {
@@ -281,7 +278,7 @@ public class ContextController {
filterDTO.name = name;
filterDTO.patterns = sort(patterns);
filterDTO.regexs = regexs;
- filterDTO.serviceId = serviceId;
+ filterDTO.serviceId = filterHolder.serviceId;
filterDTO.servletContextId = contextServiceId;
filterDTO.servletNames = sort(servletNames);
@@ -291,7 +288,7 @@ public class ContextController {
ServletContext servletContext = createServletContext(
filterHolder.getBundle(), curServletContextHelper);
FilterRegistration newRegistration = new FilterRegistration(
- filterHolder, filterDTO, filterPriority, this, legacyTCCL);
+ filterHolder, filterDTO, filterPriority, this);
FilterConfig filterConfig = new FilterConfigImpl(
name, filterInitParams, servletContext);
@@ -310,7 +307,7 @@ public class ContextController {
ListenerRegistration registration = null;
try {
if (listener == null) {
- throw new IllegalArgumentException("EventListener cannot be null");
+ throw new IllegalArgumentException("EventListener cannot be null"); //$NON-NLS-1$
}
registration = doAddListenerRegistration(listenerHolder, listenerRef);
} finally {
@@ -325,25 +322,24 @@ public class ContextController {
ServiceHolder<EventListener> listenerHolder,
ServiceReference<EventListener> listenerRef) throws ServletException {
-
EventListener eventListener = listenerHolder.get();
List<Class<? extends EventListener>> classes = getListenerClasses(listenerRef);
if (classes.isEmpty()) {
throw new IllegalArgumentException(
- "EventListener does not implement a supported type.");
+ "EventListener does not implement a supported type."); //$NON-NLS-1$
}
for (ListenerRegistration listenerRegistration : listenerRegistrations) {
if (listenerRegistration.getT().equals(eventListener)) {
throw new ServletException(
- "EventListener has already been registered.");
+ "EventListener has already been registered."); //$NON-NLS-1$
}
}
ListenerDTO listenerDTO = new ListenerDTO();
- listenerDTO.serviceId = (Long) listenerRef.getProperty(Constants.SERVICE_ID);
+ listenerDTO.serviceId = listenerHolder.serviceId;
listenerDTO.servletContextId = contextServiceId;
listenerDTO.types = asStringArray(classes);
@@ -377,24 +373,29 @@ public class ContextController {
ClassLoader legacyTCCL = (ClassLoader)resourceRef.getProperty(Const.EQUINOX_LEGACY_TCCL_PROP);
Integer rankProp = (Integer) resourceRef.getProperty(Constants.SERVICE_RANKING);
int serviceRanking = rankProp == null ? 0 : rankProp.intValue();
- List<String> patternList = StringPlus.from(
- resourceRef.getProperty(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PATTERN));
- String[] patterns = patternList.toArray(new String[patternList.size()]);
+ Object patternObj = resourceRef.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PATTERN);
+ if (!(patternObj instanceof String) &&
+ !(patternObj instanceof String[]) &&
+ !(patternObj instanceof Collection)) {
+ throw new HttpWhiteboardFailureException("Expect pattern to be String+ (String | String[] | Collection<String>)", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
+ }
+ List<String> patternList = StringPlus.from(patternObj);
+ String[] patterns = patternList.toArray(new String[0]);
Long serviceId = (Long)resourceRef.getProperty(
Constants.SERVICE_ID);
if (legacyTCCL != null) {
// this is a legacy registration; use a negative id for the DTO
serviceId = -serviceId;
}
- String prefix = (String)resourceRef.getProperty(
+ Object prefixObj = resourceRef.getProperty(
HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PREFIX);
- checkPrefix(prefix);
+ checkPrefix(prefixObj);
+ String prefix = (String)prefixObj;
if ((patterns == null) || (patterns.length < 1)) {
throw new IllegalArgumentException(
- "Patterns must contain a value.");
+ "Patterns must contain a value."); //$NON-NLS-1$
}
for (String pattern : patterns) {
@@ -417,8 +418,8 @@ public class ContextController {
ServletContext servletContext = createServletContext(
bundle, curServletContextHelper);
ResourceRegistration resourceRegistration = new ResourceRegistration(
- new ServiceHolder<Servlet>(servlet, bundle, serviceId, serviceRanking),
- resourceDTO, curServletContextHelper, this, legacyTCCL);
+ resourceRef, new ServiceHolder<Servlet>(servlet, bundle, serviceId, serviceRanking, legacyTCCL),
+ resourceDTO, curServletContextHelper, this);
ServletConfig servletConfig = new ServletConfigImpl(
resourceRegistration.getName(), new HashMap<String, String>(),
servletContext);
@@ -432,13 +433,14 @@ public class ContextController {
return Throw.unchecked(t);
}
+ recordEndpointShadowing(resourceRegistration);
+
endpointRegistrations.add(resourceRegistration);
return resourceRegistration;
}
- public ServletRegistration addServletRegistration(ServiceReference<Servlet> servletRef) throws ServletException {
-
+ public ServletRegistration addServletRegistration(ServiceReference<Servlet> servletRef) {
checkShutdown();
ServiceHolder<Servlet> servletHolder = new ServiceHolder<Servlet>(consumingContext.getServiceObjects(servletRef));
@@ -447,12 +449,13 @@ public class ContextController {
boolean addedRegisteredObject = false;
try {
if (servlet == null) {
- throw new IllegalArgumentException("Servlet cannot be null");
+ throw new IllegalArgumentException("Servlet cannot be null"); //$NON-NLS-1$
}
addedRegisteredObject = httpServiceRuntime.getRegisteredObjects().add(servlet);
- if (addedRegisteredObject) {
- registration = doAddServletRegistration(servletHolder, servletRef);
+ if (!addedRegisteredObject) {
+ throw new HttpWhiteboardFailureException("Multiple registration of instance detected. Prototype scope is recommended: " + servletRef, DTOConstants.FAILURE_REASON_SERVICE_IN_USE); //$NON-NLS-1$
}
+ registration = doAddServletRegistration(servletHolder, servletRef);
} finally {
if (registration == null) {
// Always attempt to release here; even though destroy() may have been called
@@ -468,24 +471,17 @@ public class ContextController {
return registration;
}
- private ServletRegistration doAddServletRegistration(ServiceHolder<Servlet> servletHolder, ServiceReference<Servlet> servletRef) throws ServletException {
-
+ private ServletRegistration doAddServletRegistration(ServiceHolder<Servlet> servletHolder, ServiceReference<Servlet> servletRef) {
boolean asyncSupported = ServiceProperties.parseBoolean(
servletRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED);
- ClassLoader legacyTCCL = (ClassLoader)servletRef.getProperty(Const.EQUINOX_LEGACY_TCCL_PROP);
List<String> errorPageList = StringPlus.from(
servletRef.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE));
- String[] errorPages = errorPageList.toArray(new String[errorPageList.size()]);
+ String[] errorPages = errorPageList.toArray(new String[0]);
Map<String, String> servletInitParams = ServiceProperties.parseInitParams(
servletRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX);
List<String> patternList = StringPlus.from(
servletRef.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN));
- String[] patterns = patternList.toArray(new String[patternList.size()]);
- Long serviceId = (Long)servletRef.getProperty(Constants.SERVICE_ID);
- if (legacyTCCL != null) {
- // this is a legacy registration; use a negative id for the DTO
- serviceId = -serviceId;
- }
+ String[] patterns = patternList.toArray(new String[0]);
String servletNameFromProperties = (String)servletRef.getProperty(
HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME);
String generatedServletName = ServiceProperties.parseName(
@@ -535,14 +531,14 @@ public class ContextController {
servletDTO.multipartMaxRequestSize = (multipartMaxRequestSize != null ? multipartMaxRequestSize : -1L);
servletDTO.name = generatedServletName;
servletDTO.patterns = sort(patterns);
- servletDTO.serviceId = serviceId;
+ servletDTO.serviceId = servletHolder.serviceId;
servletDTO.servletContextId = contextServiceId;
servletDTO.servletInfo = servletHolder.get().getServletInfo();
- ErrorPageDTO errorPageDTO = null;
+ ExtendedErrorPageDTO errorPageDTO = null;
if ((errorPages != null) && (errorPages.length > 0)) {
- errorPageDTO = new ErrorPageDTO();
+ errorPageDTO = new ExtendedErrorPageDTO();
errorPageDTO.asyncSupported = asyncSupported;
List<String> exceptions = new ArrayList<String>();
@@ -553,16 +549,21 @@ public class ContextController {
for(String errorPage : errorPages) {
try {
if ("4xx".equals(errorPage)) { //$NON-NLS-1$
+ errorPageDTO.erroCodeType = ErrorCodeType.RANGE_4XX;
for (long code = 400; code < 500; code++) {
errorCodeSet.add(code);
}
} else if ("5xx".equals(errorPage)) { //$NON-NLS-1$
+ errorPageDTO.erroCodeType = ErrorCodeType.RANGE_5XX;
for (long code = 500; code < 600; code++) {
errorCodeSet.add(code);
}
- } else {
+ } else if (errorPage.length() == 3) {
+ errorPageDTO.erroCodeType = ErrorCodeType.SPECIFIC;
long code = Long.parseLong(errorPage);
errorCodeSet.add(code);
+ } else {
+ exceptions.add(errorPage);
}
}
catch (NumberFormatException nfe) {
@@ -577,10 +578,10 @@ public class ContextController {
i++;
}
errorPageDTO.errorCodes = errorCodes;
- errorPageDTO.exceptions = exceptions.toArray(new String[exceptions.size()]);
+ errorPageDTO.exceptions = exceptions.toArray(new String[0]);
errorPageDTO.initParams = servletInitParams;
errorPageDTO.name = generatedServletName;
- errorPageDTO.serviceId = serviceId;
+ errorPageDTO.serviceId = servletHolder.serviceId;
errorPageDTO.servletContextId = contextServiceId;
errorPageDTO.servletInfo = servletHolder.get().getServletInfo();
}
@@ -592,7 +593,7 @@ public class ContextController {
servletHolder.getBundle(), curServletContextHelper);
ServletRegistration servletRegistration = new ServletRegistration(
servletHolder, servletDTO, errorPageDTO, curServletContextHelper, this,
- servletContext, legacyTCCL);
+ servletContext);
ServletConfig servletConfig = new ServletConfigImpl(
generatedServletName, servletInitParams, servletContext);
@@ -605,11 +606,105 @@ public class ContextController {
return Throw.unchecked(t);
}
+ recordEndpointShadowing(servletRegistration);
+ recordErrorPageShadowing(servletRegistration, errorPageDTO);
+
endpointRegistrations.add(servletRegistration);
return servletRegistration;
}
+ private void recordEndpointShadowing(EndpointRegistration<?> newRegistration) {
+ Set<EndpointRegistration<?>> shadowedRegs = new HashSet<EndpointRegistration<?>>();
+ for (EndpointRegistration<?> existingRegistration : endpointRegistrations) {
+ for (String newPattern : newRegistration.getPatterns()) {
+ for (String existingPattern : existingRegistration.getPatterns()) {
+ if (newPattern.equals(existingPattern)) {
+ // the new reg is shadowing an existing reg
+ if (newRegistration.compareTo(existingRegistration) < 0) {
+ shadowedRegs.add(existingRegistration);
+ }
+ // the new reg is shadowed by existing reg
+ else {
+ shadowedRegs.add(newRegistration);
+ }
+ // notice that we keep checking all the existing regs. more than one could be shadowed because reg's multi patterns
+ }
+ }
+ }
+ }
+ for (EndpointRegistration<?> shadowedReg : shadowedRegs) {
+ if (shadowedReg instanceof ServletRegistration) {
+ recordFailedServletDTO(shadowedReg.getServiceReference(), (ExtendedServletDTO)shadowedReg.getD(), DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
+ }
+ else {
+ recordFailedResourceDTO(shadowedReg.getServiceReference(), (ResourceDTO)shadowedReg.getD(), DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
+ }
+ }
+ }
+
+ private void recordErrorPageShadowing(ServletRegistration servletRegistration, ExtendedErrorPageDTO newErrorPageDTO) {
+ if (newErrorPageDTO == null) {
+ return;
+ }
+ Set<ServletRegistration> shadowedEPs = new HashSet<ServletRegistration>();
+ for (EndpointRegistration<?> existingRegistration : endpointRegistrations) {
+ if (!(existingRegistration instanceof ServletRegistration)) {
+ continue;
+ }
+ ServletRegistration existingSRegistration = (ServletRegistration)existingRegistration;
+ ExtendedErrorPageDTO existingErrorPageDTO = existingSRegistration.getErrorPageDTO();
+ if ((existingErrorPageDTO == null) ||
+ (((existingErrorPageDTO.erroCodeType == ErrorCodeType.RANGE_4XX) || (existingErrorPageDTO.erroCodeType == ErrorCodeType.RANGE_5XX)) && (newErrorPageDTO.erroCodeType == ErrorCodeType.SPECIFIC))) {
+ continue;
+ }
+ if (((existingErrorPageDTO.erroCodeType == ErrorCodeType.RANGE_4XX) && (newErrorPageDTO.erroCodeType == ErrorCodeType.RANGE_4XX)) ||
+ ((existingErrorPageDTO.erroCodeType == ErrorCodeType.RANGE_5XX) && (newErrorPageDTO.erroCodeType == ErrorCodeType.RANGE_5XX))) {
+ if (servletRegistration.compareTo(existingSRegistration) < 0) {
+ shadowedEPs.add(existingSRegistration);
+ }
+ // the new reg is shadowed by existing reg
+ else {
+ shadowedEPs.add(servletRegistration);
+ }
+ continue;
+ }
+ for (long newErrorCode : newErrorPageDTO.errorCodes) {
+ for (long existingCode : existingErrorPageDTO.errorCodes) {
+ if (newErrorCode == existingCode) {
+ // the new reg is shadowing an existing reg
+ if (servletRegistration.compareTo(existingSRegistration) < 0) {
+ shadowedEPs.add(existingSRegistration);
+ }
+ // the new reg is shadowed by existing reg
+ else {
+ shadowedEPs.add(servletRegistration);
+ }
+ // notice that we keep checking all the existing regs. more than one could be shadowed because reg's multi patterns
+ }
+ }
+ }
+ for (String newException : newErrorPageDTO.exceptions) {
+ for (String existingException : existingErrorPageDTO.exceptions) {
+ if (newException.equals(existingException)) {
+ // the new reg is shadowing an existing reg
+ if (servletRegistration.compareTo(existingSRegistration) < 0) {
+ shadowedEPs.add(existingSRegistration);
+ }
+ // the new reg is shadowed by existing reg
+ else {
+ shadowedEPs.add(servletRegistration);
+ }
+ // notice that we keep checking all the existing regs. more than one could be shadowed because reg's multi patterns
+ }
+ }
+ }
+ }
+ for (ServletRegistration shadowedReg : shadowedEPs) {
+ recordFailedErrorPageDTO(shadowedReg.getServiceReference(), shadowedReg.getErrorPageDTO(), DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
+ }
+ }
+
public void destroy() {
flushActiveSessions();
resourceServiceTracker.close();
@@ -920,16 +1015,13 @@ public class ContextController {
targetFilter = FrameworkUtil.createFilter(contextSelector);
}
catch (InvalidSyntaxException ise) {
- throw new IllegalArgumentException(ise);
+ throw new HttpWhiteboardFailureException(ise.getMessage(), DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
}
return matches(targetFilter);
}
private boolean visibleContextHelper(ServiceReference<?> whiteBoardService) {
- if (consumingContext.getBundle().equals(servletContextHelperRef.getBundle())) {
- return true;
- }
try {
if (whiteBoardService.getBundle().getBundleContext().getAllServiceReferences(ServletContextHelper.class.getName(), servletContextHelperRefFilter) != null) {
return true;
@@ -942,7 +1034,7 @@ public class ContextController {
}
public boolean matches(org.osgi.framework.Filter targetFilter) {
- return targetFilter.match(servletContextHelperRef);
+ return targetFilter.match(serviceReference);
}
@Override
@@ -986,17 +1078,18 @@ public class ContextController {
return;
}
- FilterDTO[] filterDTOs =
- new FilterDTO[matchedFilterRegistrations.size()];
+ List<FilterDTO> filterDTOs = new ArrayList<FilterDTO>();
- for (int i = 0; i < filterDTOs.length ; i++) {
+ for (int i = 0; i < matchedFilterRegistrations.size() ; i++) {
FilterRegistration filterRegistration =
matchedFilterRegistrations.get(i);
- filterDTOs[i] = filterRegistration.getD();
+ if (Arrays.binarySearch(filterRegistration.getD().dispatcher, DispatcherType.REQUEST.toString()) > -1) {
+ filterDTOs.add(filterRegistration.getD());
+ }
}
- requestInfoDTO.filterDTOs = filterDTOs;
+ requestInfoDTO.filterDTOs = filterDTOs.toArray(new FilterDTO[0]);
}
private String[] asStringArray(
@@ -1023,8 +1116,8 @@ public class ContextController {
DispatcherType.valueOf(type);
}
catch (IllegalArgumentException iae) {
- throw new IllegalArgumentException(
- "Invalid dispatcher '" + type + "'", iae);
+ throw new HttpWhiteboardFailureException(
+ "Invalid dispatcher '" + type + "'", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$ //$NON-NLS-2$
}
}
@@ -1035,28 +1128,53 @@ public class ContextController {
public static void checkPattern(String pattern) {
if (pattern == null) {
- throw new IllegalArgumentException("Pattern cannot be null");
+ throw new HttpWhiteboardFailureException("Pattern cannot be null", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
}
if (pattern.indexOf("*.") == 0) { //$NON-NLS-1$
return;
}
+ if (Const.BLANK.equals(pattern)) {
+ return;
+ }
+
+ if (Const.SLASH.equals(pattern)) {
+ return;
+ }
+
if (!pattern.startsWith(Const.SLASH) ||
- (pattern.endsWith(Const.SLASH) && !pattern.equals(Const.SLASH))) {
+ (pattern.endsWith(Const.SLASH) && !pattern.equals(Const.SLASH)) ||
+ pattern.contains("**")) { //$NON-NLS-1$
- throw new IllegalArgumentException(
- "Invalid pattern '" + pattern + "'");
+ throw new HttpWhiteboardFailureException(
+ "Invalid pattern '" + pattern + "'", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$ //$NON-NLS-2$
}
}
- private void checkPrefix(String prefix) {
- if (prefix == null) {
- throw new IllegalArgumentException("Prefix cannot be null");
+ private static void checkPrefix(Object prefixObj) {
+ if (prefixObj == null) {
+ throw new HttpWhiteboardFailureException("Prefix cannot be null.", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
}
+ if (!(prefixObj instanceof String)) {
+ throw new HttpWhiteboardFailureException("Prefix must be String.", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
+ }
+
+ String prefix = (String)prefixObj;
+
if (prefix.endsWith(Const.SLASH) && !prefix.equals(Const.SLASH)) {
- throw new IllegalArgumentException("Invalid prefix '" + prefix + "'");
+ throw new HttpWhiteboardFailureException("Invalid prefix '" + prefix + "'", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ private static void checkRegex(String regex) {
+ try {
+ Pattern.compile(regex);
+ }
+ catch (PatternSyntaxException pse) {
+ throw new HttpWhiteboardFailureException(
+ "Invalid regex '" + regex + "'", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$ //$NON-NLS-2$
}
}
@@ -1067,6 +1185,16 @@ public class ContextController {
}
}
+ private static String createFilter(long contextServiceId) {
+ StringBuilder filterBuilder = new StringBuilder();
+ filterBuilder.append('(');
+ filterBuilder.append(Constants.SERVICE_ID);
+ filterBuilder.append('=');
+ filterBuilder.append(contextServiceId);
+ filterBuilder.append(')');
+ return filterBuilder.toString();
+ }
+
private ServletContext createServletContext(
Bundle curBundle, ServletContextHelper curServletContextHelper) {
@@ -1086,25 +1214,28 @@ public class ContextController {
for (EndpointRegistration<?> endpointRegistration : endpointRegistrations) {
if (endpointRegistration instanceof ResourceRegistration) {
- resourceDTOs.add(DTOUtil.clone((ResourceDTO)endpointRegistration.getD()));
+ if (!httpServiceRuntime.failedResourceDTO(endpointRegistration.getServiceReference())) {
+ resourceDTOs.add(DTOUtil.clone((ResourceDTO)endpointRegistration.getD()));
+ }
}
else {
ServletRegistration servletRegistration = (ServletRegistration)endpointRegistration;
- servletDTOs.add(DTOUtil.clone(servletRegistration.getD()));
+ if (!httpServiceRuntime.failedServletDTO(servletRegistration.getServiceReference())) {
+ servletDTOs.add(DTOUtil.clone(servletRegistration.getD()));
+ }
ErrorPageDTO errorPageDTO = servletRegistration.getErrorPageDTO();
- if (errorPageDTO != null) {
+ if ((errorPageDTO != null) &&
+ !httpServiceRuntime.failedErrorPageDTO(servletRegistration.getServiceReference())) {
+
errorPageDTOs.add(DTOUtil.clone(errorPageDTO));
}
}
}
- servletContextDTO.errorPageDTOs = errorPageDTOs.toArray(
- new ErrorPageDTO[errorPageDTOs.size()]);
- servletContextDTO.resourceDTOs = resourceDTOs.toArray(
- new ResourceDTO[resourceDTOs.size()]);
- servletContextDTO.servletDTOs = servletDTOs.toArray(
- new ServletDTO[servletDTOs.size()]);
+ servletContextDTO.errorPageDTOs = errorPageDTOs.toArray(new ErrorPageDTO[0]);
+ servletContextDTO.resourceDTOs = resourceDTOs.toArray(new ResourceDTO[0]);
+ servletContextDTO.servletDTOs = servletDTOs.toArray(new ServletDTO[0]);
}
private void collectFilterDTOs(
@@ -1116,8 +1247,7 @@ public class ContextController {
filterDTOs.add(DTOUtil.clone(filterRegistration.getD()));
}
- servletContextDTO.filterDTOs = filterDTOs.toArray(
- new FilterDTO[filterDTOs.size()]);
+ servletContextDTO.filterDTOs = filterDTOs.toArray(new FilterDTO[0]);
}
private void collectListenerDTOs(
@@ -1129,8 +1259,7 @@ public class ContextController {
listenerDTOs.add(DTOUtil.clone(listenerRegistration.getD()));
}
- servletContextDTO.listenerDTOs = listenerDTOs.toArray(
- new ListenerDTO[listenerDTOs.size()]);
+ servletContextDTO.listenerDTOs = listenerDTOs.toArray(new ListenerDTO[0]);
}
private Map<String, Object> getDTOAttributes(ServletContext servletContext) {
@@ -1148,9 +1277,9 @@ public class ContextController {
}
private List<Class<? extends EventListener>> getListenerClasses(
- ServiceReference<EventListener> serviceReference) {
+ ServiceReference<EventListener> listenerReference) {
- List<String> objectClassList = StringPlus.from(serviceReference.getProperty(Constants.OBJECTCLASS));
+ List<String> objectClassList = StringPlus.from(listenerReference.getProperty(Constants.OBJECTCLASS));
List<Class<? extends EventListener>> classes =
new ArrayList<Class<? extends EventListener>>();
@@ -1184,15 +1313,19 @@ public class ContextController {
return classes;
}
+ public ServiceReference<ServletContextHelper> getServiceReference() {
+ return serviceReference;
+ }
+
private ServletContextHelper getServletContextHelper(Bundle curBundle) {
BundleContext context = curBundle.getBundleContext();
- return context.getService(servletContextHelperRef);
+ return context.getService(serviceReference);
}
public void ungetServletContextHelper(Bundle curBundle) {
BundleContext context = curBundle.getBundleContext();
try {
- context.ungetService(servletContextHelperRef);
+ context.ungetService(serviceReference);
} catch (IllegalStateException e) {
// this can happen if the whiteboard bundle is in the process of stopping
// and the framework is in the middle of auto-unregistering any services
@@ -1233,7 +1366,7 @@ public class ContextController {
HttpSessionAdaptor httpSessionAdaptor = activeSessions.remove(sessionId);
if (httpSessionAdaptor != null) {
- httpSessionTracker.removeHttpSessionAdaptor(sessionId, httpSessionAdaptor);
+ httpServiceRuntime.getHttpSessionTracker().removeHttpSessionAdaptor(sessionId, httpSessionAdaptor);
}
}
@@ -1304,27 +1437,169 @@ public class ContextController {
return previousHttpSessionAdaptor;
}
- httpSessionTracker.addHttpSessionAdaptor(sessionId, httpSessionAdaptor);
+ httpServiceRuntime.getHttpSessionTracker().addHttpSessionAdaptor(sessionId, httpSessionAdaptor);
return null;
}
- private void validate(String preValidationContextName, String preValidationContextPath) {
- if (!contextNamePattern.matcher(preValidationContextName).matches()) {
+ public void recordFailedErrorPageDTO(
+ ServiceReference<?> servletReference, ExtendedErrorPageDTO errorPageDTO, int failureReason) {
+
+ FailedErrorPageDTO failedErrorPageDTO = new FailedErrorPageDTO();
+ failedErrorPageDTO.asyncSupported = errorPageDTO.asyncSupported;
+ failedErrorPageDTO.errorCodes = errorPageDTO.errorCodes;
+ failedErrorPageDTO.exceptions = errorPageDTO.exceptions;
+ failedErrorPageDTO.failureReason = failureReason;
+ failedErrorPageDTO.initParams = errorPageDTO.initParams;
+ failedErrorPageDTO.name = errorPageDTO.name;
+ failedErrorPageDTO.serviceId = errorPageDTO.serviceId;
+ failedErrorPageDTO.servletContextId = errorPageDTO.servletContextId;
+ failedErrorPageDTO.servletInfo = errorPageDTO.servletInfo;
+
+ getHttpServiceRuntime().recordFailedErrorPageDTO(servletReference, failedErrorPageDTO);
+ }
+
+ public void recordFailedResourceDTO(
+ ServiceReference<?> resourceReference, ResourceDTO resourceDTO, int failureReason) {
+
+ FailedResourceDTO failedResourceDTO = new FailedResourceDTO();
+ failedResourceDTO.failureReason = failureReason;
+ failedResourceDTO.patterns = resourceDTO.patterns;
+ failedResourceDTO.prefix = resourceDTO.prefix;
+ failedResourceDTO.serviceId = resourceDTO.serviceId;
+ failedResourceDTO.servletContextId = resourceDTO.servletContextId;
+
+ getHttpServiceRuntime().recordFailedResourceDTO(resourceReference, failedResourceDTO);
+ }
+
+ public void recordFailedServletDTO(
+ ServiceReference<?> servletReference, ExtendedServletDTO servletDTO, int failureReason) {
+
+ ExtendedFailedServletDTO failedServletDTO = new ExtendedFailedServletDTO();
+
+ if (servletDTO != null) {
+ failedServletDTO.asyncSupported = servletDTO.asyncSupported;
+ failedServletDTO.failureReason = failureReason;
+ failedServletDTO.initParams = servletDTO.initParams;
+ failedServletDTO.multipartEnabled = servletDTO.multipartEnabled;
+ failedServletDTO.multipartFileSizeThreshold = servletDTO.multipartFileSizeThreshold;
+ failedServletDTO.multipartLocation = servletDTO.multipartLocation;
+ failedServletDTO.multipartMaxFileSize = servletDTO.multipartMaxFileSize;
+ failedServletDTO.multipartMaxRequestSize = servletDTO.multipartMaxRequestSize;
+ failedServletDTO.name = servletDTO.name;
+ failedServletDTO.patterns = servletDTO.patterns;
+ failedServletDTO.serviceId = servletDTO.serviceId;
+ failedServletDTO.servletContextId = servletDTO.servletContextId;
+ failedServletDTO.servletInfo = servletDTO.servletInfo;
+ }
+ else {
+ failedServletDTO.asyncSupported = BooleanPlus.from(
+ servletReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED), false);
+ failedServletDTO.failureReason = failureReason;
+ failedServletDTO.initParams = ServiceProperties.parseInitParams(
+ servletReference, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX);
+ failedServletDTO.multipartEnabled = ServiceProperties.parseBoolean(
+ servletReference, Const.EQUINOX_HTTP_MULTIPART_ENABLED);
+ Integer multipartFileSizeThreshold = (Integer)servletReference.getProperty(
+ Const.EQUINOX_HTTP_MULTIPART_FILESIZETHRESHOLD);
+ if (multipartFileSizeThreshold != null) {
+ failedServletDTO.multipartFileSizeThreshold = multipartFileSizeThreshold;
+ }
+ failedServletDTO.multipartLocation = (String)servletReference.getProperty(
+ Const.EQUINOX_HTTP_MULTIPART_LOCATION);
+ Long multipartMaxFileSize = (Long)servletReference.getProperty(
+ Const.EQUINOX_HTTP_MULTIPART_MAXFILESIZE);
+ if (multipartMaxFileSize != null) {
+ failedServletDTO.multipartMaxFileSize = multipartMaxFileSize;
+ }
+ Long multipartMaxRequestSize = (Long)servletReference.getProperty(
+ Const.EQUINOX_HTTP_MULTIPART_MAXREQUESTSIZE);
+ if (multipartMaxRequestSize != null) {
+ failedServletDTO.multipartMaxRequestSize = multipartMaxRequestSize;
+ }
+ failedServletDTO.name = (String)servletReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME);
+ failedServletDTO.patterns = StringPlus.from(
+ servletReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN)).toArray(new String[0]);
+ failedServletDTO.serviceId = (Long)servletReference.getProperty(Constants.SERVICE_ID);
+ if (servletReference.getProperty(Const.EQUINOX_LEGACY_TCCL_PROP) != null) {
+ failedServletDTO.serviceId = -failedServletDTO.serviceId;
+ }
+ failedServletDTO.servletContextId = getServiceId();
+ failedServletDTO.servletInfo = Const.BLANK;
+ }
+
+ getHttpServiceRuntime().recordFailedServletDTO(servletReference, failedServletDTO);
+ }
+
+ private String validateName() {
+ Object contextNameObj = serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME);
+
+ if (contextNameObj == null) {
+ throw new IllegalContextNameException(
+ HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + " is null. Ignoring!", //$NON-NLS-1$
+ DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
+ }
+ else if (!(contextNameObj instanceof String)) {
+ throw new IllegalContextNameException(
+ HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + " is not String. Ignoring!", //$NON-NLS-1$
+ DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
+ }
+
+ String name = (String)contextNameObj;
+
+ if (!contextNamePattern.matcher(name).matches()) {
throw new IllegalContextNameException(
- "The context name '" + preValidationContextName + "' does not follow Bundle-SymbolicName syntax.", //$NON-NLS-1$ //$NON-NLS-2$
+ "The context name '" + name + "' does not follow Bundle-SymbolicName syntax.", //$NON-NLS-1$ //$NON-NLS-2$
DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
}
+ // Now check for naming conflicts
+ for (ContextController existingContext : httpServiceRuntime.getContextControllers()) {
+ if (name.equals(existingContext.getContextName())) {
+ if (serviceReference.compareTo(existingContext.serviceReference) < 0) {
+ throw new HttpWhiteboardFailureException("Context with same name exists. " + serviceReference, DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
+ }
+
+ httpServiceRuntime.recordFailedServletContextDTO(
+ existingContext.serviceReference, (Long)serviceReference.getProperty(Constants.SERVICE_ID), DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
+ }
+ }
+
+ return name;
+ }
+
+ private String validatePath() {
+ Object contextPathObj = serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH);
+
+ if (contextPathObj == null) {
+ throw new IllegalContextPathException(
+ HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + " is null. Ignoring!", //$NON-NLS-1$
+ DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
+ }
+ else if (!(contextPathObj instanceof String)) {
+ throw new IllegalContextPathException(
+ HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + " is not String. Ignoring!", //$NON-NLS-1$
+ DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
+ }
+
+ String path = (String)contextPathObj;
+
try {
@SuppressWarnings("unused")
- URI uri = new URI(Const.HTTP, Const.LOCALHOST, preValidationContextPath, null);
+ URI uri = new URI(Const.HTTP, Const.LOCALHOST, path, null);
}
catch (URISyntaxException use) {
throw new IllegalContextPathException(
- "The context path '" + preValidationContextPath + "' is not valid URI path syntax.", //$NON-NLS-1$ //$NON-NLS-2$
+ "The context path '" + path + "' is not valid URI path syntax.", //$NON-NLS-1$ //$NON-NLS-2$
DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
}
+
+ path = httpServiceRuntime.adaptContextPath(path, serviceReference);
+ if (path.equals(Const.SLASH)) {
+ path = Const.BLANK;
+ }
+
+ return path;
}
private static final String[] DISPATCHER =
@@ -1347,10 +1622,9 @@ public class ContextController {
private final ConcurrentMap<String, HttpSessionAdaptor> activeSessions = new ConcurrentHashMap<String, HttpSessionAdaptor>();
private final HttpServiceRuntimeImpl httpServiceRuntime;
- private final HttpSessionTracker httpSessionTracker;
private final Set<ListenerRegistration> listenerRegistrations = new HashSet<ListenerRegistration>();
private final ProxyContext proxyContext;
- private final ServiceReference<ServletContextHelper> servletContextHelperRef;
+ private final ServiceReference<ServletContextHelper> serviceReference;
private final String servletContextHelperRefFilter;
private boolean shutdown;
private String string;
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/HttpContextHelperFactory.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/HttpContextHelperFactory.java
deleted file mode 100644
index 396181039..000000000
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/HttpContextHelperFactory.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*******************************************************************************
- * Copyright (c) Nov 21, 2014 Liferay, Inc.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Liferay, Inc. - initial API and implementation and/or initial
- * documentation
- ******************************************************************************/
-
-package org.eclipse.equinox.http.servlet.internal.context;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.*;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReference;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.osgi.framework.*;
-import org.osgi.service.http.HttpContext;
-import org.osgi.service.http.context.ServletContextHelper;
-
-public class HttpContextHelperFactory
- implements ServiceFactory<ServletContextHelper> {
-
- final HttpContext httpContext;
- final AtomicReference<ServiceRegistration<ServletContextHelper>> registrationRef =
- new AtomicReference<ServiceRegistration<ServletContextHelper>>();
- final AtomicReference<String> filterRef = new AtomicReference<String>();
- final AtomicLong useCount = new AtomicLong(0);
-
- public HttpContextHelperFactory(HttpContext httpContext) {
- this.httpContext = httpContext;
- }
-
- @Override
- public ServletContextHelper getService(
- Bundle bundle, ServiceRegistration<ServletContextHelper> registration) {
- setRegistration(registration);
- return new HttpContextHelper(bundle);
- }
-
- @Override
- public void ungetService(
- Bundle bundle, ServiceRegistration<ServletContextHelper> registration,
- ServletContextHelper service) {
- // nothing to do
- }
-
- public void setRegistration(ServiceRegistration<ServletContextHelper> registration) {
- if (this.registrationRef.compareAndSet(null, registration)) {
- StringBuilder filterBuilder = new StringBuilder();
- filterBuilder.append('(');
- filterBuilder.append(Constants.SERVICE_ID);
- filterBuilder.append('=');
- filterBuilder.append(registration.getReference().getProperty(Constants.SERVICE_ID));
- filterBuilder.append(')');
- filterRef.compareAndSet(null, filterBuilder.toString());
- }
- }
-
- public ServiceReference<ServletContextHelper> getServiceReference() {
- ServiceRegistration<ServletContextHelper> reg = registrationRef.get();
- if (reg != null) {
- try {
- return reg.getReference();
- } catch (IllegalStateException e) {
- // do nothing
- }
- }
- return null;
- }
-
- public String getFilter() {
- return filterRef.get();
- }
-
-
- public long incrementUseCount() {
- return useCount.incrementAndGet();
- }
-
- public long decrementUseCount() {
- long result = useCount.decrementAndGet();
- if (result == 0) {
- ServiceRegistration<ServletContextHelper> registration = registrationRef.get();
- if (registration != null) {
- try {
- registration.unregister();
- } catch (IllegalStateException e) {
- // ignore; already unregistered
- }
- }
- }
- return result;
- }
-
- public Object getHttpContext() {
- return httpContext;
- }
-
- public class HttpContextHelper extends ServletContextHelper {
- private final Bundle bundle;
-
- public HttpContextHelper(Bundle bundle) {
- this.bundle = bundle;
- }
-
- @Override
- public boolean handleSecurity(
- HttpServletRequest request, HttpServletResponse response)
- throws IOException {
- return httpContext.handleSecurity(request, response);
- }
-
- @Override
- public URL getResource(String name) {
- return httpContext.getResource(name);
- }
-
- @Override
- public String getMimeType(String name) {
- return httpContext.getMimeType(name);
- }
-
- @Override
- public Set<String> getResourcePaths(String path) {
- if ((path == null) || (bundle == null)) {
- return null;
- }
-
- final Enumeration<URL> enumeration = bundle.findEntries(
- path, null, false);
-
- if (enumeration == null) {
- return null;
- }
-
- final Set<String> result = new HashSet<String>();
-
- while (enumeration.hasMoreElements()) {
- result.add(enumeration.nextElement().getPath());
- }
-
- return result;
- }
- }
-}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/WrappedHttpContext.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/WrappedHttpContext.java
new file mode 100644
index 000000000..51246f5b5
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/WrappedHttpContext.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) Jan. 27, 2019 Liferay, Inc.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Liferay, Inc. - initial API and implementation and/or initial
+ * documentation
+ ******************************************************************************/
+
+package org.eclipse.equinox.http.servlet.internal.context;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.eclipse.equinox.http.servlet.internal.DefaultServletContextHelper;
+import org.osgi.framework.Bundle;
+import org.osgi.service.http.HttpContext;
+
+public class WrappedHttpContext extends DefaultServletContextHelper {
+
+ private final HttpContext httpContext;
+ private final Bundle bundle;
+
+ public WrappedHttpContext(HttpContext httpContext, Bundle bundle) {
+ super(bundle);
+ this.httpContext = httpContext;
+ this.bundle = bundle;
+ }
+
+ @Override
+ public boolean handleSecurity(
+ HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ return httpContext.handleSecurity(request, response);
+ }
+
+ @Override
+ public URL getResource(String name) {
+ return httpContext.getResource(name);
+ }
+
+ @Override
+ public String getMimeType(String name) {
+ return httpContext.getMimeType(name);
+ }
+
+ @Override
+ public Set<String> getResourcePaths(String path) {
+ if ((path == null) || (bundle == null)) {
+ return null;
+ }
+
+ final Enumeration<URL> enumeration = bundle.findEntries(
+ path, null, false);
+
+ if (enumeration == null) {
+ return null;
+ }
+
+ final Set<String> result = new HashSet<String>();
+
+ while (enumeration.hasMoreElements()) {
+ result.add(enumeration.nextElement().getPath());
+ }
+
+ return result;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextFilterTrackerCustomizer.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextFilterTrackerCustomizer.java
index 61b72b3e4..ee9efa443 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextFilterTrackerCustomizer.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextFilterTrackerCustomizer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 Raymond Augé and others.
+ * Copyright (c) 2014, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -50,11 +50,21 @@ public class ContextFilterTrackerCustomizer
return result;
}
- if (!contextController.matches(serviceReference)) {
- return result;
- }
-
try {
+ if (!contextController.matches(serviceReference)) {
+ // Only the default context will perform the "does anyone match" checks.
+ if (httpServiceRuntime.isDefaultContext(contextController) &&
+ !httpServiceRuntime.matchesAnyContext(serviceReference)) {
+
+ throw new HttpWhiteboardFailureException(
+ "Doesn't match any contexts. " + serviceReference, DTOConstants.FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING); //$NON-NLS-1$
+ }
+
+ return result;
+ }
+
+ httpServiceRuntime.removeFailedFilterDTO(serviceReference);
+
result.set(contextController.addFilterRegistration(serviceReference));
}
catch (HttpWhiteboardFailureException hwfe) {
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextListenerTrackerCustomizer.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextListenerTrackerCustomizer.java
index 8a8f18ee3..bb6ad17ce 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextListenerTrackerCustomizer.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextListenerTrackerCustomizer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 Raymond Augé and others.
+ * Copyright (c) 2014, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -50,11 +50,21 @@ public class ContextListenerTrackerCustomizer
return result;
}
- if (!contextController.matches(serviceReference)) {
- return result;
- }
-
try {
+ if (!contextController.matches(serviceReference)) {
+ // Only the default context will perform the "does anyone match" checks.
+ if (httpServiceRuntime.isDefaultContext(contextController) &&
+ !httpServiceRuntime.matchesAnyContext(serviceReference)) {
+
+ throw new HttpWhiteboardFailureException(
+ "Doesn't match any contexts. " + serviceReference, DTOConstants.FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING); //$NON-NLS-1$
+ }
+
+ return result;
+ }
+
+ httpServiceRuntime.removeFailedListenerDTO(serviceReference);
+
String listener = (String)serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER);
if (Boolean.FALSE.toString().equalsIgnoreCase(listener)) {
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextResourceTrackerCustomizer.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextResourceTrackerCustomizer.java
index d7fa1e80b..61477208e 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextResourceTrackerCustomizer.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextResourceTrackerCustomizer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 Raymond Augé and others.
+ * Copyright (c) 2014, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -48,11 +48,21 @@ public class ContextResourceTrackerCustomizer
return result;
}
- if (!contextController.matches(serviceReference)) {
- return result;
- }
-
try {
+ if (!contextController.matches(serviceReference)) {
+ // Only the default context will perform the "does anyone match" checks.
+ if (httpServiceRuntime.isDefaultContext(contextController) &&
+ !httpServiceRuntime.matchesAnyContext(serviceReference)) {
+
+ throw new HttpWhiteboardFailureException(
+ "Doesn't match any contexts. " + serviceReference, DTOConstants.FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING); //$NON-NLS-1$
+ }
+
+ return result;
+ }
+
+ httpServiceRuntime.removeFailedResourceDTO(serviceReference);
+
result.set(contextController.addResourceRegistration(serviceReference));
}
catch (HttpWhiteboardFailureException hwfe) {
@@ -100,7 +110,7 @@ public class ContextResourceTrackerCustomizer
failedResourceDTO.failureReason = failureReason;
failedResourceDTO.patterns = StringPlus.from(
serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PATTERN)).toArray(new String[0]);
- failedResourceDTO.prefix = (String)serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PREFIX);
+ failedResourceDTO.prefix = String.valueOf(serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PREFIX));
failedResourceDTO.serviceId = (Long)serviceReference.getProperty(Constants.SERVICE_ID);
failedResourceDTO.servletContextId = contextController.getServiceId();
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextServletTrackerCustomizer.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextServletTrackerCustomizer.java
index b5fddfdb5..cf5044415 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextServletTrackerCustomizer.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextServletTrackerCustomizer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 Raymond Augé and others.
+ * Copyright (c) 2014, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -16,15 +16,13 @@ package org.eclipse.equinox.http.servlet.internal.customizer;
import java.util.concurrent.atomic.AtomicReference;
import javax.servlet.Servlet;
-import org.eclipse.equinox.http.servlet.dto.ExtendedFailedServletDTO;
import org.eclipse.equinox.http.servlet.internal.HttpServiceRuntimeImpl;
import org.eclipse.equinox.http.servlet.internal.context.ContextController;
import org.eclipse.equinox.http.servlet.internal.error.HttpWhiteboardFailureException;
import org.eclipse.equinox.http.servlet.internal.registration.ServletRegistration;
-import org.eclipse.equinox.http.servlet.internal.util.*;
-import org.osgi.framework.*;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
import org.osgi.service.http.runtime.dto.DTOConstants;
-import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
/**
* @author Raymond Augé
@@ -50,22 +48,32 @@ public class ContextServletTrackerCustomizer
return result;
}
- if (!contextController.matches(serviceReference)) {
- return result;
- }
-
try {
+ if (!contextController.matches(serviceReference)) {
+ // Only the default context will perform the "does anyone match" checks.
+ if (httpServiceRuntime.isDefaultContext(contextController) &&
+ !httpServiceRuntime.matchesAnyContext(serviceReference)) {
+
+ throw new HttpWhiteboardFailureException(
+ "Doesn't match any contexts. " + serviceReference, DTOConstants.FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING); //$NON-NLS-1$
+ }
+
+ return result;
+ }
+
+ httpServiceRuntime.removeFailedServletDTO(serviceReference);
+
result.set(contextController.addServletRegistration(serviceReference));
}
catch (HttpWhiteboardFailureException hwfe) {
httpServiceRuntime.log(hwfe.getMessage(), hwfe);
- recordFailedServletDTO(serviceReference, hwfe.getFailureReason());
+ contextController.recordFailedServletDTO(serviceReference, null, hwfe.getFailureReason());
}
catch (Throwable t) {
httpServiceRuntime.log(t.getMessage(), t);
- recordFailedServletDTO(serviceReference, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
+ contextController.recordFailedServletDTO(serviceReference, null, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
}
return result;
@@ -91,46 +99,8 @@ public class ContextServletTrackerCustomizer
registration.destroy();
}
- contextController.getHttpServiceRuntime().removeFailedServletDTOs(serviceReference);
- }
-
- private void recordFailedServletDTO(
- ServiceReference<Servlet> serviceReference, int failureReason) {
-
- ExtendedFailedServletDTO failedServletDTO = new ExtendedFailedServletDTO();
-
- failedServletDTO.asyncSupported = BooleanPlus.from(
- serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED), false);
- failedServletDTO.failureReason = failureReason;
- failedServletDTO.initParams = ServiceProperties.parseInitParams(
- serviceReference, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX);
- failedServletDTO.multipartEnabled = ServiceProperties.parseBoolean(
- serviceReference, Const.EQUINOX_HTTP_MULTIPART_ENABLED);
- Integer multipartFileSizeThreshold = (Integer)serviceReference.getProperty(
- Const.EQUINOX_HTTP_MULTIPART_FILESIZETHRESHOLD);
- if (multipartFileSizeThreshold != null) {
- failedServletDTO.multipartFileSizeThreshold = multipartFileSizeThreshold;
- }
- failedServletDTO.multipartLocation = (String)serviceReference.getProperty(
- Const.EQUINOX_HTTP_MULTIPART_LOCATION);
- Long multipartMaxFileSize = (Long)serviceReference.getProperty(
- Const.EQUINOX_HTTP_MULTIPART_MAXFILESIZE);
- if (multipartMaxFileSize != null) {
- failedServletDTO.multipartMaxFileSize = multipartMaxFileSize;
- }
- Long multipartMaxRequestSize = (Long)serviceReference.getProperty(
- Const.EQUINOX_HTTP_MULTIPART_MAXREQUESTSIZE);
- if (multipartMaxRequestSize != null) {
- failedServletDTO.multipartMaxRequestSize = multipartMaxRequestSize;
- }
- failedServletDTO.name = (String)serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME);
- failedServletDTO.patterns = StringPlus.from(
- serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN)).toArray(new String[0]);
- failedServletDTO.serviceId = (Long)serviceReference.getProperty(Constants.SERVICE_ID);
- failedServletDTO.servletContextId = contextController.getServiceId();
- failedServletDTO.servletInfo = Const.BLANK;
-
- contextController.getHttpServiceRuntime().recordFailedServletDTO(serviceReference, failedServletDTO);
+ contextController.getHttpServiceRuntime().removeFailedServletDTO(serviceReference);
+ contextController.getHttpServiceRuntime().removeFailedErrorPageDTO(serviceReference);
}
private ContextController contextController;
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/RegistrationServiceTrackerCustomizer.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/RegistrationServiceTrackerCustomizer.java
index 0ef3dd136..93954b73c 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/RegistrationServiceTrackerCustomizer.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/RegistrationServiceTrackerCustomizer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 Raymond Augé and others.
+ * Copyright (c) 2014, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/dto/ExtendedErrorPageDTO.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/dto/ExtendedErrorPageDTO.java
new file mode 100644
index 000000000..b6f4b31d9
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/dto/ExtendedErrorPageDTO.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) Jan. 28, 2019 Liferay, Inc.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Liferay, Inc. - initial API and implementation and/or initial
+ * documentation
+ ******************************************************************************/
+
+package org.eclipse.equinox.http.servlet.internal.dto;
+
+import org.osgi.service.http.runtime.dto.ErrorPageDTO;
+
+/**
+ * Internal Extended DTO model used for simplifying handling logic.
+ */
+public class ExtendedErrorPageDTO extends ErrorPageDTO {
+
+ public enum ErrorCodeType {
+ RANGE_4XX, RANGE_5XX, SPECIFIC
+ }
+
+ /**
+ * Indicates the type of error codes defined. This is calculated by the system.
+ */
+ public ErrorCodeType erroCodeType;
+}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/dto/ExtendedFailedServletContextDTO.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/dto/ExtendedFailedServletContextDTO.java
new file mode 100644
index 000000000..8db94fea6
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/dto/ExtendedFailedServletContextDTO.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) Jan. 29, 2019 Liferay, Inc.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Liferay, Inc. - initial API and implementation and/or initial
+ * documentation
+ ******************************************************************************/
+
+package org.eclipse.equinox.http.servlet.internal.dto;
+
+import org.osgi.service.http.runtime.dto.FailedServletContextDTO;
+
+/**
+ * Internal Extended DTO model used for simplifying handling logic.
+ */
+public class ExtendedFailedServletContextDTO extends FailedServletContextDTO {
+
+ /**
+ * Holds the serviceId of the service that shadowed this context.
+ */
+ public long shadowingServiceId;
+
+}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/RegisteredFilterException.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/RegisteredFilterException.java
index 949ca3da5..70e0e5c5c 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/RegisteredFilterException.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/RegisteredFilterException.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 Raymond Augé and others.
+ * Copyright (c) 2014, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -15,16 +15,16 @@
package org.eclipse.equinox.http.servlet.internal.error;
import javax.servlet.Filter;
-import javax.servlet.ServletException;
+import org.osgi.service.http.runtime.dto.DTOConstants;
/**
* @author Raymond Augé
*/
-public class RegisteredFilterException extends ServletException {
+public class RegisteredFilterException extends HttpWhiteboardFailureException {
private static final long serialVersionUID = 4321327145573490998L;
public RegisteredFilterException(Filter filter) {
- super("Filter has already been registered: " + filter);
+ super("Filter has already been registered: " + filter, DTOConstants.FAILURE_REASON_SERVICE_IN_USE); //$NON-NLS-1$
}
-} \ No newline at end of file
+}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/EndpointRegistration.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/EndpointRegistration.java
index d27fb8453..4f4bd27f4 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/EndpointRegistration.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/EndpointRegistration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014, 2015 Raymond Augé and others.
+ * Copyright (c) 2014, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -22,6 +22,7 @@ import org.eclipse.equinox.http.servlet.internal.context.ContextController;
import org.eclipse.equinox.http.servlet.internal.context.ContextController.ServiceHolder;
import org.eclipse.equinox.http.servlet.internal.servlet.Match;
import org.osgi.dto.DTO;
+import org.osgi.framework.ServiceReference;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.service.http.context.ServletContextHelper;
@@ -31,22 +32,22 @@ import org.osgi.service.http.context.ServletContextHelper;
public abstract class EndpointRegistration<D extends DTO>
extends MatchableRegistration<Servlet, D> implements Comparable<EndpointRegistration<?>>{
- private final ServiceHolder<Servlet> servletHolder;
+ protected final ServiceHolder<Servlet> servletHolder;
private final ServletContextHelper servletContextHelper; //The context used during the registration of the servlet
private final ContextController contextController;
private final ClassLoader classLoader;
public EndpointRegistration(
ServiceHolder<Servlet> servletHolder, D d, ServletContextHelper servletContextHelper,
- ContextController contextController, ClassLoader legacyTCCL) {
+ ContextController contextController) {
super(servletHolder.get(), d);
this.servletHolder = servletHolder;
this.servletContextHelper = servletContextHelper;
this.contextController = contextController;
- if (legacyTCCL != null) {
+ if (servletHolder.getLegacyTCCL() != null) {
// legacy registrations used the current TCCL at registration time
- classLoader = legacyTCCL;
+ classLoader = servletHolder.getLegacyTCCL();
} else {
classLoader = servletHolder.getBundle().adapt(BundleWiring.class).getClassLoader();
}
@@ -115,6 +116,8 @@ public abstract class EndpointRegistration<D extends DTO>
return servletContextHelper;
}
+ public abstract ServiceReference<?> getServiceReference();
+
@Override
public String match(
String name, String servletPath, String pathInfo, String extension,
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/FilterRegistration.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/FilterRegistration.java
index 669fb2f47..8cc36da4f 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/FilterRegistration.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/FilterRegistration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2016 IBM Corporation and others.
+ * Copyright (c) 2011, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -25,8 +25,6 @@ import org.eclipse.equinox.http.servlet.internal.context.ContextController.Servi
import org.eclipse.equinox.http.servlet.internal.servlet.FilterChainImpl;
import org.eclipse.equinox.http.servlet.internal.servlet.Match;
import org.eclipse.equinox.http.servlet.internal.util.Const;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.service.http.runtime.dto.FilterDTO;
@@ -45,35 +43,20 @@ public class FilterRegistration
public FilterRegistration(
ServiceHolder<Filter> filterHolder, FilterDTO filterDTO, int priority,
- ContextController contextController, ClassLoader legacyTCCL) {
+ ContextController contextController) {
super(filterHolder.get(), filterDTO);
this.filterHolder = filterHolder;
this.priority = priority;
this.contextController = contextController;
this.compiledRegexs = getCompiledRegex(filterDTO);
- if (legacyTCCL != null) {
+ if (filterHolder.getLegacyTCCL() != null) {
// legacy filter registrations used the current TCCL at registration time
- classLoader = legacyTCCL;
+ classLoader = filterHolder.getLegacyTCCL();
} else {
classLoader = filterHolder.getBundle().adapt(BundleWiring.class).getClassLoader();
}
- String legacyContextFilter = (String) filterHolder.getServiceReference().getProperty(Const.EQUINOX_LEGACY_CONTEXT_SELECT);
- if (legacyContextFilter != null) {
- // This is a legacy Filter registration.
- // This filter tells us the real context controller,
- // backed by an HttpContext that should be used to init/destroy this Filter
- org.osgi.framework.Filter f = null;
- try {
- f = FrameworkUtil.createFilter(legacyContextFilter);
- }
- catch (InvalidSyntaxException e) {
- // nothing
- }
- initDestoyWithContextController = f == null || contextController.matches(f);
- } else {
- initDestoyWithContextController = true;
- }
+ initDestoyWithContextController = true;
needDecode = MatchableRegistration.patternsRequireDecode(filterDTO.patterns);
}
@@ -243,23 +226,31 @@ public class FilterRegistration
pattern = pattern.substring(0, extensionMatchIndex + 2);
}
- // first try prefix path matching; taking into account wild cards if necessary
- if ((pattern.charAt(0) == '/')) {
- if (isPathWildcardMatch(pattern, path)) {
- if (extensionWithPrefixMatch != null) {
- return extensionWithPrefixMatch.equals(extension);
+ if (pattern.isEmpty() && Const.SLASH.equals(path)) {
+ return true;
+ }
+ else if (!pattern.isEmpty()) {
+ // first try prefix path matching; taking into account wild cards if necessary
+ if (pattern.charAt(0) == '/') {
+ if (isPathWildcardMatch(pattern, path)) {
+ if (extensionWithPrefixMatch != null) {
+ return extensionWithPrefixMatch.equals(extension);
+ }
+ // special case for context path
+ if (Const.SLASH.equals(path) && Const.SLASH_STAR.equals(pattern)) {
+ return false;
+ }
+ return true;
}
- return true;
+ return false;
}
- return false;
- }
- // next try extension matching if requested
- if (pattern.charAt(0) == '*') {
- return pattern.substring(2).equals(extension);
+ // next try extension matching if requested
+ if (pattern.charAt(0) == '*') {
+ return pattern.substring(2).equals(extension);
+ }
}
- // this is really an invalid case that should have gotten caught at registration time
return false;
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/MatchableRegistration.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/MatchableRegistration.java
index 296662d82..4fc27ff39 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/MatchableRegistration.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/MatchableRegistration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014, 2015 Raymond Augé and others.
+ * Copyright (c) 2014, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -70,12 +70,18 @@ public abstract class MatchableRegistration<T, D extends DTO>
if (match == Match.EXACT) {
return pattern.equals(servletPath);
}
+ if ((match == Match.CONTEXT_ROOT) && Const.BLANK.equals(pattern)) {
+ return Const.BLANK.equals(servletPath) && Const.SLASH.equals(pathInfo);
+ }
+ if ((match == Match.DEFAULT_SERVLET) && Const.SLASH.equals(pattern)) {
+ return !servletPath.isEmpty() && pathInfo == null;
+ }
if (pattern.indexOf(Const.SLASH_STAR_DOT) == 0) {
pattern = pattern.substring(1);
}
- if (pattern.charAt(0) == '/') {
+ if (!pattern.isEmpty() && pattern.charAt(0) == '/') {
if ((match == Match.DEFAULT_SERVLET) && (pattern.length() == 1)) {
return true;
}
@@ -117,4 +123,4 @@ public abstract class MatchableRegistration<T, D extends DTO>
}
return false;
}
-} \ No newline at end of file
+}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ResourceRegistration.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ResourceRegistration.java
index 2d84f1210..5a6e535e4 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ResourceRegistration.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ResourceRegistration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 Raymond Augé and others.
+ * Copyright (c) 2014, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -17,6 +17,7 @@ package org.eclipse.equinox.http.servlet.internal.registration;
import javax.servlet.Servlet;
import org.eclipse.equinox.http.servlet.internal.context.ContextController;
import org.eclipse.equinox.http.servlet.internal.context.ContextController.ServiceHolder;
+import org.osgi.framework.ServiceReference;
import org.osgi.service.http.context.ServletContextHelper;
import org.osgi.service.http.runtime.dto.ResourceDTO;
/**
@@ -25,12 +26,13 @@ import org.osgi.service.http.runtime.dto.ResourceDTO;
public class ResourceRegistration extends EndpointRegistration<ResourceDTO> {
public ResourceRegistration(
- ServiceHolder<Servlet> servletHolder, ResourceDTO resourceDTO,
+ ServiceReference<?> serviceReference, ServiceHolder<Servlet> servletHolder, ResourceDTO resourceDTO,
ServletContextHelper servletContextHelper,
- ContextController contextController, ClassLoader legacyTCCL) {
+ ContextController contextController) {
- super(servletHolder, resourceDTO, servletContextHelper, contextController, legacyTCCL);
+ super(servletHolder, resourceDTO, servletContextHelper, contextController);
+ this.serviceReference = serviceReference;
name = servletHolder.get().getClass().getName().concat("#").concat(getD().prefix); //$NON-NLS-1$
needDecode = MatchableRegistration.patternsRequireDecode(resourceDTO.patterns);
}
@@ -51,11 +53,17 @@ public class ResourceRegistration extends EndpointRegistration<ResourceDTO> {
}
@Override
+ public ServiceReference<?> getServiceReference() {
+ return serviceReference;
+ }
+
+ @Override
public boolean needDecode() {
return needDecode;
}
private final boolean needDecode;
private final String name;
+ private final ServiceReference<?> serviceReference;
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ServletRegistration.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ServletRegistration.java
index 49df3338b..9e61c8e9f 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ServletRegistration.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ServletRegistration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2016 Cognos Incorporated, IBM Corporation and others
+ * Copyright (c) 2005, 2019 Cognos Incorporated, IBM Corporation and others
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -23,11 +23,12 @@ import javax.servlet.http.Part;
import org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO;
import org.eclipse.equinox.http.servlet.internal.context.ContextController;
import org.eclipse.equinox.http.servlet.internal.context.ContextController.ServiceHolder;
+import org.eclipse.equinox.http.servlet.internal.dto.ExtendedErrorPageDTO;
import org.eclipse.equinox.http.servlet.internal.multipart.MultipartSupport;
import org.eclipse.equinox.http.servlet.internal.multipart.MultipartSupportFactory;
import org.eclipse.equinox.http.servlet.internal.servlet.Match;
+import org.osgi.framework.ServiceReference;
import org.osgi.service.http.context.ServletContextHelper;
-import org.osgi.service.http.runtime.dto.ErrorPageDTO;
//This class wraps the servlet object registered in the HttpService.registerServlet call, to manage the context classloader when handleRequests are being asked.
public class ServletRegistration extends EndpointRegistration<ExtendedServletDTO> {
@@ -51,11 +52,11 @@ public class ServletRegistration extends EndpointRegistration<ExtendedServletDTO
}
public ServletRegistration(
- ServiceHolder<Servlet> servletHolder, ExtendedServletDTO servletDTO, ErrorPageDTO errorPageDTO,
+ ServiceHolder<Servlet> servletHolder, ExtendedServletDTO servletDTO, ExtendedErrorPageDTO errorPageDTO,
ServletContextHelper servletContextHelper,
- ContextController contextController, ServletContext servletContext, ClassLoader legacyTCCL) {
+ ContextController contextController, ServletContext servletContext) {
- super(servletHolder, servletDTO, servletContextHelper, contextController, legacyTCCL);
+ super(servletHolder, servletDTO, servletContextHelper, contextController);
this.errorPageDTO = errorPageDTO;
@@ -72,7 +73,7 @@ public class ServletRegistration extends EndpointRegistration<ExtendedServletDTO
needDecode = MatchableRegistration.patternsRequireDecode(servletDTO.patterns);
}
- public ErrorPageDTO getErrorPageDTO() {
+ public ExtendedErrorPageDTO getErrorPageDTO() {
return errorPageDTO;
}
@@ -92,6 +93,11 @@ public class ServletRegistration extends EndpointRegistration<ExtendedServletDTO
}
@Override
+ public ServiceReference<?> getServiceReference() {
+ return servletHolder.getServiceReference();
+ }
+
+ @Override
public String match(
String name, String servletPath, String pathInfo, String extension,
Match match) {
@@ -126,6 +132,6 @@ public class ServletRegistration extends EndpointRegistration<ExtendedServletDTO
}
private final boolean needDecode;
- private final ErrorPageDTO errorPageDTO;
+ private final ExtendedErrorPageDTO errorPageDTO;
private final MultipartSupport multipartSupport;
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletRequestWrapperImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletRequestWrapperImpl.java
index bd5e63e1d..e7f5bc44a 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletRequestWrapperImpl.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletRequestWrapperImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2016 Cognos Incorporated, IBM Corporation and others.
+ * Copyright (c) 2005, 2019 Cognos Incorporated, IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -25,6 +25,7 @@ import javax.servlet.http.*;
import org.eclipse.equinox.http.servlet.internal.context.ContextController;
import org.eclipse.equinox.http.servlet.internal.context.DispatchTargets;
import org.eclipse.equinox.http.servlet.internal.registration.EndpointRegistration;
+import org.eclipse.equinox.http.servlet.internal.registration.ServletRegistration;
import org.eclipse.equinox.http.servlet.internal.util.Const;
import org.eclipse.equinox.http.servlet.internal.util.EventListeners;
import org.osgi.service.http.HttpContext;
@@ -443,6 +444,20 @@ public class HttpServletRequestWrapperImpl extends HttpServletRequestWrapper {
return new ArrayList<Part>(getParts0().values());
}
+ public AsyncContext startAsync() throws IllegalStateException {
+ EndpointRegistration<?> endpointRegistration = dispatchTargets.peek().getServletRegistration();
+
+ if (endpointRegistration instanceof ServletRegistration) {
+ ServletRegistration servletRegistration = (ServletRegistration)endpointRegistration;
+
+ if (servletRegistration.getD().asyncSupported) {
+ return request.startAsync();
+ }
+ }
+
+ throw new IllegalStateException("Async not supported by " + endpointRegistration); //$NON-NLS-1$
+ }
+
private Map<String, Part> getParts0() throws IOException, ServletException {
org.eclipse.equinox.http.servlet.internal.registration.ServletRegistration servletRegistration = getServletRegistration();
@@ -474,4 +489,4 @@ public class HttpServletRequestWrapperImpl extends HttpServletRequestWrapper {
return null;
}
-} \ No newline at end of file
+}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpSessionAdaptor.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpSessionAdaptor.java
index 2cfcd70ed..8bb8aebd1 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpSessionAdaptor.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpSessionAdaptor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2016 Cognos Incorporated, IBM Corporation and others.
+ * Copyright (c) 2005, 2019 Cognos Incorporated, IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -85,7 +85,7 @@ public class HttpSessionAdaptor implements HttpSession, Serializable {
/**@deprecated*/
public String[] getValueNames() {
Collection<String> result = getAttributeNames0();
- return result.toArray(new String[result.size()]);
+ return result.toArray(new String[0]);
}
public void invalidate() {
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/Match.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/Match.java
index 6d512d6d4..ab69bf783 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/Match.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/Match.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 Raymond Augé and others.
+ * Copyright (c) 2014, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -19,6 +19,6 @@ package org.eclipse.equinox.http.servlet.internal.servlet;
*/
public enum Match {
- EXACT, EXTENSION, REGEX, DEFAULT_SERVLET
+ EXACT, EXTENSION, REGEX, DEFAULT_SERVLET, CONTEXT_ROOT
-} \ No newline at end of file
+}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResponseStateHandler.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResponseStateHandler.java
index 7aa55ac08..c3f820753 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResponseStateHandler.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResponseStateHandler.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014, 2016 Raymond Augé and others.
+ * Copyright (c) 2014, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -24,6 +24,7 @@ import org.eclipse.equinox.http.servlet.internal.context.ContextController;
import org.eclipse.equinox.http.servlet.internal.context.DispatchTargets;
import org.eclipse.equinox.http.servlet.internal.registration.EndpointRegistration;
import org.eclipse.equinox.http.servlet.internal.registration.FilterRegistration;
+import org.eclipse.equinox.http.servlet.internal.util.HttpStatus;
/**
* @author Raymond Augé
@@ -84,7 +85,9 @@ public class ResponseStateHandler {
setException(e);
- if (dispatchTargets.getDispatcherType() != DispatcherType.REQUEST) {
+ if (dispatchTargets.getDispatcherType() != DispatcherType.ERROR &&
+ dispatchTargets.getDispatcherType() != DispatcherType.REQUEST) {
+
throwException(e);
}
}
@@ -95,6 +98,43 @@ public class ResponseStateHandler {
filterRegistration.removeReference();
}
+ if ((exception != null) && dispatchTargets.getDispatcherType() == DispatcherType.ERROR) {
+ // This was the error handler throwing an error.
+ // We have to handle this with a custom error page of our own.
+
+ PrintWriter writer = response.getWriter();
+
+ Integer status = (Integer)request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
+ String message = (String)request.getAttribute(RequestDispatcher.ERROR_MESSAGE);
+
+ if (message == null) {
+ message = exception.getMessage();
+ }
+
+ request.getServletContext().log(message, exception);
+
+ final HttpStatus httpStatus = HttpStatus.of(status);
+
+ writer.println("<!DOCTYPE html>"); //$NON-NLS-1$
+ writer.println("<html lang=\"en\"><head>"); //$NON-NLS-1$
+ writer.println("<meta charset=\"utf-8\" />"); //$NON-NLS-1$
+ writer.println("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />"); //$NON-NLS-1$
+ writer.println("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />"); //$NON-NLS-1$
+ writer.print("<title>"); //$NON-NLS-1$
+ writer.print(httpStatus.value());
+ writer.print(" - "); //$NON-NLS-1$
+ writer.print(httpStatus.description());
+ writer.println("</title></head>"); //$NON-NLS-1$
+ writer.print("<body><div><h1>"); //$NON-NLS-1$
+ writer.print(httpStatus.value());
+ writer.print(" <small>"); //$NON-NLS-1$
+ writer.print(httpStatus.description());
+ writer.println("</small></h1>"); //$NON-NLS-1$
+ writer.print("<p>"); //$NON-NLS-1$
+ writer.print(message);
+ writer.println("</p></div></body></html>"); //$NON-NLS-1$
+ }
+
if (dispatchTargets.getDispatcherType() == DispatcherType.FORWARD) {
response.flushBuffer();
@@ -171,11 +211,24 @@ public class ResponseStateHandler {
}
ContextController contextController = dispatchTargets.getContextController();
- Class<? extends Exception> clazz = exception.getClass();
- final String className = clazz.getName();
+ Class<?> clazz = exception.getClass();
+ final String originalClassName = clazz.getName();
+ String className = originalClassName;
+
+ DispatchTargets errorDispatchTargets;
+
+ do {
+ errorDispatchTargets = contextController.getDispatchTargets(
+ className, null, null, null, null, null, Match.EXACT, null);
- final DispatchTargets errorDispatchTargets = contextController.getDispatchTargets(
- className, null, null, null, null, null, Match.EXACT, null);
+ if (errorDispatchTargets != null) {
+ break;
+ }
+
+ clazz = clazz.getSuperclass();
+ className = clazz.getName();
+ }
+ while (Exception.class.isAssignableFrom(clazz));
if (errorDispatchTargets == null) {
throwException(exception);
@@ -196,7 +249,7 @@ public class ResponseStateHandler {
if (attributeName.equals(RequestDispatcher.ERROR_EXCEPTION)) {
return exception;
} else if (attributeName.equals(RequestDispatcher.ERROR_EXCEPTION_TYPE)) {
- return className;
+ return originalClassName;
} else if (attributeName.equals(RequestDispatcher.ERROR_MESSAGE)) {
return exception.getMessage();
} else if (attributeName.equals(RequestDispatcher.ERROR_REQUEST_URI)) {
@@ -340,4 +393,4 @@ public class ResponseStateHandler {
HttpServletRequest request;
HttpServletResponse response;
-} \ No newline at end of file
+}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java
index c71f0f806..2a725ff97 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014, 2016 Raymond Augé and others.
+ * Copyright (c) 2014, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -48,7 +48,6 @@ public class Const {
public static final String EQUINOX_HTTP_MULTIPART_MAXFILESIZE = "equinox.http.whiteboard.servlet.multipart.maxFileSize"; //$NON-NLS-1$
public static final String EQUINOX_HTTP_MULTIPART_MAXREQUESTSIZE = "equinox.http.whiteboard.servlet.multipart.maxRequestSize"; //$NON-NLS-1$
public static final String EQUINOX_LEGACY_TCCL_PROP = "equinox.legacy.tccl"; //$NON-NLS-1$
- public static final String EQUINOX_LEGACY_CONTEXT_SELECT = "equinox.context.select"; //$NON-NLS-1$
public static final String EQUINOX_LEGACY_CONTEXT_HELPER = "equinox.legacy.context.helper"; //$NON-NLS-1$
public static final String EQUINOX_LEGACY_HTTP_CONTEXT_INITIATING_ID = "equinox.legacy.http.context.initiating.id"; //$NON-NLS-1$
public static final String UTF8 = "UTF-8"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java
index d22f41344..59899f3fc 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015, 2016 Raymond Augé and others.
+ * Copyright (c) 2015, 2019 Raymond Augé and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -41,6 +41,22 @@ public class DTOUtil {
return clone;
}
+ public static FailedErrorPageDTO clone(FailedErrorPageDTO original) {
+ FailedErrorPageDTO clone = new FailedErrorPageDTO();
+
+ clone.asyncSupported = copy(original.asyncSupported);
+ clone.errorCodes = copy(original.errorCodes);
+ clone.exceptions = copy(original.exceptions);
+ clone.failureReason = copy(original.failureReason);
+ clone.initParams = copyStringMap(original.initParams);
+ clone.name = copy(original.name);
+ clone.serviceId = copy(original.serviceId);
+ clone.servletContextId = copy(original.servletContextId);
+ clone.servletInfo = copy(original.servletInfo);
+
+ return clone;
+ }
+
public static FailedFilterDTO clone(FailedFilterDTO original) {
FailedFilterDTO clone = new FailedFilterDTO();
@@ -177,7 +193,7 @@ public class DTOUtil {
private static long[] copy(long[] array) {
if (array == null) {
- return null;
+ return new long[0];
}
if (array.length == 0) {
return array;
@@ -188,7 +204,7 @@ public class DTOUtil {
private static String[] copy(String[] array) {
if (array == null) {
- return null;
+ return new String[0];
}
if (array.length == 0) {
return array;
@@ -223,14 +239,14 @@ public class DTOUtil {
}
private static Map<String, String> copyStringMap(Map<String, String> initParams) {
+ if (initParams == null) {
+ return Collections.emptyMap();
+ }
return new HashMap<String, String>(initParams);
}
public static <V> Map<String, Object> copyGenericMap(Map<String, V> value) {
- if (value == null) {
- return null;
- }
- if (value.isEmpty()) {
+ if ((value == null) || value.isEmpty()) {
return Collections.emptyMap();
}
HashMap<String, Object> result = new HashMap<String, Object>();
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/HttpStatus.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/HttpStatus.java
new file mode 100644
index 000000000..5db5d3e08
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/HttpStatus.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) Jan. 26, 2019 Liferay, Inc.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Liferay, Inc. - initial API and implementation and/or initial
+ * documentation
+ ******************************************************************************/
+
+package org.eclipse.equinox.http.servlet.internal.util;
+
+/**
+ * @author Raymond Augé
+ */
+public enum HttpStatus {
+
+ UNKNOWN_STATUS(-1, "Unknown Status", ""), //$NON-NLS-1$ //$NON-NLS-2$
+
+ CONTINUE(100, "Continue", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ SWITCHING_PROTOCOLS(101, "Switching Protocols", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ PROCESSING(102, "Processing", "RFC2518"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ EARLY_HINTS(103, "Early Hints", "RFC8297"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ OK(200, "OK", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ CREATED(201, "Created", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ ACCEPTED(202, "Accepted", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ NON_AUTHORITATIVE_INFORMATION(203, "Non Authoritative Information", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ NO_CONTENT(204, "No Content", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ RESET_CONTENT(205, "Reset Content", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ PARTIAL_CONTENT(206, "Partial Content", "RFC7233"), //$NON-NLS-1$ //$NON-NLS-2$
+ /** )*/
+ MULTI_STATUS(207, "Partial Update OK", "RFC4918"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ ALREADY_REPORTED(208, "Already Reported", "RFC5842"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ IM_USED(226, "IM Used", "RFC3229"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ MULTIPLE_CHOICES(300, "Multiple Choices", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ MOVED_PERMANENTLY(301, "Moved Permanently", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ MOVED_TEMPORARILY(302, "Found", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ SEE_OTHER(303, "See Other", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ NOT_MODIFIED(304, "Not Modified", "RFC7232"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ USE_PROXY(305, "Use Proxy", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ TEMPORARY_REDIRECT(307, "Temporary Redirect", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ PERMANENT_REDIRECT(308, "Permanent Redirect", "RFC7538"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ BAD_REQUEST(400, "Bad Request", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ UNAUTHORIZED(401, "Unauthorized", "RFC7235"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ PAYMENT_REQUIRED(402, "Payment Required", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ FORBIDDEN(403, "Forbidden", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ NOT_FOUND(404, "Not Found", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ METHOD_NOT_ALLOWED(405, "Method Not Allowed", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ NOT_ACCEPTABLE(406, "Not Acceptable", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ PROXY_AUTHENTICATION_REQUIRED(407, "Proxy Authentication Required", "RFC7235"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ REQUEST_TIMEOUT(408, "Request Timeout", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ CONFLICT(409, "Conflict", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ GONE(410, "Gone", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ LENGTH_REQUIRED(411, "Length Required", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ PRECONDITION_FAILED(412, "Precondition Failed", "RFC7232"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ PAYLOAD_TOO_LARGE(413, "Payload Too Large", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ URI_TOO_LONG(414, "URI Too Long", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ RANGE_NOT_SATISFIABLE(416, "Range Not Satisfiable", "RFC7233"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ EXPECTATION_FAILED(417, "Expectation Failed", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ MISDIRECTED_REQUEST(421, "Misdirected Request", "RFC7540"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ UNPROCESSABLE_ENTITY(422, "Unprocessable Entity", "RFC4918"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ LOCKED(423, "Locked", "RFC4918"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ FAILED_DEPENDENCY(424, "Failed Dependency", "RFC4918"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ PRECONDITION_REQUIRED(428, "Precondition Required", "RFC6585"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ TOO_MANY_REQUESTS(429, "Too Many Requests", "RFC6585"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ REQUEST_HEADER_FIELDS_TOO_LARGE(431, "Request Header Fields Too Large", "RFC6585"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ UNAVAILABLE_FOR_LEGAL_REASONS(451, "Unavailable For Legal Reasons", "RFC7725"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ INTERNAL_SERVER_ERROR(500, "Internal Server Error", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ NOT_IMPLEMENTED(501, "Not Implemented", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ BAD_GATEWAY(502, "Bad Gateway", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ SERVICE_UNAVAILABLE(503, "Service Unavailable", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ GATEWAY_TIMEOUT(504, "Gateway Timeout", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ HTTP_VERSION_NOT_SUPPORTED(505, "HTTP Version Not Supported", "RFC7231"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ VARIANT_ALSO_NEGOTIATES(506, "Variant Also Negotiates", "RFC2295"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ INSUFFICIENT_STORAGE(507, "Insufficient Storage", "RFC4918"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ LOOP_DETECTED(508, "Loop Detected", "RFC5842"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ NOT_EXTENDED(510, "Not Extended", "RFC2774"), //$NON-NLS-1$ //$NON-NLS-2$
+
+ NETWORK_AUTHENTICATION_REQUIRED(511, "Network Authentication Required", "RFC6585"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ private HttpStatus(int value, String description, String reference) {
+ this.value = value;
+ this.description = description;
+ this.reference = reference;
+ }
+
+ public String description() {
+ return description;
+ }
+
+ public String reference() {
+ return reference;
+ }
+
+ public int value() {
+ return value;
+ }
+
+ private final int value;
+ private final String description;
+ private final String reference;
+
+ public static HttpStatus of(int value) {
+ for (HttpStatus v : HttpStatus.values()) {
+ if (v.value == value) {
+ return v;
+ }
+ }
+ return UNKNOWN_STATUS;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/ServiceProperties.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/ServiceProperties.java
index bca5f1031..7ef15ed07 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/ServiceProperties.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/ServiceProperties.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014, 2015 Liferay, Inc.
+ * Copyright (c) 2014, 2019 Liferay, Inc.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -50,9 +50,11 @@ public class ServiceProperties {
}
for (String key : serviceReference.getPropertyKeys()) {
if (key.startsWith(prefix)) {
+ Object value = serviceReference.getProperty(key);
+ if (value instanceof String) {
initParams.put(
- key.substring(prefix.length()),
- String.valueOf(serviceReference.getProperty(key)));
+ key.substring(prefix.length()), (String)value);
+ }
}
}

Back to the top