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 19package org.eclipse.jetty.server.handler; 20 21import java.io.IOException; 22 23import javax.servlet.ServletException; 24import javax.servlet.http.HttpServletRequest; 25import javax.servlet.http.HttpServletResponse; 26 27import 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 */ 96public 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