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 doStart()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 handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)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 */ doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)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 */ nextScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)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 */ doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)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 */ nextHandle(String target, final Request baseRequest, HttpServletRequest request, HttpServletResponse response)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 /* ------------------------------------------------------------ */ never()188 protected boolean never() 189 { 190 return false; 191 } 192 193 } 194