1 // 2 // ======================================================================== 3 // Copyright (c) 1995-2016 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. 35 * 36 * <p>When {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)} 37 * is called on the first ScopedHandler in a chain of HandlerWrappers, 38 * the {@link #doScope(String, Request, HttpServletRequest, HttpServletResponse)} method is 39 * called on all contained ScopedHandlers, before the 40 * {@link #doHandle(String, Request, HttpServletRequest, HttpServletResponse)} method 41 * is called on all contained handlers.</p> 42 * 43 * <p>For example if Scoped handlers A, B & C were chained together, then 44 * the calling order would be:</p> 45 * <pre> 46 * A.handle(...) 47 * A.doScope(...) 48 * B.doScope(...) 49 * C.doScope(...) 50 * A.doHandle(...) 51 * B.doHandle(...) 52 * C.doHandle(...) 53 * </pre> 54 * 55 * <p>If non scoped handler X was in the chained A, B, X & C, then 56 * the calling order would be:</p> 57 * <pre> 58 * A.handle(...) 59 * A.doScope(...) 60 * B.doScope(...) 61 * C.doScope(...) 62 * A.doHandle(...) 63 * B.doHandle(...) 64 * X.handle(...) 65 * C.handle(...) 66 * C.doHandle(...) 67 * </pre> 68 * 69 * <p>A typical usage pattern is:</p> 70 * <pre> 71 * private static class MyHandler extends ScopedHandler 72 * { 73 * public void doScope(String target, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException 74 * { 75 * try 76 * { 77 * setUpMyScope(); 78 * super.doScope(target,request,response); 79 * } 80 * finally 81 * { 82 * tearDownMyScope(); 83 * } 84 * } 85 * 86 * public void doHandle(String target, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException 87 * { 88 * try 89 * { 90 * doMyHandling(); 91 * super.doHandle(target,request,response); 92 * } 93 * finally 94 * { 95 * cleanupMyHandling(); 96 * } 97 * } 98 * } 99 * </pre> 100 */ 101 public abstract class ScopedHandler extends HandlerWrapper 102 { 103 private static final ThreadLocal<ScopedHandler> __outerScope= new ThreadLocal<ScopedHandler>(); 104 protected ScopedHandler _outerScope; 105 protected ScopedHandler _nextScope; 106 107 /* ------------------------------------------------------------ */ 108 /** 109 * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStart() 110 */ 111 @Override 112 protected void doStart() throws Exception 113 { 114 try 115 { 116 _outerScope=__outerScope.get(); 117 if (_outerScope==null) 118 __outerScope.set(this); 119 120 super.doStart(); 121 122 _nextScope= getChildHandlerByClass(ScopedHandler.class); 123 124 } 125 finally 126 { 127 if (_outerScope==null) 128 __outerScope.set(null); 129 } 130 } 131 132 /* ------------------------------------------------------------ */ 133 /* 134 */ 135 @Override 136 public final void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException 137 { 138 if (isStarted()) 139 { 140 if (_outerScope==null) 141 doScope(target,baseRequest,request, response); 142 else 143 doHandle(target,baseRequest,request, response); 144 } 145 } 146 147 /* ------------------------------------------------------------ */ 148 /* 149 * Scope the handler 150 */ 151 public abstract void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) 152 throws IOException, ServletException; 153 154 /* ------------------------------------------------------------ */ 155 /* 156 * Scope the handler 157 */ 158 public final void nextScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) 159 throws IOException, ServletException 160 { 161 // this method has been manually inlined in several locations, but 162 // is called protected by an if(never()), so your IDE can find those 163 // locations if this code is changed. 164 if (_nextScope!=null) 165 _nextScope.doScope(target,baseRequest,request, response); 166 else if (_outerScope!=null) 167 _outerScope.doHandle(target,baseRequest,request, response); 168 else 169 doHandle(target,baseRequest,request, response); 170 } 171 172 /* ------------------------------------------------------------ */ 173 /* 174 * Do the handler work within the scope. 175 */ 176 public abstract void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) 177 throws IOException, ServletException; 178 179 /* ------------------------------------------------------------ */ 180 /* 181 * Do the handler work within the scope. 182 */ 183 public final void nextHandle(String target, final Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException 184 { 185 // this method has been manually inlined in several locations, but 186 // is called protected by an if(never()), so your IDE can find those 187 // locations if this code is changed. 188 if (_nextScope!=null && _nextScope==_handler) 189 _nextScope.doHandle(target,baseRequest,request, response); 190 else if (_handler!=null) 191 _handler.handle(target,baseRequest, request, response); 192 } 193 194 /* ------------------------------------------------------------ */ 195 protected boolean never() 196 { 197 return false; 198 } 199 200 }