Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox')
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedFailedServletDTO.java28
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedServletDTO.java30
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/Activator.java20
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceImpl.java56
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceObjectRegistration.java5
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java400
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/PreprocessorCustomizer.java170
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java486
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/DispatchTargets.java40
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/HttpContextHolder.java75
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ProxyContext.java2
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ServiceHolder.java110
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextErrorPageTrackerCustomizer.java112
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextFilterTrackerCustomizer.java39
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextListenerTrackerCustomizer.java39
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextResourceTrackerCustomizer.java53
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextServletTrackerCustomizer.java55
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/RegistrationServiceTrackerCustomizer.java48
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/dto/ExtendedErrorPageDTO.java2
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/NullServletContextHelperException.java2
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/PatternInUseException.java2
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/RegisteredServletContextHelperException.java2
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/ServletAlreadyRegisteredException.java2
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactory.java6
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactoryImpl.java6
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportImpl.java8
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/EndpointRegistration.java16
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ErrorPageRegistration.java92
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/FilterRegistration.java6
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ListenerRegistration.java21
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/PreprocessorRegistration.java104
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ResourceRegistration.java2
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ServletRegistration.java39
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/FilterChainImpl.java11
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletResponseWrapperImpl.java10
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/IncludeDispatchResponseWrapper.java1
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/Match.java2
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/PreprocessorChainImpl.java58
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java50
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResourceServlet.java18
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResponseStateHandler.java35
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ServletContextAdaptor.java4
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java278
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/EventListeners.java6
-rw-r--r--bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/HttpTuple.java1
45 files changed, 1753 insertions, 799 deletions
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedFailedServletDTO.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedFailedServletDTO.java
index e68aaad65..99aba1f1b 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedFailedServletDTO.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedFailedServletDTO.java
@@ -20,31 +20,7 @@ import org.osgi.service.http.runtime.dto.FailedServletDTO;
* This type may become irrelevant if the properties appear as part of a
* future OSGi Http Whiteboard specification.
*/
+@Deprecated
public class ExtendedFailedServletDTO extends FailedServletDTO {
-
- /**
- * Specifies whether multipart support is enabled.
- */
- public boolean multipartEnabled;
-
- /**
- * Specifies the size threshold after which the file will be written to disk.
- */
- public int multipartFileSizeThreshold;
-
- /**
- * Specifies the location where the files can be stored on disk.
- */
- public String multipartLocation;
-
- /**
- * Specifies the maximum size of a file being uploaded.
- */
- public long multipartMaxFileSize;
-
- /**
- * Specifies the maximum request size.
- */
- public long multipartMaxRequestSize;
-
+ // ignore
} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedServletDTO.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedServletDTO.java
index 5a509a99e..e1fd833f9 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedServletDTO.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/dto/ExtendedServletDTO.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016 Raymond Augé.
+ * Copyright (c) 2016, 2019 Raymond Augé.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -20,31 +20,7 @@ import org.osgi.service.http.runtime.dto.ServletDTO;
* This type may become irrelevant if the properties appear as part of a
* future OSGi Http Whiteboard specification.
*/
+@Deprecated
public class ExtendedServletDTO extends ServletDTO {
-
- /**
- * Specifies whether multipart support is enabled.
- */
- public boolean multipartEnabled;
-
- /**
- * Specifies the size threshold after which the file will be written to disk.
- */
- public int multipartFileSizeThreshold;
-
- /**
- * Specifies the location where the files can be stored on disk.
- */
- public String multipartLocation;
-
- /**
- * Specifies the maximum size of a file being uploaded.
- */
- public long multipartMaxFileSize;
-
- /**
- * Specifies the maximum request size.
- */
- public long multipartMaxRequestSize;
-
+ // deprecated
} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/Activator.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/Activator.java
index 02eba5344..b96d57927 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/Activator.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/Activator.java
@@ -167,21 +167,25 @@ public class Activator
BundleContext trackingContext = useSystemContext ? context.getBundle(Constants.SYSTEM_BUNDLE_LOCATION).getBundleContext() : context;
HttpServiceRuntimeImpl httpServiceRuntime = new HttpServiceRuntimeImpl(
trackingContext, context, servletContext, serviceProperties);
+ httpServiceRuntime.open();
proxyServlet.setHttpServiceRuntimeImpl(httpServiceRuntime);
// imperative API support;
// the http service must be registered first so we can get its service id
- HttpServiceFactory httpServiceFactory = new HttpServiceFactory(
- httpServiceRuntime);
+ HttpServiceFactory httpServiceFactory = new HttpServiceFactory(httpServiceRuntime);
ServiceRegistration<?> hsfRegistration = context.registerService(
HTTP_SERVICES_CLASSES, httpServiceFactory, serviceProperties);
serviceProperties.put(HttpServiceRuntimeConstants.HTTP_SERVICE_ID, Collections.singletonList(hsfRegistration.getReference().getProperty(Constants.SERVICE_ID)));
+
ServiceRegistration<HttpServiceRuntime> hsrRegistration =
context.registerService(
HttpServiceRuntime.class, httpServiceRuntime,
serviceProperties);
+
+ httpServiceRuntime.setHsrRegistration(hsrRegistration);
+
return new HttpTuple(
proxyServlet, httpServiceFactory, hsfRegistration,
httpServiceRuntime, hsrRegistration);
@@ -243,18 +247,6 @@ public class Activator
}
}
- int majorVersion = servletContext.getMajorVersion();
-
- if (majorVersion < 3) {
- servletContext.log(
- "The http container does not support servlet 3.0+. " +
- "Therefore, the value of " +
- HttpServiceRuntimeConstants.HTTP_SERVICE_ENDPOINT +
- " cannot be calculated.");
-
- return new String[0];
- }
-
contextPath = servletContext.getContextPath();
ServletRegistration servletRegistration = null;
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 296235d45..8b023bd06 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
@@ -16,23 +16,22 @@
package org.eclipse.equinox.http.servlet.internal;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.*;
+
import java.security.*;
import java.util.Dictionary;
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 javax.servlet.*;
import org.eclipse.equinox.http.servlet.ExtendedHttpService;
+import org.eclipse.equinox.http.servlet.internal.context.HttpContextHolder;
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.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceRegistration;
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 {
@@ -42,15 +41,11 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService {
final HttpServiceRuntimeImpl httpServiceRuntime;
private volatile boolean shutdown = false; // We prevent use of this instance if HttpServiceFactory.ungetService has called unregisterAliases.
- 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);
}
/**
@@ -59,9 +54,10 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService {
public synchronized HttpContext createDefaultHttpContext() {
checkShutdown();
- DefaultServletContextHelper defaultServletContextHelper = bundle.getBundleContext().getService(defaultHttpContextReference);
-
- contextMap.putIfAbsent(defaultServletContextHelper, defaultHttpContextReference);
+ DefaultServletContextHelper defaultServletContextHelper = bundle.getBundleContext().getService(httpServiceRuntime.defaultContextReg.getReference());
+ HttpContextHolder httpContextHolder = new HttpContextHolder(defaultServletContextHelper, httpServiceRuntime.defaultContextReg);
+ httpContextHolder.incrementUseCount();
+ httpServiceRuntime.legacyContextMap.putIfAbsent(defaultServletContextHelper, httpContextHolder);
return defaultServletContextHelper;
}
@@ -78,12 +74,12 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService {
checkShutdown();
httpContext = httpContext == null ? createDefaultHttpContext() : registerContext(httpContext);
- final ServiceReference<DefaultServletContextHelper> serviceReference = contextMap.get(httpContext);
+ final HttpContextHolder httpContextHolder = httpServiceRuntime.legacyContextMap.get(httpContext);
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
@Override
- public Void run() throws ServletException {
- httpServiceRuntime.registerHttpServiceFilter(bundle, alias, filter, initparams, serviceReference);
+ public Void run() {
+ httpServiceRuntime.registerHttpServiceFilter(bundle, alias, filter, initparams, httpContextHolder);
return null;
}
});
@@ -104,12 +100,12 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService {
checkShutdown();
httpContext = httpContext == null ? createDefaultHttpContext() : registerContext(httpContext);
- final ServiceReference<DefaultServletContextHelper> serviceReference = contextMap.get(httpContext);
+ final HttpContextHolder httpContextHolder = httpServiceRuntime.legacyContextMap.get(httpContext);
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws NamespaceException {
- httpServiceRuntime.registerHttpServiceResources(bundle, alias, name, serviceReference);
+ httpServiceRuntime.registerHttpServiceResources(bundle, alias, name, httpContextHolder);
return null;
}
});
@@ -126,17 +122,17 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService {
*/
public synchronized void registerServlet(
final String alias, final Servlet servlet,
- final Dictionary initparams, HttpContext httpContext)
+ final Dictionary<?, ?> initparams, HttpContext httpContext)
throws ServletException, NamespaceException {
checkShutdown();
httpContext = httpContext == null ? createDefaultHttpContext() : registerContext(httpContext);
- final ServiceReference<DefaultServletContextHelper> serviceReference = contextMap.get(httpContext);
+ final HttpContextHolder httpContextHolder = httpServiceRuntime.legacyContextMap.get(httpContext);
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws NamespaceException, ServletException {
- httpServiceRuntime.registerHttpServiceServlet(bundle, alias, servlet, initparams, serviceReference);
+ httpServiceRuntime.registerHttpServiceServlet(bundle, alias, servlet, initparams, httpContextHolder);
return null;
}
});
@@ -182,20 +178,24 @@ public class HttpServiceImpl implements HttpService, ExtendedHttpService {
}
private HttpContext registerContext(HttpContext httpContext) {
- ServiceReference<? extends HttpContext> serviceReference = contextMap.get(httpContext);
+ HttpContextHolder httpContextHolder = httpServiceRuntime.legacyContextMap.get(httpContext);
- if (serviceReference == null) {
+ if (httpContextHolder == null) {
+ String legacyId = httpContext.getClass().getName().replaceAll("[^a-zA-Z_0-9\\-]", "_") + "-" + generateLegacyId(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
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(HTTP_WHITEBOARD_CONTEXT_NAME, legacyId);
+ props.put(HTTP_WHITEBOARD_CONTEXT_PATH, "/"); //$NON-NLS-1$
+ props.put(HTTP_WHITEBOARD_TARGET, httpServiceRuntime.getTargetFilter());
+ props.put(HTTP_SERVICE_CONTEXT_PROPERTY, legacyId);
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);
+ httpContextHolder = new HttpContextHolder(httpContext, registration);
+ httpContextHolder.incrementUseCount();
- contextMap.put(httpContext, registration.getReference());
+ httpServiceRuntime.legacyContextMap.put(httpContext, httpContextHolder);
}
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 c78adbfc9..7a56eadb6 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
@@ -15,18 +15,21 @@
package org.eclipse.equinox.http.servlet.internal;
+import org.eclipse.equinox.http.servlet.internal.context.HttpContextHolder;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceRegistration;
public class HttpServiceObjectRegistration {
public final Object serviceKey;
public final ServiceRegistration<?> registration;
+ public final HttpContextHolder httpContextHolder;
public final Bundle bundle;
public HttpServiceObjectRegistration(
Object serviceKey, ServiceRegistration<?> registration,
- Bundle bundle) {
+ HttpContextHolder httpContextHolder, Bundle bundle) {
this.serviceKey = serviceKey;
this.registration = registration;
+ this.httpContextHolder = httpContextHolder;
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 a69f1117a..cc3fcae95 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
@@ -14,34 +14,36 @@
package org.eclipse.equinox.http.servlet.internal;
+import static org.osgi.service.http.runtime.HttpServiceRuntimeConstants.HTTP_SERVICE_ENDPOINT;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.*;
+
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import javax.servlet.*;
import javax.servlet.Filter;
-import javax.servlet.http.HttpSessionAttributeListener;
-import javax.servlet.http.HttpSessionListener;
+import javax.servlet.http.*;
import org.eclipse.equinox.http.servlet.context.ContextPathCustomizer;
-import org.eclipse.equinox.http.servlet.dto.ExtendedFailedServletDTO;
-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.context.*;
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.registration.PreprocessorRegistration;
import org.eclipse.equinox.http.servlet.internal.servlet.HttpSessionTracker;
import org.eclipse.equinox.http.servlet.internal.servlet.Match;
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;
-import org.osgi.service.http.runtime.HttpServiceRuntimeConstants;
import org.osgi.service.http.runtime.dto.*;
-import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
+import org.osgi.service.http.whiteboard.Preprocessor;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
@@ -53,6 +55,7 @@ public class HttpServiceRuntimeImpl
HttpServiceRuntime,
ServiceTrackerCustomizer<ServletContextHelper, AtomicReference<ContextController>> {
+ @SuppressWarnings("unchecked")
public HttpServiceRuntimeImpl(
BundleContext trackingContext, BundleContext consumingContext,
ServletContext parentServletContext, Dictionary<String, Object> attributes) {
@@ -60,10 +63,11 @@ public class HttpServiceRuntimeImpl
this.trackingContext = trackingContext;
this.consumingContext = consumingContext;
+ this.errorPageServiceFilter = createErrorPageFilter(consumingContext);
this.servletServiceFilter = createServletFilter(consumingContext);
this.resourceServiceFilter = createResourceFilter(consumingContext);
this.filterServiceFilter = createFilterFilter(consumingContext);
- this.listenerServiceFilter = createListenerFilter(consumingContext, parentServletContext);
+ this.listenerServiceFilter = createListenerFilter(consumingContext);
this.parentServletContext = parentServletContext;
this.attributes = new UMDictionaryMap<String, Object>(attributes);
@@ -75,22 +79,30 @@ public class HttpServiceRuntimeImpl
new ServiceTracker<ServletContextHelper, AtomicReference<ContextController>>(
trackingContext, ServletContextHelper.class, this);
+ preprocessorServiceTracker =
+ new ServiceTracker<Preprocessor, AtomicReference<PreprocessorRegistration>>(
+ trackingContext, Preprocessor.class, new PreprocessorCustomizer(this));
+
contextPathCustomizerHolder = new ContextPathCustomizerHolder(consumingContext, contextServiceTracker);
contextPathAdaptorTracker = new ServiceTracker<ContextPathCustomizer, ContextPathCustomizer>(
consumingContext, ContextPathCustomizer.class, contextPathCustomizerHolder);
- contextPathAdaptorTracker.open();
-
- contextServiceTracker.open();
Hashtable<String, Object> defaultContextProps = new Hashtable<String, Object>();
- defaultContextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, HttpWhiteboardConstants.HTTP_WHITEBOARD_DEFAULT_CONTEXT_NAME);
+ defaultContextProps.put(HTTP_WHITEBOARD_CONTEXT_NAME, HTTP_WHITEBOARD_DEFAULT_CONTEXT_NAME);
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(
+ defaultContextProps.put(HTTP_WHITEBOARD_CONTEXT_PATH, Const.SLASH);
+ defaultContextProps.put(HTTP_WHITEBOARD_TARGET, this.targetFilter);
+ defaultContextProps.put(HTTP_SERVICE_CONTEXT_PROPERTY, HTTP_WHITEBOARD_DEFAULT_CONTEXT_NAME);
+ defaultContextReg = (ServiceRegistration<DefaultServletContextHelper>) consumingContext.registerService(
new String [] {ServletContextHelper.class.getName(), DefaultServletContextHelper.class.getName()}, new DefaultServletContextHelperFactory(), defaultContextProps);
}
+ public synchronized void open() {
+ contextPathAdaptorTracker.open();
+ contextServiceTracker.open();
+ preprocessorServiceTracker.open();
+ }
+
@Override
public synchronized AtomicReference<ContextController> addingService(
ServiceReference<ServletContextHelper> serviceReference) {
@@ -118,6 +130,9 @@ public class HttpServiceRuntimeImpl
recordFailedServletContextDTO(serviceReference, 0, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
}
+ finally {
+ incrementServiceChangecount();
+ }
return result;
}
@@ -140,6 +155,10 @@ public class HttpServiceRuntimeImpl
return contextPath;
}
+ public BundleContext getConsumingContext() {
+ return consumingContext;
+ }
+
public String getDefaultContextSelectFilter(ServiceReference<?> httpWhiteBoardService) {
ContextPathCustomizer pathAdaptor = contextPathCustomizerHolder.getHighestRanked();
if (pathAdaptor != null) {
@@ -156,6 +175,18 @@ public class HttpServiceRuntimeImpl
return thisReference.equals(contextReference);
}
+ public boolean isFailedResourceDTO(ServiceReference<?> serviceReference) {
+ return failedResourceDTOs.containsKey(serviceReference);
+ }
+
+ public boolean isFailedServletDTO(ServiceReference<?> serviceReference) {
+ return failedServletDTOs.containsKey(serviceReference);
+ }
+
+ public boolean isFailedErrorPageDTO(ServiceReference<?> serviceReference) {
+ return failedErrorPageDTOs.containsKey(serviceReference);
+ }
+
@Override
public synchronized RequestInfoDTO calculateRequestInfoDTO(String path) {
RequestInfoDTO requestInfoDTO = new RequestInfoDTO();
@@ -174,30 +205,34 @@ public class HttpServiceRuntimeImpl
public synchronized void destroy() {
invalidatorReg.unregister();
- defaultContextReg.unregister();
+
+ try {
+ defaultContextReg.unregister();
+ }
+ catch (IllegalStateException ise) {
+ // ignore
+ }
contextServiceTracker.close();
contextPathAdaptorTracker.close();
+ preprocessorServiceTracker.close();
controllerMap.clear();
+ preprocessorMap.clear();
registeredObjects.clear();
+ legacyContextMap.clear();
+ failedErrorPageDTOs.clear();
failedFilterDTOs.clear();
failedListenerDTOs.clear();
+ failedPreprocessorDTOs.clear();
failedResourceDTOs.clear();
failedServletContextDTOs.clear();
failedServletDTOs.clear();
httpSessionTracker.clear();
registeredObjects.clear();
-
- httpSessionTracker = null;
- attributes = null;
- trackingContext = null;
- consumingContext = null;
- parentServletContext = null;
- contextServiceTracker = null;
- contextPathCustomizerHolder = null;
+ scheduledExecutor.shutdown();
}
public DispatchTargets getDispatchTargets(
@@ -220,7 +255,7 @@ public class HttpServiceRuntimeImpl
requestInfoDTO);
}
- if (dispatchTargets == null && !Const.SLASH.equals(pathString)) {
+ if (dispatchTargets == null) {
// regex match
dispatchTargets = getDispatchTargets(
requestURI, null, queryString, Match.REGEX, requestInfoDTO);
@@ -257,10 +292,13 @@ public class HttpServiceRuntimeImpl
return targetFilter;
}
+ public ServletContext getParentServletContext() {
+ return parentServletContext;
+ }
+
public List<String> getHttpServiceEndpoints() {
return StringPlus.from(
- attributes.get(
- HttpServiceRuntimeConstants.HTTP_SERVICE_ENDPOINT));
+ attributes.get(HTTP_SERVICE_ENDPOINT));
}
@Override
@@ -270,9 +308,11 @@ public class HttpServiceRuntimeImpl
runtimeDTO.failedErrorPageDTOs = getFailedErrorPageDTOs();
runtimeDTO.failedFilterDTOs = getFailedFilterDTOs();
runtimeDTO.failedListenerDTOs = getFailedListenerDTOs();
+ runtimeDTO.failedPreprocessorDTOs = getFailedPreprocessorDTOs();
runtimeDTO.failedResourceDTOs = getFailedResourceDTOs();
runtimeDTO.failedServletContextDTOs = getFailedServletContextDTO();
runtimeDTO.failedServletDTOs = getFailedServletDTOs();
+ runtimeDTO.preprocessorDTOs = getPreprocessorDTOs();
runtimeDTO.serviceDTO = getServiceDTO();
runtimeDTO.servletContextDTOs = getServletContextDTOs();
@@ -313,8 +353,7 @@ public class HttpServiceRuntimeImpl
}
public boolean matches(ServiceReference<?> serviceReference) {
- String target = (String)serviceReference.getProperty(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_TARGET);
+ String target = (String)serviceReference.getProperty(HTTP_WHITEBOARD_TARGET);
if (target == null) {
return true;
@@ -360,19 +399,24 @@ public class HttpServiceRuntimeImpl
ServiceReference<ServletContextHelper> serviceReference,
AtomicReference<ContextController> contextControllerRef) {
- 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();
+ try {
+ 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();
}
- contextController.destroy();
+ failedServletContextDTOs.remove(serviceReference);
+ controllerMap.remove(serviceReference);
+ trackingContext.ungetService(serviceReference);
+ }
+ finally {
+ incrementServiceChangecount();
}
- failedServletContextDTOs.remove(serviceReference);
- controllerMap.remove(serviceReference);
- trackingContext.ungetService(serviceReference);
}
Collection<ContextController> getContextControllers(String requestURI) {
@@ -491,7 +535,7 @@ public class HttpServiceRuntimeImpl
return copies.toArray(new FailedListenerDTO[0]);
}
- public FailedResourceDTO[] getFailedResourceDTOs() {
+ private FailedResourceDTO[] getFailedResourceDTOs() {
Collection<FailedResourceDTO> frDTOs = failedResourceDTOs.values();
List<FailedResourceDTO> copies = new ArrayList<FailedResourceDTO>();
@@ -516,17 +560,29 @@ public class HttpServiceRuntimeImpl
}
private FailedServletDTO[] getFailedServletDTOs() {
- Collection<ExtendedFailedServletDTO> fsDTOs = failedServletDTOs.values();
+ Collection<FailedServletDTO> fsDTOs = failedServletDTOs.values();
List<FailedServletDTO> copies = new ArrayList<FailedServletDTO>();
- for (ExtendedFailedServletDTO failedServletDTO : fsDTOs) {
+ for (FailedServletDTO failedServletDTO : fsDTOs) {
copies.add(DTOUtil.clone(failedServletDTO));
}
return copies.toArray(new FailedServletDTO[0]);
}
+ private FailedPreprocessorDTO[] getFailedPreprocessorDTOs() {
+ Collection<FailedPreprocessorDTO> fpDTOs = failedPreprocessorDTOs.values();
+
+ List<FailedPreprocessorDTO> copies = new ArrayList<FailedPreprocessorDTO>();
+
+ for (FailedPreprocessorDTO failedPreprocessorDTO : fpDTOs) {
+ copies.add(DTOUtil.clone(failedPreprocessorDTO));
+ }
+
+ return copies.toArray(new FailedPreprocessorDTO[0]);
+ }
+
public ServletContextDTO[] getServletContextDTOs() {
List<ServletContextDTO> servletContextDTOs = new ArrayList<ServletContextDTO>();
@@ -537,8 +593,22 @@ public class HttpServiceRuntimeImpl
return servletContextDTOs.toArray(new ServletContextDTO[0]);
}
+ public PreprocessorDTO[] getPreprocessorDTOs() {
+ List<PreprocessorDTO> pDTOs = new ArrayList<PreprocessorDTO>();
+
+ for (PreprocessorRegistration registration : preprocessorMap.values()) {
+ pDTOs.add(registration.getD());
+ }
+
+ return pDTOs.toArray(new PreprocessorDTO[0]);
+ }
+
+ public Map<ServiceReference<Preprocessor>, PreprocessorRegistration> getPreprocessorRegistrations() {
+ return preprocessorMap;
+ }
+
public void registerHttpServiceFilter(
- Bundle bundle, String alias, Filter filter, Dictionary<String, String> initparams, ServiceReference<? extends ServletContextHelper> serviceReference) {
+ Bundle bundle, String alias, Filter filter, Dictionary<String, String> initparams, HttpContextHolder httpContextHolder) {
if (alias == null) {
throw new IllegalArgumentException("Alias cannot be null"); //$NON-NLS-1$
@@ -575,21 +645,23 @@ public class HttpServiceRuntimeImpl
ServiceRegistration<Filter> registration = null;
try {
Dictionary<String, Object> props = new Hashtable<String, Object>();
- 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, getFilter(serviceReference));
+ props.put(HTTP_WHITEBOARD_TARGET, targetFilter);
+ props.put(HTTP_WHITEBOARD_FILTER_PATTERN, alias);
+ props.put(HTTP_WHITEBOARD_FILTER_NAME, filterName);
+ props.put(HTTP_WHITEBOARD_CONTEXT_SELECT, getFilter(httpContextHolder.getServiceReference()));
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);
+ fillInitParams(props, initparams, HTTP_WHITEBOARD_FILTER_INIT_PARAM_PREFIX);
LegacyFilterFactory filterFactory = new LegacyFilterFactory(filter);
+
registration = bundle.getBundleContext().registerService(Filter.class, filterFactory, props);
// check that init got called and did not throw an exception
filterFactory.checkForError();
+ httpContextHolder.incrementUseCount();
- objectRegistration = new HttpServiceObjectRegistration(filter, registration, bundle);
+ objectRegistration = new HttpServiceObjectRegistration(filter, registration, httpContextHolder, bundle);
Set<HttpServiceObjectRegistration> objectRegistrations = bundleRegistrations.get(bundle);
if (objectRegistrations == null) {
objectRegistrations = new HashSet<HttpServiceObjectRegistration>();
@@ -600,6 +672,7 @@ public class HttpServiceRuntimeImpl
} finally {
if (objectRegistration == null || !legacyMappings.containsKey(objectRegistration.serviceKey)) {
// something bad happened above (likely going to throw a runtime exception)
+ decrementFactoryUseCount(httpContextHolder);
if (registration != null) {
registration.unregister();
}
@@ -610,11 +683,11 @@ public class HttpServiceRuntimeImpl
private void fillInitParams(
Dictionary<String, Object> props,
- Dictionary<String, String> initparams, String prefix) {
+ Dictionary<?, ?> initparams, String prefix) {
if (initparams != null) {
- for (Enumeration<String> eKeys = initparams.keys(); eKeys.hasMoreElements();) {
- String key = eKeys.nextElement();
- String value = initparams.get(key);
+ for (Enumeration<?> eKeys = initparams.keys(); eKeys.hasMoreElements();) {
+ String key = String.valueOf(eKeys.nextElement());
+ String value = String.valueOf(initparams.get(key));
if (value != null) {
props.put(prefix + key, value);
}
@@ -649,7 +722,7 @@ public class HttpServiceRuntimeImpl
}
public void registerHttpServiceResources(
- Bundle bundle, String alias, String name, ServiceReference<? extends ServletContextHelper> serviceReference) throws NamespaceException {
+ Bundle bundle, String alias, String name, HttpContextHolder httpContextHolder) throws NamespaceException {
if (alias == null) {
throw new IllegalArgumentException("Alias cannot be null"); //$NON-NLS-1$
}
@@ -672,20 +745,22 @@ public class HttpServiceRuntimeImpl
HttpServiceObjectRegistration objectRegistration = null;
ServiceRegistration<?> registration = null;
try {
- String fullAlias = getFullAlias(alias, serviceReference);
+ String fullAlias = getFullAlias(alias, httpContextHolder);
HttpServiceObjectRegistration existing = legacyMappings.get(fullAlias);
if (existing != null) {
throw new PatternInUseException(alias);
}
Dictionary<String, Object> props = new Hashtable<String, Object>();
- 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, getFilter(serviceReference));
+ props.put(HTTP_WHITEBOARD_TARGET, targetFilter);
+ props.put(HTTP_WHITEBOARD_RESOURCE_PATTERN, pattern);
+ props.put(HTTP_WHITEBOARD_RESOURCE_PREFIX, name);
+ props.put(HTTP_WHITEBOARD_CONTEXT_SELECT, getFilter(httpContextHolder.getServiceReference()));
props.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE);
props.put(Const.EQUINOX_LEGACY_TCCL_PROP, Thread.currentThread().getContextClassLoader());
registration = bundle.getBundleContext().registerService(String.class, "resource", props); //$NON-NLS-1$
- objectRegistration = new HttpServiceObjectRegistration(fullAlias, registration, bundle);
+ httpContextHolder.incrementUseCount();
+
+ objectRegistration = new HttpServiceObjectRegistration(fullAlias, registration, httpContextHolder, bundle);
Set<HttpServiceObjectRegistration> objectRegistrations = bundleRegistrations.get(bundle);
if (objectRegistrations == null) {
@@ -705,6 +780,7 @@ 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(httpContextHolder);
if (registration != null) {
registration.unregister();
}
@@ -714,12 +790,12 @@ public class HttpServiceRuntimeImpl
}
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$
+ String ctxName = (String)serviceReference.getProperty(HTTP_WHITEBOARD_CONTEXT_NAME);
+ return String.format("(&(%s=%s)(%s=%s))", HTTP_SERVICE_CONTEXT_PROPERTY, ctxName, HTTP_WHITEBOARD_CONTEXT_NAME, ctxName); //$NON-NLS-1$
}
public void registerHttpServiceServlet(
- Bundle bundle, String alias, Servlet servlet, Dictionary<String, String> initparams, ServiceReference<? extends ServletContextHelper> serviceReference) throws NamespaceException, ServletException{
+ Bundle bundle, String alias, Servlet servlet, Dictionary<?, ?> initparams, HttpContextHolder httpContextHolder) throws NamespaceException, ServletException{
if (alias == null) {
throw new IllegalArgumentException("Alias cannot be null"); //$NON-NLS-1$
}
@@ -748,31 +824,32 @@ public class HttpServiceRuntimeImpl
HttpServiceObjectRegistration objectRegistration = null;
ServiceRegistration<Servlet> registration = null;
try {
- String fullAlias = getFullAlias(alias, serviceReference);
+ String fullAlias = getFullAlias(alias, httpContextHolder);
HttpServiceObjectRegistration existing = legacyMappings.get(fullAlias);
if (existing != null) {
throw new PatternInUseException(alias);
}
String servletName = servlet.getClass().getName();
if ((initparams != null) && (initparams.get(Const.SERVLET_NAME) != null)) {
- servletName = initparams.get(Const.SERVLET_NAME);
+ servletName = String.valueOf(initparams.get(Const.SERVLET_NAME));
}
Dictionary<String, Object> props = new Hashtable<String, Object>();
- 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, getFilter(serviceReference));
+ props.put(HTTP_WHITEBOARD_TARGET, targetFilter);
+ props.put(HTTP_WHITEBOARD_SERVLET_PATTERN, pattern);
+ props.put(HTTP_WHITEBOARD_SERVLET_NAME, servletName);
+ props.put(HTTP_WHITEBOARD_CONTEXT_SELECT, getFilter(httpContextHolder.getServiceReference()));
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);
+ fillInitParams(props, initparams, HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX);
registration = bundle.getBundleContext().registerService(Servlet.class, legacyServlet, props);
// check that init got called and did not throw an exception
legacyServlet.checkForError();
+ httpContextHolder.incrementUseCount();
- objectRegistration = new HttpServiceObjectRegistration(fullAlias, registration, bundle);
+ objectRegistration = new HttpServiceObjectRegistration(fullAlias, registration, httpContextHolder, bundle);
Set<HttpServiceObjectRegistration> objectRegistrations = bundleRegistrations.get(bundle);
if (objectRegistrations == null) {
@@ -793,6 +870,7 @@ 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(httpContextHolder);
if (registration != null) {
registration.unregister();
}
@@ -801,9 +879,9 @@ public class HttpServiceRuntimeImpl
}
}
- private String getFullAlias(String alias, ServiceReference<? extends ServletContextHelper> serviceReference) {
+ private String getFullAlias(String alias, HttpContextHolder httpContextHolder) {
@SuppressWarnings("unchecked")
- AtomicReference<ContextController> controllerRef = contextServiceTracker.getService((ServiceReference<ServletContextHelper>)serviceReference);
+ AtomicReference<ContextController> controllerRef = contextServiceTracker.getService((ServiceReference<ServletContextHelper>)httpContextHolder.getServiceReference());
if (controllerRef != null) {
ContextController controller = controllerRef.get();
if (controller != null) {
@@ -835,6 +913,7 @@ public class HttpServiceRuntimeImpl
} catch (IllegalStateException e) {
// ignore; already unregistered
}
+ decrementFactoryUseCount(objectRegistration.httpContextHolder);
legacyMappings.remove(aliasCustomization);
}
@@ -856,6 +935,7 @@ public class HttpServiceRuntimeImpl
} catch (IllegalStateException e) {
// ignore; already unregistered
}
+ decrementFactoryUseCount(objectRegistration.httpContextHolder);
legacyMappings.remove(filter);
}
}
@@ -871,19 +951,43 @@ public class HttpServiceRuntimeImpl
} catch (IllegalStateException e) {
// ignore; already unregistered
}
+ decrementFactoryUseCount(objectRegistration.httpContextHolder);
legacyMappings.remove(objectRegistration.serviceKey);
}
}
}
}
+ private void decrementFactoryUseCount(HttpContextHolder holder) {
+ synchronized (legacyContextMap) {
+ if (holder.decrementUseCount() == 0) {
+ legacyContextMap.remove(holder.getHttpContext());
+ }
+ }
+ }
+
+ private static org.osgi.framework.Filter createErrorPageFilter(BundleContext context) {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("("); //$NON-NLS-1$
+ sb.append(HTTP_WHITEBOARD_SERVLET_ERROR_PAGE);
+ sb.append("=*)"); //$NON-NLS-1$
+
+ try {
+ return context.createFilter(sb.toString());
+ }
+ catch (InvalidSyntaxException ise) {
+ throw new IllegalArgumentException(ise);
+ }
+ }
+
private static org.osgi.framework.Filter createResourceFilter(BundleContext context) {
StringBuilder sb = new StringBuilder();
sb.append("(&("); //$NON-NLS-1$
- sb.append(HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PREFIX);
+ sb.append(HTTP_WHITEBOARD_RESOURCE_PREFIX);
sb.append("=*)("); //$NON-NLS-1$
- sb.append(HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PATTERN);
+ sb.append(HTTP_WHITEBOARD_RESOURCE_PATTERN);
sb.append("=*))"); //$NON-NLS-1$
try {
@@ -900,11 +1004,9 @@ public class HttpServiceRuntimeImpl
sb.append("(&(objectClass="); //$NON-NLS-1$
sb.append(Servlet.class.getName());
sb.append(")(|("); //$NON-NLS-1$
- sb.append(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE);
- sb.append("=*)("); //$NON-NLS-1$
- sb.append(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME);
+ sb.append(HTTP_WHITEBOARD_SERVLET_NAME);
sb.append("=*)("); //$NON-NLS-1$
- sb.append(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN);
+ sb.append(HTTP_WHITEBOARD_SERVLET_PATTERN);
sb.append("=*)))"); //$NON-NLS-1$
try {
@@ -921,11 +1023,11 @@ public class HttpServiceRuntimeImpl
sb.append("(&(objectClass="); //$NON-NLS-1$
sb.append(Filter.class.getName());
sb.append(")(|("); //$NON-NLS-1$
- sb.append(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN);
+ sb.append(HTTP_WHITEBOARD_FILTER_PATTERN);
sb.append("=*)("); //$NON-NLS-1$
- sb.append(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_REGEX);
+ sb.append(HTTP_WHITEBOARD_FILTER_REGEX);
sb.append("=*)("); //$NON-NLS-1$
- sb.append(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_SERVLET);
+ sb.append(HTTP_WHITEBOARD_FILTER_SERVLET);
sb.append("=*)))"); //$NON-NLS-1$
try {
@@ -936,11 +1038,11 @@ public class HttpServiceRuntimeImpl
}
}
- private static org.osgi.framework.Filter createListenerFilter(BundleContext context, ServletContext servletContext) {
+ private static org.osgi.framework.Filter createListenerFilter(BundleContext context) {
StringBuilder sb = new StringBuilder();
sb.append("(&"); //$NON-NLS-1$
- sb.append("(").append(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER).append("=*)"); //$NON-NLS-1$ //$NON-NLS-2$
+ sb.append("(").append(HTTP_WHITEBOARD_LISTENER).append("=*)"); //$NON-NLS-1$ //$NON-NLS-2$
sb.append("(|"); //$NON-NLS-1$
sb.append("(objectClass=").append(ServletContextListener.class.getName()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
sb.append("(objectClass=").append(ServletContextAttributeListener.class.getName()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
@@ -948,11 +1050,7 @@ public class HttpServiceRuntimeImpl
sb.append("(objectClass=").append(ServletRequestAttributeListener.class.getName()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
sb.append("(objectClass=").append(HttpSessionListener.class.getName()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
sb.append("(objectClass=").append(HttpSessionAttributeListener.class.getName()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
-
- if ((servletContext.getMajorVersion() >= 3) && (servletContext.getMinorVersion() > 0)) {
- sb.append("(objectClass=").append(javax.servlet.http.HttpSessionIdListener.class.getName()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
+ sb.append("(objectClass=").append(HttpSessionIdListener.class.getName()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
sb.append(")"); //$NON-NLS-1$
sb.append(")"); //$NON-NLS-1$
@@ -968,6 +1066,10 @@ public class HttpServiceRuntimeImpl
return listenerServiceFilter;
}
+ public org.osgi.framework.Filter getErrorPageFilter() {
+ return errorPageServiceFilter;
+ }
+
public org.osgi.framework.Filter getFilterFilter() {
return filterServiceFilter;
}
@@ -1029,14 +1131,14 @@ public class HttpServiceRuntimeImpl
ExtendedFailedServletContextDTO failedServletContextDTO = new ExtendedFailedServletContextDTO();
failedServletContextDTO.attributes = Collections.emptyMap();
- failedServletContextDTO.contextPath = String.valueOf(serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH));
+ failedServletContextDTO.contextPath = String.valueOf(serviceReference.getProperty(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);
+ serviceReference, HTTP_WHITEBOARD_CONTEXT_INIT_PARAM_PREFIX);
failedServletContextDTO.listenerDTOs = new ListenerDTO[0];
- failedServletContextDTO.name = String.valueOf(serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME));
+ failedServletContextDTO.name = String.valueOf(serviceReference.getProperty(HTTP_WHITEBOARD_CONTEXT_NAME));
failedServletContextDTO.resourceDTOs = new ResourceDTO[0];
failedServletContextDTO.serviceId = (Long)serviceReference.getProperty(Constants.SERVICE_ID);
failedServletContextDTO.servletDTOs = new ServletDTO[0];
@@ -1047,7 +1149,7 @@ public class HttpServiceRuntimeImpl
public void recordFailedServletDTO(
ServiceReference<?> serviceReference,
- ExtendedFailedServletDTO failedServletDTO) {
+ FailedServletDTO failedServletDTO) {
if (failedServletDTOs.containsKey(serviceReference)) {
return;
@@ -1056,6 +1158,17 @@ public class HttpServiceRuntimeImpl
failedServletDTOs.put(serviceReference, failedServletDTO);
}
+ public void recordFailedPreprocessorDTO(
+ ServiceReference<Preprocessor> serviceReference,
+ FailedPreprocessorDTO failedPreprocessorDTO) {
+
+ if (failedPreprocessorDTOs.containsKey(serviceReference)) {
+ return;
+ }
+
+ failedPreprocessorDTOs.put(serviceReference, failedPreprocessorDTO);
+ }
+
public void removeFailedErrorPageDTO(
ServiceReference<Servlet> serviceReference) {
@@ -1086,6 +1199,12 @@ public class HttpServiceRuntimeImpl
failedServletDTOs.remove(serviceReference);
}
+ public void removeFailedPreprocessorDTO(
+ ServiceReference<Preprocessor> serviceReference) {
+
+ failedPreprocessorDTOs.remove(serviceReference);
+ }
+
public synchronized void fireSessionIdChanged(String oldSessionId) {
for (ContextController contextController : controllerMap.values()) {
contextController.fireSessionIdChanged(oldSessionId);
@@ -1096,20 +1215,44 @@ public class HttpServiceRuntimeImpl
httpSessionTracker.invalidate(sessionId, false);
}
- private Map<String, Object> attributes;
- private final String targetFilter;
- private final ServiceRegistration<?> defaultContextReg;
- private ServletContext parentServletContext;
+ public void setHsrRegistration(ServiceRegistration<HttpServiceRuntime> hsrRegistration) {
+ this.hsrRegistration.set(hsrRegistration);
+ }
- private BundleContext trackingContext;
- private BundleContext consumingContext;
+ ServiceRegistration<HttpServiceRuntime> getHsrRegistration() {
+ return hsrRegistration.get();
+ }
+
+ long getServiceChangecount() {
+ return serviceChangecount.get();
+ }
+ public void incrementServiceChangecount() {
+ serviceChangecount.incrementAndGet();
+ if (hsrRegistration.get() != null && !scheduledExecutor.isShutdown() && semaphore.tryAcquire()) {
+ scheduledExecutor.schedule(new ChangeCountTimer(), 100, TimeUnit.MILLISECONDS);
+ }
+ }
+
+ Semaphore getSemaphore() {
+ return semaphore;
+ }
+
+ private final Map<String, Object> attributes;
+ private final String targetFilter;
+ final ServiceRegistration<DefaultServletContextHelper> defaultContextReg;
+ private final ServletContext parentServletContext;
+ private final BundleContext trackingContext;
+ private final BundleContext consumingContext;
+ private final org.osgi.framework.Filter errorPageServiceFilter;
private final org.osgi.framework.Filter servletServiceFilter;
private final org.osgi.framework.Filter resourceServiceFilter;
private final org.osgi.framework.Filter filterServiceFilter;
private final org.osgi.framework.Filter listenerServiceFilter;
// BEGIN of old HttpService support
+ final ConcurrentMap<HttpContext, HttpContextHolder> legacyContextMap =
+ new ConcurrentHashMap<HttpContext, HttpContextHolder>();
private final Map<Object, HttpServiceObjectRegistration> legacyMappings =
Collections.synchronizedMap(new HashMap<Object, HttpServiceObjectRegistration>());
private final Map<Bundle, Set<HttpServiceObjectRegistration>> bundleRegistrations =
@@ -1119,27 +1262,52 @@ public class HttpServiceRuntimeImpl
private final ConcurrentMap<ServiceReference<ServletContextHelper>, ContextController> controllerMap =
new ConcurrentSkipListMap<ServiceReference<ServletContextHelper>, ContextController>(Collections.reverseOrder());
+ private final ConcurrentMap<ServiceReference<Preprocessor>, PreprocessorRegistration> preprocessorMap =
+ new ConcurrentSkipListMap<ServiceReference<Preprocessor>, PreprocessorRegistration>(Collections.reverseOrder());
- private final ConcurrentMap<ServiceReference<?>, FailedErrorPageDTO> failedErrorPageDTOs =
+ final ConcurrentMap<ServiceReference<?>, FailedErrorPageDTO> failedErrorPageDTOs =
new ConcurrentHashMap<ServiceReference<?>, FailedErrorPageDTO>();
- private final ConcurrentMap<ServiceReference<Filter>, FailedFilterDTO> failedFilterDTOs =
+ final ConcurrentMap<ServiceReference<Filter>, FailedFilterDTO> failedFilterDTOs =
new ConcurrentHashMap<ServiceReference<Filter>, FailedFilterDTO>();
- private final ConcurrentMap<ServiceReference<EventListener>, FailedListenerDTO> failedListenerDTOs =
+ final ConcurrentMap<ServiceReference<EventListener>, FailedListenerDTO> failedListenerDTOs =
new ConcurrentHashMap<ServiceReference<EventListener>, FailedListenerDTO>();
- private final ConcurrentMap<ServiceReference<?>, FailedResourceDTO> failedResourceDTOs =
+ final ConcurrentMap<ServiceReference<?>, FailedResourceDTO> failedResourceDTOs =
new ConcurrentHashMap<ServiceReference<?>, FailedResourceDTO>();
- private final ConcurrentMap<ServiceReference<ServletContextHelper>, ExtendedFailedServletContextDTO> failedServletContextDTOs =
+ final ConcurrentMap<ServiceReference<ServletContextHelper>, ExtendedFailedServletContextDTO> failedServletContextDTOs =
new ConcurrentHashMap<ServiceReference<ServletContextHelper>, ExtendedFailedServletContextDTO>();
- private final ConcurrentMap<ServiceReference<?>, ExtendedFailedServletDTO> failedServletDTOs =
- new ConcurrentHashMap<ServiceReference<?>, ExtendedFailedServletDTO>();
+ final ConcurrentMap<ServiceReference<?>, FailedServletDTO> failedServletDTOs =
+ new ConcurrentHashMap<ServiceReference<?>, FailedServletDTO>();
+ final ConcurrentMap<ServiceReference<?>, FailedPreprocessorDTO> failedPreprocessorDTOs =
+ new ConcurrentHashMap<ServiceReference<?>, FailedPreprocessorDTO>();
private final Set<Object> registeredObjects = Collections.newSetFromMap(new ConcurrentHashMap<Object, Boolean>());
- private ServiceTracker<ServletContextHelper, AtomicReference<ContextController>> contextServiceTracker;
- private ServiceTracker<ContextPathCustomizer, ContextPathCustomizer> contextPathAdaptorTracker;
- private ContextPathCustomizerHolder contextPathCustomizerHolder;
- private HttpSessionTracker httpSessionTracker;
+ private final ServiceTracker<ServletContextHelper, AtomicReference<ContextController>> contextServiceTracker;
+ private final ServiceTracker<Preprocessor, AtomicReference<PreprocessorRegistration>> preprocessorServiceTracker;
+ private final ServiceTracker<ContextPathCustomizer, ContextPathCustomizer> contextPathAdaptorTracker;
+ private final ContextPathCustomizerHolder contextPathCustomizerHolder;
+ private final HttpSessionTracker httpSessionTracker;
private final ServiceRegistration<HttpSessionInvalidator> invalidatorReg;
+ private final AtomicReference<ServiceRegistration<HttpServiceRuntime>> hsrRegistration = new AtomicReference<>();
+
+ private final AtomicLong serviceChangecount = new AtomicLong();
+ private final ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
+ private final Semaphore semaphore = new Semaphore(1);
+
+ class ChangeCountTimer implements Callable<Void> {
+ @Override
+ public Void call() {
+ try {
+ Dictionary<String,Object> properties = getHsrRegistration().getReference().getProperties();
+ properties.put(Constants.SERVICE_CHANGECOUNT, getServiceChangecount());
+ getHsrRegistration().setProperties(properties);
+ return null;
+ }
+ finally {
+ getSemaphore().release();
+ }
+ }
+ }
static class LegacyServiceObject {
final AtomicReference<Exception> error = new AtomicReference<Exception>(new ServletException("The init() method was never called.")); //$NON-NLS-1$
@@ -1325,16 +1493,4 @@ 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/PreprocessorCustomizer.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/PreprocessorCustomizer.java
new file mode 100644
index 000000000..20730e6a7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/PreprocessorCustomizer.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) Feb. 2, 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 static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_PREPROCESSOR_INIT_PARAM_PREFIX;
+
+import java.util.concurrent.atomic.AtomicReference;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import org.eclipse.equinox.http.servlet.internal.context.ServiceHolder;
+import org.eclipse.equinox.http.servlet.internal.error.HttpWhiteboardFailureException;
+import org.eclipse.equinox.http.servlet.internal.registration.PreprocessorRegistration;
+import org.eclipse.equinox.http.servlet.internal.servlet.FilterConfigImpl;
+import org.eclipse.equinox.http.servlet.internal.util.ServiceProperties;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.runtime.dto.*;
+import org.osgi.service.http.whiteboard.Preprocessor;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ * @author Raymond Augé
+ */
+public class PreprocessorCustomizer
+ implements ServiceTrackerCustomizer<Preprocessor, AtomicReference<PreprocessorRegistration>> {
+
+ public PreprocessorCustomizer(HttpServiceRuntimeImpl httpServiceRuntime) {
+ this.httpServiceRuntime = httpServiceRuntime;
+ }
+
+ @Override
+ public AtomicReference<PreprocessorRegistration> addingService(
+ ServiceReference<Preprocessor> serviceReference) {
+
+ AtomicReference<PreprocessorRegistration> result = new AtomicReference<PreprocessorRegistration>();
+ if (!httpServiceRuntime.matches(serviceReference)) {
+ return result;
+ }
+
+ try {
+ removeFailed(serviceReference);
+
+ result.set(addPreprocessorRegistration(serviceReference));
+ }
+ catch (HttpWhiteboardFailureException hwfe) {
+ httpServiceRuntime.log(hwfe.getMessage(), hwfe);
+
+ recordFailed(serviceReference, hwfe.getFailureReason());
+ }
+ catch (Exception e) {
+ httpServiceRuntime.log(e.getMessage(), e);
+
+ recordFailed(serviceReference, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
+ }
+ finally {
+ httpServiceRuntime.incrementServiceChangecount();
+ }
+
+ return result;
+ }
+
+ @Override
+ public void modifiedService(
+ ServiceReference<Preprocessor> serviceReference, AtomicReference<PreprocessorRegistration> reference) {
+
+ removedService(serviceReference, reference);
+ AtomicReference<PreprocessorRegistration> added = addingService(serviceReference);
+ reference.set(added.get());
+ }
+
+ @Override
+ public void removedService(
+ ServiceReference<Preprocessor> serviceReference, AtomicReference<PreprocessorRegistration> reference) {
+ try {
+ PreprocessorRegistration registration = reference.get();
+ if (registration != null) {
+ registration.destroy();
+ }
+
+ removeFailed(serviceReference);
+ }
+ finally {
+ httpServiceRuntime.incrementServiceChangecount();
+ }
+ }
+
+ void removeFailed(ServiceReference<Preprocessor> serviceReference) {
+ httpServiceRuntime.removeFailedPreprocessorDTO(serviceReference);
+ }
+
+ private void recordFailed(
+ ServiceReference<Preprocessor> serviceReference, int failureReason) {
+
+ FailedPreprocessorDTO failedPreprocessorDTO = new FailedPreprocessorDTO();
+
+ failedPreprocessorDTO.failureReason = failureReason;
+ failedPreprocessorDTO.initParams = ServiceProperties.parseInitParams(
+ serviceReference, HTTP_WHITEBOARD_PREPROCESSOR_INIT_PARAM_PREFIX);
+ failedPreprocessorDTO.serviceId = (Long)serviceReference.getProperty(Constants.SERVICE_ID);
+
+ httpServiceRuntime.recordFailedPreprocessorDTO(serviceReference, failedPreprocessorDTO);
+ }
+
+ private PreprocessorRegistration addPreprocessorRegistration(
+ ServiceReference<Preprocessor> preprocessorRef) throws ServletException {
+
+ ServiceHolder<Preprocessor> preprocessorHolder = new ServiceHolder<Preprocessor>(httpServiceRuntime.getConsumingContext().getServiceObjects(preprocessorRef));
+ Preprocessor preprocessor = preprocessorHolder.get();
+ PreprocessorRegistration registration = null;
+ boolean addedRegisteredObject = false;
+ try {
+ if (preprocessor == null) {
+ throw new IllegalArgumentException("Preprocessor cannot be null"); //$NON-NLS-1$
+ }
+ addedRegisteredObject = httpServiceRuntime.getRegisteredObjects().add(preprocessor);
+ if (!addedRegisteredObject) {
+ throw new HttpWhiteboardFailureException("Multiple registration of instance detected. Prototype scope is recommended: " + preprocessorRef, DTOConstants.FAILURE_REASON_SERVICE_IN_USE); //$NON-NLS-1$
+ }
+ registration = doAddPreprocessorRegistration(preprocessorHolder, preprocessorRef);
+ } finally {
+ if (registration == null) {
+ preprocessorHolder.release();
+ if (addedRegisteredObject) {
+ httpServiceRuntime.getRegisteredObjects().remove(preprocessor);
+ }
+ }
+ }
+ return registration;
+ }
+
+ private PreprocessorRegistration doAddPreprocessorRegistration(
+ ServiceHolder<Preprocessor> preprocessorHolder,
+ ServiceReference<Preprocessor> preprocessorRef) throws ServletException {
+
+ PreprocessorDTO preprocessorDTO = new PreprocessorDTO();
+
+ preprocessorDTO.initParams = ServiceProperties.parseInitParams(
+ preprocessorRef, HTTP_WHITEBOARD_PREPROCESSOR_INIT_PARAM_PREFIX);
+ preprocessorDTO.serviceId = preprocessorHolder.getServiceId();
+
+ PreprocessorRegistration newRegistration = new PreprocessorRegistration(
+ preprocessorHolder, preprocessorDTO, httpServiceRuntime);
+ FilterConfig filterConfig = new FilterConfigImpl(
+ preprocessorHolder.get().getClass().getCanonicalName(),
+ preprocessorDTO.initParams,
+ httpServiceRuntime.getParentServletContext());
+
+ newRegistration.init(filterConfig);
+
+ httpServiceRuntime.getPreprocessorRegistrations().put(preprocessorHolder.getServiceReference(), newRegistration);
+
+ return newRegistration;
+ }
+
+ private final HttpServiceRuntimeImpl httpServiceRuntime;
+
+}
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 16f115b5f..2a2f40463 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
@@ -14,6 +14,8 @@
package org.eclipse.equinox.http.servlet.internal.context;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.*;
+
import java.net.URI;
import java.net.URISyntaxException;
import java.security.AccessController;
@@ -25,8 +27,6 @@ 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;
@@ -40,7 +40,6 @@ import org.eclipse.equinox.http.servlet.internal.util.*;
import org.osgi.framework.*;
import org.osgi.service.http.context.ServletContextHelper;
import org.osgi.service.http.runtime.dto.*;
-import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
import org.osgi.util.tracker.ServiceTracker;
/**
@@ -48,84 +47,6 @@ import org.osgi.util.tracker.ServiceTracker;
*/
public class ContextController {
- public static final class ServiceHolder<S> implements Comparable<ServiceHolder<?>> {
- final ServiceObjects<S> serviceObjects;
- final S service;
- 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.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, 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;
- }
-
- public Bundle getBundle() {
- return bundle;
- }
-
- public ClassLoader getLegacyTCCL() {
- return legacyTCCL;
- }
-
- public void release() {
- if (serviceObjects != null && service != null) {
- try {
- serviceObjects.ungetService(service);
- } 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
- // the bundle forgot to unregister on stop
- }
- }
- }
-
- public ServiceReference<S> getServiceReference() {
- return serviceObjects == null ? null : serviceObjects.getServiceReference();
- }
- @Override
- public int compareTo(ServiceHolder<?> o) {
- final int thisRanking = serviceRanking;
- final int otherRanking = o.serviceRanking;
- if (thisRanking != otherRanking) {
- if (thisRanking < otherRanking) {
- return 1;
- }
- return -1;
- }
- final long thisId = this.serviceId;
- final long otherId = o.serviceId;
- if (thisId == otherId) {
- return 0;
- }
- if (thisId < otherId) {
- return -1;
- }
- return 1;
- }
- }
-
public ContextController(
BundleContext trackingContextParam, BundleContext consumingContext,
ServiceReference<ServletContextHelper> serviceReference,
@@ -142,7 +63,7 @@ public class ContextController {
this.servletContextHelperRefFilter = createFilter(contextServiceId);
this.initParams = ServiceProperties.parseInitParams(
- serviceReference, HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_INIT_PARAM_PREFIX, parentServletContext);
+ serviceReference, HTTP_WHITEBOARD_CONTEXT_INIT_PARAM_PREFIX, parentServletContext);
listenerServiceTracker = new ServiceTracker<EventListener, AtomicReference<ListenerRegistration>>(
trackingContext, httpServiceRuntime.getListenerFilter(),
@@ -158,6 +79,13 @@ public class ContextController {
filterServiceTracker.open();
+ errorPageServiceTracker = new ServiceTracker<Servlet, AtomicReference<ErrorPageRegistration>>(
+ trackingContext, httpServiceRuntime.getErrorPageFilter(),
+ new ContextErrorPageTrackerCustomizer(
+ trackingContext, httpServiceRuntime, this));
+
+ errorPageServiceTracker.open();
+
servletServiceTracker = new ServiceTracker<Servlet, AtomicReference<ServletRegistration>>(
trackingContext, httpServiceRuntime.getServletFilter(),
new ContextServletTrackerCustomizer(
@@ -173,9 +101,77 @@ public class ContextController {
resourceServiceTracker.open();
}
- public FilterRegistration addFilterRegistration(ServiceReference<Filter> filterRef) throws ServletException {
- checkShutdown();
+ public ErrorPageRegistration addErrorPageRegistration(ServiceReference<Servlet> servletRef) {
+ ServiceHolder<Servlet> servletHolder = new ServiceHolder<Servlet>(consumingContext.getServiceObjects(servletRef));
+ Servlet servlet = servletHolder.get();
+ ErrorPageRegistration registration = null;
+ //boolean addedRegisteredObject = false;
+ try {
+ if (servlet == null) {
+ throw new IllegalArgumentException("Servlet cannot be null"); //$NON-NLS-1$
+ }
+ //addedRegisteredObject = httpServiceRuntime.getRegisteredObjects().add(servlet);
+ //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 = doAddErrorPageRegistration(servletHolder, servletRef);
+ } finally {
+ if (registration == null) {
+ // Always attempt to release here; even though destroy() may have been called
+ // on the registration while failing to add. There are cases where no
+ // ServletRegistration may have even been created at all to call destory() on.
+ // Also, addedRegisteredObject may be false which means we never call doAddServletRegistration
+ servletHolder.release();
+ //if (addedRegisteredObject) {
+ // httpServiceRuntime.getRegisteredObjects().remove(servlet);
+ //}
+ }
+ }
+ return registration;
+ }
+
+ private ErrorPageRegistration doAddErrorPageRegistration(ServiceHolder<Servlet> servletHolder, ServiceReference<Servlet> servletRef) {
+ ExtendedErrorPageDTO errorPageDTO = DTOUtil.assembleErrorPageDTO(servletRef, getServiceId(), true);
+ errorPageDTO.servletInfo = servletHolder.get().getServletInfo();
+ errorPageDTO.serviceId = servletHolder.getServiceId();
+
+ if (((errorPageDTO.errorCodes == null) || (errorPageDTO.errorCodes.length == 0)) &&
+ ((errorPageDTO.exceptions == null) || (errorPageDTO.exceptions.length == 0))) {
+
+ throw new HttpWhiteboardFailureException("'errorPage' expects String, String[] or Collection<String>.", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
+ }
+
+ if (errorPageDTO.name == null) {
+ errorPageDTO.name = servletHolder.get().getClass().getName();
+ }
+
+ ServletContextHelper curServletContextHelper = getServletContextHelper(
+ servletHolder.getBundle());
+
+ ServletContext servletContext = createServletContext(
+ servletHolder.getBundle(), curServletContextHelper);
+ ErrorPageRegistration errorPageRegistration = new ErrorPageRegistration(
+ servletHolder, errorPageDTO, curServletContextHelper, this);
+ ServletConfig servletConfig = new ServletConfigImpl(
+ errorPageDTO.name, errorPageDTO.initParams, servletContext);
+
+ try {
+ errorPageRegistration.init(servletConfig);
+ }
+ catch (Throwable t) {
+ errorPageRegistration.destroy();
+
+ return Throw.unchecked(t);
+ }
+
+ recordErrorPageShadowing(errorPageRegistration);
+
+ endpointRegistrations.add(errorPageRegistration);
+ return errorPageRegistration;
+ }
+
+ public FilterRegistration addFilterRegistration(ServiceReference<Filter> filterRef) throws ServletException {
ServiceHolder<Filter> filterHolder = new ServiceHolder<Filter>(consumingContext.getServiceObjects(filterRef));
Filter filter = filterHolder.get();
FilterRegistration registration = null;
@@ -201,13 +197,12 @@ public class ContextController {
}
private FilterRegistration doAddFilterRegistration(ServiceHolder<Filter> filterHolder, ServiceReference<Filter> filterRef) throws ServletException {
-
boolean asyncSupported = ServiceProperties.parseBoolean(
- filterRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_ASYNC_SUPPORTED);
+ filterRef, HTTP_WHITEBOARD_FILTER_ASYNC_SUPPORTED);
List<String> dispatcherList = StringPlus.from(
filterRef.getProperty(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_DISPATCHER));
+ HTTP_WHITEBOARD_FILTER_DISPATCHER));
String[] dispatchers = dispatcherList.toArray(new String[0]);
Integer filterPriority = (Integer)filterRef.getProperty(
Constants.SERVICE_RANKING);
@@ -215,24 +210,22 @@ public class ContextController {
filterPriority = Integer.valueOf(0);
}
Map<String, String> filterInitParams = ServiceProperties.parseInitParams(
- filterRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_INIT_PARAM_PREFIX);
+ filterRef, HTTP_WHITEBOARD_FILTER_INIT_PARAM_PREFIX);
List<String> patternList = StringPlus.from(
filterRef.getProperty(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN));
+ HTTP_WHITEBOARD_FILTER_PATTERN));
String[] patterns = patternList.toArray(new String[0]);
List<String> regexList = StringPlus.from(
filterRef.getProperty(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_REGEX));
+ HTTP_WHITEBOARD_FILTER_REGEX));
String[] regexs = regexList.toArray(new String[0]);
List<String> servletList = StringPlus.from(
filterRef.getProperty(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_SERVLET));
+ HTTP_WHITEBOARD_FILTER_SERVLET));
String[] servletNames = servletList.toArray(new String[0]);
String name = ServiceProperties.parseName(filterRef.getProperty(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_NAME), filterHolder.get());
-
- Filter filter = filterHolder.get();
+ HTTP_WHITEBOARD_FILTER_NAME), filterHolder.get());
if (((patterns == null) || (patterns.length == 0)) &&
((regexs == null) || (regexs.length == 0)) &&
@@ -254,20 +247,12 @@ public class ContextController {
}
}
- if (filter == null) {
- throw new HttpWhiteboardFailureException("Filter cannot be null", DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE); //$NON-NLS-1$
- }
+ Filter filter = filterHolder.get();
if (name == null) {
name = filter.getClass().getName();
}
- for (FilterRegistration filterRegistration : filterRegistrations) {
- if (filterRegistration.getT().equals(filter)) {
- throw new RegisteredFilterException(filter);
- }
- }
-
dispatchers = checkDispatcher(dispatchers);
FilterDTO filterDTO = new FilterDTO();
@@ -278,7 +263,7 @@ public class ContextController {
filterDTO.name = name;
filterDTO.patterns = sort(patterns);
filterDTO.regexs = regexs;
- filterDTO.serviceId = filterHolder.serviceId;
+ filterDTO.serviceId = filterHolder.getServiceId();
filterDTO.servletContextId = contextServiceId;
filterDTO.servletNames = sort(servletNames);
@@ -299,9 +284,6 @@ public class ContextController {
}
public ListenerRegistration addListenerRegistration(ServiceReference<EventListener> listenerRef) throws ServletException {
-
- checkShutdown();
-
ServiceHolder<EventListener> listenerHolder = new ServiceHolder<EventListener>(consumingContext.getServiceObjects(listenerRef));
EventListener listener = listenerHolder.get();
ListenerRegistration registration = null;
@@ -339,7 +321,7 @@ public class ContextController {
ListenerDTO listenerDTO = new ListenerDTO();
- listenerDTO.serviceId = listenerHolder.serviceId;
+ listenerDTO.serviceId = listenerHolder.getServiceId();
listenerDTO.servletContextId = contextServiceId;
listenerDTO.types = asStringArray(classes);
@@ -367,13 +349,10 @@ public class ContextController {
}
public ResourceRegistration addResourceRegistration(ServiceReference<?> resourceRef) {
-
- checkShutdown();
-
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();
- Object patternObj = resourceRef.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PATTERN);
+ Object patternObj = resourceRef.getProperty(HTTP_WHITEBOARD_RESOURCE_PATTERN);
if (!(patternObj instanceof String) &&
!(patternObj instanceof String[]) &&
!(patternObj instanceof Collection)) {
@@ -388,7 +367,7 @@ public class ContextController {
serviceId = -serviceId;
}
Object prefixObj = resourceRef.getProperty(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PREFIX);
+ HTTP_WHITEBOARD_RESOURCE_PREFIX);
checkPrefix(prefixObj);
String prefix = (String)prefixObj;
@@ -441,8 +420,6 @@ public class ContextController {
}
public ServletRegistration addServletRegistration(ServiceReference<Servlet> servletRef) {
- checkShutdown();
-
ServiceHolder<Servlet> servletHolder = new ServiceHolder<Servlet>(consumingContext.getServiceObjects(servletRef));
Servlet servlet = servletHolder.get();
ServletRegistration registration = null;
@@ -472,118 +449,25 @@ public class ContextController {
}
private ServletRegistration doAddServletRegistration(ServiceHolder<Servlet> servletHolder, ServiceReference<Servlet> servletRef) {
- boolean asyncSupported = ServiceProperties.parseBoolean(
- servletRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED);
- List<String> errorPageList = StringPlus.from(
- servletRef.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE));
- 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[0]);
- String servletNameFromProperties = (String)servletRef.getProperty(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME);
- String generatedServletName = ServiceProperties.parseName(
- servletRef.getProperty(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME), servletHolder.get());
- boolean multipartEnabled = ServiceProperties.parseBoolean(
- servletRef, Const.EQUINOX_HTTP_MULTIPART_ENABLED);
- Integer multipartFileSizeThreshold = (Integer)servletRef.getProperty(
- Const.EQUINOX_HTTP_MULTIPART_FILESIZETHRESHOLD);
- String multipartLocation = (String)servletRef.getProperty(
- Const.EQUINOX_HTTP_MULTIPART_LOCATION);
- Long multipartMaxFileSize = (Long)servletRef.getProperty(
- Const.EQUINOX_HTTP_MULTIPART_MAXFILESIZE);
- Long multipartMaxRequestSize = (Long)servletRef.getProperty(
- Const.EQUINOX_HTTP_MULTIPART_MAXREQUESTSIZE);
+ ServletDTO servletDTO = DTOUtil.assembleServletDTO(servletRef, getServiceId(), true);
+ servletDTO.servletInfo = servletHolder.get().getServletInfo();
+ servletDTO.serviceId = servletHolder.getServiceId();
- if (((patterns == null) || (patterns.length == 0)) &&
- ((errorPages == null) || errorPages.length == 0) &&
- (servletNameFromProperties == null)) {
+ if (((servletDTO.patterns == null) || (servletDTO.patterns.length == 0)) &&
+ (servletDTO.name == null)) {
StringBuilder sb = new StringBuilder();
sb.append("One of the service properties "); //$NON-NLS-1$
- sb.append(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE);
+ sb.append(HTTP_WHITEBOARD_SERVLET_NAME);
sb.append(", "); //$NON-NLS-1$
- sb.append(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME);
- sb.append(", "); //$NON-NLS-1$
- sb.append(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN);
+ sb.append(HTTP_WHITEBOARD_SERVLET_PATTERN);
sb.append(" must contain a value."); //$NON-NLS-1$
- throw new IllegalArgumentException(sb.toString());
+ throw new HttpWhiteboardFailureException(sb.toString(), DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
}
- if (patterns != null) {
- for (String pattern : patterns) {
- checkPattern(pattern);
- }
- }
-
- ExtendedServletDTO servletDTO = new ExtendedServletDTO();
-
- servletDTO.asyncSupported = asyncSupported;
- servletDTO.initParams = servletInitParams;
- servletDTO.multipartEnabled = multipartEnabled;
- servletDTO.multipartFileSizeThreshold = (multipartFileSizeThreshold != null ? multipartFileSizeThreshold : 0);
- servletDTO.multipartLocation = (multipartLocation != null ? multipartLocation : Const.BLANK);
- servletDTO.multipartMaxFileSize = (multipartMaxFileSize != null ? multipartMaxFileSize : -1L);
- servletDTO.multipartMaxRequestSize = (multipartMaxRequestSize != null ? multipartMaxRequestSize : -1L);
- servletDTO.name = generatedServletName;
- servletDTO.patterns = sort(patterns);
- servletDTO.serviceId = servletHolder.serviceId;
- servletDTO.servletContextId = contextServiceId;
- servletDTO.servletInfo = servletHolder.get().getServletInfo();
-
- ExtendedErrorPageDTO errorPageDTO = null;
-
- if ((errorPages != null) && (errorPages.length > 0)) {
- errorPageDTO = new ExtendedErrorPageDTO();
-
- errorPageDTO.asyncSupported = asyncSupported;
- List<String> exceptions = new ArrayList<String>();
- // Not sure if it is important to maintain order of insertion or natural ordering here.
- // Using insertion ordering with linked hash set.
- Set<Long> errorCodeSet = new LinkedHashSet<Long>();
-
- 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 if (errorPage.length() == 3) {
- errorPageDTO.erroCodeType = ErrorCodeType.SPECIFIC;
- long code = Long.parseLong(errorPage);
- errorCodeSet.add(code);
- } else {
- exceptions.add(errorPage);
- }
- }
- catch (NumberFormatException nfe) {
- exceptions.add(errorPage);
- }
- }
-
- long[] errorCodes = new long[errorCodeSet.size()];
- int i = 0;
- for(Long code : errorCodeSet) {
- errorCodes[i] = code;
- i++;
- }
- errorPageDTO.errorCodes = errorCodes;
- errorPageDTO.exceptions = exceptions.toArray(new String[0]);
- errorPageDTO.initParams = servletInitParams;
- errorPageDTO.name = generatedServletName;
- errorPageDTO.serviceId = servletHolder.serviceId;
- errorPageDTO.servletContextId = contextServiceId;
- errorPageDTO.servletInfo = servletHolder.get().getServletInfo();
+ if (servletDTO.name == null) {
+ servletDTO.name = servletHolder.get().getClass().getName();
}
ServletContextHelper curServletContextHelper = getServletContextHelper(
@@ -592,10 +476,10 @@ public class ContextController {
ServletContext servletContext = createServletContext(
servletHolder.getBundle(), curServletContextHelper);
ServletRegistration servletRegistration = new ServletRegistration(
- servletHolder, servletDTO, errorPageDTO, curServletContextHelper, this,
+ servletHolder, servletDTO, curServletContextHelper, this,
servletContext);
ServletConfig servletConfig = new ServletConfigImpl(
- generatedServletName, servletInitParams, servletContext);
+ servletDTO.name, servletDTO.initParams, servletContext);
try {
servletRegistration.init(servletConfig);
@@ -607,7 +491,6 @@ public class ContextController {
}
recordEndpointShadowing(servletRegistration);
- recordErrorPageShadowing(servletRegistration, errorPageDTO);
endpointRegistrations.add(servletRegistration);
@@ -635,7 +518,7 @@ public class ContextController {
}
for (EndpointRegistration<?> shadowedReg : shadowedRegs) {
if (shadowedReg instanceof ServletRegistration) {
- recordFailedServletDTO(shadowedReg.getServiceReference(), (ExtendedServletDTO)shadowedReg.getD(), DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
+ recordFailedServletDTO(shadowedReg.getServiceReference(), (ServletDTO)shadowedReg.getD(), DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
}
else {
recordFailedResourceDTO(shadowedReg.getServiceReference(), (ResourceDTO)shadowedReg.getD(), DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
@@ -643,72 +526,70 @@ public class ContextController {
}
}
- private void recordErrorPageShadowing(ServletRegistration servletRegistration, ExtendedErrorPageDTO newErrorPageDTO) {
- if (newErrorPageDTO == null) {
- return;
- }
- Set<ServletRegistration> shadowedEPs = new HashSet<ServletRegistration>();
+ private void recordErrorPageShadowing(ErrorPageRegistration newRegistration) {
+ Set<ErrorPageRegistration> shadowedEPs = new HashSet<ErrorPageRegistration>();
for (EndpointRegistration<?> existingRegistration : endpointRegistrations) {
- if (!(existingRegistration instanceof ServletRegistration)) {
+ if (!(existingRegistration instanceof ErrorPageRegistration)) {
continue;
}
- ServletRegistration existingSRegistration = (ServletRegistration)existingRegistration;
- ExtendedErrorPageDTO existingErrorPageDTO = existingSRegistration.getErrorPageDTO();
+ ErrorPageRegistration existingSRegistration = (ErrorPageRegistration)existingRegistration;
+ ExtendedErrorPageDTO existingErrorPageDTO = existingSRegistration.getD();
if ((existingErrorPageDTO == null) ||
- (((existingErrorPageDTO.erroCodeType == ErrorCodeType.RANGE_4XX) || (existingErrorPageDTO.erroCodeType == ErrorCodeType.RANGE_5XX)) && (newErrorPageDTO.erroCodeType == ErrorCodeType.SPECIFIC))) {
+ (((existingErrorPageDTO.errorCodeType == ErrorCodeType.RANGE_4XX) || (existingErrorPageDTO.errorCodeType == ErrorCodeType.RANGE_5XX)) && (newRegistration.getD().errorCodeType == 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) {
+ if (((existingErrorPageDTO.errorCodeType == ErrorCodeType.RANGE_4XX) && (newRegistration.getD().errorCodeType == ErrorCodeType.RANGE_4XX)) ||
+ ((existingErrorPageDTO.errorCodeType == ErrorCodeType.RANGE_5XX) && (newRegistration.getD().errorCodeType == ErrorCodeType.RANGE_5XX))) {
+ if (newRegistration.compareTo(existingSRegistration) < 0) {
shadowedEPs.add(existingSRegistration);
}
// the new reg is shadowed by existing reg
else {
- shadowedEPs.add(servletRegistration);
+ shadowedEPs.add(newRegistration);
}
continue;
}
- for (long newErrorCode : newErrorPageDTO.errorCodes) {
+ for (long newErrorCode : newRegistration.getD().errorCodes) {
for (long existingCode : existingErrorPageDTO.errorCodes) {
if (newErrorCode == existingCode) {
// the new reg is shadowing an existing reg
- if (servletRegistration.compareTo(existingSRegistration) < 0) {
+ if (newRegistration.compareTo(existingSRegistration) < 0) {
shadowedEPs.add(existingSRegistration);
}
// the new reg is shadowed by existing reg
else {
- shadowedEPs.add(servletRegistration);
+ shadowedEPs.add(newRegistration);
}
// 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 newException : newRegistration.getD().exceptions) {
for (String existingException : existingErrorPageDTO.exceptions) {
if (newException.equals(existingException)) {
// the new reg is shadowing an existing reg
- if (servletRegistration.compareTo(existingSRegistration) < 0) {
+ if (newRegistration.compareTo(existingSRegistration) < 0) {
shadowedEPs.add(existingSRegistration);
}
// the new reg is shadowed by existing reg
else {
- shadowedEPs.add(servletRegistration);
+ shadowedEPs.add(newRegistration);
}
// 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);
+ for (ErrorPageRegistration shadowedReg : shadowedEPs) {
+ recordFailedErrorPageDTO(shadowedReg.getServiceReference(), shadowedReg.getD(), DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
}
}
- public void destroy() {
+ public synchronized void destroy() {
flushActiveSessions();
resourceServiceTracker.close();
servletServiceTracker.close();
+ errorPageServiceTracker.close();
filterServiceTracker.close();
listenerServiceTracker.close();
@@ -721,6 +602,10 @@ public class ContextController {
shutdown = true;
}
+ public boolean isLegacyContext() {
+ return serviceReference.getProperty(HTTP_SERVICE_CONTEXT_PROPERTY) != null;
+ }
+
public String getContextName() {
checkShutdown();
@@ -988,7 +873,7 @@ public class ContextController {
public boolean matches(ServiceReference<?> whiteBoardService) {
String contextSelector = (String) whiteBoardService.getProperty(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT);
+ HTTP_WHITEBOARD_CONTEXT_SELECT);
// make sure the context helper is either one of the built-in ones registered by this http whiteboard implementation;
// or is visible to the whiteboard registering bundle.
if (!visibleContextHelper(whiteBoardService)) {
@@ -998,14 +883,14 @@ public class ContextController {
contextSelector = httpServiceRuntime.getDefaultContextSelectFilter(whiteBoardService);
if (contextSelector == null) {
contextSelector = "(" + //$NON-NLS-1$
- HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=" //$NON-NLS-1$
- + HttpWhiteboardConstants.HTTP_WHITEBOARD_DEFAULT_CONTEXT_NAME + ")"; //$NON-NLS-1$
+ HTTP_WHITEBOARD_CONTEXT_NAME + "=" //$NON-NLS-1$
+ + HTTP_WHITEBOARD_DEFAULT_CONTEXT_NAME + ")"; //$NON-NLS-1$
}
}
if (!contextSelector.startsWith(Const.OPEN_PAREN)) {
contextSelector = Const.OPEN_PAREN +
- HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME +
+ HTTP_WHITEBOARD_CONTEXT_NAME +
Const.EQUAL + contextSelector + Const.CLOSE_PAREN;
}
@@ -1178,7 +1063,7 @@ public class ContextController {
}
}
- private void checkShutdown() {
+ public synchronized void checkShutdown() {
if (shutdown) {
throw new IllegalStateException(
"Context is already shutdown"); //$NON-NLS-1$
@@ -1214,21 +1099,18 @@ public class ContextController {
for (EndpointRegistration<?> endpointRegistration : endpointRegistrations) {
if (endpointRegistration instanceof ResourceRegistration) {
- if (!httpServiceRuntime.failedResourceDTO(endpointRegistration.getServiceReference())) {
+ if (!httpServiceRuntime.isFailedResourceDTO(endpointRegistration.getServiceReference())) {
resourceDTOs.add(DTOUtil.clone((ResourceDTO)endpointRegistration.getD()));
}
}
- else {
- ServletRegistration servletRegistration = (ServletRegistration)endpointRegistration;
- if (!httpServiceRuntime.failedServletDTO(servletRegistration.getServiceReference())) {
- servletDTOs.add(DTOUtil.clone(servletRegistration.getD()));
+ else if (endpointRegistration instanceof ErrorPageRegistration) {
+ if (!httpServiceRuntime.isFailedErrorPageDTO(endpointRegistration.getServiceReference())) {
+ errorPageDTOs.add(DTOUtil.clone((ExtendedErrorPageDTO)endpointRegistration.getD()));
}
-
- ErrorPageDTO errorPageDTO = servletRegistration.getErrorPageDTO();
- if ((errorPageDTO != null) &&
- !httpServiceRuntime.failedErrorPageDTO(servletRegistration.getServiceReference())) {
-
- errorPageDTOs.add(DTOUtil.clone(errorPageDTO));
+ }
+ else {
+ if (!httpServiceRuntime.isFailedServletDTO(endpointRegistration.getServiceReference())) {
+ servletDTOs.add(DTOUtil.clone((ServletDTO)endpointRegistration.getD()));
}
}
}
@@ -1472,76 +1354,37 @@ public class ContextController {
getHttpServiceRuntime().recordFailedResourceDTO(resourceReference, failedResourceDTO);
}
- public void recordFailedServletDTO(
- ServiceReference<?> servletReference, ExtendedServletDTO servletDTO, int failureReason) {
+ public void recordFailedServletDTO(ServiceReference<?> servletReference, ServletDTO servletDTO, int failureReason) {
+ FailedServletDTO failedServletDTO = new FailedServletDTO();
- 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;
- }
+ 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;
getHttpServiceRuntime().recordFailedServletDTO(servletReference, failedServletDTO);
}
private String validateName() {
- Object contextNameObj = serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME);
+ Object contextNameObj = serviceReference.getProperty(HTTP_WHITEBOARD_CONTEXT_NAME);
if (contextNameObj == null) {
throw new IllegalContextNameException(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + " is null. Ignoring!", //$NON-NLS-1$
+ 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$
+ HTTP_WHITEBOARD_CONTEXT_NAME + " is not String. Ignoring!", //$NON-NLS-1$
DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
}
@@ -1569,16 +1412,16 @@ public class ContextController {
}
private String validatePath() {
- Object contextPathObj = serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH);
+ Object contextPathObj = serviceReference.getProperty(HTTP_WHITEBOARD_CONTEXT_PATH);
if (contextPathObj == null) {
throw new IllegalContextPathException(
- HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + " is null. Ignoring!", //$NON-NLS-1$
+ 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$
+ HTTP_WHITEBOARD_CONTEXT_PATH + " is not String. Ignoring!", //$NON-NLS-1$
DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
}
@@ -1629,8 +1472,9 @@ public class ContextController {
private boolean shutdown;
private String string;
+ private final ServiceTracker<Servlet, AtomicReference<ErrorPageRegistration>> errorPageServiceTracker;
private final ServiceTracker<Filter, AtomicReference<FilterRegistration>> filterServiceTracker;
private final ServiceTracker<EventListener, AtomicReference<ListenerRegistration>> listenerServiceTracker;
- private final ServiceTracker<Servlet, AtomicReference<ServletRegistration>> servletServiceTracker;
private final ServiceTracker<Object, AtomicReference<ResourceRegistration>> resourceServiceTracker;
+ private final ServiceTracker<Servlet, AtomicReference<ServletRegistration>> servletServiceTracker;
} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/DispatchTargets.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/DispatchTargets.java
index 2e45f122e..4b5b64316 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/DispatchTargets.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/DispatchTargets.java
@@ -85,32 +85,30 @@ public class DispatchTargets {
setDispatcherType(requestedDispatcherType);
- RequestAttributeSetter setter = new RequestAttributeSetter(originalRequest);
-
- if (dispatcherType == DispatcherType.INCLUDE) {
- setter.setAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH, contextController.getFullContextPath());
- setter.setAttribute(RequestDispatcher.INCLUDE_PATH_INFO, getPathInfo());
- setter.setAttribute(RequestDispatcher.INCLUDE_QUERY_STRING, getQueryString());
- setter.setAttribute(RequestDispatcher.INCLUDE_REQUEST_URI, getRequestURI());
- setter.setAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH, getServletPath());
- }
- else if (dispatcherType == DispatcherType.FORWARD) {
- response.resetBuffer();
-
- setter.setAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH, originalRequest.getContextPath());
- setter.setAttribute(RequestDispatcher.FORWARD_PATH_INFO, originalRequest.getPathInfo());
- setter.setAttribute(RequestDispatcher.FORWARD_QUERY_STRING, originalRequest.getQueryString());
- setter.setAttribute(RequestDispatcher.FORWARD_REQUEST_URI, originalRequest.getRequestURI());
- setter.setAttribute(RequestDispatcher.FORWARD_SERVLET_PATH, originalRequest.getServletPath());
- }
-
HttpServletRequest request = originalRequest;
HttpServletRequestWrapperImpl requestWrapper = HttpServletRequestWrapperImpl.findHttpRuntimeRequest(originalRequest);
HttpServletResponseWrapper responseWrapper = HttpServletResponseWrapperImpl.findHttpRuntimeResponse(response);
boolean includeWrapperAdded = false;
- try {
+ try (RequestAttributeSetter setter = new RequestAttributeSetter(originalRequest)) {
+ if (dispatcherType == DispatcherType.INCLUDE) {
+ setter.setAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH, contextController.getFullContextPath());
+ setter.setAttribute(RequestDispatcher.INCLUDE_PATH_INFO, getPathInfo());
+ setter.setAttribute(RequestDispatcher.INCLUDE_QUERY_STRING, getQueryString());
+ setter.setAttribute(RequestDispatcher.INCLUDE_REQUEST_URI, getRequestURI());
+ setter.setAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH, getServletPath());
+ }
+ else if (dispatcherType == DispatcherType.FORWARD) {
+ response.resetBuffer();
+
+ setter.setAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH, originalRequest.getContextPath());
+ setter.setAttribute(RequestDispatcher.FORWARD_PATH_INFO, originalRequest.getPathInfo());
+ setter.setAttribute(RequestDispatcher.FORWARD_QUERY_STRING, originalRequest.getQueryString());
+ setter.setAttribute(RequestDispatcher.FORWARD_REQUEST_URI, originalRequest.getRequestURI());
+ setter.setAttribute(RequestDispatcher.FORWARD_SERVLET_PATH, originalRequest.getServletPath());
+ }
+
if (requestWrapper == null) {
requestWrapper = new HttpServletRequestWrapperImpl(originalRequest);
request = requestWrapper;
@@ -140,8 +138,6 @@ public class DispatchTargets {
}
requestWrapper.pop();
-
- setter.close();
}
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/HttpContextHolder.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/HttpContextHolder.java
new file mode 100644
index 000000000..d73724c8d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/HttpContextHolder.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * 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
+ * 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.util.concurrent.atomic.AtomicLong;
+import org.eclipse.equinox.http.servlet.internal.DefaultServletContextHelper;
+import org.osgi.framework.*;
+import org.osgi.service.http.HttpContext;
+import org.osgi.service.http.context.ServletContextHelper;
+
+public class HttpContextHolder {
+
+ final HttpContext httpContext;
+ final ServiceRegistration<? extends ServletContextHelper> registration;
+ final String filter;
+ final AtomicLong useCount = new AtomicLong(0);
+
+ public HttpContextHolder(HttpContext httpContext, ServiceRegistration<DefaultServletContextHelper> registration) {
+ this.httpContext = httpContext;
+ this.registration = registration;
+ StringBuilder filterBuilder = new StringBuilder();
+ filterBuilder.append('(');
+ filterBuilder.append(Constants.SERVICE_ID);
+ filterBuilder.append('=');
+ filterBuilder.append(registration.getReference().getProperty(Constants.SERVICE_ID));
+ filterBuilder.append(')');
+ filter = filterBuilder.toString();
+ }
+
+ public ServiceReference<? extends ServletContextHelper> getServiceReference() {
+ try {
+ return registration.getReference();
+ } catch (IllegalStateException e) {
+ // do nothing
+ }
+ return null;
+ }
+
+ public String getFilter() {
+ return filter;
+ }
+
+ public long incrementUseCount() {
+ return useCount.incrementAndGet();
+ }
+
+ public long decrementUseCount() {
+ long result = useCount.decrementAndGet();
+ if (result == 0) {
+ try {
+ registration.unregister();
+ } catch (IllegalStateException e) {
+ // ignore; already unregistered
+ }
+ }
+ return result;
+ }
+
+ public Object getHttpContext() {
+ return httpContext;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ProxyContext.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ProxyContext.java
index 6741914fd..60ffe5458 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ProxyContext.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ProxyContext.java
@@ -83,7 +83,7 @@ public class ProxyContext {
ContextAttributes contextAttributes = attributesMap.get(controller);
if (contextAttributes == null) {
- throw new IllegalStateException("too many calls");
+ throw new IllegalStateException("too many calls"); //$NON-NLS-1$
}
if (contextAttributes.removeReference() == 0) {
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ServiceHolder.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ServiceHolder.java
new file mode 100644
index 000000000..e82c1569a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ServiceHolder.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) Feb. 2, 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 org.eclipse.equinox.http.servlet.internal.util.Const;
+import org.osgi.framework.*;
+
+public final class ServiceHolder<S> implements Comparable<ServiceHolder<?>> {
+
+ final ServiceObjects<S> serviceObjects;
+ final S service;
+ final Bundle bundle;
+ final long serviceId;
+ final int serviceRanking;
+ final ClassLoader legacyTCCL;
+ private volatile boolean released = false;
+
+ public ServiceHolder(ServiceObjects<S> serviceObjects) {
+ this.serviceObjects = serviceObjects;
+ this.bundle = serviceObjects.getServiceReference().getBundle();
+ this.service = serviceObjects.getService();
+ 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;
+ Object rankProp = serviceObjects.getServiceReference().getProperty(Constants.SERVICE_RANKING);
+ this.serviceRanking = !Integer.class.isInstance(rankProp) ? 0 : ((Integer)rankProp).intValue();
+ }
+
+ 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;
+ }
+
+ public Bundle getBundle() {
+ return bundle;
+ }
+
+ public ClassLoader getLegacyTCCL() {
+ return legacyTCCL;
+ }
+
+ public long getServiceId() {
+ return serviceId;
+ }
+
+ public void release() {
+ if (!released && (serviceObjects != null) && (service != null)) {
+ try {
+ serviceObjects.ungetService(service);
+ } 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
+ // the bundle forgot to unregister on stop
+ }
+ finally {
+ released = true;
+ }
+ }
+ }
+
+ public ServiceReference<S> getServiceReference() {
+ return serviceObjects == null ? null : serviceObjects.getServiceReference();
+ }
+
+ @Override
+ public int compareTo(ServiceHolder<?> o) {
+ final int thisRanking = serviceRanking;
+ final int otherRanking = o.serviceRanking;
+ if (thisRanking != otherRanking) {
+ if (thisRanking < otherRanking) {
+ return 1;
+ }
+ return -1;
+ }
+ final long thisId = this.getServiceId();
+ final long otherId = o.getServiceId();
+ if (thisId == otherId) {
+ return 0;
+ }
+ if (thisId < otherId) {
+ return -1;
+ }
+ return 1;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextErrorPageTrackerCustomizer.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextErrorPageTrackerCustomizer.java
new file mode 100644
index 000000000..b87ef5f9e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextErrorPageTrackerCustomizer.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) Feb. 1, 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.customizer;
+
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.*;
+
+import java.util.concurrent.atomic.AtomicReference;
+import javax.servlet.Servlet;
+import org.eclipse.equinox.http.servlet.internal.HttpServiceRuntimeImpl;
+import org.eclipse.equinox.http.servlet.internal.context.ContextController;
+import org.eclipse.equinox.http.servlet.internal.dto.ExtendedErrorPageDTO;
+import org.eclipse.equinox.http.servlet.internal.error.HttpWhiteboardFailureException;
+import org.eclipse.equinox.http.servlet.internal.registration.ErrorPageRegistration;
+import org.eclipse.equinox.http.servlet.internal.util.Const;
+import org.eclipse.equinox.http.servlet.internal.util.DTOUtil;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.runtime.dto.DTOConstants;
+
+/**
+ * @author Raymond Augé
+ */
+public class ContextErrorPageTrackerCustomizer
+ extends RegistrationServiceTrackerCustomizer<Servlet, ErrorPageRegistration>{
+
+ public ContextErrorPageTrackerCustomizer(
+ BundleContext bundleContext, HttpServiceRuntimeImpl httpServiceRuntime,
+ ContextController contextController) {
+
+ super(bundleContext, httpServiceRuntime, contextController);
+ }
+
+ @Override
+ public AtomicReference<ErrorPageRegistration>
+ addingService(ServiceReference<Servlet> serviceReference) {
+
+ AtomicReference<ErrorPageRegistration> result = new AtomicReference<ErrorPageRegistration>();
+ if (!httpServiceRuntime.matches(serviceReference)) {
+ return result;
+ }
+
+ try {
+ contextController.checkShutdown();
+
+ 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;
+ }
+ else if (contextController.isLegacyContext() &&
+ (serviceReference.getProperty(Const.EQUINOX_LEGACY_TCCL_PROP) == null) && // IS a whiteboard service
+ (serviceReference.getProperty(HTTP_WHITEBOARD_CONTEXT_SELECT) != null) &&
+ (((String)serviceReference.getProperty(HTTP_WHITEBOARD_CONTEXT_SELECT))).contains(HTTP_SERVICE_CONTEXT_PROPERTY.concat(Const.EQUAL)) &&
+ (serviceReference.getProperty(HTTP_WHITEBOARD_SERVLET_PATTERN) != null)) {
+
+ // don't allow whiteboard Servlets that specifically attempt to bind to a legacy context
+ throw new HttpWhiteboardFailureException(
+ "Whiteboard ErrorPages with pattern cannot bind to legacy contexts. " + serviceReference, DTOConstants.FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING); //$NON-NLS-1$
+ }
+
+ httpServiceRuntime.removeFailedErrorPageDTO(serviceReference);
+
+ result.set(contextController.addErrorPageRegistration(serviceReference));
+ }
+ catch (HttpWhiteboardFailureException hwfe) {
+ httpServiceRuntime.log(hwfe.getMessage(), hwfe);
+
+ recordFailed(serviceReference, hwfe.getFailureReason());
+ }
+ catch (Throwable t) {
+ httpServiceRuntime.log(t.getMessage(), t);
+
+ recordFailed(serviceReference, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
+ }
+ finally {
+ httpServiceRuntime.incrementServiceChangecount();
+ }
+
+ return result;
+ }
+
+ @Override
+ void removeFailed(ServiceReference<Servlet> serviceReference) {
+ contextController.getHttpServiceRuntime().removeFailedErrorPageDTO(serviceReference);
+ }
+
+ void recordFailed(ServiceReference<?> servletReference, int failureReason) {
+ ExtendedErrorPageDTO errorPageDTO = DTOUtil.assembleErrorPageDTO(servletReference, contextController.getServiceId(), false);
+
+ contextController.recordFailedErrorPageDTO(servletReference, errorPageDTO, failureReason);
+ }
+
+}
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 ee9efa443..3ab68807b 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
@@ -30,15 +30,13 @@ import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
* @author Raymond Augé
*/
public class ContextFilterTrackerCustomizer
- extends RegistrationServiceTrackerCustomizer<Filter, AtomicReference<FilterRegistration>> {
+ extends RegistrationServiceTrackerCustomizer<Filter, FilterRegistration> {
public ContextFilterTrackerCustomizer(
BundleContext bundleContext, HttpServiceRuntimeImpl httpServiceRuntime,
ContextController contextController) {
- super(bundleContext, httpServiceRuntime);
-
- this.contextController = contextController;
+ super(bundleContext, httpServiceRuntime, contextController);
}
@Override
@@ -51,6 +49,8 @@ public class ContextFilterTrackerCustomizer
}
try {
+ contextController.checkShutdown();
+
if (!contextController.matches(serviceReference)) {
// Only the default context will perform the "does anyone match" checks.
if (httpServiceRuntime.isDefaultContext(contextController) &&
@@ -70,41 +70,26 @@ public class ContextFilterTrackerCustomizer
catch (HttpWhiteboardFailureException hwfe) {
httpServiceRuntime.log(hwfe.getMessage(), hwfe);
- recordFailedFilterDTO(serviceReference, hwfe.getFailureReason());
+ recordFailed(serviceReference, hwfe.getFailureReason());
}
catch (Exception e) {
httpServiceRuntime.log(e.getMessage(), e);
- recordFailedFilterDTO(serviceReference, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
+ recordFailed(serviceReference, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
+ }
+ finally {
+ httpServiceRuntime.incrementServiceChangecount();
}
return result;
}
@Override
- public void modifiedService(
- ServiceReference<Filter> serviceReference,
- AtomicReference<FilterRegistration> filterReference) {
-
- removedService(serviceReference, filterReference);
- AtomicReference<FilterRegistration> added = addingService(serviceReference);
- filterReference.set(added.get());
- }
-
- @Override
- public void removedService(
- ServiceReference<Filter> serviceReference,
- AtomicReference<FilterRegistration> filterReference) {
- FilterRegistration registration = filterReference.get();
- if (registration != null) {
- // Destroy now ungets the object we are using
- registration.destroy();
- }
-
+ void removeFailed(ServiceReference<Filter> serviceReference) {
contextController.getHttpServiceRuntime().removeFailedFilterDTO(serviceReference);
}
- private void recordFailedFilterDTO(
+ private void recordFailed(
ServiceReference<Filter> serviceReference, int failureReason) {
FailedFilterDTO failedFilterDTO = new FailedFilterDTO();
@@ -129,6 +114,4 @@ public class ContextFilterTrackerCustomizer
contextController.getHttpServiceRuntime().recordFailedFilterDTO(serviceReference, failedFilterDTO);
}
- private ContextController contextController;
-
}
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 bb6ad17ce..8edc635be 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
@@ -30,15 +30,13 @@ import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
* @author Raymond Augé
*/
public class ContextListenerTrackerCustomizer
- extends RegistrationServiceTrackerCustomizer<EventListener, AtomicReference<ListenerRegistration>> {
+ extends RegistrationServiceTrackerCustomizer<EventListener, ListenerRegistration> {
public ContextListenerTrackerCustomizer(
BundleContext bundleContext, HttpServiceRuntimeImpl httpServiceRuntime,
ContextController contextController) {
- super(bundleContext, httpServiceRuntime);
-
- this.contextController = contextController;
+ super(bundleContext, httpServiceRuntime, contextController);
}
@Override
@@ -51,6 +49,8 @@ public class ContextListenerTrackerCustomizer
}
try {
+ contextController.checkShutdown();
+
if (!contextController.matches(serviceReference)) {
// Only the default context will perform the "does anyone match" checks.
if (httpServiceRuntime.isDefaultContext(contextController) &&
@@ -82,41 +82,26 @@ public class ContextListenerTrackerCustomizer
catch (HttpWhiteboardFailureException hwfe) {
httpServiceRuntime.log(hwfe.getMessage(), hwfe);
- recordFailedListenerDTO(serviceReference, hwfe.getFailureReason());
+ recordFailed(serviceReference, hwfe.getFailureReason());
}
catch (Exception e) {
httpServiceRuntime.log(e.getMessage(), e);
- recordFailedListenerDTO(serviceReference, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
+ recordFailed(serviceReference, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
+ }
+ finally {
+ httpServiceRuntime.incrementServiceChangecount();
}
return result;
}
@Override
- public void modifiedService(
- ServiceReference<EventListener> serviceReference,
- AtomicReference<ListenerRegistration> listenerRegistration) {
-
- removedService(serviceReference, listenerRegistration);
- addingService(serviceReference);
- }
-
- @Override
- public void removedService(
- ServiceReference<EventListener> serviceReference,
- AtomicReference<ListenerRegistration> listenerReference) {
-
- ListenerRegistration listenerRegistration = listenerReference.get();
- if (listenerRegistration != null) {
- // Destroy now ungets the object we are using
- listenerRegistration.destroy();
- }
-
+ void removeFailed(ServiceReference<EventListener> serviceReference) {
contextController.getHttpServiceRuntime().removeFailedListenerDTO(serviceReference);
}
- private void recordFailedListenerDTO(
+ private void recordFailed(
ServiceReference<EventListener> serviceReference, int failureReason) {
FailedListenerDTO failedListenerDTO = new FailedListenerDTO();
@@ -130,6 +115,4 @@ public class ContextListenerTrackerCustomizer
contextController.getHttpServiceRuntime().recordFailedListenerDTO(serviceReference, failedListenerDTO);
}
- private ContextController contextController;
-
}
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 61477208e..b146baa25 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
@@ -14,11 +14,15 @@
package org.eclipse.equinox.http.servlet.internal.customizer;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_SERVICE_CONTEXT_PROPERTY;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT;
+
import java.util.concurrent.atomic.AtomicReference;
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.ResourceRegistration;
+import org.eclipse.equinox.http.servlet.internal.util.Const;
import org.eclipse.equinox.http.servlet.internal.util.StringPlus;
import org.osgi.framework.*;
import org.osgi.service.http.runtime.dto.DTOConstants;
@@ -29,26 +33,27 @@ import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
* @author Raymond Augé
*/
public class ContextResourceTrackerCustomizer
- extends RegistrationServiceTrackerCustomizer<Object, AtomicReference<ResourceRegistration>> {
+ extends RegistrationServiceTrackerCustomizer<Object, ResourceRegistration> {
public ContextResourceTrackerCustomizer(
BundleContext bundleContext, HttpServiceRuntimeImpl httpServiceRuntime,
ContextController contextController) {
- super(bundleContext, httpServiceRuntime);
-
- this.contextController = contextController;
+ super(bundleContext, httpServiceRuntime, contextController);
}
@Override
public AtomicReference<ResourceRegistration> addingService(
ServiceReference<Object> serviceReference) {
+
AtomicReference<ResourceRegistration> result = new AtomicReference<ResourceRegistration>();
if (!httpServiceRuntime.matches(serviceReference)) {
return result;
}
try {
+ contextController.checkShutdown();
+
if (!contextController.matches(serviceReference)) {
// Only the default context will perform the "does anyone match" checks.
if (httpServiceRuntime.isDefaultContext(contextController) &&
@@ -60,6 +65,15 @@ public class ContextResourceTrackerCustomizer
return result;
}
+ else if (contextController.isLegacyContext() &&
+ (serviceReference.getProperty(Const.EQUINOX_LEGACY_TCCL_PROP) == null) && // IS a whiteboard service
+ (serviceReference.getProperty(HTTP_WHITEBOARD_CONTEXT_SELECT) != null) &&
+ (((String)serviceReference.getProperty(HTTP_WHITEBOARD_CONTEXT_SELECT))).contains(HTTP_SERVICE_CONTEXT_PROPERTY.concat(Const.EQUAL))) {
+
+ // don't allow whiteboard Servlets that specifically attempt to bind to a legacy context
+ throw new HttpWhiteboardFailureException(
+ "Whiteboard resources cannot bind to legacy contexts. " + serviceReference, DTOConstants.FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING); //$NON-NLS-1$
+ }
httpServiceRuntime.removeFailedResourceDTO(serviceReference);
@@ -68,41 +82,26 @@ public class ContextResourceTrackerCustomizer
catch (HttpWhiteboardFailureException hwfe) {
httpServiceRuntime.log(hwfe.getMessage(), hwfe);
- recordFailedResourceDTO(serviceReference, hwfe.getFailureReason());
+ recordFailed(serviceReference, hwfe.getFailureReason());
}
catch (Throwable t) {
httpServiceRuntime.log(t.getMessage(), t);
- recordFailedResourceDTO(serviceReference, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
+ recordFailed(serviceReference, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
+ }
+ finally {
+ httpServiceRuntime.incrementServiceChangecount();
}
return result;
}
@Override
- public void modifiedService(
- ServiceReference<Object> serviceReference,
- AtomicReference<ResourceRegistration> resourceReference) {
-
- removedService(serviceReference, resourceReference);
- AtomicReference<ResourceRegistration> added = addingService(serviceReference);
- resourceReference.set(added.get());
- }
-
- @Override
- public void removedService(
- ServiceReference<Object> serviceReference,
- AtomicReference<ResourceRegistration> resourceReference) {
- ResourceRegistration registration = resourceReference.get();
- if (registration != null) {
- // destroy will unget the service object we were using
- registration.destroy();
- }
-
+ void removeFailed(ServiceReference<Object> serviceReference) {
contextController.getHttpServiceRuntime().removeFailedResourceDTO(serviceReference);
}
- private void recordFailedResourceDTO(
+ private void recordFailed(
ServiceReference<Object> serviceReference, int failureReason) {
FailedResourceDTO failedResourceDTO = new FailedResourceDTO();
@@ -117,6 +116,4 @@ public class ContextResourceTrackerCustomizer
contextController.getHttpServiceRuntime().recordFailedResourceDTO(serviceReference, failedResourceDTO);
}
- private ContextController contextController;
-
}
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 cf5044415..e6e862e16 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
@@ -14,29 +14,32 @@
package org.eclipse.equinox.http.servlet.internal.customizer;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.*;
+
import java.util.concurrent.atomic.AtomicReference;
import javax.servlet.Servlet;
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.Const;
+import org.eclipse.equinox.http.servlet.internal.util.DTOUtil;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.runtime.dto.DTOConstants;
+import org.osgi.service.http.runtime.dto.ServletDTO;
/**
* @author Raymond Augé
*/
public class ContextServletTrackerCustomizer
- extends RegistrationServiceTrackerCustomizer<Servlet, AtomicReference<ServletRegistration>> {
+ extends RegistrationServiceTrackerCustomizer<Servlet, ServletRegistration> {
public ContextServletTrackerCustomizer(
BundleContext bundleContext, HttpServiceRuntimeImpl httpServiceRuntime,
ContextController contextController) {
- super(bundleContext, httpServiceRuntime);
-
- this.contextController = contextController;
+ super(bundleContext, httpServiceRuntime, contextController);
}
@Override
@@ -49,6 +52,8 @@ public class ContextServletTrackerCustomizer
}
try {
+ contextController.checkShutdown();
+
if (!contextController.matches(serviceReference)) {
// Only the default context will perform the "does anyone match" checks.
if (httpServiceRuntime.isDefaultContext(contextController) &&
@@ -60,6 +65,16 @@ public class ContextServletTrackerCustomizer
return result;
}
+ else if (contextController.isLegacyContext() &&
+ (serviceReference.getProperty(Const.EQUINOX_LEGACY_TCCL_PROP) == null) && // IS a whiteboard service
+ (serviceReference.getProperty(HTTP_WHITEBOARD_CONTEXT_SELECT) != null) &&
+ (((String)serviceReference.getProperty(HTTP_WHITEBOARD_CONTEXT_SELECT))).contains(HTTP_SERVICE_CONTEXT_PROPERTY.concat(Const.EQUAL)) &&
+ (serviceReference.getProperty(HTTP_WHITEBOARD_SERVLET_PATTERN) != null)) {
+
+ // don't allow whiteboard Servlets that specifically attempt to bind to a legacy context
+ throw new HttpWhiteboardFailureException(
+ "Whiteboard Servlets with pattern cannot bind to legacy contexts. " + serviceReference, DTOConstants.FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING); //$NON-NLS-1$
+ }
httpServiceRuntime.removeFailedServletDTO(serviceReference);
@@ -68,41 +83,29 @@ public class ContextServletTrackerCustomizer
catch (HttpWhiteboardFailureException hwfe) {
httpServiceRuntime.log(hwfe.getMessage(), hwfe);
- contextController.recordFailedServletDTO(serviceReference, null, hwfe.getFailureReason());
+ recordFailed(serviceReference, hwfe.getFailureReason());
}
catch (Throwable t) {
httpServiceRuntime.log(t.getMessage(), t);
- contextController.recordFailedServletDTO(serviceReference, null, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
+ recordFailed(serviceReference, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
+ }
+ finally {
+ httpServiceRuntime.incrementServiceChangecount();
}
return result;
}
@Override
- public void modifiedService(
- ServiceReference<Servlet> serviceReference,
- AtomicReference<ServletRegistration> servletReference) {
-
- removedService(serviceReference, servletReference);
- AtomicReference<ServletRegistration> added = addingService(serviceReference);
- servletReference.set(added.get());
+ void removeFailed(ServiceReference<Servlet> serviceReference) {
+ contextController.getHttpServiceRuntime().removeFailedServletDTO(serviceReference);
}
- @Override
- public void removedService(
- ServiceReference<Servlet> serviceReference,
- AtomicReference<ServletRegistration> servletReference) {
- ServletRegistration registration = servletReference.get();
- if (registration != null) {
- // destroy will unget the service object we were using
- registration.destroy();
- }
+ void recordFailed(ServiceReference<?> servletReference, int failureReason) {
+ ServletDTO servletDTO = DTOUtil.assembleServletDTO(servletReference, contextController.getServiceId(), false);
- contextController.getHttpServiceRuntime().removeFailedServletDTO(serviceReference);
- contextController.getHttpServiceRuntime().removeFailedErrorPageDTO(serviceReference);
+ contextController.recordFailedServletDTO(servletReference, servletDTO, failureReason);
}
- 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 93954b73c..b974df1f6 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
@@ -14,24 +14,62 @@
package org.eclipse.equinox.http.servlet.internal.customizer;
+import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.equinox.http.servlet.internal.HttpServiceRuntimeImpl;
+import org.eclipse.equinox.http.servlet.internal.context.ContextController;
+import org.eclipse.equinox.http.servlet.internal.registration.Registration;
+import org.osgi.dto.DTO;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
/**
* @author Raymond Augé
*/
-public abstract class RegistrationServiceTrackerCustomizer<S, T>
- implements ServiceTrackerCustomizer<S, T> {
+public abstract class RegistrationServiceTrackerCustomizer<S, T extends Registration<?, ? extends DTO>>
+ implements ServiceTrackerCustomizer<S, AtomicReference<T>> {
public RegistrationServiceTrackerCustomizer(
- BundleContext bundleContext, HttpServiceRuntimeImpl httpServiceRuntime) {
+ BundleContext bundleContext, HttpServiceRuntimeImpl httpServiceRuntime, ContextController contextController) {
this.bundleContext = bundleContext;
this.httpServiceRuntime = httpServiceRuntime;
+ this.contextController = contextController;
}
- protected BundleContext bundleContext;
- protected HttpServiceRuntimeImpl httpServiceRuntime;
+ @Override
+ public void modifiedService(
+ ServiceReference<S> serviceReference,
+ AtomicReference<T> filterReference) {
+
+ removedService(serviceReference, filterReference);
+ AtomicReference<T> added = addingService(serviceReference);
+ filterReference.set(added.get());
+ }
+
+
+ @Override
+ public void removedService(
+ ServiceReference<S> serviceReference,
+ AtomicReference<T> filterReference) {
+
+ try {
+ T registration = filterReference.get();
+ if (registration != null) {
+ registration.destroy();
+ }
+
+ removeFailed(serviceReference);
+ }
+ finally {
+ httpServiceRuntime.incrementServiceChangecount();
+ }
+ }
+
+ abstract void removeFailed(ServiceReference<S> serviceReference);
+
+ protected final BundleContext bundleContext;
+ protected final ContextController contextController;
+ protected final HttpServiceRuntimeImpl httpServiceRuntime;
} \ No newline at end of file
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
index b6f4b31d9..dd105afa9 100644
--- 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
@@ -29,5 +29,5 @@ public class ExtendedErrorPageDTO extends ErrorPageDTO {
/**
* Indicates the type of error codes defined. This is calculated by the system.
*/
- public ErrorCodeType erroCodeType;
+ public ErrorCodeType errorCodeType;
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/NullServletContextHelperException.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/NullServletContextHelperException.java
index f66e798cd..87f5e8bdd 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/NullServletContextHelperException.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/NullServletContextHelperException.java
@@ -22,7 +22,7 @@ public class NullServletContextHelperException extends IllegalArgumentException
private static final long serialVersionUID = 8516340810740210836L;
public NullServletContextHelperException() {
- super("ServletContexHelper cannot be null.");
+ super("ServletContexHelper cannot be null."); //$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/error/PatternInUseException.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/PatternInUseException.java
index 41f2e0843..9fb53303f 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/PatternInUseException.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/PatternInUseException.java
@@ -24,6 +24,6 @@ public class PatternInUseException extends NamespaceException {
private static final long serialVersionUID = -4196149175131735927L;
public PatternInUseException(String pattern) {
- super("Pattern already in use: " + pattern);
+ super("Pattern already in use: " + pattern); //$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/error/RegisteredServletContextHelperException.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/RegisteredServletContextHelperException.java
index 940a139e1..3d0aba890 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/RegisteredServletContextHelperException.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/RegisteredServletContextHelperException.java
@@ -25,7 +25,7 @@ public class RegisteredServletContextHelperException
private static final long serialVersionUID = 7301237379456486249L;
public RegisteredServletContextHelperException() {
- super("ServletContextHelper has already been registered.");
+ super("ServletContextHelper has already been registered."); //$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/error/ServletAlreadyRegisteredException.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/ServletAlreadyRegisteredException.java
index 2af4eec32..522bd5548 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/ServletAlreadyRegisteredException.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/ServletAlreadyRegisteredException.java
@@ -25,7 +25,7 @@ public class ServletAlreadyRegisteredException extends ServletException {
private static final long serialVersionUID = 8838939310124336724L;
public ServletAlreadyRegisteredException(Servlet servlet) {
- super("Servlet has already been registered: " + servlet);
+ super("Servlet has already been registered: " + servlet); //$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/multipart/MultipartSupportFactory.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactory.java
index 05b03d3d3..0d7066edc 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactory.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactory.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
@@ -14,10 +14,10 @@
package org.eclipse.equinox.http.servlet.internal.multipart;
import javax.servlet.ServletContext;
-import org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO;
+import org.osgi.service.http.runtime.dto.ServletDTO;
public interface MultipartSupportFactory {
- MultipartSupport newInstance(ExtendedServletDTO servletDTO, ServletContext servletContext);
+ MultipartSupport newInstance(ServletDTO servletDTO, ServletContext servletContext);
} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactoryImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactoryImpl.java
index cb63bf6a1..d60a08fe6 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactoryImpl.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportFactoryImpl.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
@@ -15,7 +15,7 @@ package org.eclipse.equinox.http.servlet.internal.multipart;
import javax.servlet.ServletContext;
import org.apache.commons.fileupload.FileUploadException;
-import org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO;
+import org.osgi.service.http.runtime.dto.ServletDTO;
public class MultipartSupportFactoryImpl
implements MultipartSupportFactory {
@@ -23,7 +23,7 @@ public class MultipartSupportFactoryImpl
public static final Class<?> FAIL_EARLY = FileUploadException.class;
@Override
- public MultipartSupport newInstance(ExtendedServletDTO servletDTO, ServletContext servletContext) {
+ public MultipartSupport newInstance(ServletDTO servletDTO, ServletContext servletContext) {
return new MultipartSupportImpl(servletDTO, servletContext);
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportImpl.java
index e23b27940..7f7c2b74d 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportImpl.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/multipart/MultipartSupportImpl.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
@@ -25,13 +25,13 @@ import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
-import org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
+import org.osgi.service.http.runtime.dto.ServletDTO;
public class MultipartSupportImpl implements MultipartSupport {
- public MultipartSupportImpl(ExtendedServletDTO servletDTO, ServletContext servletContext) {
+ public MultipartSupportImpl(ServletDTO servletDTO, ServletContext servletContext) {
this.servletDTO = servletDTO;
// Must return non-null File. See Servlet 3.1 §4.8.1
@@ -107,7 +107,7 @@ public class MultipartSupportImpl implements MultipartSupport {
return parts;
}
- private final ExtendedServletDTO servletDTO;
+ private final ServletDTO servletDTO;
private final ServletFileUpload upload;
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 4f4bd27f4..52044f977 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
@@ -19,7 +19,7 @@ import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.context.ServiceHolder;
import org.eclipse.equinox.http.servlet.internal.servlet.Match;
import org.osgi.dto.DTO;
import org.osgi.framework.ServiceReference;
@@ -81,12 +81,12 @@ public abstract class EndpointRegistration<D extends DTO>
EndpointRegistration<?> endpointRegistration = (EndpointRegistration<?>)obj;
- return getT().equals(endpointRegistration.getT());
+ return getD().equals(endpointRegistration.getD());
}
@Override
public int hashCode() {
- return Long.valueOf(getServiceId()).hashCode();
+ return getD().hashCode();
}
//Delegate the init call to the actual servlet
@@ -123,6 +123,10 @@ public abstract class EndpointRegistration<D extends DTO>
String name, String servletPath, String pathInfo, String extension,
Match match) {
+ if (match == Match.ERROR) {
+ return null;
+ }
+
if (name != null) {
if (getName().equals(name)) {
return name;
@@ -169,7 +173,11 @@ public abstract class EndpointRegistration<D extends DTO>
@Override
public int compareTo(EndpointRegistration<?> o) {
- return servletHolder.compareTo(o.servletHolder);
+ int result = servletHolder.compareTo(o.servletHolder);
+ if (result == 0) {
+ result = Long.compare(getD().hashCode(), o.getD().hashCode());
+ }
+ return result;
}
@Override
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ErrorPageRegistration.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ErrorPageRegistration.java
new file mode 100644
index 000000000..d833b2b4b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ErrorPageRegistration.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) Feb. 1, 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.registration;
+
+import javax.servlet.Servlet;
+import org.eclipse.equinox.http.servlet.internal.context.ContextController;
+import org.eclipse.equinox.http.servlet.internal.context.ServiceHolder;
+import org.eclipse.equinox.http.servlet.internal.dto.ExtendedErrorPageDTO;
+import org.eclipse.equinox.http.servlet.internal.servlet.Match;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.context.ServletContextHelper;
+
+/**
+ * @author Raymond Augé
+ */
+public class ErrorPageRegistration extends EndpointRegistration<ExtendedErrorPageDTO> {
+
+ public ErrorPageRegistration(
+ ServiceHolder<Servlet> servletHolder, ExtendedErrorPageDTO errorPageDTO,
+ ServletContextHelper servletContextHelper,
+ ContextController contextController) {
+
+ super(servletHolder, errorPageDTO, servletContextHelper, contextController);
+ }
+
+ @Override
+ public String getName() {
+ return getD().name;
+ }
+
+ @Override
+ public String[] getPatterns() {
+ return EMPTY;
+ }
+
+ @Override
+ public long getServiceId() {
+ return getD().serviceId;
+ }
+
+ @Override
+ public ServiceReference<?> getServiceReference() {
+ return servletHolder.getServiceReference();
+ }
+
+ @Override
+ public boolean needDecode() {
+ return false;
+ }
+
+ @Override
+ public String match(
+ String name, String servletPath, String pathInfo, String extension,
+ Match match) {
+
+ if (match != Match.ERROR) {
+ return null;
+ }
+
+ if (name != null) {
+ for (long errorCode : getD().errorCodes) {
+ if (String.valueOf(errorCode).equals(name)) {
+ return name;
+ }
+ }
+
+ for (String exception : getD().exceptions) {
+ if (exception.equals(name)) {
+ return name;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private static final String[] EMPTY = new String[0];
+
+}
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 8cc36da4f..6c84a4590 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
@@ -21,7 +21,7 @@ import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.context.ServiceHolder;
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;
@@ -236,10 +236,6 @@ public class FilterRegistration
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 false;
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ListenerRegistration.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ListenerRegistration.java
index cf79c4d3f..5e4321e67 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ListenerRegistration.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/ListenerRegistration.java
@@ -19,7 +19,7 @@ import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
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.context.ServiceHolder;
import org.eclipse.equinox.http.servlet.internal.servlet.HttpSessionAdaptor;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.service.http.runtime.dto.ListenerDTO;
@@ -131,27 +131,36 @@ public class ListenerRegistration extends Registration<EventListener, ListenerDT
contextController);
}
+ ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
+ EventListener getDelegate() {
+ return super.getT();
+ }
+
private class EventListenerInvocationHandler implements InvocationHandler {
public EventListenerInvocationHandler() {
}
@Override
- public Object invoke(Object proxy, Method method, Object[] args)
+ public Object invoke(Object theProxy, Method method, Object[] args)
throws Throwable {
- ClassLoader original = Thread.currentThread().getContextClassLoader();
+ Thread thread = Thread.currentThread();
+ ClassLoader original = thread.getContextClassLoader();
try {
- Thread.currentThread().setContextClassLoader(classLoader);
+ thread.setContextClassLoader(getClassLoader());
try {
- return method.invoke(ListenerRegistration.super.getT(), args);
+ return method.invoke(getDelegate(), args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
finally {
- Thread.currentThread().setContextClassLoader(original);
+ thread.setContextClassLoader(original);
}
}
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/PreprocessorRegistration.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/PreprocessorRegistration.java
new file mode 100644
index 000000000..99f018300
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/registration/PreprocessorRegistration.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) Feb. 2, 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.registration;
+
+import java.io.IOException;
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.eclipse.equinox.http.servlet.internal.HttpServiceRuntimeImpl;
+import org.eclipse.equinox.http.servlet.internal.context.ServiceHolder;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.service.http.runtime.dto.PreprocessorDTO;
+import org.osgi.service.http.whiteboard.Preprocessor;
+
+/**
+ * @author Raymond Augé
+ */
+public class PreprocessorRegistration extends Registration<Preprocessor, PreprocessorDTO>
+ implements Comparable<PreprocessorRegistration> {
+
+ private final ServiceHolder<Preprocessor> preprocessorHolder;
+ private final ClassLoader classLoader;
+ private final HttpServiceRuntimeImpl httpServiceRuntime;
+
+ public PreprocessorRegistration(
+ ServiceHolder<Preprocessor> preprocessorHolder, PreprocessorDTO preprocessorDTO,
+ HttpServiceRuntimeImpl httpServiceRuntime) {
+
+ super(preprocessorHolder.get(), preprocessorDTO);
+ this.preprocessorHolder = preprocessorHolder;
+ this.httpServiceRuntime = httpServiceRuntime;
+ this.classLoader = preprocessorHolder.getBundle().adapt(BundleWiring.class).getClassLoader();
+ }
+
+ @Override
+ public int compareTo(PreprocessorRegistration o) {
+ ServiceReference<Preprocessor> thisRef = preprocessorHolder.getServiceReference();
+ ServiceReference<Preprocessor> otherRef = o.preprocessorHolder.getServiceReference();
+ return thisRef.compareTo(otherRef);
+ }
+
+ public void doFilter(
+ HttpServletRequest request, HttpServletResponse response,
+ FilterChain chain)
+ throws IOException, ServletException {
+
+ ClassLoader original = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(classLoader);
+ getT().doFilter(request, response, chain);
+ }
+ finally {
+ Thread.currentThread().setContextClassLoader(original);
+ }
+ }
+
+ @Override
+ public void destroy() {
+ ClassLoader original = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(classLoader);
+ httpServiceRuntime.getPreprocessorRegistrations().remove(preprocessorHolder.getServiceReference());
+ preprocessorHolder.getBundle().getBundleContext().ungetService(preprocessorHolder.getServiceReference());
+ super.destroy();
+ getT().destroy();
+ }
+ finally {
+ Thread.currentThread().setContextClassLoader(original);
+ preprocessorHolder.release();
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Long.valueOf(getD().serviceId).hashCode();
+ }
+
+ public void init(FilterConfig filterConfig) throws ServletException {
+ ClassLoader original = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(classLoader);
+
+ getT().init(filterConfig);
+ }
+ finally {
+ Thread.currentThread().setContextClassLoader(original);
+ }
+ }
+
+}
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 5a6e535e4..671f7d49f 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
@@ -16,7 +16,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.eclipse.equinox.http.servlet.internal.context.ServiceHolder;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.context.ServletContextHelper;
import org.osgi.service.http.runtime.dto.ResourceDTO;
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 9e61c8e9f..761a39146 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
@@ -20,18 +20,16 @@ import java.util.*;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
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.context.ServiceHolder;
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.ServletDTO;
//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> {
+public class ServletRegistration extends EndpointRegistration<ServletDTO> {
private static MultipartSupportFactory factory;
@@ -52,14 +50,12 @@ public class ServletRegistration extends EndpointRegistration<ExtendedServletDTO
}
public ServletRegistration(
- ServiceHolder<Servlet> servletHolder, ExtendedServletDTO servletDTO, ExtendedErrorPageDTO errorPageDTO,
+ ServiceHolder<Servlet> servletHolder, ServletDTO servletDTO,
ServletContextHelper servletContextHelper,
ContextController contextController, ServletContext servletContext) {
super(servletHolder, servletDTO, servletContextHelper, contextController);
- this.errorPageDTO = errorPageDTO;
-
if (servletDTO.multipartEnabled) {
if (factory == null) {
throw new IllegalStateException(
@@ -73,10 +69,6 @@ public class ServletRegistration extends EndpointRegistration<ExtendedServletDTO
needDecode = MatchableRegistration.patternsRequireDecode(servletDTO.patterns);
}
- public ExtendedErrorPageDTO getErrorPageDTO() {
- return errorPageDTO;
- }
-
@Override
public String getName() {
return getD().name;
@@ -97,28 +89,6 @@ public class ServletRegistration extends EndpointRegistration<ExtendedServletDTO
return servletHolder.getServiceReference();
}
- @Override
- public String match(
- String name, String servletPath, String pathInfo, String extension,
- Match match) {
-
- if ((errorPageDTO != null) && (name != null)) {
- for (long errorCode : errorPageDTO.errorCodes) {
- if (String.valueOf(errorCode).equals(name)) {
- return name;
- }
- }
-
- for (String exception : errorPageDTO.exceptions) {
- if (exception.equals(name)) {
- return name;
- }
- }
- }
-
- return super.match(name, servletPath, pathInfo, extension, match);
- }
-
public Map<String, Part> parseRequest(HttpServletRequest request) throws IOException, ServletException {
if (multipartSupport == null) {
throw new IOException("Servlet not configured for multipart!"); //$NON-NLS-1$
@@ -132,6 +102,5 @@ public class ServletRegistration extends EndpointRegistration<ExtendedServletDTO
}
private final boolean needDecode;
- 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/FilterChainImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/FilterChainImpl.java
index ea3dfeba6..6f9474e69 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/FilterChainImpl.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/FilterChainImpl.java
@@ -24,11 +24,11 @@ import org.eclipse.equinox.http.servlet.internal.registration.FilterRegistration
public class FilterChainImpl implements FilterChain {
- private List<FilterRegistration> matchingFilterRegistrations;
- private EndpointRegistration<?> registration;
- private DispatcherType dispatcherType;
+ private final List<FilterRegistration> matchingFilterRegistrations;
+ private final EndpointRegistration<?> registration;
+ private final DispatcherType dispatcherType;
+ private final int filterCount;
private int filterIndex = 0;
- private int filterCount;
public FilterChainImpl(
List<FilterRegistration> matchingFilterRegistrations,
@@ -41,7 +41,7 @@ public class FilterChainImpl implements FilterChain {
}
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
- while (filterIndex < filterCount) {
+ if (filterIndex < filterCount) {
FilterRegistration filterRegistration = matchingFilterRegistrations.get(filterIndex++);
if (filterRegistration.appliesTo(this)) {
@@ -50,6 +50,7 @@ public class FilterChainImpl implements FilterChain {
return;
}
}
+
registration.service((HttpServletRequest) request, (HttpServletResponse) response);
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletResponseWrapperImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletResponseWrapperImpl.java
index 9f8755d93..ede5cefe8 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletResponseWrapperImpl.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/HttpServletResponseWrapperImpl.java
@@ -32,14 +32,14 @@ public class HttpServletResponseWrapperImpl extends HttpServletResponseWrapper {
}
@Override
- public void sendError(int status) {
- this.status = status;
+ public void sendError(int theStatus) {
+ this.status = theStatus;
}
@Override
- public void sendError(int status, String message) {
- this.status = status;
- this.message = message;
+ public void sendError(int theStatus, String theMessage) {
+ this.status = theStatus;
+ this.message = theMessage;
}
public String getMessage() {
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/IncludeDispatchResponseWrapper.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/IncludeDispatchResponseWrapper.java
index a3a8cf667..5fe6d0235 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/IncludeDispatchResponseWrapper.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/IncludeDispatchResponseWrapper.java
@@ -97,6 +97,7 @@ public class IncludeDispatchResponseWrapper extends HttpServletResponseWrapper {
}
@Override
+ @SuppressWarnings("deprecation")
public void setStatus(int sc, String sm) {
return;
}
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 ab69bf783..270bb07fd 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
@@ -19,6 +19,6 @@ package org.eclipse.equinox.http.servlet.internal.servlet;
*/
public enum Match {
- EXACT, EXTENSION, REGEX, DEFAULT_SERVLET, CONTEXT_ROOT
+ EXACT, ERROR, EXTENSION, REGEX, DEFAULT_SERVLET, CONTEXT_ROOT
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/PreprocessorChainImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/PreprocessorChainImpl.java
new file mode 100644
index 000000000..47f416fc3
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/PreprocessorChainImpl.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 IBM Corporation and others.
+ *
+ * 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:
+ * IBM Corporation - initial API and implementation
+ * Raymond Augé <raymond.auge@liferay.com> - Bug 436698
+ *******************************************************************************/
+package org.eclipse.equinox.http.servlet.internal.servlet;
+
+import java.io.IOException;
+import java.util.List;
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.eclipse.equinox.http.servlet.internal.registration.PreprocessorRegistration;
+
+public class PreprocessorChainImpl implements FilterChain {
+
+ private final ProxyServlet proxyServlet;
+ private final List<PreprocessorRegistration> preprocessors;
+ private final String alias;
+ private final DispatcherType dispatcherType;
+ private final int filterCount;
+ private int filterIndex = 0;
+
+ public PreprocessorChainImpl(
+ List<PreprocessorRegistration> preprocessors,
+ String alias, DispatcherType dispatcherType, ProxyServlet proxyServlet) {
+
+ this.preprocessors = preprocessors;
+ this.alias = alias;
+ this.dispatcherType = dispatcherType;
+ this.proxyServlet = proxyServlet;
+ this.filterCount = preprocessors.size();
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
+ if (filterIndex < filterCount) {
+ PreprocessorRegistration registration = preprocessors.get(filterIndex++);
+
+ registration.doFilter(
+ (HttpServletRequest) request, (HttpServletResponse) response, this);
+
+ return;
+ }
+
+ proxyServlet.dispatch(
+ (HttpServletRequest) request, (HttpServletResponse) response, alias, dispatcherType);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java
index 9e97b0a0e..d56f08259 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java
@@ -17,12 +17,19 @@
package org.eclipse.equinox.http.servlet.internal.servlet;
import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.CopyOnWriteArrayList;
import javax.servlet.*;
import javax.servlet.http.*;
import org.eclipse.equinox.http.servlet.internal.Activator;
import org.eclipse.equinox.http.servlet.internal.HttpServiceRuntimeImpl;
import org.eclipse.equinox.http.servlet.internal.context.DispatchTargets;
+import org.eclipse.equinox.http.servlet.internal.registration.PreprocessorRegistration;
import org.eclipse.equinox.http.servlet.internal.util.Const;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.whiteboard.Preprocessor;
/**
* The ProxyServlet is the private side of a Servlet that when registered (and init() called) in a servlet container
@@ -88,11 +95,50 @@ public class ProxyServlet extends HttpServlet {
alias = Const.SLASH;
}
+ preprocess(request, response, alias, request.getDispatcherType());
+ }
+
+ public void preprocess(
+ HttpServletRequest request,
+ HttpServletResponse response, String alias, DispatcherType dispatcherType)
+ throws ServletException, IOException {
+
+ Map<ServiceReference<Preprocessor>, PreprocessorRegistration> registrations = httpServiceRuntimeImpl.getPreprocessorRegistrations();
+
+ if (registrations.isEmpty()) {
+ dispatch(request, response, alias, dispatcherType);
+ }
+ else {
+ List<PreprocessorRegistration> preprocessors = new CopyOnWriteArrayList<>();
+
+ for (Entry<ServiceReference<Preprocessor>, PreprocessorRegistration> entry : registrations.entrySet()) {
+ PreprocessorRegistration registration = entry.getValue();
+ preprocessors.add(registration);
+ registration.addReference();
+ }
+
+ try {
+ FilterChain chain = new PreprocessorChainImpl(preprocessors, alias, dispatcherType, this);
+
+ chain.doFilter(request, response);
+ }
+ finally {
+ for (PreprocessorRegistration registration : preprocessors) {
+ registration.removeReference();
+ }
+ }
+ }
+ }
+
+ public void dispatch(
+ HttpServletRequest request,
+ HttpServletResponse response, String alias, DispatcherType dispatcherType)
+ throws ServletException, IOException {
+
DispatchTargets dispatchTargets = httpServiceRuntimeImpl.getDispatchTargets(alias, null);
if (dispatchTargets != null) {
- dispatchTargets.doDispatch(
- request, response, alias, request.getDispatcherType());
+ dispatchTargets.doDispatch(request, response, alias, dispatcherType);
return;
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResourceServlet.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResourceServlet.java
index 3bbb79755..c3d23e404 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResourceServlet.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ResourceServlet.java
@@ -148,9 +148,7 @@ public class ResourceServlet extends HttpServlet {
if (contentLength != 0) {
// open the input stream
- InputStream is = null;
- try {
- is = connection.getInputStream();
+ try (InputStream is = connection.getInputStream()) {
// write the resource
try {
OutputStream os = resp.getOutputStream();
@@ -173,13 +171,6 @@ public class ResourceServlet extends HttpServlet {
// SecurityException may indicate the following scenarios
// - url is not accessible
sendError(resp, HttpServletResponse.SC_FORBIDDEN);
- } finally {
- if (is != null)
- try {
- is.close();
- } catch (IOException e) {
- // ignore
- }
}
}
return Boolean.TRUE;
@@ -233,8 +224,7 @@ public class ResourceServlet extends HttpServlet {
}
}
- Reader reader = new InputStreamReader(is);
- try {
+ try (Reader reader = new InputStreamReader(is)) {
char[] buffer = new char[8192];
int charsRead = reader.read(buffer);
int writtenContentLength = 0;
@@ -246,10 +236,6 @@ public class ResourceServlet extends HttpServlet {
writtenContentLength += charsRead;
charsRead = reader.read(buffer);
}
- } finally {
- if (reader != null) {
- reader.close(); // will also close input stream
- }
}
}
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 c3f820753..caffecf6b 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
@@ -62,16 +62,21 @@ public class ResponseStateHandler {
}
if (endpoint.getServletContextHelper().handleSecurity(request, response)) {
- if (filters.isEmpty()) {
- endpoint.service(request, response);
- }
- else {
- Collections.sort(filters);
+ try {
+ if (filters.isEmpty()) {
+ endpoint.service(request, response);
+ }
+ else {
+ Collections.sort(filters);
- FilterChain chain = new FilterChainImpl(
- filters, endpoint, dispatchTargets.getDispatcherType());
+ FilterChain chain = new FilterChainImpl(
+ filters, endpoint, dispatchTargets.getDispatcherType());
- chain.doFilter(request, response);
+ chain.doFilter(request, response);
+ }
+ }
+ finally {
+ endpoint.getServletContextHelper().finishSecurity(request, response);
}
}
}
@@ -144,14 +149,12 @@ public class ResponseStateHandler {
responseWrapper.setCompleted(true);
}
else {
- try {
- PrintWriter writer = response.getWriter();
- writer.close();
+ try (PrintWriter writer = response.getWriter()) {
+ // just force a close
}
catch (IllegalStateException ise1) {
- try {
- ServletOutputStream outputStream = response.getOutputStream();
- outputStream.close();
+ try (ServletOutputStream outputStream = response.getOutputStream()) {
+ // just force a close
}
catch (IllegalStateException ise2) {
// ignore
@@ -219,7 +222,7 @@ public class ResponseStateHandler {
do {
errorDispatchTargets = contextController.getDispatchTargets(
- className, null, null, null, null, null, Match.EXACT, null);
+ className, null, null, null, null, null, Match.ERROR, null);
if (errorDispatchTargets != null) {
break;
@@ -319,7 +322,7 @@ public class ResponseStateHandler {
ContextController contextController = dispatchTargets.getContextController();
DispatchTargets errorDispatchTargets = contextController.getDispatchTargets(
- String.valueOf(status), null, null, null, null, null, Match.EXACT, null);
+ String.valueOf(status), null, null, null, null, null, Match.ERROR, null);
if (errorDispatchTargets == null) {
wrappedResponse.sendError(status, responseWrapper.getMessage());
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ServletContextAdaptor.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ServletContextAdaptor.java
index b70a0165a..d72037e56 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ServletContextAdaptor.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ServletContextAdaptor.java
@@ -395,8 +395,8 @@ public class ServletContextAdaptor {
Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
boolean useThreadLocal =
- "removeAttribute".equals(method.getName()) ||
- "setAttribute".equals(method.getName());
+ "removeAttribute".equals(method.getName()) || //$NON-NLS-1$
+ "setAttribute".equals(method.getName()); //$NON-NLS-1$
if (useThreadLocal) {
servletContextTL.set((ServletContext)proxy);
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 59899f3fc..c7353a7ab 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
@@ -14,11 +14,16 @@
package org.eclipse.equinox.http.servlet.internal.util;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.*;
+
import java.lang.reflect.Array;
import java.util.*;
-import org.eclipse.equinox.http.servlet.dto.ExtendedFailedServletDTO;
-import org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO;
+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.HttpWhiteboardFailureException;
import org.osgi.dto.DTO;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
import org.osgi.service.http.runtime.dto.*;
/**
@@ -26,6 +31,220 @@ import org.osgi.service.http.runtime.dto.*;
*/
public class DTOUtil {
+ public static ExtendedErrorPageDTO assembleErrorPageDTO(ServiceReference<?> serviceReference, long contextId, boolean validated) {
+ Object errorPageObj = serviceReference.getProperty(HTTP_WHITEBOARD_SERVLET_ERROR_PAGE);
+
+ if (errorPageObj == null) {
+ return null;
+ }
+
+ ExtendedErrorPageDTO errorPageDTO = new ExtendedErrorPageDTO();
+
+ errorPageDTO.asyncSupported = false;
+ Object asyncSupportedObj = serviceReference.getProperty(HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED);
+ if (asyncSupportedObj == null) {
+ // ignored
+ }
+ else if (Boolean.class.isInstance(asyncSupportedObj)) {
+ errorPageDTO.asyncSupported = ((Boolean)asyncSupportedObj).booleanValue();
+ }
+ else if (String.class.isInstance(asyncSupportedObj)) {
+ errorPageDTO.asyncSupported = Boolean.valueOf((String)asyncSupportedObj);
+ }
+ // There is no validation for this scenario, truthiness of any other input is false
+
+ List<String> errorPages = StringPlus.from(errorPageObj);
+ if (errorPages.isEmpty()) {
+ throw new HttpWhiteboardFailureException("'errorPage' expects String, String[] or Collection<String>", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
+ }
+
+ List<String> exceptions = new ArrayList<String>();
+ Set<Long> errorCodeSet = new LinkedHashSet<Long>();
+
+ for(String errorPage : errorPages) {
+ try {
+ if ("4xx".equals(errorPage)) { //$NON-NLS-1$
+ errorPageDTO.errorCodeType = ErrorCodeType.RANGE_4XX;
+ for (long code = 400; code < 500; code++) {
+ errorCodeSet.add(code);
+ }
+ } else if ("5xx".equals(errorPage)) { //$NON-NLS-1$
+ errorPageDTO.errorCodeType = ErrorCodeType.RANGE_5XX;
+ for (long code = 500; code < 600; code++) {
+ errorCodeSet.add(code);
+ }
+ } else if (errorPage.matches("\\d{3}")) { //$NON-NLS-1$
+ errorPageDTO.errorCodeType = ErrorCodeType.SPECIFIC;
+ long code = Long.parseLong(errorPage);
+ errorCodeSet.add(code);
+ } else {
+ exceptions.add(errorPage);
+ }
+ }
+ catch (NumberFormatException nfe) {
+ exceptions.add(errorPage);
+ }
+ }
+
+ errorPageDTO.errorCodes = new long[errorCodeSet.size()];
+ int i = 0;
+ for(Long code : errorCodeSet) {
+ errorPageDTO.errorCodes[i] = code;
+ i++;
+ }
+
+ errorPageDTO.exceptions = exceptions.toArray(new String[0]);
+
+ errorPageDTO.initParams = ServiceProperties.parseInitParams(
+ serviceReference, HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX);
+
+ Object servletNameObj = serviceReference.getProperty(HTTP_WHITEBOARD_SERVLET_NAME);
+ if (servletNameObj == null) {
+ // ignore
+ }
+ else if (String.class.isInstance(servletNameObj)) {
+ errorPageDTO.name = (String)servletNameObj;
+ }
+ else if (validated) {
+ throw new HttpWhiteboardFailureException("'name' expects String", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
+ }
+
+ errorPageDTO.serviceId = (Long)serviceReference.getProperty(Constants.SERVICE_ID);
+ errorPageDTO.servletContextId = contextId;
+
+ return errorPageDTO;
+ }
+
+ @SuppressWarnings("deprecation")
+ public static org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO assembleServletDTO(ServiceReference<?> serviceReference, long contextId, boolean validated) {
+ org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO servletDTO = new org.eclipse.equinox.http.servlet.dto.ExtendedServletDTO();
+
+ servletDTO.asyncSupported = false;
+ Object asyncSupportedObj = serviceReference.getProperty(HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED);
+ if (asyncSupportedObj == null) {
+ // ignored
+ }
+ else if (Boolean.class.isInstance(asyncSupportedObj)) {
+ servletDTO.asyncSupported = ((Boolean)asyncSupportedObj).booleanValue();
+ }
+ else if (String.class.isInstance(asyncSupportedObj)) {
+ servletDTO.asyncSupported = Boolean.valueOf((String)asyncSupportedObj);
+ }
+ // There is no validation for this scenario, truthiness of any other input is false
+
+ servletDTO.initParams = ServiceProperties.parseInitParams(
+ serviceReference, HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX);
+
+ servletDTO.multipartEnabled = false;
+ Object multipartEnabledObj = serviceReference.getProperty(HTTP_WHITEBOARD_SERVLET_MULTIPART_ENABLED);
+ if (multipartEnabledObj == null) {
+ multipartEnabledObj = serviceReference.getProperty(Const.EQUINOX_HTTP_MULTIPART_ENABLED);
+ }
+ if (multipartEnabledObj == null) {
+ // ignore
+ }
+ else if (Boolean.class.isInstance(multipartEnabledObj)) {
+ servletDTO.multipartEnabled = ((Boolean)multipartEnabledObj).booleanValue();
+ }
+ else if (String.class.isInstance(multipartEnabledObj)) {
+ servletDTO.multipartEnabled = Boolean.valueOf((String)multipartEnabledObj);
+ }
+ // There is no validation for this scenario, truthiness of any other input is false
+
+ servletDTO.multipartFileSizeThreshold = 0;
+ servletDTO.multipartLocation = Const.BLANK;
+ servletDTO.multipartMaxFileSize = -1L;
+ servletDTO.multipartMaxRequestSize = -1L;
+
+ if (servletDTO.multipartEnabled) {
+ Object multipartFileSizeThresholdObj = serviceReference.getProperty(HTTP_WHITEBOARD_SERVLET_MULTIPART_FILESIZETHRESHOLD);
+ if (multipartFileSizeThresholdObj == null) {
+ multipartFileSizeThresholdObj = serviceReference.getProperty(Const.EQUINOX_HTTP_MULTIPART_FILESIZETHRESHOLD);
+ }
+ if (multipartFileSizeThresholdObj == null) {
+ // ignore
+ }
+ else if (Integer.class.isInstance(multipartFileSizeThresholdObj)) {
+ servletDTO.multipartFileSizeThreshold = ((Integer)multipartFileSizeThresholdObj).intValue();
+ }
+ else if (validated) {
+ throw new HttpWhiteboardFailureException("'multipartFileSizeThreshold' expects int or Integer", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
+ }
+
+ Object multipartLocationObj = serviceReference.getProperty(HTTP_WHITEBOARD_SERVLET_MULTIPART_LOCATION);
+ if (multipartLocationObj == null) {
+ multipartLocationObj = serviceReference.getProperty(Const.EQUINOX_HTTP_MULTIPART_LOCATION);
+ }
+ if (multipartLocationObj == null) {
+ // ignore
+ }
+ else if (String.class.isInstance(multipartLocationObj)) {
+ servletDTO.multipartLocation = (String)multipartLocationObj;
+ }
+ else if (validated) {
+ throw new HttpWhiteboardFailureException("'multipartLocation' expects String", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
+ }
+
+ Object multipartMaxFileSizeObj = serviceReference.getProperty(HTTP_WHITEBOARD_SERVLET_MULTIPART_MAXFILESIZE);
+ if (multipartMaxFileSizeObj == null) {
+ multipartMaxFileSizeObj = serviceReference.getProperty(Const.EQUINOX_HTTP_MULTIPART_MAXFILESIZE);
+ }
+ if (multipartMaxFileSizeObj == null) {
+ // ignore
+ }
+ else if (Long.class.isInstance(multipartMaxFileSizeObj)) {
+ servletDTO.multipartMaxFileSize = ((Long)multipartMaxFileSizeObj).longValue();
+ }
+ else if (validated) {
+ throw new HttpWhiteboardFailureException("'multipartMaxFileSize' expects [L|l]ong", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
+ }
+
+ Object multipartMaxRequestSizeObj = serviceReference.getProperty(HTTP_WHITEBOARD_SERVLET_MULTIPART_MAXREQUESTSIZE);
+ if (multipartMaxRequestSizeObj == null) {
+ multipartMaxRequestSizeObj = serviceReference.getProperty(Const.EQUINOX_HTTP_MULTIPART_MAXREQUESTSIZE);
+ }
+ if (multipartMaxRequestSizeObj == null) {
+ // ignore
+ }
+ else if (Long.class.isInstance(multipartMaxRequestSizeObj)) {
+ servletDTO.multipartMaxRequestSize = ((Long)multipartMaxRequestSizeObj).longValue();
+ }
+ else if (validated) {
+ throw new HttpWhiteboardFailureException("'multipartMaxRequestSize' expects [L|l]ong", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
+ }
+ }
+
+ Object servletNameObj = serviceReference.getProperty(HTTP_WHITEBOARD_SERVLET_NAME);
+ if (servletNameObj == null) {
+ // ignore
+ }
+ else if (String.class.isInstance(servletNameObj)) {
+ servletDTO.name = (String)servletNameObj;
+ }
+ else if (validated) {
+ throw new HttpWhiteboardFailureException("'name' expects String", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$
+ }
+
+ Object patternObj = serviceReference.getProperty(HTTP_WHITEBOARD_SERVLET_PATTERN);
+ if (patternObj == null) {
+ servletDTO.patterns = new String[0];
+ }
+ else {
+ servletDTO.patterns = sort(StringPlus.from(patternObj).toArray(new String[0]));
+
+ if (validated && (servletDTO.patterns.length > 0)) {
+ for (String pattern : servletDTO.patterns) {
+ checkPattern(pattern);
+ }
+ }
+ }
+
+ servletDTO.serviceId = (Long)serviceReference.getProperty(Constants.SERVICE_ID);
+ servletDTO.servletContextId = contextId;
+
+ return servletDTO;
+ }
+
public static ErrorPageDTO clone(ErrorPageDTO original) {
ErrorPageDTO clone = new ErrorPageDTO();
@@ -85,6 +304,16 @@ public class DTOUtil {
return clone;
}
+ public static FailedPreprocessorDTO clone(FailedPreprocessorDTO original) {
+ FailedPreprocessorDTO clone = new FailedPreprocessorDTO();
+
+ clone.failureReason = copy(original.failureReason);
+ clone.initParams = copyStringMap(original.initParams);
+ clone.serviceId = copy(original.serviceId);
+
+ return clone;
+ }
+
public static FailedResourceDTO clone(FailedResourceDTO original) {
FailedResourceDTO clone = new FailedResourceDTO();
@@ -115,8 +344,8 @@ public class DTOUtil {
return clone;
}
- public static ExtendedFailedServletDTO clone(ExtendedFailedServletDTO original) {
- ExtendedFailedServletDTO clone = new ExtendedFailedServletDTO();
+ public static FailedServletDTO clone(FailedServletDTO original) {
+ FailedServletDTO clone = new FailedServletDTO();
clone.asyncSupported = copy(original.asyncSupported);
clone.failureReason = copy(original.failureReason);
@@ -172,8 +401,8 @@ public class DTOUtil {
return clone;
}
- public static ExtendedServletDTO clone(ExtendedServletDTO original) {
- ExtendedServletDTO clone = new ExtendedServletDTO();
+ public static ServletDTO clone(ServletDTO original) {
+ ServletDTO clone = new ServletDTO();
clone.asyncSupported = copy(original.asyncSupported);
clone.initParams = copyStringMap(original.initParams);
@@ -301,6 +530,32 @@ public class DTOUtil {
return String.valueOf(v);
}
+ private static void checkPattern(String pattern) {
+ if (pattern == 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.contains("**")) { //$NON-NLS-1$
+
+ throw new HttpWhiteboardFailureException(
+ "Invalid pattern '" + pattern + "'", DTOConstants.FAILURE_REASON_VALIDATION_FAILED); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
private static Class<?> mapComponentType(Class<?> componentType) {
if (componentType.isPrimitive()
|| componentType.isArray()
@@ -335,4 +590,15 @@ public class DTOUtil {
private static <K, V> Map<K, V> newMap(int size) {
return new HashMap<K, V>(size);
}
+
+ private static String[] sort(String[] values) {
+ if (values == null) {
+ return null;
+ }
+
+ Arrays.sort(values);
+
+ return values;
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/EventListeners.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/EventListeners.java
index ff1d9fd8c..e19f00e62 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/EventListeners.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/EventListeners.java
@@ -26,7 +26,7 @@ public class EventListeners {
public <E extends EventListener> List<E> get(Class<E> clazz) {
if (clazz == null) {
- throw new NullPointerException("clazz can't be null");
+ throw new NullPointerException("clazz can't be null"); //$NON-NLS-1$
}
List<ListenerRegistration> list = map.get(clazz);
@@ -42,7 +42,7 @@ public class EventListeners {
Class<E> clazz, ListenerRegistration listenerRegistration) {
if (clazz == null) {
- throw new NullPointerException("clazz can't be null");
+ throw new NullPointerException("clazz can't be null"); //$NON-NLS-1$
}
List<ListenerRegistration> list = map.get(clazz);
@@ -74,7 +74,7 @@ public class EventListeners {
Class<E> clazz, ListenerRegistration listenerRegistration) {
if (clazz == null) {
- throw new NullPointerException("clazz can't be null");
+ throw new NullPointerException("clazz can't be null"); //$NON-NLS-1$
}
List<ListenerRegistration> list = map.get(clazz);
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/HttpTuple.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/HttpTuple.java
index 016437e51..b7183c9f1 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/HttpTuple.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/HttpTuple.java
@@ -39,6 +39,7 @@ public class HttpTuple {
Activator.unregisterHttpService(proxyServlet);
proxyServlet.setHttpServiceRuntimeImpl(null);
hsfRegistration.unregister();
+ httpServiceRuntime.setHsrRegistration(null);
hsrRegistration.unregister();
httpServiceRuntime.destroy();
}

Back to the top