| /******************************************************************************* |
| * Copyright (c) 2016 Raymond Augé and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Raymond Augé <raymond.auge@liferay.com> - Bug 436698 |
| ******************************************************************************/ |
| |
| package org.eclipse.equinox.http.servlet.internal.context; |
| |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.security.AccessController; |
| import java.util.*; |
| import java.util.concurrent.*; |
| import java.util.concurrent.atomic.AtomicReference; |
| import java.util.regex.Pattern; |
| import javax.servlet.*; |
| import javax.servlet.Filter; |
| import javax.servlet.http.*; |
| 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.error.*; |
| import org.eclipse.equinox.http.servlet.internal.registration.*; |
| import org.eclipse.equinox.http.servlet.internal.registration.FilterRegistration; |
| import org.eclipse.equinox.http.servlet.internal.registration.ServletRegistration; |
| import org.eclipse.equinox.http.servlet.internal.servlet.*; |
| 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; |
| |
| /** |
| * @author Raymond Augé |
| */ |
| 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; |
| public ServiceHolder(ServiceObjects<S> serviceObjects) { |
| this.serviceObjects = serviceObjects; |
| this.bundle = serviceObjects.getServiceReference().getBundle(); |
| this.service = serviceObjects.getService(); |
| this.serviceId = (Long) serviceObjects.getServiceReference().getProperty(Constants.SERVICE_ID); |
| 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) { |
| this.service = service; |
| this.bundle = bundle; |
| this.serviceObjects = null; |
| this.serviceId = serviceId; |
| this.serviceRanking = serviceRanking; |
| } |
| public S get() { |
| return service; |
| } |
| |
| public Bundle getBundle() { |
| return bundle; |
| } |
| 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> servletContextHelperRef, |
| ProxyContext proxyContext, HttpServiceRuntimeImpl httpServiceRuntime, |
| String contextName, String contextPath) { |
| |
| validate(contextName, contextPath); |
| |
| this.servletContextHelperRef = servletContextHelperRef; |
| |
| long serviceId = (Long)servletContextHelperRef.getProperty(Constants.SERVICE_ID); |
| |
| StringBuilder filterBuilder = new StringBuilder(); |
| filterBuilder.append('('); |
| filterBuilder.append(Constants.SERVICE_ID); |
| filterBuilder.append('='); |
| filterBuilder.append(serviceId); |
| filterBuilder.append(')'); |
| this.servletContextHelperRefFilter = filterBuilder.toString(); |
| this.proxyContext = proxyContext; |
| this.httpServiceRuntime = httpServiceRuntime; |
| this.contextName = contextName; |
| |
| if (contextPath.equals(Const.SLASH)) { |
| contextPath = Const.BLANK; |
| } |
| |
| this.contextPath = contextPath; |
| this.contextServiceId = serviceId; |
| |
| this.initParams = ServiceProperties.parseInitParams( |
| servletContextHelperRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_INIT_PARAM_PREFIX, proxyContext.getServletContext()); |
| |
| this.trackingContext = trackingContextParam; |
| this.consumingContext = consumingContext; |
| |
| listenerServiceTracker = new ServiceTracker<EventListener, AtomicReference<ListenerRegistration>>( |
| trackingContext, httpServiceRuntime.getListenerFilter(), |
| new ContextListenerTrackerCustomizer( |
| trackingContext, httpServiceRuntime, this)); |
| |
| listenerServiceTracker.open(); |
| |
| filterServiceTracker = new ServiceTracker<Filter, AtomicReference<FilterRegistration>>( |
| trackingContext, httpServiceRuntime.getFilterFilter(), |
| new ContextFilterTrackerCustomizer( |
| trackingContext, httpServiceRuntime, this)); |
| |
| filterServiceTracker.open(); |
| |
| servletServiceTracker = new ServiceTracker<Servlet, AtomicReference<ServletRegistration>>( |
| trackingContext, httpServiceRuntime.getServletFilter(), |
| new ContextServletTrackerCustomizer( |
| trackingContext, httpServiceRuntime, this)); |
| |
| servletServiceTracker.open(); |
| |
| resourceServiceTracker = new ServiceTracker<Object, AtomicReference<ResourceRegistration>>( |
| trackingContext, httpServiceRuntime.getResourceFilter(), |
| new ContextResourceTrackerCustomizer( |
| trackingContext, httpServiceRuntime, this)); |
| |
| resourceServiceTracker.open(); |
| } |
| |
| public FilterRegistration addFilterRegistration(ServiceReference<Filter> filterRef) throws ServletException { |
| checkShutdown(); |
| |
| ServiceHolder<Filter> filterHolder = new ServiceHolder<Filter>(consumingContext.getServiceObjects(filterRef)); |
| Filter filter = filterHolder.get(); |
| FilterRegistration registration = null; |
| boolean addedRegisteredObject = false; |
| try { |
| if (filter == null) { |
| throw new IllegalArgumentException("Filter cannot be null"); |
| } |
| addedRegisteredObject = httpServiceRuntime.getRegisteredObjects().add(filter); |
| if (addedRegisteredObject) { |
| registration = doAddFilterRegistration(filterHolder, filterRef); |
| } |
| } finally { |
| if (registration == null) { |
| filterHolder.release(); |
| if (addedRegisteredObject) { |
| httpServiceRuntime.getRegisteredObjects().remove(filter); |
| } |
| } |
| } |
| return registration; |
| } |
| |
| private FilterRegistration doAddFilterRegistration(ServiceHolder<Filter> filterHolder, ServiceReference<Filter> filterRef) throws ServletException { |
| |
| ClassLoader legacyTCCL = (ClassLoader)filterRef.getProperty(Const.EQUINOX_LEGACY_TCCL_PROP); |
| boolean asyncSupported = ServiceProperties.parseBoolean( |
| filterRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_ASYNC_SUPPORTED); |
| |
| List<String> dispatcherList = StringPlus.from( |
| filterRef.getProperty( |
| HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_DISPATCHER)); |
| String[] dispatchers = dispatcherList.toArray( |
| new String[dispatcherList.size()]); |
| Long serviceId = (Long)filterRef.getProperty( |
| Constants.SERVICE_ID); |
| if (legacyTCCL != null) { |
| // this is a legacy registration; use a negative id for the DTO |
| serviceId = -serviceId; |
| } |
| Integer filterPriority = (Integer)filterRef.getProperty( |
| Constants.SERVICE_RANKING); |
| if (filterPriority == null) { |
| filterPriority = Integer.valueOf(0); |
| } |
| Map<String, String> filterInitParams = ServiceProperties.parseInitParams( |
| filterRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_INIT_PARAM_PREFIX); |
| List<String> patternList = StringPlus.from( |
| filterRef.getProperty( |
| HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN)); |
| String[] patterns = patternList.toArray(new String[patternList.size()]); |
| List<String> regexList = StringPlus.from( |
| filterRef.getProperty( |
| HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_REGEX)); |
| String[] regexs = regexList.toArray(new String[regexList.size()]); |
| List<String> servletList = StringPlus.from( |
| filterRef.getProperty( |
| HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_SERVLET)); |
| String[] servletNames = servletList.toArray(new String[servletList.size()]); |
| |
| String name = ServiceProperties.parseName(filterRef.getProperty( |
| HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_NAME), filterHolder.get()); |
| |
| Filter filter = filterHolder.get(); |
| |
| if (((patterns == null) || (patterns.length == 0)) && |
| ((regexs == null) || (regexs.length == 0)) && |
| ((servletNames == null) || (servletNames.length == 0))) { |
| |
| throw new IllegalArgumentException( |
| "Patterns, regex or servletNames must contain a value."); |
| } |
| |
| if (patterns != null) { |
| for (String pattern : patterns) { |
| checkPattern(pattern); |
| } |
| } |
| |
| if (filter == null) { |
| throw new IllegalArgumentException("Filter cannot be null"); |
| } |
| |
| 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(); |
| |
| filterDTO.asyncSupported = asyncSupported; |
| filterDTO.dispatcher = sort(dispatchers); |
| filterDTO.initParams = filterInitParams; |
| filterDTO.name = name; |
| filterDTO.patterns = sort(patterns); |
| filterDTO.regexs = regexs; |
| filterDTO.serviceId = serviceId; |
| filterDTO.servletContextId = contextServiceId; |
| filterDTO.servletNames = sort(servletNames); |
| |
| ServletContextHelper curServletContextHelper = getServletContextHelper( |
| filterHolder.getBundle()); |
| |
| ServletContext servletContext = createServletContext( |
| filterHolder.getBundle(), curServletContextHelper); |
| FilterRegistration newRegistration = new FilterRegistration( |
| filterHolder, filterDTO, filterPriority, this, legacyTCCL); |
| FilterConfig filterConfig = new FilterConfigImpl( |
| name, filterInitParams, servletContext); |
| |
| newRegistration.init(filterConfig); |
| |
| filterRegistrations.add(newRegistration); |
| return newRegistration; |
| } |
| |
| 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; |
| try { |
| if (listener == null) { |
| throw new IllegalArgumentException("EventListener cannot be null"); |
| } |
| registration = doAddListenerRegistration(listenerHolder, listenerRef); |
| } finally { |
| if (registration == null) { |
| listenerHolder.release(); |
| } |
| } |
| return registration; |
| } |
| |
| private ListenerRegistration doAddListenerRegistration( |
| ServiceHolder<EventListener> listenerHolder, |
| ServiceReference<EventListener> listenerRef) throws ServletException { |
| |
| |
| EventListener eventListener = listenerHolder.get(); |
| List<Class<? extends EventListener>> classes = getListenerClasses(listenerRef); |
| |
| if (classes.isEmpty()) { |
| throw new IllegalArgumentException( |
| "EventListener does not implement a supported type."); |
| } |
| |
| for (ListenerRegistration listenerRegistration : listenerRegistrations) { |
| if (listenerRegistration.getT().equals(eventListener)) { |
| throw new ServletException( |
| "EventListener has already been registered."); |
| } |
| } |
| |
| ListenerDTO listenerDTO = new ListenerDTO(); |
| |
| listenerDTO.serviceId = (Long) listenerRef.getProperty(Constants.SERVICE_ID); |
| listenerDTO.servletContextId = contextServiceId; |
| listenerDTO.types = asStringArray(classes); |
| |
| ServletContextHelper curServletContextHelper = getServletContextHelper( |
| listenerHolder.getBundle()); |
| |
| ServletContext servletContext = createServletContext( |
| listenerHolder.getBundle(), curServletContextHelper); |
| ListenerRegistration listenerRegistration = new ListenerRegistration( |
| listenerHolder, classes, listenerDTO, servletContext, this); |
| |
| if (classes.contains(ServletContextListener.class)) { |
| ServletContextListener servletContextListener = |
| (ServletContextListener)listenerRegistration.getT(); |
| |
| servletContextListener.contextInitialized( |
| new ServletContextEvent(servletContext)); |
| } |
| |
| listenerRegistrations.add(listenerRegistration); |
| |
| eventListeners.put(classes, listenerRegistration); |
| |
| return listenerRegistration; |
| } |
| |
| 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(); |
| List<String> patternList = StringPlus.from( |
| resourceRef.getProperty( |
| HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PATTERN)); |
| String[] patterns = patternList.toArray(new String[patternList.size()]); |
| Long serviceId = (Long)resourceRef.getProperty( |
| Constants.SERVICE_ID); |
| if (legacyTCCL != null) { |
| // this is a legacy registration; use a negative id for the DTO |
| serviceId = -serviceId; |
| } |
| String prefix = (String)resourceRef.getProperty( |
| HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PREFIX); |
| |
| checkPrefix(prefix); |
| |
| if ((patterns == null) || (patterns.length < 1)) { |
| throw new IllegalArgumentException( |
| "Patterns must contain a value."); |
| } |
| |
| for (String pattern : patterns) { |
| checkPattern(pattern); |
| } |
| |
| Bundle bundle = resourceRef.getBundle(); |
| ServletContextHelper curServletContextHelper = getServletContextHelper( |
| bundle); |
| Servlet servlet = new ResourceServlet( |
| prefix, curServletContextHelper, AccessController.getContext()); |
| |
| ResourceDTO resourceDTO = new ResourceDTO(); |
| |
| resourceDTO.patterns = sort(patterns); |
| resourceDTO.prefix = prefix; |
| resourceDTO.serviceId = serviceId; |
| resourceDTO.servletContextId = contextServiceId; |
| |
| ServletContext servletContext = createServletContext( |
| bundle, curServletContextHelper); |
| ResourceRegistration resourceRegistration = new ResourceRegistration( |
| new ServiceHolder<Servlet>(servlet, bundle, serviceId, serviceRanking), |
| resourceDTO, curServletContextHelper, this, legacyTCCL); |
| ServletConfig servletConfig = new ServletConfigImpl( |
| resourceRegistration.getName(), new HashMap<String, String>(), |
| servletContext); |
| |
| try { |
| resourceRegistration.init(servletConfig); |
| } |
| catch (Throwable t) { |
| resourceRegistration.destroy(); |
| |
| return Throw.unchecked(t); |
| } |
| |
| endpointRegistrations.add(resourceRegistration); |
| |
| return resourceRegistration; |
| } |
| |
| public ServletRegistration addServletRegistration(ServiceReference<Servlet> servletRef) throws ServletException { |
| |
| checkShutdown(); |
| |
| ServiceHolder<Servlet> servletHolder = new ServiceHolder<Servlet>(consumingContext.getServiceObjects(servletRef)); |
| Servlet servlet = servletHolder.get(); |
| ServletRegistration registration = null; |
| boolean addedRegisteredObject = false; |
| try { |
| if (servlet == null) { |
| throw new IllegalArgumentException("Servlet cannot be null"); |
| } |
| addedRegisteredObject = httpServiceRuntime.getRegisteredObjects().add(servlet); |
| if (addedRegisteredObject) { |
| registration = doAddServletRegistration(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 ServletRegistration doAddServletRegistration(ServiceHolder<Servlet> servletHolder, ServiceReference<Servlet> servletRef) throws ServletException { |
| |
| boolean asyncSupported = ServiceProperties.parseBoolean( |
| servletRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED); |
| ClassLoader legacyTCCL = (ClassLoader)servletRef.getProperty(Const.EQUINOX_LEGACY_TCCL_PROP); |
| List<String> errorPageList = StringPlus.from( |
| servletRef.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE)); |
| String[] errorPages = errorPageList.toArray(new String[errorPageList.size()]); |
| Map<String, String> servletInitParams = ServiceProperties.parseInitParams( |
| servletRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX); |
| List<String> patternList = StringPlus.from( |
| servletRef.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN)); |
| String[] patterns = patternList.toArray(new String[patternList.size()]); |
| Long serviceId = (Long)servletRef.getProperty(Constants.SERVICE_ID); |
| if (legacyTCCL != null) { |
| // this is a legacy registration; use a negative id for the DTO |
| serviceId = -serviceId; |
| } |
| String 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); |
| |
| if (((patterns == null) || (patterns.length == 0)) && |
| ((errorPages == null) || errorPages.length == 0) && |
| (servletNameFromProperties == 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(", "); //$NON-NLS-1$ |
| sb.append(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME); |
| sb.append(", "); //$NON-NLS-1$ |
| sb.append(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN); |
| sb.append(" must contain a value."); //$NON-NLS-1$ |
| |
| throw new IllegalArgumentException(sb.toString()); |
| } |
| |
| 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 = serviceId; |
| servletDTO.servletContextId = contextServiceId; |
| servletDTO.servletInfo = servletHolder.get().getServletInfo(); |
| |
| ErrorPageDTO errorPageDTO = null; |
| |
| if ((errorPages != null) && (errorPages.length > 0)) { |
| errorPageDTO = new ErrorPageDTO(); |
| |
| 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$ |
| for (long code = 400; code < 500; code++) { |
| errorCodeSet.add(code); |
| } |
| } else if ("5xx".equals(errorPage)) { //$NON-NLS-1$ |
| for (long code = 500; code < 600; code++) { |
| errorCodeSet.add(code); |
| } |
| } else { |
| long code = Long.parseLong(errorPage); |
| errorCodeSet.add(code); |
| } |
| } |
| 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[exceptions.size()]); |
| errorPageDTO.initParams = servletInitParams; |
| errorPageDTO.name = generatedServletName; |
| errorPageDTO.serviceId = serviceId; |
| errorPageDTO.servletContextId = contextServiceId; |
| errorPageDTO.servletInfo = servletHolder.get().getServletInfo(); |
| } |
| |
| ServletContextHelper curServletContextHelper = getServletContextHelper( |
| servletHolder.getBundle()); |
| |
| ServletContext servletContext = createServletContext( |
| servletHolder.getBundle(), curServletContextHelper); |
| ServletRegistration servletRegistration = new ServletRegistration( |
| servletHolder, servletDTO, errorPageDTO, curServletContextHelper, this, |
| servletContext, legacyTCCL); |
| ServletConfig servletConfig = new ServletConfigImpl( |
| generatedServletName, servletInitParams, servletContext); |
| |
| try { |
| servletRegistration.init(servletConfig); |
| } |
| catch (Throwable t) { |
| servletRegistration.destroy(); |
| |
| return Throw.unchecked(t); |
| } |
| |
| endpointRegistrations.add(servletRegistration); |
| |
| return servletRegistration; |
| } |
| |
| public void destroy() { |
| flushActiveSessions(); |
| resourceServiceTracker.close(); |
| servletServiceTracker.close(); |
| filterServiceTracker.close(); |
| listenerServiceTracker.close(); |
| |
| endpointRegistrations.clear(); |
| filterRegistrations.clear(); |
| listenerRegistrations.clear(); |
| eventListeners.clear(); |
| proxyContext.destroy(); |
| |
| shutdown = true; |
| } |
| |
| public String getContextName() { |
| checkShutdown(); |
| |
| return contextName; |
| } |
| |
| public String getContextPath() { |
| checkShutdown(); |
| |
| return contextPath; |
| } |
| |
| public DispatchTargets getDispatchTargets( |
| String pathString, RequestInfoDTO requestInfoDTO) { |
| |
| Path path = new Path(pathString); |
| |
| String queryString = path.getQueryString(); |
| String requestURI = path.getRequestURI(); |
| |
| // perfect match |
| DispatchTargets dispatchTargets = getDispatchTargets( |
| requestURI, null, queryString, Match.EXACT, requestInfoDTO); |
| |
| if (dispatchTargets == null) { |
| // extension match |
| |
| dispatchTargets = getDispatchTargets( |
| requestURI, path.getExtension(), queryString, Match.EXTENSION, |
| requestInfoDTO); |
| } |
| |
| if (dispatchTargets == null) { |
| // regex match |
| dispatchTargets = getDispatchTargets( |
| requestURI, null, queryString, Match.REGEX, requestInfoDTO); |
| } |
| |
| if (dispatchTargets == null) { |
| // handle '/' aliases |
| dispatchTargets = getDispatchTargets( |
| requestURI, null, queryString, Match.DEFAULT_SERVLET, |
| requestInfoDTO); |
| } |
| |
| return dispatchTargets; |
| } |
| |
| private DispatchTargets getDispatchTargets( |
| String requestURI, String extension, String queryString, Match match, |
| RequestInfoDTO requestInfoDTO) { |
| |
| int pos = requestURI.lastIndexOf('/'); |
| |
| String servletPath = requestURI; |
| String pathInfo = null; |
| |
| if (match == Match.DEFAULT_SERVLET) { |
| pathInfo = servletPath; |
| servletPath = Const.SLASH; |
| } |
| |
| do { |
| DispatchTargets dispatchTargets = getDispatchTargets( |
| null, requestURI, servletPath, pathInfo, |
| extension, queryString, match, requestInfoDTO); |
| |
| if (dispatchTargets != null) { |
| return dispatchTargets; |
| } |
| |
| if (match == Match.EXACT) { |
| break; |
| } |
| |
| if (pos > -1) { |
| String newServletPath = requestURI.substring(0, pos); |
| pathInfo = requestURI.substring(pos); |
| servletPath = newServletPath; |
| pos = servletPath.lastIndexOf('/'); |
| |
| continue; |
| } |
| |
| break; |
| } |
| while (true); |
| |
| return null; |
| } |
| |
| public DispatchTargets getDispatchTargets( |
| String servletName, String requestURI, String servletPath, |
| String pathInfo, String extension, String queryString, Match match, |
| RequestInfoDTO requestInfoDTO) { |
| |
| checkShutdown(); |
| |
| EndpointRegistration<?> endpointRegistration = null; |
| for (EndpointRegistration<?> curEndpointRegistration : endpointRegistrations) { |
| if (curEndpointRegistration.match(servletName, servletPath, pathInfo, extension, match) != null) { |
| endpointRegistration = curEndpointRegistration; |
| |
| break; |
| } |
| } |
| |
| if (endpointRegistration == null) { |
| return null; |
| } |
| |
| if (match == Match.EXTENSION) { |
| servletPath = servletPath + pathInfo; |
| pathInfo = null; |
| } |
| |
| addEnpointRegistrationsToRequestInfo( |
| endpointRegistration, requestInfoDTO); |
| |
| if (filterRegistrations.isEmpty()) { |
| return new DispatchTargets( |
| this, endpointRegistration, servletName, requestURI, servletPath, |
| pathInfo, queryString); |
| } |
| |
| if (requestURI != null) { |
| int x = requestURI.lastIndexOf('.'); |
| |
| if (x != -1) { |
| extension = requestURI.substring(x + 1); |
| } |
| } |
| |
| List<FilterRegistration> matchingFilterRegistrations = |
| new ArrayList<FilterRegistration>(); |
| |
| collectFilters( |
| matchingFilterRegistrations, endpointRegistration.getName(), requestURI, |
| servletPath, pathInfo, extension); |
| |
| addFilterRegistrationsToRequestInfo( |
| matchingFilterRegistrations, requestInfoDTO); |
| |
| return new DispatchTargets( |
| this, endpointRegistration, matchingFilterRegistrations, servletName, |
| requestURI, servletPath, pathInfo, queryString); |
| } |
| |
| private void collectFilters( |
| List<FilterRegistration> matchingFilterRegistrations, |
| String servletName, String requestURI, String servletPath, String pathInfo, String extension) { |
| |
| for (FilterRegistration filterRegistration : filterRegistrations) { |
| if ((filterRegistration.match( |
| servletName, requestURI, extension, null) != null) && |
| !matchingFilterRegistrations.contains(filterRegistration)) { |
| |
| matchingFilterRegistrations.add(filterRegistration); |
| } |
| } |
| } |
| |
| public Map<String, HttpSessionAdaptor> getActiveSessions() { |
| checkShutdown(); |
| |
| return activeSessions; |
| } |
| |
| public Set<EndpointRegistration<?>> getEndpointRegistrations() { |
| checkShutdown(); |
| |
| return endpointRegistrations; |
| } |
| |
| public EventListeners getEventListeners() { |
| checkShutdown(); |
| |
| return eventListeners; |
| } |
| |
| public Set<FilterRegistration> getFilterRegistrations() { |
| checkShutdown(); |
| |
| return filterRegistrations; |
| } |
| |
| public String getFullContextPath() { |
| List<String> endpoints = httpServiceRuntime.getHttpServiceEndpoints(); |
| |
| if (endpoints.isEmpty()) { |
| return proxyContext.getServletPath().concat(contextPath); |
| } |
| |
| String defaultEndpoint = endpoints.get(0); |
| |
| if ((defaultEndpoint.length() > 0) && defaultEndpoint.endsWith("/")) { |
| defaultEndpoint = defaultEndpoint.substring( |
| 0, defaultEndpoint.length() - 1); |
| } |
| |
| return defaultEndpoint + contextPath; |
| } |
| |
| public HttpServiceRuntimeImpl getHttpServiceRuntime() { |
| checkShutdown(); |
| |
| return httpServiceRuntime; |
| } |
| |
| public Map<String, String> getInitParams() { |
| return initParams; |
| } |
| |
| public Set<ListenerRegistration> getListenerRegistrations() { |
| checkShutdown(); |
| |
| return listenerRegistrations; |
| } |
| |
| public ProxyContext getProxyContext() { |
| checkShutdown(); |
| |
| return proxyContext; |
| } |
| |
| public long getServiceId() { |
| checkShutdown(); |
| |
| return contextServiceId; |
| } |
| |
| public synchronized ServletContextDTO getServletContextDTO(){ |
| checkShutdown(); |
| |
| ServletContextDTO servletContextDTO = new ServletContextDTO(); |
| |
| ServletContext servletContext = getProxyContext().getServletContext(); |
| |
| servletContextDTO.attributes = getDTOAttributes(servletContext); |
| servletContextDTO.contextPath = getContextPath(); |
| servletContextDTO.initParams = new HashMap<String, String>(initParams); |
| servletContextDTO.name = getContextName(); |
| servletContextDTO.serviceId = getServiceId(); |
| |
| collectEndpointDTOs(servletContextDTO); |
| collectFilterDTOs(servletContextDTO); |
| collectListenerDTOs(servletContextDTO); |
| |
| return servletContextDTO; |
| } |
| |
| public boolean matches(ServiceReference<?> whiteBoardService) { |
| String contextSelector = (String) whiteBoardService.getProperty( |
| HttpWhiteboardConstants.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)) { |
| return false; |
| } |
| if (contextSelector == null) { |
| 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$ |
| } |
| } |
| |
| if (!contextSelector.startsWith(Const.OPEN_PAREN)) { |
| contextSelector = Const.OPEN_PAREN + |
| HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + |
| Const.EQUAL + contextSelector + Const.CLOSE_PAREN; |
| } |
| |
| org.osgi.framework.Filter targetFilter; |
| |
| try { |
| targetFilter = FrameworkUtil.createFilter(contextSelector); |
| } |
| catch (InvalidSyntaxException ise) { |
| throw new IllegalArgumentException(ise); |
| } |
| |
| return matches(targetFilter); |
| } |
| |
| private boolean visibleContextHelper(ServiceReference<?> whiteBoardService) { |
| if (consumingContext.getBundle().equals(servletContextHelperRef.getBundle())) { |
| return true; |
| } |
| try { |
| if (whiteBoardService.getBundle().getBundleContext().getAllServiceReferences(ServletContextHelper.class.getName(), servletContextHelperRefFilter) != null) { |
| return true; |
| } |
| } |
| catch (InvalidSyntaxException e) { |
| // ignore |
| } |
| return false; |
| } |
| |
| public boolean matches(org.osgi.framework.Filter targetFilter) { |
| return targetFilter.match(servletContextHelperRef); |
| } |
| |
| @Override |
| public String toString() { |
| String value = string; |
| |
| if (value == null) { |
| value = SIMPLE_NAME + '[' + contextName + ", " + trackingContext.getBundle() + ']'; //$NON-NLS-1$ |
| |
| string = value; |
| } |
| |
| return value; |
| } |
| |
| private void addEnpointRegistrationsToRequestInfo( |
| EndpointRegistration<?> endpointRegistration, |
| RequestInfoDTO requestInfoDTO) { |
| |
| if (requestInfoDTO == null) { |
| return; |
| } |
| |
| requestInfoDTO.servletContextId = getServiceId(); |
| |
| if (endpointRegistration instanceof ResourceRegistration) { |
| requestInfoDTO.resourceDTO = |
| (ResourceDTO)endpointRegistration.getD(); |
| } |
| else { |
| requestInfoDTO.servletDTO = |
| (ServletDTO)endpointRegistration.getD(); |
| } |
| } |
| |
| private void addFilterRegistrationsToRequestInfo( |
| List<FilterRegistration> matchedFilterRegistrations, |
| RequestInfoDTO requestInfoDTO) { |
| |
| if (requestInfoDTO == null) { |
| return; |
| } |
| |
| FilterDTO[] filterDTOs = |
| new FilterDTO[matchedFilterRegistrations.size()]; |
| |
| for (int i = 0; i < filterDTOs.length ; i++) { |
| FilterRegistration filterRegistration = |
| matchedFilterRegistrations.get(i); |
| |
| filterDTOs[i] = filterRegistration.getD(); |
| } |
| |
| requestInfoDTO.filterDTOs = filterDTOs; |
| } |
| |
| private String[] asStringArray( |
| List<Class<? extends EventListener>> clazzes) { |
| |
| String[] classesArray = new String[clazzes.size()]; |
| |
| for (int i = 0; i < classesArray.length; i++) { |
| classesArray[i] = clazzes.get(i).getName(); |
| } |
| |
| Arrays.sort(classesArray); |
| |
| return classesArray; |
| } |
| |
| private String[] checkDispatcher(String[] dispatcher) { |
| if ((dispatcher == null) || (dispatcher.length == 0)) { |
| return DISPATCHER; |
| } |
| |
| for (String type : dispatcher) { |
| try { |
| DispatcherType.valueOf(type); |
| } |
| catch (IllegalArgumentException iae) { |
| throw new IllegalArgumentException( |
| "Invalid dispatcher '" + type + "'", iae); |
| } |
| } |
| |
| Arrays.sort(dispatcher); |
| |
| return dispatcher; |
| } |
| |
| public static void checkPattern(String pattern) { |
| if (pattern == null) { |
| throw new IllegalArgumentException("Pattern cannot be null"); |
| } |
| |
| if (pattern.indexOf("*.") == 0) { //$NON-NLS-1$ |
| return; |
| } |
| |
| if (!pattern.startsWith(Const.SLASH) || |
| (pattern.endsWith(Const.SLASH) && !pattern.equals(Const.SLASH))) { |
| |
| throw new IllegalArgumentException( |
| "Invalid pattern '" + pattern + "'"); |
| } |
| } |
| |
| private void checkPrefix(String prefix) { |
| if (prefix == null) { |
| throw new IllegalArgumentException("Prefix cannot be null"); |
| } |
| |
| if (prefix.endsWith(Const.SLASH) && !prefix.equals(Const.SLASH)) { |
| throw new IllegalArgumentException("Invalid prefix '" + prefix + "'"); |
| } |
| } |
| |
| private void checkShutdown() { |
| if (shutdown) { |
| throw new IllegalStateException( |
| "Context is already shutdown"); //$NON-NLS-1$ |
| } |
| } |
| |
| private ServletContext createServletContext( |
| Bundle curBundle, ServletContextHelper curServletContextHelper) { |
| |
| ServletContextAdaptor adaptor = new ServletContextAdaptor( |
| this, curBundle, curServletContextHelper, eventListeners, |
| AccessController.getContext()); |
| |
| return adaptor.createServletContext(); |
| } |
| |
| private void collectEndpointDTOs( |
| ServletContextDTO servletContextDTO) { |
| |
| List<ErrorPageDTO> errorPageDTOs = new ArrayList<ErrorPageDTO>(); |
| List<ResourceDTO> resourceDTOs = new ArrayList<ResourceDTO>(); |
| List<ServletDTO> servletDTOs = new ArrayList<ServletDTO>(); |
| |
| for (EndpointRegistration<?> endpointRegistration : endpointRegistrations) { |
| if (endpointRegistration instanceof ResourceRegistration) { |
| resourceDTOs.add(DTOUtil.clone((ResourceDTO)endpointRegistration.getD())); |
| } |
| else { |
| ServletRegistration servletRegistration = (ServletRegistration)endpointRegistration; |
| servletDTOs.add(DTOUtil.clone(servletRegistration.getD())); |
| |
| ErrorPageDTO errorPageDTO = servletRegistration.getErrorPageDTO(); |
| if (errorPageDTO != null) { |
| errorPageDTOs.add(DTOUtil.clone(errorPageDTO)); |
| } |
| } |
| } |
| |
| servletContextDTO.errorPageDTOs = errorPageDTOs.toArray( |
| new ErrorPageDTO[errorPageDTOs.size()]); |
| servletContextDTO.resourceDTOs = resourceDTOs.toArray( |
| new ResourceDTO[resourceDTOs.size()]); |
| servletContextDTO.servletDTOs = servletDTOs.toArray( |
| new ServletDTO[servletDTOs.size()]); |
| } |
| |
| private void collectFilterDTOs( |
| ServletContextDTO servletContextDTO) { |
| |
| List<FilterDTO> filterDTOs = new ArrayList<FilterDTO>(); |
| |
| for (FilterRegistration filterRegistration : filterRegistrations) { |
| filterDTOs.add(DTOUtil.clone(filterRegistration.getD())); |
| } |
| |
| servletContextDTO.filterDTOs = filterDTOs.toArray( |
| new FilterDTO[filterDTOs.size()]); |
| } |
| |
| private void collectListenerDTOs( |
| ServletContextDTO servletContextDTO) { |
| |
| List<ListenerDTO> listenerDTOs = new ArrayList<ListenerDTO>(); |
| |
| for (ListenerRegistration listenerRegistration : listenerRegistrations) { |
| listenerDTOs.add(DTOUtil.clone(listenerRegistration.getD())); |
| } |
| |
| servletContextDTO.listenerDTOs = listenerDTOs.toArray( |
| new ListenerDTO[listenerDTOs.size()]); |
| } |
| |
| private Map<String, Object> getDTOAttributes(ServletContext servletContext) { |
| Map<String, Object> map = new HashMap<String, Object>(); |
| |
| for (Enumeration<String> names = servletContext.getAttributeNames(); |
| names.hasMoreElements();) { |
| |
| String name = names.nextElement(); |
| |
| map.put(name, DTOUtil.mapValue(servletContext.getAttribute(name))); |
| } |
| |
| return Collections.unmodifiableMap(map); |
| } |
| |
| private List<Class<? extends EventListener>> getListenerClasses( |
| ServiceReference<EventListener> serviceReference) { |
| |
| List<String> objectClassList = StringPlus.from(serviceReference.getProperty(Constants.OBJECTCLASS)); |
| |
| List<Class<? extends EventListener>> classes = |
| new ArrayList<Class<? extends EventListener>>(); |
| |
| if (objectClassList.contains(ServletContextListener.class.getName())) { |
| classes.add(ServletContextListener.class); |
| } |
| if (objectClassList.contains(ServletContextAttributeListener.class.getName())) { |
| classes.add(ServletContextAttributeListener.class); |
| } |
| if (objectClassList.contains(ServletRequestListener.class.getName())) { |
| classes.add(ServletRequestListener.class); |
| } |
| if (objectClassList.contains(ServletRequestAttributeListener.class.getName())) { |
| classes.add(ServletRequestAttributeListener.class); |
| } |
| if (objectClassList.contains(HttpSessionListener.class.getName())) { |
| classes.add(HttpSessionListener.class); |
| } |
| if (objectClassList.contains(HttpSessionAttributeListener.class.getName())) { |
| classes.add(HttpSessionAttributeListener.class); |
| } |
| |
| ServletContext servletContext = proxyContext.getServletContext(); |
| if ((servletContext.getMajorVersion() >= 3) && (servletContext.getMinorVersion() > 0)) { |
| if (objectClassList.contains(javax.servlet.http.HttpSessionIdListener.class.getName())) { |
| classes.add(javax.servlet.http.HttpSessionIdListener.class); |
| } |
| } |
| |
| return classes; |
| } |
| |
| private ServletContextHelper getServletContextHelper(Bundle curBundle) { |
| BundleContext context = curBundle.getBundleContext(); |
| return context.getService(servletContextHelperRef); |
| } |
| |
| public void ungetServletContextHelper(Bundle curBundle) { |
| BundleContext context = curBundle.getBundleContext(); |
| try { |
| context.ungetService(servletContextHelperRef); |
| } 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 |
| } |
| } |
| |
| private String[] sort(String[] values) { |
| if (values == null) { |
| return null; |
| } |
| |
| Arrays.sort(values); |
| |
| return values; |
| } |
| |
| private void flushActiveSessions() { |
| Collection<HttpSessionAdaptor> httpSessionAdaptors = |
| activeSessions.values(); |
| |
| Iterator<HttpSessionAdaptor> iterator = httpSessionAdaptors.iterator(); |
| |
| while (iterator.hasNext()) { |
| HttpSessionAdaptor httpSessionAdaptor = iterator.next(); |
| |
| httpSessionAdaptor.invalidate(); |
| |
| iterator.remove(); |
| } |
| } |
| |
| public void removeActiveSession(HttpSession session) { |
| activeSessions.remove(session.getId()); |
| } |
| |
| public void fireSessionIdChanged(String oldSessionId) { |
| ServletContext servletContext = proxyContext.getServletContext(); |
| if ((servletContext.getMajorVersion() <= 3) && (servletContext.getMinorVersion() < 1)) { |
| return; |
| } |
| |
| List<javax.servlet.http.HttpSessionIdListener> listeners = eventListeners.get(javax.servlet.http.HttpSessionIdListener.class); |
| |
| if (listeners.isEmpty()) { |
| return; |
| } |
| |
| for (HttpSessionAdaptor httpSessionAdaptor : activeSessions.values()) { |
| HttpSessionEvent httpSessionEvent = new HttpSessionEvent(httpSessionAdaptor); |
| for (javax.servlet.http.HttpSessionIdListener listener : listeners) { |
| listener.sessionIdChanged(httpSessionEvent, oldSessionId); |
| } |
| } |
| } |
| |
| public HttpSessionAdaptor getSessionAdaptor( |
| HttpSession session, ServletContext servletContext) { |
| |
| String sessionId = session.getId(); |
| |
| HttpSessionAdaptor httpSessionAdaptor = activeSessions.get(sessionId); |
| |
| if (httpSessionAdaptor != null) { |
| return httpSessionAdaptor; |
| } |
| |
| httpSessionAdaptor = HttpSessionAdaptor.createHttpSessionAdaptor( |
| session, servletContext, this); |
| |
| HttpSessionAdaptor previousHttpSessionAdaptor = |
| activeSessions.putIfAbsent(sessionId, httpSessionAdaptor); |
| |
| if (previousHttpSessionAdaptor != null) { |
| return previousHttpSessionAdaptor; |
| } |
| |
| List<HttpSessionListener> listeners = eventListeners.get(HttpSessionListener.class); |
| |
| if (listeners.isEmpty()) { |
| return httpSessionAdaptor; |
| } |
| |
| HttpSessionEvent httpSessionEvent = new HttpSessionEvent( |
| httpSessionAdaptor); |
| |
| for (HttpSessionListener listener : listeners) { |
| listener.sessionCreated(httpSessionEvent); |
| } |
| |
| return httpSessionAdaptor; |
| } |
| |
| private void validate(String preValidationContextName, String preValidationContextPath) { |
| if (!contextNamePattern.matcher(preValidationContextName).matches()) { |
| throw new IllegalContextNameException( |
| "The context name '" + preValidationContextName + "' does not follow Bundle-SymbolicName syntax.", //$NON-NLS-1$ //$NON-NLS-2$ |
| DTOConstants.FAILURE_REASON_VALIDATION_FAILED); |
| } |
| |
| try { |
| @SuppressWarnings("unused") |
| URI uri = new URI(Const.HTTP, Const.LOCALHOST, preValidationContextPath, null); |
| } |
| catch (URISyntaxException use) { |
| throw new IllegalContextPathException( |
| "The context path '" + preValidationContextPath + "' is not valid URI path syntax.", //$NON-NLS-1$ //$NON-NLS-2$ |
| DTOConstants.FAILURE_REASON_VALIDATION_FAILED); |
| } |
| } |
| |
| private static final String[] DISPATCHER = |
| new String[] {DispatcherType.REQUEST.toString()}; |
| |
| private static final String SIMPLE_NAME = ContextController.class.getSimpleName(); |
| |
| private static final Pattern contextNamePattern = Pattern.compile("^([a-zA-Z_0-9\\-]+\\.)*[a-zA-Z_0-9\\-]+$"); //$NON-NLS-1$ |
| |
| private final Map<String, String> initParams; |
| private final BundleContext trackingContext; |
| private final BundleContext consumingContext; |
| private final String contextName; |
| private final String contextPath; |
| private final long contextServiceId; |
| private final Set<EndpointRegistration<?>> endpointRegistrations = new ConcurrentSkipListSet<EndpointRegistration<?>>(); |
| private final EventListeners eventListeners = new EventListeners(); |
| private final Set<FilterRegistration> filterRegistrations = new ConcurrentSkipListSet<FilterRegistration>(); |
| private final ConcurrentMap<String, HttpSessionAdaptor> activeSessions = new ConcurrentHashMap<String, HttpSessionAdaptor>(); |
| |
| private final HttpServiceRuntimeImpl httpServiceRuntime; |
| private final Set<ListenerRegistration> listenerRegistrations = new HashSet<ListenerRegistration>(); |
| private final ProxyContext proxyContext; |
| private final ServiceReference<ServletContextHelper> servletContextHelperRef; |
| private final String servletContextHelperRefFilter; |
| private boolean shutdown; |
| private String string; |
| |
| 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; |
| } |