View Javadoc

1   package com.bradmcevoy.http;
2   
3   import com.bradmcevoy.http.exceptions.BadRequestException;
4   import com.bradmcevoy.http.exceptions.ConflictException;
5   import com.bradmcevoy.http.exceptions.NotAuthorizedException;
6   import com.bradmcevoy.http.http11.CustomPostHandler;
7   import com.bradmcevoy.http.http11.Http11ResponseHandler;
8   import com.bradmcevoy.http.webdav.DefaultWebDavResponseHandler;
9   import com.bradmcevoy.http.webdav.WebDavResponseHandler;
10  import com.bradmcevoy.property.PropertyHandler;
11  import com.bradmcevoy.property.PropertyAuthoriser;
12  import com.ettrema.event.EventManager;
13  import com.ettrema.event.EventManagerImpl;
14  import com.ettrema.event.RequestEvent;
15  import com.ettrema.event.ResponseEvent;
16  import java.util.ArrayList;
17  import java.util.Collection;
18  import java.util.List;
19  import java.util.Map;
20  import java.util.concurrent.ConcurrentHashMap;
21  
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  
25  /**
26   * Milton's main class. All the servlets and stuff is just fluff, this is where stuff really starts to happen
27   *
28   *
29   * @author brad
30   */
31  public class HttpManager {
32  
33      private static final Logger log = LoggerFactory.getLogger(HttpManager.class);
34  
35      public static String decodeUrl(String s) {
36          return Utils.decodePath(s);
37      }
38      private static final ThreadLocal<Request> tlRequest = new ThreadLocal<Request>();
39      private static final ThreadLocal<Response> tlResponse = new ThreadLocal<Response>();
40  
41      public static Request request() {
42          return tlRequest.get();
43      }
44  
45      public static Response response() {
46          return tlResponse.get();
47      }
48      private final ProtocolHandlers handlers;
49      private Map<String, Handler> methodHandlers = new ConcurrentHashMap<String, Handler>();
50      List<Filter> filters = new ArrayList<Filter>();
51      List<EventListener> eventListeners = new ArrayList<EventListener>();
52      protected final ResourceFactory resourceFactory;
53      protected final Http11ResponseHandler responseHandler;
54      private SessionAuthenticationHandler sessionAuthenticationHandler;
55      private PropertyAuthoriser propertyPermissionService;
56      private EventManager eventManager = new EventManagerImpl();
57  
58  
59  
60      /**
61       * Creates the manager with a DefaultResponseHandler
62       *
63       * @param resourceFactory
64       */
65      public HttpManager(ResourceFactory resourceFactory) {
66          if (resourceFactory == null) {
67              throw new NullPointerException("resourceFactory cannot be null");
68          }
69          this.resourceFactory = resourceFactory;
70          AuthenticationService authenticationService = new AuthenticationService();
71          DefaultWebDavResponseHandler webdavResponseHandler = new DefaultWebDavResponseHandler(authenticationService);
72          this.responseHandler = webdavResponseHandler;
73          this.handlers = new ProtocolHandlers(webdavResponseHandler, authenticationService);
74  
75          initHandlers();
76      }
77  
78      public HttpManager(ResourceFactory resourceFactory, AuthenticationService authenticationService) {
79          if (resourceFactory == null) {
80              throw new NullPointerException("resourceFactory cannot be null");
81          }
82          this.resourceFactory = resourceFactory;
83          DefaultWebDavResponseHandler webdavResponseHandler = new DefaultWebDavResponseHandler(authenticationService);
84          this.responseHandler = webdavResponseHandler;
85          this.handlers = new ProtocolHandlers(webdavResponseHandler, authenticationService);
86  
87          initHandlers();
88      }
89  
90      public HttpManager(ResourceFactory resourceFactory, WebDavResponseHandler responseHandler, AuthenticationService authenticationService) {
91          if (resourceFactory == null) {
92              throw new NullPointerException("resourceFactory cannot be null");
93          }
94          this.resourceFactory = resourceFactory;
95          this.responseHandler = responseHandler;
96          this.handlers = new ProtocolHandlers(responseHandler, authenticationService);
97  
98          initHandlers();
99      }
100 
101     public HttpManager(ResourceFactory resourceFactory, WebDavResponseHandler responseHandler, ProtocolHandlers handlers) {
102         if (resourceFactory == null) {
103             throw new NullPointerException("resourceFactory cannot be null");
104         }
105         this.resourceFactory = resourceFactory;
106         this.responseHandler = responseHandler;
107         this.handlers = handlers;
108 
109         initHandlers();
110     }
111 
112     private void initHandlers() {
113         for (HttpExtension ext : handlers) {
114             for (Handler h : ext.getHandlers()) {
115                 for (String m : h.getMethods()) {
116                     this.methodHandlers.put(m, h);
117                 }
118             }
119         }
120         // The standard filter must always be there, its what invokes the main milton processing
121         filters.add(createStandardFilter());
122     }
123 
124     public Handler getMethodHandler(Request.Method m) {
125         return methodHandlers.get(m.code);
126     }
127 
128     public ResourceFactory getResourceFactory() {
129         return resourceFactory;
130     }
131 
132     public SessionAuthenticationHandler getSessionAuthenticationHandler() {
133         return sessionAuthenticationHandler;
134     }
135 
136     public void setSessionAuthenticationHandler(SessionAuthenticationHandler sessionAuthenticationHandler) {
137         this.sessionAuthenticationHandler = sessionAuthenticationHandler;
138     }
139 
140     /**
141      * @deprecated - use an AuthenticationHandler instead
142      * 
143      * @param request
144      * @return - if no SessionAuthenticationHandler has been set returns null. Otherwise,
145      *  calls getSessionAuthentication on it and returns the result
146      * 
147      * 
148      */
149     @Deprecated
150     public Auth getSessionAuthentication(Request request) {
151         if (this.sessionAuthenticationHandler == null) {
152             return null;
153         }
154         return this.sessionAuthenticationHandler.getSessionAuthentication(request);
155     }
156 
157     public void process(Request request, Response response) {
158         if (log.isInfoEnabled()) {
159             log.info(request.getMethod() + " :: " + request.getAbsoluteUrl() + " - " + request.getAbsoluteUrl());
160         }
161         tlRequest.set(request);
162         tlResponse.set(response);
163         try {
164             fireRequestEvent(request);
165         } catch (ConflictException ex) {
166             responseHandler.respondConflict(null, response, request, null);
167         } catch (BadRequestException ex) {
168             responseHandler.respondBadRequest(null, response, request);
169         } catch (NotAuthorizedException ex) {
170             responseHandler.respondUnauthorised(null, response, request);
171         }
172         try {
173             FilterChain chain = new FilterChain(this);
174             chain.process(request, response);
175             try {
176                 fireResponseEvent(request, response);
177             } catch (ConflictException ex) {
178                 log.warn("exception thrown from event handler after response is complete", ex);
179             } catch (BadRequestException ex) {
180                 log.warn("exception thrown from event handler after response is complete", ex);
181             } catch (NotAuthorizedException ex) {
182                 log.warn("exception thrown from event handler after response is complete", ex);
183             }
184         } finally {
185             tlRequest.remove();
186             tlResponse.remove();
187         }
188     }
189 
190     protected Filter createStandardFilter() {
191         return new StandardFilter();
192     }
193 
194     public void addFilter(int pos, Filter filter) {
195         filters.add(pos, filter);
196     }
197 
198     public void addEventListener(EventListener l) {
199         eventListeners.add(l);
200     }
201 
202     public void removeEventListener(EventListener l) {
203         eventListeners.remove(l);
204     }
205 
206     public void onProcessResourceFinish(Request request, Response response, Resource resource, long duration) {
207         for (EventListener l : eventListeners) {
208             l.onProcessResourceFinish(request, response, resource, duration);
209         }
210     }
211 
212     public void onProcessResourceStart(Request request, Response response, Resource resource) {
213         for (EventListener l : eventListeners) {
214             l.onProcessResourceStart(request, response, resource);
215         }
216     }
217 
218     public void onPost(Request request, Response response, Resource resource, Map<String, String> params, Map<String, FileItem> files) {
219         for (EventListener l : eventListeners) {
220             l.onPost(request, response, resource, params, files);
221         }
222     }
223 
224     public void onGet(Request request, Response response, Resource resource, Map<String, String> params) {
225         for (EventListener l : eventListeners) {
226             l.onGet(request, response, resource, params);
227         }
228     }
229 
230     public List<Filter> getFilters() {
231         ArrayList<Filter> col = new ArrayList<Filter>(filters);
232         return col;
233     }
234 
235     public void setFilters(List<Filter> filters) {
236         this.filters = filters;
237         filters.add(createStandardFilter());
238     }
239 
240     public void setEventListeners(List<EventListener> eventListeners) {
241         this.eventListeners = eventListeners;
242     }
243 
244     public Collection<Handler> getAllHandlers() {
245         return this.methodHandlers.values();
246     }
247 
248     public Http11ResponseHandler getResponseHandler() {
249         return responseHandler;
250     }
251 
252     public ProtocolHandlers getHandlers() {
253         return handlers;
254     }
255 
256     public PropertyAuthoriser getPropertyPermissionService() {
257         return propertyPermissionService;
258     }
259 
260     public void setPropertyPermissionService(PropertyAuthoriser propertyPermissionService) {
261         log.trace("setPropertyPermissionService: " + propertyPermissionService.getClass().getCanonicalName());
262         this.propertyPermissionService = propertyPermissionService;
263         for (Handler h : methodHandlers.values()) {
264             if (h instanceof PropertyHandler) {
265                 PropertyHandler ph = (PropertyHandler) h;
266                 log.trace("set propertyPermissionService on: " + ph.getClass().getCanonicalName());
267                 ph.setPermissionService(propertyPermissionService);
268             }
269         }
270     }
271 
272     public boolean isEnableExpectContinue() {
273         return handlers.isEnableExpectContinue();
274     }
275 
276     public void setEnableExpectContinue(boolean enableExpectContinue) {
277         handlers.setEnableExpectContinue(enableExpectContinue);
278     }
279 
280     public EventManager getEventManager() {
281         return eventManager;
282     }
283 
284     public void setEventManager(EventManager eventManager) {
285         this.eventManager = eventManager;
286     }
287 
288     private void fireRequestEvent(Request request) throws ConflictException, BadRequestException, NotAuthorizedException {
289         if (eventManager == null) {
290             return;
291         }
292         eventManager.fireEvent(new RequestEvent(request));
293     }
294 
295     private void fireResponseEvent(Request request, Response response) throws ConflictException, BadRequestException, NotAuthorizedException {
296         if (eventManager == null) {
297             return;
298         }
299         eventManager.fireEvent(new ResponseEvent(request, response));
300 
301     }
302 
303     public List<CustomPostHandler> getCustomPostHandlers() {
304         List<CustomPostHandler> list = new ArrayList<CustomPostHandler>();
305         for( HttpExtension p : this.handlers) {
306             if( p.getCustomPostHandlers() != null ) {
307                 for(CustomPostHandler h : p.getCustomPostHandlers()) {
308                     list.add(h);
309                 }
310             }
311         }
312         return list;
313     }
314 }