001 /*
002 GRANITE DATA SERVICES
003 Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004
005 This file is part of Granite Data Services.
006
007 Granite Data Services is free software; you can redistribute it and/or modify
008 it under the terms of the GNU Library General Public License as published by
009 the Free Software Foundation; either version 2 of the License, or (at your
010 option) any later version.
011
012 Granite Data Services is distributed in the hope that it will be useful, but
013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015 for more details.
016
017 You should have received a copy of the GNU Library General Public License
018 along with this library; if not, see <http://www.gnu.org/licenses/>.
019 */
020
021 package org.granite.messaging.webapp;
022
023 import java.util.AbstractMap;
024 import java.util.Enumeration;
025 import java.util.HashSet;
026 import java.util.Map;
027 import java.util.Set;
028
029 import javax.servlet.ServletContext;
030 import javax.servlet.http.HttpServletRequest;
031 import javax.servlet.http.HttpServletResponse;
032 import javax.servlet.http.HttpSession;
033
034 import org.granite.clustering.TransientReference;
035 import org.granite.clustering.TransientReferenceHolder;
036 import org.granite.config.GraniteConfig;
037 import org.granite.config.flex.ServicesConfig;
038 import org.granite.context.GraniteContext;
039
040 /**
041 * @author Franck WOLFF
042 */
043 public class HttpGraniteContext extends GraniteContext {
044
045 private static final String SESSION_LOCK_KEY = HttpGraniteContext.class.getName() + ".LOCK";
046
047 private final ServletContext context;
048 private final HttpServletRequest request;
049 private final HttpServletResponse response;
050
051 private InitialisationMap initialisationMap = null;
052 private ApplicationMap applicationMap = null;
053 private SessionMap sessionMap = null;
054 private RequestMap requestMap = null;
055
056
057 public static HttpGraniteContext createThreadIntance(
058 GraniteConfig graniteConfig,
059 ServicesConfig servicesConfig,
060 ServletContext context,
061 HttpServletRequest request,
062 HttpServletResponse response) {
063
064 HttpGraniteContext graniteContext = new HttpGraniteContext(graniteConfig, servicesConfig, context, request, response);
065 setCurrentInstance(graniteContext);
066 return graniteContext;
067 }
068
069
070 private HttpGraniteContext(
071 GraniteConfig graniteConfig,
072 ServicesConfig servicesConfig,
073 ServletContext context,
074 HttpServletRequest request,
075 HttpServletResponse response) {
076
077 super(graniteConfig, servicesConfig);
078 this.context = context;
079 this.request = request;
080 this.response = response;
081 }
082
083 public ServletContext getServletContext() {
084 return context;
085 }
086
087 public HttpServletRequest getRequest() {
088 return request;
089 }
090
091 public HttpServletResponse getResponse() {
092 return response;
093 }
094
095 public HttpSession getSession(boolean create) {
096 return request.getSession(create);
097 }
098
099 public HttpSession getSession() {
100 return request.getSession(true);
101 }
102
103 @Override
104 public synchronized Object getSessionLock() {
105 Object lock = request.getSession(true).getAttribute(SESSION_LOCK_KEY);
106 if (lock == null) {
107 lock = new Boolean(true);
108 request.getSession(true).setAttribute(SESSION_LOCK_KEY, lock);
109 }
110 return lock;
111 }
112
113
114 @Override
115 public Map<String, String> getInitialisationMap() {
116 if (initialisationMap == null)
117 initialisationMap = new InitialisationMap(context);
118 return initialisationMap;
119 }
120
121 @Override
122 public Map<String, Object> getApplicationMap() {
123 if (applicationMap == null)
124 applicationMap = new ApplicationMap(context);
125 return applicationMap;
126 }
127
128 @Override
129 public Map<String, Object> getSessionMap() {
130 return getSessionMap(true);
131 }
132 @Override
133 public Map<String, Object> getSessionMap(boolean create) {
134 if (sessionMap == null && (create || request.getSession(false) != null))
135 sessionMap = new SessionMap(request);
136 return sessionMap;
137 }
138
139 @Override
140 public Map<String, Object> getRequestMap() {
141 if (requestMap == null)
142 requestMap = new RequestMap(request);
143 return requestMap;
144 }
145 }
146
147 abstract class BaseContextMap<T,U> extends AbstractMap<T,U> {
148
149 protected static final String KEY_STRING_ERROR = "Key should be a non null String: ";
150
151 @Override
152 public void clear() {
153 throw new UnsupportedOperationException();
154 }
155
156 @Override
157 public void putAll(Map<? extends T, ? extends U> t) {
158 throw new UnsupportedOperationException();
159 }
160
161 @Override
162 public U remove(Object key) {
163 throw new UnsupportedOperationException();
164 }
165
166 static class Entry<T,U> implements Map.Entry<T,U> {
167
168 private final T key;
169 private final U value;
170
171 Entry(T key, U value) {
172 this.key = key;
173 this.value = value;
174 }
175
176 public T getKey() {
177 return key;
178 }
179
180 public U getValue() {
181 return value;
182 }
183
184 public U setValue(U value) {
185 throw new UnsupportedOperationException();
186 }
187
188 @Override
189 public int hashCode() {
190 return ((key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()));
191 }
192
193 @Override
194 public boolean equals(Object obj) {
195 if (obj == this)
196 return true;
197
198 if (obj == null || !(obj instanceof Map.Entry<?, ?>))
199 return false;
200
201 Map.Entry<?, ?> input = (Map.Entry<?, ?>)obj;
202 Object inputKey = input.getKey();
203 Object inputValue = input.getValue();
204
205 if (inputKey == key || (inputKey != null && inputKey.equals(key))) {
206 if (inputValue == value || (inputValue != null && inputValue.equals(value)))
207 return true;
208 }
209 return false;
210 }
211 }
212 }
213
214 class InitialisationMap extends BaseContextMap<String, String> {
215
216 private ServletContext servletContext = null;
217
218 InitialisationMap(ServletContext servletContext) {
219 if (servletContext == null)
220 throw new NullPointerException("servletContext is null");
221 this.servletContext = servletContext;
222 }
223
224 @Override
225 public String get(Object key) {
226 if (!(key instanceof String))
227 return null;
228 return servletContext.getInitParameter(key.toString());
229 }
230
231 @Override
232 public String put(String key, String value) {
233 throw new UnsupportedOperationException();
234 }
235
236 @Override
237 public Set<Map.Entry<String, String>> entrySet() {
238 Set<Map.Entry<String, String>> entries = new HashSet<Map.Entry<String, String>>();
239 for (Enumeration<?> e = servletContext.getInitParameterNames(); e.hasMoreElements();) {
240 String key = (String)e.nextElement();
241 entries.add(new Entry<String, String>(key, servletContext.getInitParameter(key)));
242 }
243 return entries;
244 }
245
246 @Override
247 public boolean equals(Object obj) {
248 if (obj == null || !(obj instanceof InitialisationMap))
249 return false;
250 return super.equals(obj);
251 }
252 }
253
254 class ApplicationMap extends BaseContextMap<String, Object> {
255
256 private ServletContext servletContext = null;
257
258 ApplicationMap(ServletContext servletContext) {
259 if (servletContext == null)
260 throw new NullPointerException("servletContext is null");
261 this.servletContext = servletContext;
262 }
263
264 @Override
265 public Object get(Object key) {
266 if (!(key instanceof String))
267 return null;
268 return servletContext.getAttribute(key.toString());
269 }
270
271 @Override
272 public Object put(String key, Object value) {
273 if (key == null)
274 throw new IllegalArgumentException(KEY_STRING_ERROR + key);
275 Object result = servletContext.getAttribute(key);
276 servletContext.setAttribute(key, value);
277 return (result);
278 }
279
280 @Override
281 public Object remove(Object key) {
282 if (!(key instanceof String))
283 return null;
284 Object result = servletContext.getAttribute(key.toString());
285 servletContext.removeAttribute(key.toString());
286 return result;
287 }
288
289 @Override
290 public Set<Map.Entry<String, Object>> entrySet() {
291 Set<Map.Entry<String, Object>> entries = new HashSet<Map.Entry<String, Object>>();
292 for (Enumeration<?> e = servletContext.getAttributeNames(); e.hasMoreElements();) {
293 String key = (String)e.nextElement();
294 entries.add(new Entry<String, Object>(key, servletContext.getAttribute(key)));
295 }
296 return entries;
297 }
298
299 @Override
300 public boolean equals(Object obj) {
301 if (obj == null || !(obj instanceof ApplicationMap))
302 return false;
303 return super.equals(obj);
304 }
305 }
306
307 class SessionMap extends BaseContextMap<String, Object> {
308
309 private HttpServletRequest request = null;
310
311 SessionMap(HttpServletRequest request) {
312 if (request == null)
313 throw new NullPointerException("request is null");
314 this.request = request;
315 }
316
317 @Override
318 public Object get(Object key) {
319 if (!(key instanceof String))
320 return null;
321 Object value = getSession().getAttribute(key.toString());
322 if (value instanceof TransientReferenceHolder)
323 return ((TransientReferenceHolder)value).get();
324 return value;
325 }
326
327 @Override
328 public Object put(String key, Object value) {
329 if (key == null)
330 throw new IllegalArgumentException(KEY_STRING_ERROR + key);
331 HttpSession session = getSession();
332 Object result = session.getAttribute(key);
333 if (result instanceof TransientReferenceHolder)
334 result = ((TransientReferenceHolder)result).get();
335 if (value != null && value.getClass().isAnnotationPresent(TransientReference.class))
336 value = new TransientReferenceHolder(value);
337 session.setAttribute(key, value);
338 return result;
339 }
340
341 @Override
342 public Object remove(Object key) {
343 if (!(key instanceof String))
344 return null;
345 HttpSession session = getSession();
346 Object result = session.getAttribute(key.toString());
347 if (result instanceof TransientReferenceHolder)
348 result = ((TransientReferenceHolder)result).get();
349 session.removeAttribute(key.toString());
350 return result;
351 }
352
353 @Override
354 public Set<Map.Entry<String, Object>> entrySet() {
355 Set<Map.Entry<String, Object>> entries = new HashSet<Map.Entry<String, Object>>();
356 HttpSession session = getSession();
357 for (Enumeration<?> e = session.getAttributeNames(); e.hasMoreElements(); ) {
358 String key = (String)e.nextElement();
359 Object value = session.getAttribute(key);
360 if (value instanceof TransientReferenceHolder)
361 value = ((TransientReferenceHolder)value).get();
362 entries.add(new Entry<String, Object>(key, value));
363 }
364 return entries;
365 }
366
367 @Override
368 public boolean equals(Object obj) {
369 if (obj == null || !(obj instanceof SessionMap))
370 return false;
371 return super.equals(obj);
372 }
373
374 private HttpSession getSession() {
375 return request.getSession(true);
376 }
377 }
378
379 class RequestMap extends BaseContextMap<String, Object> {
380
381 private HttpServletRequest request = null;
382
383 RequestMap(HttpServletRequest request) {
384 if (request == null)
385 throw new NullPointerException("request is null");
386 this.request = request;
387 }
388
389 @Override
390 public Object get(Object key) {
391 if (!(key instanceof String))
392 return null;
393 return request.getAttribute(key.toString());
394 }
395
396 @Override
397 public Object put(String key, Object value) {
398 if (key == null)
399 throw new IllegalArgumentException(KEY_STRING_ERROR + key);
400 Object result = request.getAttribute(key);
401 request.setAttribute(key, value);
402 return result;
403 }
404
405 @Override
406 public Object remove(Object key) {
407 if (!(key instanceof String))
408 return null;
409 Object result = request.getAttribute(key.toString());
410 request.removeAttribute(key.toString());
411 return result;
412 }
413
414 @Override
415 public Set<Map.Entry<String, Object>> entrySet() {
416 Set<Map.Entry<String, Object>> entries = new HashSet<Map.Entry<String, Object>>();
417 for (Enumeration<?> e = request.getAttributeNames(); e.hasMoreElements();) {
418 String key = (String)e.nextElement();
419 entries.add(new Entry<String, Object>(key, request.getAttribute(key)));
420 }
421 return entries;
422 }
423
424 @Override
425 public boolean equals(Object obj) {
426 if (obj == null || !(obj instanceof RequestMap))
427 return false;
428 return super.equals(obj);
429 }
430 }