| // |
| // ======================================================================== |
| // Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. |
| // ------------------------------------------------------------------------ |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // and Apache License v2.0 which accompanies this distribution. |
| // |
| // The Eclipse Public License is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // The Apache License v2.0 is available at |
| // http://www.opensource.org/licenses/apache2.0.php |
| // |
| // You may elect to redistribute this code under either of these licenses. |
| // ======================================================================== |
| // |
| |
| package org.eclipse.jetty.server.handler; |
| |
| import java.io.IOException; |
| |
| import javax.servlet.ServletException; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| |
| import org.eclipse.jetty.server.Request; |
| |
| |
| /* ------------------------------------------------------------ */ |
| /** ScopedHandler. |
| * |
| * A ScopedHandler is a HandlerWrapper where the wrapped handlers |
| * each define a scope. |
| * |
| * <p>When {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)} |
| * is called on the first ScopedHandler in a chain of HandlerWrappers, |
| * the {@link #doScope(String, Request, HttpServletRequest, HttpServletResponse)} method is |
| * called on all contained ScopedHandlers, before the |
| * {@link #doHandle(String, Request, HttpServletRequest, HttpServletResponse)} method |
| * is called on all contained handlers.</p> |
| * |
| * <p>For example if Scoped handlers A, B & C were chained together, then |
| * the calling order would be:</p> |
| * <pre> |
| * A.handle(...) |
| * A.doScope(...) |
| * B.doScope(...) |
| * C.doScope(...) |
| * A.doHandle(...) |
| * B.doHandle(...) |
| * C.doHandle(...) |
| * </pre> |
| * |
| * <p>If non scoped handler X was in the chained A, B, X & C, then |
| * the calling order would be:</p> |
| * <pre> |
| * A.handle(...) |
| * A.doScope(...) |
| * B.doScope(...) |
| * C.doScope(...) |
| * A.doHandle(...) |
| * B.doHandle(...) |
| * X.handle(...) |
| * C.handle(...) |
| * C.doHandle(...) |
| * </pre> |
| * |
| * <p>A typical usage pattern is:</p> |
| * <pre> |
| * private static class MyHandler extends ScopedHandler |
| * { |
| * public void doScope(String target, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException |
| * { |
| * try |
| * { |
| * setUpMyScope(); |
| * super.doScope(target,request,response); |
| * } |
| * finally |
| * { |
| * tearDownMyScope(); |
| * } |
| * } |
| * |
| * public void doHandle(String target, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException |
| * { |
| * try |
| * { |
| * doMyHandling(); |
| * super.doHandle(target,request,response); |
| * } |
| * finally |
| * { |
| * cleanupMyHandling(); |
| * } |
| * } |
| * } |
| * </pre> |
| */ |
| public abstract class ScopedHandler extends HandlerWrapper |
| { |
| private static final ThreadLocal<ScopedHandler> __outerScope= new ThreadLocal<ScopedHandler>(); |
| protected ScopedHandler _outerScope; |
| protected ScopedHandler _nextScope; |
| |
| /* ------------------------------------------------------------ */ |
| /** |
| * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStart() |
| */ |
| @Override |
| protected void doStart() throws Exception |
| { |
| try |
| { |
| _outerScope=__outerScope.get(); |
| if (_outerScope==null) |
| __outerScope.set(this); |
| |
| super.doStart(); |
| |
| _nextScope= getChildHandlerByClass(ScopedHandler.class); |
| |
| } |
| finally |
| { |
| if (_outerScope==null) |
| __outerScope.set(null); |
| } |
| } |
| |
| /* ------------------------------------------------------------ */ |
| /* |
| */ |
| @Override |
| public final void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException |
| { |
| if (isStarted()) |
| { |
| if (_outerScope==null) |
| doScope(target,baseRequest,request, response); |
| else |
| doHandle(target,baseRequest,request, response); |
| } |
| } |
| |
| /* ------------------------------------------------------------ */ |
| /* |
| * Scope the handler |
| */ |
| public abstract void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) |
| throws IOException, ServletException; |
| |
| /* ------------------------------------------------------------ */ |
| /* |
| * Scope the handler |
| */ |
| public final void nextScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) |
| throws IOException, ServletException |
| { |
| // this method has been manually inlined in several locations, but |
| // is called protected by an if(never()), so your IDE can find those |
| // locations if this code is changed. |
| if (_nextScope!=null) |
| _nextScope.doScope(target,baseRequest,request, response); |
| else if (_outerScope!=null) |
| _outerScope.doHandle(target,baseRequest,request, response); |
| else |
| doHandle(target,baseRequest,request, response); |
| } |
| |
| /* ------------------------------------------------------------ */ |
| /* |
| * Do the handler work within the scope. |
| */ |
| public abstract void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) |
| throws IOException, ServletException; |
| |
| /* ------------------------------------------------------------ */ |
| /* |
| * Do the handler work within the scope. |
| */ |
| public final void nextHandle(String target, final Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException |
| { |
| // this method has been manually inlined in several locations, but |
| // is called protected by an if(never()), so your IDE can find those |
| // locations if this code is changed. |
| if (_nextScope!=null && _nextScope==_handler) |
| _nextScope.doHandle(target,baseRequest,request, response); |
| else if (_handler!=null) |
| _handler.handle(target,baseRequest, request, response); |
| } |
| |
| /* ------------------------------------------------------------ */ |
| protected boolean never() |
| { |
| return false; |
| } |
| |
| } |