Return-Path: Delivered-To: apmail-sling-commits-archive@www.apache.org Received: (qmail 81470 invoked from network); 7 Sep 2010 08:46:21 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 7 Sep 2010 08:46:21 -0000 Received: (qmail 26557 invoked by uid 500); 7 Sep 2010 08:46:21 -0000 Delivered-To: apmail-sling-commits-archive@sling.apache.org Received: (qmail 26494 invoked by uid 500); 7 Sep 2010 08:46:19 -0000 Mailing-List: contact commits-help@sling.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@sling.apache.org Delivered-To: mailing list commits@sling.apache.org Received: (qmail 26487 invoked by uid 99); 7 Sep 2010 08:46:19 -0000 Received: from Unknown (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 Sep 2010 08:46:19 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 Sep 2010 08:45:59 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 7E8A12388A41; Tue, 7 Sep 2010 08:45:37 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r993280 [2/2] - in /sling/trunk/bundles/engine: ./ src/main/java/org/apache/sling/engine/ src/main/java/org/apache/sling/engine/impl/ src/main/java/org/apache/sling/engine/impl/filter/ src/main/java/org/apache/sling/engine/impl/request/ Date: Tue, 07 Sep 2010 08:45:37 -0000 To: commits@sling.apache.org From: fmeschbe@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100907084537.7E8A12388A41@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/WebConsoleConfigPrinter.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/WebConsoleConfigPrinter.java?rev=993280&r1=993279&r2=993280&view=diff ============================================================================== --- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/WebConsoleConfigPrinter.java (original) +++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/WebConsoleConfigPrinter.java Tue Sep 7 08:45:36 2010 @@ -23,7 +23,9 @@ import java.util.Dictionary; import java.util.Hashtable; import org.apache.felix.webconsole.ConfigurationPrinter; +import org.apache.sling.engine.impl.filter.ServletFilterManager; import org.apache.sling.engine.impl.filter.SlingFilterChainHelper; +import org.apache.sling.engine.impl.filter.ServletFilterManager.FilterChainType; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; @@ -35,13 +37,10 @@ import org.osgi.framework.ServiceRegistr */ public class WebConsoleConfigPrinter implements ConfigurationPrinter { - private final SlingFilterChainHelper requestFilterChain; - private final SlingFilterChainHelper innerFilterChain; + private final ServletFilterManager filterManager; - public WebConsoleConfigPrinter(final SlingFilterChainHelper requestFilterChain, - final SlingFilterChainHelper innerFilterChain) { - this.requestFilterChain = requestFilterChain; - this.innerFilterChain = innerFilterChain; + public WebConsoleConfigPrinter(final ServletFilterManager filterManager) { + this.filterManager = filterManager; } private static final class Registration { @@ -49,12 +48,11 @@ public class WebConsoleConfigPrinter imp } public static Object register(final BundleContext bundleContext, - final SlingFilterChainHelper requestFilterChain, - final SlingFilterChainHelper innerFilterChain) { + final ServletFilterManager filterManager) { final Registration reg = new Registration(); // first we register the plugin for the filters - final WebConsoleConfigPrinter filterPrinter = new WebConsoleConfigPrinter(requestFilterChain, innerFilterChain); + final WebConsoleConfigPrinter filterPrinter = new WebConsoleConfigPrinter(filterManager); final Dictionary serviceProps = new Hashtable(); serviceProps.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Servlet Filter Configuration Printer"); @@ -108,11 +106,11 @@ public class WebConsoleConfigPrinter imp */ public void printConfiguration(PrintWriter pw) { pw.println("Current Apache Sling Servlet Filter Configuration"); - pw.println(); - pw.println("Request Filters:"); - printFilterChain(pw, requestFilterChain.getFilterListEntries()); - pw.println(); - pw.println("Component Filters:"); - printFilterChain(pw, innerFilterChain.getFilterListEntries()); + for (FilterChainType type : FilterChainType.values()) { + pw.println(); + pw.println(type + " Filters:"); + printFilterChain(pw, + filterManager.getFilterChain(type).getFilterListEntries()); + } } } Modified: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/RequestSlingFilterChain.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/RequestSlingFilterChain.java?rev=993280&r1=993279&r2=993280&view=diff ============================================================================== --- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/RequestSlingFilterChain.java (original) +++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/RequestSlingFilterChain.java Tue Sep 7 08:45:36 2010 @@ -25,7 +25,8 @@ import javax.servlet.ServletException; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; -import org.apache.sling.engine.impl.SlingMainServlet; +import org.apache.sling.engine.impl.SlingRequestProcessorImpl; +import org.apache.sling.engine.impl.filter.ServletFilterManager.FilterChainType; /** * The RequestSlingFilterChain implements the filter chain for @@ -35,9 +36,9 @@ import org.apache.sling.engine.impl.Slin */ public class RequestSlingFilterChain extends AbstractSlingFilterChain { - private final SlingMainServlet handler; + private final SlingRequestProcessorImpl handler; - public RequestSlingFilterChain(SlingMainServlet handler, Filter[] filters) { + public RequestSlingFilterChain(SlingRequestProcessorImpl handler, Filter[] filters) { super(filters); this.handler = handler; } @@ -45,6 +46,6 @@ public class RequestSlingFilterChain ext protected void render(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { - handler.processRequest(request, response); + handler.processComponent(request, response,FilterChainType.COMPONENT); } } \ No newline at end of file Added: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/ServletFilterManager.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/ServletFilterManager.java?rev=993280&view=auto ============================================================================== --- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/ServletFilterManager.java (added) +++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/ServletFilterManager.java Tue Sep 7 08:45:36 2010 @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.engine.impl.filter; + +import javax.servlet.Filter; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; + +import org.apache.sling.commons.osgi.OsgiUtil; +import org.apache.sling.engine.EngineConstants; +import org.apache.sling.engine.impl.helper.SlingFilterConfig; +import org.apache.sling.engine.impl.helper.SlingServletContext; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ServletFilterManager extends ServiceTracker { + + public static enum FilterChainType { + /** + * Indicates request level filters. + * + * @see EngineConstants#FILTER_SCOPE_REQUEST + */ + REQUEST("Request"), + + /** + * Indicates error level filters. + * + * @see EngineConstants#FILTER_SCOPE_ERROR + */ + ERROR("Error"), + + /** + * Indicates include level filters. + * + * @see EngineConstants#FILTER_SCOPE_INCLUDE + */ + INCLUDE("Include"), + + /** + * Indicates forward level filters. + * + * @see EngineConstants#FILTER_SCOPE_FORWARD + */ + FORWARD("Forward"), + + /** + * Indicates component level filters. + * + * @see EngineConstants#FILTER_SCOPE_COMPONENT + */ + COMPONENT("Component"); + + private final String message; + + private FilterChainType(final String message) { + this.message = message; + } + + @Override + public String toString() { + return message; + } + } + + /** + * The service property used by Felix's HttpService whiteboard + * implementation. + */ + private static String FELIX_WHITEBOARD_PATTERN_PROPERTY = "pattern"; + + // TODO: use filter (&(objectclass=javax.servlet.Filter)(filter.scope=*)) + private static final String FILTER_SERVICE_NAME = Filter.class.getName(); + + /** default log */ + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final SlingServletContext servletContext; + + private final SlingFilterChainHelper[] filterChains; + + public ServletFilterManager(BundleContext context, + final SlingServletContext servletContext) { + super(context, FILTER_SERVICE_NAME, null); + this.servletContext = servletContext; + this.filterChains = new SlingFilterChainHelper[FilterChainType.values().length]; + this.filterChains[FilterChainType.REQUEST.ordinal()] = new SlingFilterChainHelper(); + this.filterChains[FilterChainType.ERROR.ordinal()] = new SlingFilterChainHelper(); + this.filterChains[FilterChainType.INCLUDE.ordinal()] = new SlingFilterChainHelper(); + this.filterChains[FilterChainType.FORWARD.ordinal()] = new SlingFilterChainHelper(); + this.filterChains[FilterChainType.COMPONENT.ordinal()] = new SlingFilterChainHelper(); + } + + public SlingFilterChainHelper getFilterChain(final FilterChainType chain) { + return filterChains[chain.ordinal()]; + } + + public Filter[] getFilters(final FilterChainType chain) { + return getFilterChain(chain).getFilters(); + } + + @Override + public Object addingService(ServiceReference reference) { + Object service = super.addingService(reference); + if (service instanceof Filter) { + initFilter(reference, (Filter) service); + } + return service; + } + + @Override + public void modifiedService(ServiceReference reference, Object service) { + // TODO Auto-generated method stub + if (service instanceof Filter) { + destroyFilter(reference, (Filter) service); + initFilter(reference, (Filter) service); + } + + super.modifiedService(reference, service); + } + + @Override + public void removedService(ServiceReference reference, Object service) { + if (service instanceof Filter) { + destroyFilter(reference, (Filter) service); + } + super.removedService(reference, service); + } + + private void initFilter(final ServiceReference reference, + final Filter filter) { + // Check if filter will be registered by Felix HttpService Whiteboard + if (reference.getProperty(FELIX_WHITEBOARD_PATTERN_PROPERTY) != null) { + return; + } + + final String filterName = SlingFilterConfig.getName(reference); + if (filterName == null) { + log.error("initFilter: Missing name for filter {}", reference); + } else { + + // initialize the filter first + try { + final FilterConfig config = new SlingFilterConfig( + servletContext, reference, filterName); + filter.init(config); + + // service id + Long serviceId = (Long) reference.getProperty(Constants.SERVICE_ID); + + // get the order, Integer.MAX_VALUE by default + Object orderObj = reference.getProperty(Constants.SERVICE_RANKING); + if (orderObj == null) { + orderObj = reference.getProperty(EngineConstants.FILTER_ORDER); + } + int order = (orderObj instanceof Integer) + ? ((Integer) orderObj).intValue() + : 0; + + // register by scope + String[] scopes = OsgiUtil.toStringArray( + reference.getProperty(EngineConstants.FILTER_SCOPE), null); + if (scopes != null && scopes.length > 0) { + for (String scope : scopes) { + scope = scope.toUpperCase(); + try { + FilterChainType type = FilterChainType.valueOf(scope.toString()); + getFilterChain(type).addFilter(filter, serviceId, + order); + + if (type == FilterChainType.COMPONENT) { + getFilterChain(FilterChainType.INCLUDE).addFilter( + filter, serviceId, order); + getFilterChain(FilterChainType.FORWARD).addFilter( + filter, serviceId, order); + } + + } catch (IllegalArgumentException iae) { + // TODO: log ... + } + } + } else { + log.warn(String.format( + "A Filter (Service ID %s) has been registered without a filter.scope property.", + reference.getProperty(Constants.SERVICE_ID))); + getFilterChain(FilterChainType.REQUEST).addFilter(filter, + serviceId, order); + } + + } catch (ServletException ce) { + log.error("Filter " + filterName + " failed to initialize", ce); + } catch (Throwable t) { + log.error("Unexpected Problem initializing ComponentFilter " + + "", t); + } + } + } + + private void destroyFilter(final ServiceReference reference, + final Filter filter) { + // service id + Object serviceId = reference.getProperty(Constants.SERVICE_ID); + boolean removed = false; + for (SlingFilterChainHelper filterChain : filterChains) { + removed |= filterChain.removeFilterById(serviceId); + } + + // destroy it + if (removed) { + try { + filter.destroy(); + } catch (Throwable t) { + log.error("Unexpected problem destroying Filter {}", filter, t); + } + } + } +} Propchange: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/ServletFilterManager.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/ServletFilterManager.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev Url Modified: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/SlingFilterChainHelper.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/SlingFilterChainHelper.java?rev=993280&r1=993279&r2=993280&view=diff ============================================================================== --- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/SlingFilterChainHelper.java (original) +++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/SlingFilterChainHelper.java Tue Sep 7 08:45:36 2010 @@ -37,7 +37,7 @@ public class SlingFilterChainHelper { Filter[] filters; - public SlingFilterChainHelper() { + SlingFilterChainHelper() { } public synchronized Filter addFilter(Filter filter, @@ -76,7 +76,7 @@ public class SlingFilterChainHelper { return null; } - public synchronized Filter removeFilterById(Object filterId) { + public synchronized boolean removeFilterById(Object filterId) { if (filterList != null) { filters = null; for (Iterator fi = filterList.iterator(); fi.hasNext();) { @@ -85,13 +85,13 @@ public class SlingFilterChainHelper { || (test.getFitlerId() != null && test.getFitlerId().equals( filterId))) { fi.remove(); - return test.getFilter(); + return true; } } } // no removed ComponentFilter - return null; + return false; } /** Modified: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java?rev=993280&r1=993279&r2=993280&view=diff ============================================================================== --- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java (original) +++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java Tue Sep 7 08:45:36 2010 @@ -40,7 +40,6 @@ import javax.servlet.http.HttpServletRes import org.apache.sling.api.SlingConstants; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; -import org.apache.sling.api.adapter.AdapterManager; import org.apache.sling.api.request.RecursionTooDeepException; import org.apache.sling.api.request.RequestPathInfo; import org.apache.sling.api.request.RequestProgressTracker; @@ -51,6 +50,7 @@ import org.apache.sling.api.resource.Res import org.apache.sling.api.servlets.ServletResolver; import org.apache.sling.api.wrappers.SlingHttpServletRequestWrapper; import org.apache.sling.api.wrappers.SlingHttpServletResponseWrapper; +import org.apache.sling.engine.impl.SlingRequestProcessorImpl; import org.apache.sling.engine.impl.SlingHttpServletRequestImpl; import org.apache.sling.engine.impl.SlingHttpServletResponseImpl; import org.apache.sling.engine.impl.SlingMainServlet; @@ -108,8 +108,10 @@ public class RequestData implements Buff */ private static int maxCallCounter = DEFAULT_MAX_CALL_COUNTER; + private static SlingMainServlet SLING_MAIN_SERVLET; + /** The SlingMainServlet used for request dispatching and other stuff */ - private final SlingMainServlet slingMainServlet; + private final SlingRequestProcessorImpl slingRequestProcessor; /** The original servlet Servlet Request Object */ private HttpServletRequest servletRequest; @@ -166,10 +168,14 @@ public class RequestData implements Buff return maxInclusionCounter; } - public RequestData(SlingMainServlet slingMainServlet, + public static void setSlingMainServlet(final SlingMainServlet slingMainServlet) { + RequestData.SLING_MAIN_SERVLET = slingMainServlet; + } + + public RequestData(SlingRequestProcessorImpl slingRequestProcessor, HttpServletRequest request, HttpServletResponse response) { - this.slingMainServlet = slingMainServlet; + this.slingRequestProcessor = slingRequestProcessor; this.servletRequest = request; this.servletResponse = response; @@ -208,7 +214,7 @@ public class RequestData implements Buff requestProgressTracker.log("Resource Path Info: {0}", requestPathInfo); // finally resolve the servlet for the resource - ServletResolver sr = slingMainServlet.getServletResolver(); + ServletResolver sr = slingRequestProcessor.getServletResolver(); if (sr != null) { requestProgressTracker.startTimer("ServletResolution"); Servlet servlet = sr.resolveServlet(slingRequest); @@ -247,8 +253,8 @@ public class RequestData implements Buff resourceResolver = null; } - public SlingMainServlet getSlingMainServlet() { - return slingMainServlet; + public SlingRequestProcessorImpl getSlingRequestProcessor() { + return slingRequestProcessor; } public HttpServletRequest getServletRequest() { @@ -616,13 +622,12 @@ public class RequestData implements Buff return activeServletName; } - /** - * Returns the AdapterManager instance bound to the - * {@link SlingMainServlet} of this request data instance. This may be - * null if no adapter manager is bound to the SlingMainServlet. - */ - public AdapterManager getAdapterManager() { - return slingMainServlet.getAdapterManager(); + public Type adaptTo(Object object, Class type) { + return SLING_MAIN_SERVLET.adaptTo(object, type); + } + + public String getMimeType(String fileName) { + return SLING_MAIN_SERVLET.getMimeType(fileName); } // ---------- BufferProvider ----------------------------------------- Modified: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/SlingRequestDispatcher.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/SlingRequestDispatcher.java?rev=993280&r1=993279&r2=993280&view=diff ============================================================================== --- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/SlingRequestDispatcher.java (original) +++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/SlingRequestDispatcher.java Tue Sep 7 08:45:36 2010 @@ -99,7 +99,7 @@ public class SlingRequestDispatcher impl try { - dispatch(request, sResponse); + dispatch(request, sResponse, true); } finally { @@ -140,7 +140,7 @@ public class SlingRequestDispatcher impl request.removeAttribute(SlingConstants.ATTR_INCLUDE_SERVLET_PATH); // now just include as normal - dispatch(request, response); + dispatch(request, response, false); // finally, we would have to ensure the response is committed // and closed. Let's just flush the buffer and thus commit the @@ -165,8 +165,8 @@ public class SlingRequestDispatcher impl return uri + '/' + path; } - private void dispatch(ServletRequest request, ServletResponse sResponse) - throws ServletException, IOException { + private void dispatch(ServletRequest request, ServletResponse sResponse, + boolean include) throws ServletException, IOException { /** * TODO: I have made some quick fixes in this method for SLING-221 and @@ -186,8 +186,6 @@ public class SlingRequestDispatcher impl return; } - final HttpServletResponse response = (HttpServletResponse) sResponse; - if (resource == null) { // resolve the absolute path in the resource resolver, using @@ -204,6 +202,24 @@ public class SlingRequestDispatcher impl } // ensure request path info and optional merges + SlingRequestPathInfo info = getMergedRequestPathInfo(cRequest); + cRequest.getRequestProgressTracker().log( + "Including resource {0} ({1})", resource, info); + rd.getSlingRequestProcessor().dispatchRequest(request, sResponse, resource, + info, include); + } + + /** + * Returns a {@link SlingRequestPathInfo} object to use to select the + * servlet or script to call to render the resource to be dispatched to. + *

+ * Note: If this request dispatcher has been created with resource + * type overwriting request dispatcher options, the resource to dispatch to + * may be wrapped with a {@link TypeOverwritingResourceWrapper} as a result + * of calling this method. + */ + private SlingRequestPathInfo getMergedRequestPathInfo( + final SlingHttpServletRequest cRequest) { SlingRequestPathInfo info = new SlingRequestPathInfo(resource); info = info.merge(cRequest.getRequestPathInfo()); @@ -220,10 +236,7 @@ public class SlingRequestDispatcher impl } } - cRequest.getRequestProgressTracker().log( - "Including resource {0} ({1})", resource, info); - rd.getSlingMainServlet().includeContent(request, response, resource, - info); + return info; } private Object setAttribute(final ServletRequest request, @@ -236,6 +249,7 @@ public class SlingRequestDispatcher impl private static class TypeOverwritingResourceWrapper extends ResourceWrapper { private final String resourceType; + TypeOverwritingResourceWrapper(Resource delegatee, String resourceType) { super(delegatee); this.resourceType = resourceType; @@ -251,7 +265,7 @@ public class SlingRequestDispatcher impl */ @Override public String getResourceSuperType() { - return null; + return null; } } } \ No newline at end of file