1 14 package org.wings.session; 15 16 17 import java.beans.PropertyChangeListener ; 18 import java.io.Serializable ; 19 import java.util.Arrays ; 20 import java.util.Collections ; 21 import java.util.Enumeration ; 22 import java.util.EventListener ; 23 import java.util.HashMap ; 24 import java.util.HashSet ; 25 import java.util.Iterator ; 26 import java.util.Locale ; 27 import java.util.Map ; 28 import java.util.Set ; 29 30 import javax.servlet.ServletConfig ; 31 import javax.servlet.ServletContext ; 32 import javax.servlet.ServletException ; 33 import javax.servlet.http.HttpServletRequest ; 34 import javax.servlet.http.HttpServletResponse ; 35 import javax.swing.event.EventListenerList ; 36 37 import org.apache.commons.logging.Log; 38 import org.apache.commons.logging.LogFactory; 39 import org.wings.DefaultReloadManager; 40 import org.wings.ReloadManager; 41 import org.wings.SContainer; 42 import org.wings.SFrame; 43 import org.wings.SToolTipManager; 44 import org.wings.event.ExitVetoException; 45 import org.wings.event.SExitEvent; 46 import org.wings.event.SExitListener; 47 import org.wings.event.SRequestEvent; 48 import org.wings.event.SRequestListener; 49 import org.wings.externalizer.ExternalizeManager; 50 import org.wings.externalizer.ExternalizedResource; 51 import org.wings.plaf.CGManager; 52 import org.wings.plaf.LookAndFeel; 53 import org.wings.plaf.LookAndFeelFactory; 54 import org.wings.util.LocaleCharSet; 55 import org.wings.util.StringUtil; 56 import org.wings.util.WeakPropertyChangeSupport; 57 58 62 public class Session 63 implements PropertyService, Serializable { 64 65 private final transient static Log log = LogFactory.getLog(Session.class); 66 67 70 public final static String LOCALE_PROPERTY = "locale"; 71 72 75 public final static String LOOK_AND_FEEL_PROPERTY = "lookAndFeel"; 76 77 private final SessionStatistics statistics = new SessionStatistics(); 78 79 83 private CGManager CGManager = new CGManager(); 84 85 private SToolTipManager toolTipManager = new SToolTipManager(); 86 87 private ReloadManager reloadManager = null; 88 89 private ExternalizeManager externalizeManager = new ExternalizeManager(); 90 91 private LowLevelEventDispatcher dispatcher = new LowLevelEventDispatcher(); 92 93 private final HashMap props = new HashMap (); 94 95 private final HashSet frames = new HashSet (); 96 97 private long uniqueIdCounter = 1; 98 99 103 private int maxContentLength = 64; 104 105 private transient ServletContext servletContext; 106 107 private transient Browser userAgent; 108 109 protected transient HttpServletResponse servletResponse; 110 111 protected transient HttpServletRequest servletRequest; 112 113 private String redirectAddress; 114 115 private String exitAddress; 116 117 private Locale locale = Locale.getDefault(); 118 119 private boolean localeFromHeader = true; 120 121 126 private Locale [] supportedLocales = null; 127 128 133 private String characterEncoding = null; 134 135 136 139 protected final EventListenerList listenerList = new EventListenerList (); 140 141 public final SessionStatistics getStatistics() { 142 return statistics; 143 } 144 145 static boolean collectStatistics = true; 146 147 static final SRequestListener SESSION_STATISTIC_COLLECTOR = new SRequestListener() { 148 public void processRequest(SRequestEvent e) { 149 Session session = SessionManager.getSession(); 150 if (session == null) { 151 154 return; 155 } 156 switch (e.getType()) { 157 case SRequestEvent.DISPATCH_START: 158 session.getStatistics().startDispatching(); 159 break; 160 case SRequestEvent.DISPATCH_DONE: 161 session.getStatistics().endDispatching(); 162 break; 163 case SRequestEvent.DELIVER_START: 164 session.getStatistics().startDelivering(); 165 break; 166 case SRequestEvent.DELIVER_DONE: 167 session.getStatistics().endDelivering(); 168 break; 169 case SRequestEvent.REQUEST_START: 170 session.getStatistics().startRequest(); 171 break; 172 case SRequestEvent.REQUEST_END: 173 session.getStatistics().endRequest(); 174 break; 175 } 176 } 177 }; 178 179 180 public Session() { 181 if (collectStatistics) { 182 WingsStatistics.getStatistics().incrementSessionCount(); 183 WingsStatistics.getStatistics().incrementActiveSessionCount(); 184 WingsStatistics.getStatistics().incrementAllocatedSessionCount(); 185 186 addRequestListener(SESSION_STATISTIC_COLLECTOR); 187 } } 189 190 198 public void init(ServletConfig servletConfig, HttpServletRequest request) throws ServletException { 199 servletContext = request.getSession().getServletContext(); 200 setServletRequest(request); 201 setUserAgentFromRequest(request); 202 203 initProps(servletConfig); 204 initMaxContentLength(); 205 206 try { 207 LookAndFeel lookAndFeel = LookAndFeelFactory.getLookAndFeelFactory().create(); 208 CGManager.setLookAndFeel(lookAndFeel); 209 } catch (Exception ex) { 210 log.fatal("could not load look and feel: " + 211 servletContext.getInitParameter("wings.lookandfeel.factory"), ex); 212 throw new ServletException (ex); 213 } 214 215 } 216 217 protected void initMaxContentLength() { 218 String maxCL = servletContext.getInitParameter("content.maxlength"); 219 if (maxCL != null) { 220 try { 221 maxContentLength = Integer.parseInt(maxCL); 222 } catch (NumberFormatException e) { 223 log.warn("invalid content.maxlength: " + maxCL, e); 224 } 225 } 226 } 227 228 231 protected void initProps(ServletConfig servletConfig) { 232 Enumeration params = servletConfig.getInitParameterNames(); 233 while (params.hasMoreElements()) { 234 String name = (String ) params.nextElement(); 235 props.put(name, servletConfig.getInitParameter(name)); 236 } 237 } 238 239 void setServletRequest(HttpServletRequest servletRequest) { 240 this.servletRequest = servletRequest; 241 } 242 243 244 public HttpServletRequest getServletRequest() { 245 return servletRequest; 246 } 247 248 void setServletResponse(HttpServletResponse servletResponse) { 249 this.servletResponse = servletResponse; 250 } 251 252 public HttpServletResponse getServletResponse() { 253 return servletResponse; 254 } 255 256 public ServletContext getServletContext() { 257 return servletContext; 258 } 259 260 public void setReloadManager(ReloadManager reloadManager) { 261 this.reloadManager = reloadManager; 262 } 263 264 public ReloadManager getReloadManager() { 265 if (reloadManager == null) 266 reloadManager = new DefaultReloadManager(); 267 return reloadManager; 268 } 269 270 public ExternalizeManager getExternalizeManager() { 271 return externalizeManager; 272 } 273 274 public CGManager getCGManager() { 275 return CGManager; 276 } 277 278 public SToolTipManager getToolTipManager() { 279 return toolTipManager; 280 } 281 282 288 public Browser getUserAgent() { 289 return userAgent; 290 } 291 292 297 public void setUserAgentFromRequest(HttpServletRequest request) { 298 try { 299 userAgent = new Browser(request.getHeader("User-Agent")); 300 log.debug("User-Agent is " + userAgent); 301 } catch (Exception ex) { 302 log.warn("Cannot get User-Agent from request", ex); 303 } 304 } 305 306 307 public LowLevelEventDispatcher getDispatcher() { 308 return dispatcher; 309 } 310 311 316 public void addFrame(SFrame frame) { 317 frames.add(frame); 318 } 319 320 325 public void removeFrame(SFrame frame) { 326 frames.remove(frame); 327 } 328 329 334 public Set getFrames() { 335 return frames; 336 } 337 338 343 public SFrame getRootFrame() { 344 if (frames.size() == 0) 345 return null; 346 347 SFrame rootFrame = (SFrame) frames.iterator().next(); 348 while (rootFrame.getParent() != null) 349 rootFrame = (SFrame) rootFrame.getParent(); 350 351 return rootFrame; 352 } 353 354 359 public final Map getProperties() { 360 return Collections.unmodifiableMap(props); 361 } 362 363 370 public Object getProperty(String key) { 371 return props.get(key); 372 } 373 374 383 public Object getProperty(String key, Object def) { 384 if (!props.containsKey(key)) { 385 return def; 386 } else { 387 return props.get(key); 388 } 389 } 390 391 401 public Object setProperty(String key, Object value) { 402 Object old = props.put(key, value); 404 propertyChangeSupport.firePropertyChange(key, old, value); 405 return old; 406 } 407 408 public boolean containsProperty(String key) { 409 return props.containsKey(key); 410 } 411 412 public Object removeProperty(String key) { 413 Object old = props.remove(key); 415 propertyChangeSupport.firePropertyChange(key, old, null); 416 return old; 417 } 418 419 private final WeakPropertyChangeSupport propertyChangeSupport = 420 new WeakPropertyChangeSupport(this); 421 422 423 public void addPropertyChangeListener(PropertyChangeListener listener) { 424 propertyChangeSupport.addPropertyChangeListener(listener); 425 } 426 427 428 public void removePropertyChangeListener(PropertyChangeListener listener) { 429 propertyChangeSupport.removePropertyChangeListener(listener); 430 } 431 432 438 public void addPropertyChangeListener(String propertyName, 439 PropertyChangeListener listener) { 440 propertyChangeSupport.addPropertyChangeListener(propertyName, listener); 441 } 442 443 449 public void removePropertyChangeListener(String propertyName, 450 PropertyChangeListener listener) { 451 propertyChangeSupport.addPropertyChangeListener(propertyName, listener); 452 } 453 454 455 464 public void setLocale(Locale l) throws IllegalArgumentException { 465 if (l == null || locale.equals(l)) 466 return; 467 if (supportedLocales == null || 468 supportedLocales.length == 0 || 469 Arrays.asList(supportedLocales).contains(l)) { 470 locale = l; 471 propertyChangeSupport.firePropertyChange(LOCALE_PROPERTY, locale, l); 472 log.info("Set Locale " + l); 473 } else 474 throw new IllegalArgumentException ("Locale " + l + " not supported"); 475 } 476 477 482 public Locale getLocale() { 483 return locale; 484 } 485 486 492 public final void setLocaleFromHeader(boolean adoptLocale) { 493 localeFromHeader = adoptLocale; 494 } 495 496 500 public final boolean getLocaleFromHeader() { 501 return localeFromHeader; 502 } 503 504 505 508 public final void setSupportedLocales(Locale [] locales) { 509 supportedLocales = locales; 510 } 511 512 515 public final Locale [] getSupportedLocales() { 516 return supportedLocales; 517 } 518 519 520 528 public void setCharacterEncoding(String characterEncoding) { 529 this.characterEncoding = characterEncoding; 530 } 531 532 539 public String getCharacterEncoding() { 540 if (this.characterEncoding == null) { 541 return LocaleCharSet.getInstance().getCharSet(getLocale()); 542 } else { 543 return this.characterEncoding; 544 } 545 } 546 547 private final long getUniqueId() { 548 return uniqueIdCounter++; 549 } 550 551 557 public final String createUniqueId() { 558 return StringUtil.toIdentifierString(getUniqueId()); 559 } 560 561 568 public final int getMaxContentLength() { 569 return maxContentLength; 570 } 571 572 579 public final void setMaxContentLength(int l) { 580 maxContentLength = l; 581 } 582 583 586 protected void destroy() { 587 588 try { 589 firePrepareExit(true); 590 } catch (ExitVetoException ex) { 591 } 593 594 if (collectStatistics) { 595 WingsStatistics.getStatistics().decrementActiveSessionCount(); 596 } 598 599 Iterator it = frames.iterator(); 600 while (it.hasNext()) { 601 SContainer container = ((SFrame) it.next()).getContentPane(); 602 if (container != null) 603 container.removeAll(); 604 } 605 606 reloadManager.clear(); 607 reloadManager = null; 608 externalizeManager.clear(); 609 externalizeManager = null; 610 dispatcher.clear(); 611 dispatcher = null; 612 613 frames.clear(); 614 props.clear(); 615 616 617 Object [] listeners = listenerList.getListenerList(); 618 for (int i = listeners.length - 2; i >= 0; i -= 2) { 619 listenerList.remove((Class ) listeners[i], (EventListener ) listeners[i + 1]); 620 } 622 } 623 624 646 public void exit(String redirectAddress) { 647 this.exitAddress = redirectAddress; 648 } 649 650 666 public void exit() { 667 exit(""); 668 } 669 670 public String getExitAddress() { 671 return exitAddress; 672 } 673 674 public String getRedirectAddress() { 675 return redirectAddress; 676 } 677 678 683 public void setRedirectAddress(String redirectAddress) { 684 this.redirectAddress = redirectAddress; 685 } 686 687 688 public void addExitListener(SExitListener listener) { 689 listenerList.add(SExitListener.class, 690 listener); 691 } 692 693 694 public void removeExitListener(SExitListener listener) { 695 listenerList.remove(SExitListener.class, 696 listener); 697 } 698 699 704 public SExitListener[] getExitListeners() { 705 return (SExitListener[]) listenerList.getListeners(SExitListener.class); 706 } 707 708 709 712 final void firePrepareExit() throws ExitVetoException { 713 firePrepareExit(false); 714 } 715 716 final void firePrepareExit(boolean ignoreVeto) throws ExitVetoException { 717 SExitEvent event = null; 718 719 Object [] listeners = listenerList.getListenerList(); 720 for (int i = listeners.length - 2; i >= 0; i -= 2) { 721 if (listeners[i] == SExitListener.class) { 722 if (event == null) { 724 event = new SExitEvent(this); 725 } 726 try { 727 ((SExitListener) listeners[i + 1]).prepareExit(event); 728 } catch (ExitVetoException ex) { 729 if (!ignoreVeto) { 730 throw ex; 731 } 732 } 733 } 734 } 735 } 736 737 738 public void addRequestListener(SRequestListener listener) { 739 listenerList.add(SRequestListener.class, listener); 740 } 741 742 743 public void removeRequestListener(SRequestListener listener) { 744 listenerList.remove(SRequestListener.class, listener); 745 } 746 747 750 void fireRequestEvent(int type) { 751 fireRequestEvent(type, null); 752 } 753 754 757 void fireRequestEvent(int type, ExternalizedResource resource) { 758 SRequestEvent event = null; 759 760 Object [] listeners = listenerList.getListenerList(); 761 for (int i = listeners.length - 2; i >= 0; i -= 2) { 762 if (listeners[i] == SRequestListener.class) { 763 if (event == null) { 765 event = new SRequestEvent(this, type, resource); 766 } 767 ((SRequestListener) listeners[i + 1]).processRequest(event); 768 } 769 } 770 } 771 772 protected void finalize() { 773 log.info("gc session"); 774 if (collectStatistics) { 775 WingsStatistics.getStatistics().decrementAllocatedSessionCount(); 776 } } 778 } 779 780 781 | Popular Tags |