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 */ 022package org.granite.messaging.webapp; 023 024import java.io.BufferedReader; 025import java.io.IOException; 026import java.io.PrintWriter; 027import java.io.UnsupportedEncodingException; 028import java.security.Principal; 029import java.util.AbstractMap; 030import java.util.Collection; 031import java.util.Enumeration; 032import java.util.HashMap; 033import java.util.HashSet; 034import java.util.Hashtable; 035import java.util.Locale; 036import java.util.Map; 037import java.util.Set; 038 039import javax.servlet.AsyncContext; 040import javax.servlet.DispatcherType; 041import javax.servlet.RequestDispatcher; 042import javax.servlet.ServletContext; 043import javax.servlet.ServletException; 044import javax.servlet.ServletInputStream; 045import javax.servlet.ServletOutputStream; 046import javax.servlet.ServletRequest; 047import javax.servlet.ServletResponse; 048import javax.servlet.http.Cookie; 049import javax.servlet.http.HttpServletRequest; 050import javax.servlet.http.HttpServletResponse; 051import javax.servlet.http.HttpSession; 052import javax.servlet.http.Part; 053 054import org.granite.clustering.TransientReference; 055import org.granite.clustering.TransientReferenceHolder; 056import org.granite.config.GraniteConfig; 057import org.granite.config.GraniteConfigListener; 058import org.granite.config.flex.ServicesConfig; 059import org.granite.context.GraniteContext; 060 061/** 062 * @author Franck WOLFF 063 */ 064public 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 590abstract 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 657class 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 697class 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 750class 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