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