001 /**
002 * GRANITE DATA SERVICES
003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S.
004 *
005 * This file is part of the Granite Data Services Platform.
006 *
007 * Granite Data Services is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * Granite Data Services is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
015 * General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
020 * USA, or see <http://www.gnu.org/licenses/>.
021 */
022 package org.granite.messaging.webapp;
023
024 import java.io.BufferedReader;
025 import java.io.IOException;
026 import java.io.PrintWriter;
027 import java.io.UnsupportedEncodingException;
028 import java.security.Principal;
029 import java.util.AbstractMap;
030 import java.util.Collection;
031 import java.util.Enumeration;
032 import java.util.HashMap;
033 import java.util.HashSet;
034 import java.util.Hashtable;
035 import java.util.Locale;
036 import java.util.Map;
037 import java.util.Set;
038
039 import javax.servlet.AsyncContext;
040 import javax.servlet.DispatcherType;
041 import javax.servlet.RequestDispatcher;
042 import javax.servlet.ServletContext;
043 import javax.servlet.ServletException;
044 import javax.servlet.ServletInputStream;
045 import javax.servlet.ServletOutputStream;
046 import javax.servlet.ServletRequest;
047 import javax.servlet.ServletResponse;
048 import javax.servlet.http.Cookie;
049 import javax.servlet.http.HttpServletRequest;
050 import javax.servlet.http.HttpServletResponse;
051 import javax.servlet.http.HttpSession;
052 import javax.servlet.http.Part;
053
054 import org.granite.clustering.TransientReference;
055 import org.granite.clustering.TransientReferenceHolder;
056 import org.granite.config.GraniteConfig;
057 import org.granite.config.GraniteConfigListener;
058 import org.granite.config.flex.ServicesConfig;
059 import org.granite.context.GraniteContext;
060
061 /**
062 * @author Franck WOLFF
063 */
064 public class ServletGraniteContext extends GraniteContext {
065
066 private final ServletContext servletContext;
067
068 protected InitialisationMap initialisationMap = null;
069 protected ApplicationMap applicationMap = null;
070 protected SessionMap sessionMap = null;
071 protected HttpServletRequest request = null;
072 protected HttpServletResponse response = null;
073 protected HttpSession session = null;
074
075
076 public static ServletGraniteContext createThreadInstance(
077 GraniteConfig graniteConfig,
078 ServicesConfig servicesConfig,
079 ServletContext context,
080 String sessionId,
081 String clientType) {
082
083 ServletGraniteContext graniteContext = new ServletGraniteContext(graniteConfig, servicesConfig, context, sessionId, clientType);
084 setCurrentInstance(graniteContext);
085 return graniteContext;
086 }
087
088 public static ServletGraniteContext createThreadInstance(
089 GraniteConfig graniteConfig,
090 ServicesConfig servicesConfig,
091 ServletContext context,
092 HttpSession session,
093 String clientType) {
094
095 ServletGraniteContext graniteContext = new ServletGraniteContext(graniteConfig, servicesConfig, context, session, clientType);
096 setCurrentInstance(graniteContext);
097 return graniteContext;
098 }
099
100
101 protected ServletGraniteContext(
102 GraniteConfig graniteConfig,
103 ServicesConfig servicesConfig,
104 ServletContext servletContext,
105 String sessionId,
106 String clientType) {
107
108 super(graniteConfig, servicesConfig, sessionId, clientType);
109 this.servletContext = servletContext;
110 }
111
112 protected ServletGraniteContext(
113 GraniteConfig graniteConfig,
114 ServicesConfig servicesConfig,
115 ServletContext servletContext,
116 HttpSession session,
117 String clientType) {
118
119 super(graniteConfig, servicesConfig, session.getId(), clientType);
120 this.servletContext = servletContext;
121 this.session = session;
122 }
123
124 public ServletContext getServletContext() {
125 return servletContext;
126 }
127
128 public HttpServletRequest getRequest() {
129 if (request == null)
130 request = new BasicRequest();
131 return request;
132 }
133
134 public HttpServletResponse getResponse() {
135 if (response == null)
136 response = new BasicResponse();
137 return response;
138 }
139
140 public HttpSession getSession(boolean create) {
141 return getSession();
142 }
143
144 public HttpSession getSession() {
145 if (session != null)
146 return session;
147
148 if (getSessionId() == null)
149 return null;
150
151 // Lookup session in session map when using embedded Jetty
152 @SuppressWarnings("unchecked")
153 Map<String, HttpSession> sessionMap = (Map<String, HttpSession>)servletContext.getAttribute(GraniteConfigListener.GRANITE_SESSION_MAP);
154 return sessionMap != null ? sessionMap.get(getSessionId()) : null;
155 }
156
157 @Override
158 public Object getSessionLock() {
159 return null;
160 }
161
162
163 @Override
164 public Map<String, String> getInitialisationMap() {
165 if (initialisationMap == null)
166 initialisationMap = new InitialisationMap(servletContext);
167 return initialisationMap;
168 }
169
170 @Override
171 public Map<String, Object> getApplicationMap() {
172 if (applicationMap == null)
173 applicationMap = new ApplicationMap(servletContext);
174 return applicationMap;
175 }
176
177 @Override
178 public Map<String, Object> getSessionMap() {
179 return null;
180 }
181 @Override
182 public Map<String, Object> getSessionMap(boolean create) {
183 if (sessionMap == null && getSession() != null)
184 sessionMap = new SessionMap(getSession());
185 return sessionMap;
186 }
187
188 @Override
189 public Map<String, Object> getRequestMap() {
190 return null;
191 }
192
193
194 private class BasicRequest implements HttpServletRequest {
195
196 private Map<String, Object> attributes = new HashMap<String, Object>();
197
198 public ServletContext getServletContext() {
199 return servletContext;
200 }
201
202 public Object getAttribute(String key) {
203 return attributes.get(key);
204 }
205
206 public void removeAttribute(String key) {
207 attributes.remove(key);
208 }
209
210 public void setAttribute(String key, Object value) {
211 attributes.put(key, value);
212 }
213
214 public Enumeration<String> getAttributeNames() {
215 return new Hashtable<String, Object>(attributes).keys();
216 }
217
218 public HttpSession getSession() {
219 return ServletGraniteContext.this.getSession();
220 }
221
222 public HttpSession getSession(boolean create) {
223 return ServletGraniteContext.this.getSession(create);
224 }
225
226 public String getRequestedSessionId() {
227 return null;
228 }
229
230 public boolean isRequestedSessionIdFromCookie() {
231 return false;
232 }
233
234 public boolean isRequestedSessionIdFromURL() {
235 return false;
236 }
237
238 public boolean isRequestedSessionIdFromUrl() {
239 return false;
240 }
241
242 public boolean isRequestedSessionIdValid() {
243 return false;
244 }
245
246 public Principal getUserPrincipal() {
247 return null;
248 }
249
250 public boolean isUserInRole(String arg0) {
251 return false;
252 }
253
254 public void login(String arg0, String arg1) throws ServletException {
255 }
256
257 public void logout() throws ServletException {
258 }
259
260 public String getCharacterEncoding() {
261 return null;
262 }
263
264 public int getContentLength() {
265 return 0;
266 }
267
268 public String getContentType() {
269 return null;
270 }
271
272 public DispatcherType getDispatcherType() {
273 return null;
274 }
275
276 public ServletInputStream getInputStream() throws IOException {
277 return null;
278 }
279
280 public String getLocalAddr() {
281 return null;
282 }
283
284 public String getLocalName() {
285 return null;
286 }
287
288 public int getLocalPort() {
289 return 0;
290 }
291
292 public Locale getLocale() {
293 return null;
294 }
295
296 public Enumeration<Locale> getLocales() {
297 return null;
298 }
299
300 public String getParameter(String arg0) {
301 return null;
302 }
303
304 public Map<String, String[]> getParameterMap() {
305 return null;
306 }
307
308 public Enumeration<String> getParameterNames() {
309 return null;
310 }
311
312 public String[] getParameterValues(String arg0) {
313 return null;
314 }
315
316 public String getProtocol() {
317 return null;
318 }
319
320 public BufferedReader getReader() throws IOException {
321 return null;
322 }
323
324 public String getRealPath(String arg0) {
325 return null;
326 }
327
328 public String getRemoteAddr() {
329 return null;
330 }
331
332 public String getRemoteHost() {
333 return null;
334 }
335
336 public int getRemotePort() {
337 return 0;
338 }
339
340 public RequestDispatcher getRequestDispatcher(String arg0) {
341 return null;
342 }
343
344 public String getScheme() {
345 return null;
346 }
347
348 public String getServerName() {
349 return null;
350 }
351
352 public int getServerPort() {
353 return 0;
354 }
355
356 public AsyncContext getAsyncContext() {
357 return null;
358 }
359
360 public boolean isAsyncStarted() {
361 return false;
362 }
363
364 public boolean isAsyncSupported() {
365 return false;
366 }
367
368 public boolean isSecure() {
369 return false;
370 }
371
372 public void setCharacterEncoding(String arg0) throws UnsupportedEncodingException {
373 }
374
375 public AsyncContext startAsync() throws IllegalStateException {
376 return null;
377 }
378
379 public AsyncContext startAsync(ServletRequest request, ServletResponse response) throws IllegalStateException {
380 return null;
381 }
382
383 public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
384 return false;
385 }
386
387 public String getAuthType() {
388 return null;
389 }
390
391 public String getContextPath() {
392 return null;
393 }
394
395 public Cookie[] getCookies() {
396 return null;
397 }
398
399 public long getDateHeader(String name) {
400 return 0;
401 }
402
403 public String getHeader(String name) {
404 return null;
405 }
406
407 public Enumeration<String> getHeaderNames() {
408 return null;
409 }
410
411 public Enumeration<String> getHeaders(String name) {
412 return null;
413 }
414
415 public int getIntHeader(String name) {
416 return 0;
417 }
418
419 public String getMethod() {
420 return null;
421 }
422
423 public Part getPart(String name) throws IOException, ServletException {
424 return null;
425 }
426
427 public Collection<Part> getParts() throws IOException, ServletException {
428 return null;
429 }
430
431 public String getPathInfo() {
432 return null;
433 }
434
435 public String getPathTranslated() {
436 return null;
437 }
438
439 public String getQueryString() {
440 return null;
441 }
442
443 public String getRemoteUser() {
444 return null;
445 }
446
447 public String getRequestURI() {
448 return null;
449 }
450
451 public StringBuffer getRequestURL() {
452 return null;
453 }
454
455 public String getServletPath() {
456 return null;
457 }
458 }
459
460 private class BasicResponse implements HttpServletResponse {
461
462 public void flushBuffer() throws IOException {
463 }
464
465 public int getBufferSize() {
466 return 0;
467 }
468
469 public String getCharacterEncoding() {
470 return null;
471 }
472
473 public String getContentType() {
474 return null;
475 }
476
477 public Locale getLocale() {
478 return null;
479 }
480
481 public ServletOutputStream getOutputStream() throws IOException {
482 return null;
483 }
484
485 public PrintWriter getWriter() throws IOException {
486 return null;
487 }
488
489 public boolean isCommitted() {
490 return false;
491 }
492
493 public void reset() {
494 }
495
496 public void resetBuffer() {
497 }
498
499 public void setBufferSize(int size) {
500 }
501
502 public void setCharacterEncoding(String charset) {
503 }
504
505 public void setContentLength(int length) {
506 }
507
508 public void setContentType(String contentType) {
509 }
510
511 public void setLocale(Locale locale) {
512 }
513
514 public void addCookie(Cookie cookie) {
515 }
516
517 public void addDateHeader(String name, long value) {
518 }
519
520 public void addHeader(String name, String value) {
521 }
522
523 public void addIntHeader(String name, int value) {
524 }
525
526 public boolean containsHeader(String name) {
527 return false;
528 }
529
530 public String encodeRedirectURL(String url) {
531 return null;
532 }
533
534 public String encodeRedirectUrl(String url) {
535 return null;
536 }
537
538 public String encodeURL(String url) {
539 return null;
540 }
541
542 public String encodeUrl(String url) {
543 return null;
544 }
545
546 public String getHeader(String name) {
547 return null;
548 }
549
550 public Collection<String> getHeaderNames() {
551 return null;
552 }
553
554 public Collection<String> getHeaders(String name) {
555 return null;
556 }
557
558 public int getStatus() {
559 return 0;
560 }
561
562 public void sendError(int code) throws IOException {
563 }
564
565 public void sendError(int code, String msg) throws IOException {
566 }
567
568 public void sendRedirect(String url) throws IOException {
569 }
570
571 public void setDateHeader(String name, long value) {
572 }
573
574 public void setHeader(String name, String value) {
575 }
576
577 public void setIntHeader(String name, int value) {
578 }
579
580 public void setStatus(int code) {
581 }
582
583 public void setStatus(int code, String msg) {
584 }
585
586 }
587 }
588
589
590 abstract class BaseContextMap<T,U> extends AbstractMap<T,U> {
591
592 protected static final String KEY_STRING_ERROR = "Key should be a non null String: ";
593
594 @Override
595 public void clear() {
596 throw new UnsupportedOperationException();
597 }
598
599 @Override
600 public void putAll(Map<? extends T, ? extends U> t) {
601 throw new UnsupportedOperationException();
602 }
603
604 @Override
605 public U remove(Object key) {
606 throw new UnsupportedOperationException();
607 }
608
609 static class Entry<T,U> implements Map.Entry<T,U> {
610
611 private final T key;
612 private final U value;
613
614 Entry(T key, U value) {
615 this.key = key;
616 this.value = value;
617 }
618
619 public T getKey() {
620 return key;
621 }
622
623 public U getValue() {
624 return value;
625 }
626
627 public U setValue(U value) {
628 throw new UnsupportedOperationException();
629 }
630
631 @Override
632 public int hashCode() {
633 return ((key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode()));
634 }
635
636 @Override
637 public boolean equals(Object obj) {
638 if (obj == this)
639 return true;
640
641 if (obj == null || !(obj instanceof Map.Entry<?, ?>))
642 return false;
643
644 Map.Entry<?, ?> input = (Map.Entry<?, ?>)obj;
645 Object inputKey = input.getKey();
646 Object inputValue = input.getValue();
647
648 if (inputKey == key || (inputKey != null && inputKey.equals(key))) {
649 if (inputValue == value || (inputValue != null && inputValue.equals(value)))
650 return true;
651 }
652 return false;
653 }
654 }
655 }
656
657 class InitialisationMap extends BaseContextMap<String, String> {
658
659 private ServletContext servletContext = null;
660
661 InitialisationMap(ServletContext servletContext) {
662 if (servletContext == null)
663 throw new NullPointerException("servletContext is null");
664 this.servletContext = servletContext;
665 }
666
667 @Override
668 public String get(Object key) {
669 if (!(key instanceof String))
670 return null;
671 return servletContext.getInitParameter(key.toString());
672 }
673
674 @Override
675 public String put(String key, String value) {
676 throw new UnsupportedOperationException();
677 }
678
679 @Override
680 public Set<Map.Entry<String, String>> entrySet() {
681 Set<Map.Entry<String, String>> entries = new HashSet<Map.Entry<String, String>>();
682 for (Enumeration<?> e = servletContext.getInitParameterNames(); e.hasMoreElements();) {
683 String key = (String)e.nextElement();
684 entries.add(new Entry<String, String>(key, servletContext.getInitParameter(key)));
685 }
686 return entries;
687 }
688
689 @Override
690 public boolean equals(Object obj) {
691 if (obj == null || !(obj instanceof InitialisationMap))
692 return false;
693 return super.equals(obj);
694 }
695 }
696
697 class ApplicationMap extends BaseContextMap<String, Object> {
698
699 private ServletContext servletContext = null;
700
701 ApplicationMap(ServletContext servletContext) {
702 if (servletContext == null)
703 throw new NullPointerException("servletContext is null");
704 this.servletContext = servletContext;
705 }
706
707 @Override
708 public Object get(Object key) {
709 if (!(key instanceof String))
710 return null;
711 return servletContext.getAttribute(key.toString());
712 }
713
714 @Override
715 public Object put(String key, Object value) {
716 if (key == null)
717 throw new IllegalArgumentException(KEY_STRING_ERROR + key);
718 Object result = servletContext.getAttribute(key);
719 servletContext.setAttribute(key, value);
720 return (result);
721 }
722
723 @Override
724 public Object remove(Object key) {
725 if (!(key instanceof String))
726 return null;
727 Object result = servletContext.getAttribute(key.toString());
728 servletContext.removeAttribute(key.toString());
729 return result;
730 }
731
732 @Override
733 public Set<Map.Entry<String, Object>> entrySet() {
734 Set<Map.Entry<String, Object>> entries = new HashSet<Map.Entry<String, Object>>();
735 for (Enumeration<?> e = servletContext.getAttributeNames(); e.hasMoreElements();) {
736 String key = (String)e.nextElement();
737 entries.add(new Entry<String, Object>(key, servletContext.getAttribute(key)));
738 }
739 return entries;
740 }
741
742 @Override
743 public boolean equals(Object obj) {
744 if (obj == null || !(obj instanceof ApplicationMap))
745 return false;
746 return super.equals(obj);
747 }
748 }
749
750 class SessionMap extends BaseContextMap<String, Object> {
751
752 private HttpServletRequest request = null;
753 private HttpSession session = null;
754
755 SessionMap(HttpSession session) {
756 if (session == null)
757 throw new NullPointerException("session is null");
758 this.session = session;
759 }
760
761 SessionMap(HttpServletRequest request) {
762 if (request == null)
763 throw new NullPointerException("request is null");
764 this.request = request;
765 }
766
767 @Override
768 public Object get(Object key) {
769 if (!(key instanceof String))
770 return null;
771 Object value = getSession().getAttribute(key.toString());
772 if (value instanceof TransientReferenceHolder)
773 return ((TransientReferenceHolder)value).get();
774 return value;
775 }
776
777 @Override
778 public Object put(String key, Object value) {
779 if (key == null)
780 throw new IllegalArgumentException(KEY_STRING_ERROR + key);
781 HttpSession session = getSession();
782 Object result = session.getAttribute(key);
783 if (result instanceof TransientReferenceHolder)
784 result = ((TransientReferenceHolder)result).get();
785 if (value != null && value.getClass().isAnnotationPresent(TransientReference.class))
786 value = new TransientReferenceHolder(value);
787 session.setAttribute(key, value);
788 return result;
789 }
790
791 @Override
792 public Object remove(Object key) {
793 if (!(key instanceof String))
794 return null;
795 HttpSession session = getSession();
796 Object result = session.getAttribute(key.toString());
797 if (result instanceof TransientReferenceHolder)
798 result = ((TransientReferenceHolder)result).get();
799 session.removeAttribute(key.toString());
800 return result;
801 }
802
803 @Override
804 public Set<Map.Entry<String, Object>> entrySet() {
805 Set<Map.Entry<String, Object>> entries = new HashSet<Map.Entry<String, Object>>();
806 HttpSession session = getSession();
807 for (Enumeration<?> e = session.getAttributeNames(); e.hasMoreElements(); ) {
808 String key = (String)e.nextElement();
809 Object value = session.getAttribute(key);
810 if (value instanceof TransientReferenceHolder)
811 value = ((TransientReferenceHolder)value).get();
812 entries.add(new Entry<String, Object>(key, value));
813 }
814 return entries;
815 }
816
817 @Override
818 public boolean equals(Object obj) {
819 if (obj == null || !(obj instanceof SessionMap))
820 return false;
821 return super.equals(obj);
822 }
823
824 private HttpSession getSession() {
825 if (request != null)
826 return request.getSession(true);
827 return session;
828 }
829 }
830