Home | History | Annotate | Download | only in handler
      1 //
      2 //  ========================================================================
      3 //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
      4 //  ------------------------------------------------------------------------
      5 //  All rights reserved. This program and the accompanying materials
      6 //  are made available under the terms of the Eclipse Public License v1.0
      7 //  and Apache License v2.0 which accompanies this distribution.
      8 //
      9 //      The Eclipse Public License is available at
     10 //      http://www.eclipse.org/legal/epl-v10.html
     11 //
     12 //      The Apache License v2.0 is available at
     13 //      http://www.opensource.org/licenses/apache2.0.php
     14 //
     15 //  You may elect to redistribute this code under either of these licenses.
     16 //  ========================================================================
     17 //
     18 
     19 package org.eclipse.jetty.server.handler;
     20 
     21 import java.io.IOException;
     22 
     23 import javax.servlet.ServletException;
     24 import javax.servlet.http.HttpServletRequest;
     25 import javax.servlet.http.HttpServletResponse;
     26 
     27 import org.eclipse.jetty.server.Request;
     28 
     29 
     30 /* ------------------------------------------------------------ */
     31 /** ScopedHandler.
     32  *
     33  * A ScopedHandler is a HandlerWrapper where the wrapped handlers
     34  * each define a scope.   When {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)}
     35  * is called on the first ScopedHandler in a chain of HandlerWrappers,
     36  * the {@link #doScope(String, Request, HttpServletRequest, HttpServletResponse)} method is
     37  * called on all contained ScopedHandlers, before the
     38  * {@link #doHandle(String, Request, HttpServletRequest, HttpServletResponse)} method
     39  * is called on all contained handlers.
     40  *
     41  * <p>For example if Scoped handlers A, B & C were chained together, then
     42  * the calling order would be:<pre>
     43  * A.handle(...)
     44  *   A.doScope(...)
     45  *     B.doScope(...)
     46  *       C.doScope(...)
     47  *         A.doHandle(...)
     48  *           B.doHandle(...)
     49  *              C.doHandle(...)
     50  * <pre>
     51  *
     52  * <p>If non scoped handler X was in the chained A, B, X & C, then
     53  * the calling order would be:<pre>
     54  * A.handle(...)
     55  *   A.doScope(...)
     56  *     B.doScope(...)
     57  *       C.doScope(...)
     58  *         A.doHandle(...)
     59  *           B.doHandle(...)
     60  *             X.handle(...)
     61  *               C.handle(...)
     62  *                 C.doHandle(...)
     63  * <pre>
     64  *
     65  * <p>A typical usage pattern is:<pre>
     66  *     private static class MyHandler extends ScopedHandler
     67  *     {
     68  *         public void doScope(String target, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
     69  *         {
     70  *             try
     71  *             {
     72  *                 setUpMyScope();
     73  *                 super.doScope(target,request,response);
     74  *             }
     75  *             finally
     76  *             {
     77  *                 tearDownMyScope();
     78  *             }
     79  *         }
     80  *
     81  *         public void doHandle(String target, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
     82  *         {
     83  *             try
     84  *             {
     85  *                 doMyHandling();
     86  *                 super.doHandle(target,request,response);
     87  *             }
     88  *             finally
     89  *             {
     90  *                 cleanupMyHandling();
     91  *             }
     92  *         }
     93  *     }
     94  * </pre>
     95  */
     96 public abstract class ScopedHandler extends HandlerWrapper
     97 {
     98     private static final ThreadLocal<ScopedHandler> __outerScope= new ThreadLocal<ScopedHandler>();
     99     protected ScopedHandler _outerScope;
    100     protected ScopedHandler _nextScope;
    101 
    102     /* ------------------------------------------------------------ */
    103     /**
    104      * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStart()
    105      */
    106     @Override
    107     protected void doStart() throws Exception
    108     {
    109         try
    110         {
    111             _outerScope=__outerScope.get();
    112             if (_outerScope==null)
    113                 __outerScope.set(this);
    114 
    115             super.doStart();
    116 
    117             _nextScope= (ScopedHandler)getChildHandlerByClass(ScopedHandler.class);
    118 
    119         }
    120         finally
    121         {
    122             if (_outerScope==null)
    123                 __outerScope.set(null);
    124         }
    125     }
    126 
    127 
    128     /* ------------------------------------------------------------ */
    129     /*
    130      */
    131     @Override
    132     public final void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    133     {
    134         if (_outerScope==null)
    135             doScope(target,baseRequest,request, response);
    136         else
    137             doHandle(target,baseRequest,request, response);
    138     }
    139 
    140     /* ------------------------------------------------------------ */
    141     /*
    142      * Scope the handler
    143      */
    144     public abstract void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
    145         throws IOException, ServletException;
    146 
    147     /* ------------------------------------------------------------ */
    148     /*
    149      * Scope the handler
    150      */
    151     public final void nextScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
    152         throws IOException, ServletException
    153     {
    154         // this method has been manually inlined in several locations, but
    155         // is called protected by an if(never()), so your IDE can find those
    156         // locations if this code is changed.
    157         if (_nextScope!=null)
    158             _nextScope.doScope(target,baseRequest,request, response);
    159         else if (_outerScope!=null)
    160             _outerScope.doHandle(target,baseRequest,request, response);
    161         else
    162             doHandle(target,baseRequest,request, response);
    163     }
    164 
    165     /* ------------------------------------------------------------ */
    166     /*
    167      * Do the handler work within the scope.
    168      */
    169     public abstract void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
    170         throws IOException, ServletException;
    171 
    172     /* ------------------------------------------------------------ */
    173     /*
    174      * Do the handler work within the scope.
    175      */
    176     public final void nextHandle(String target, final Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    177     {
    178         // this method has been manually inlined in several locations, but
    179         // is called protected by an if(never()), so your IDE can find those
    180         // locations if this code is changed.
    181         if (_nextScope!=null && _nextScope==_handler)
    182             _nextScope.doHandle(target,baseRequest,request, response);
    183         else if (_handler!=null)
    184             _handler.handle(target,baseRequest, request, response);
    185     }
    186 
    187     /* ------------------------------------------------------------ */
    188     protected boolean never()
    189     {
    190         return false;
    191     }
    192 
    193 }
    194