| 1 17 18 19 package org.apache.catalina.session; 20 21 22 import java.beans.PropertyChangeSupport ; 23 import java.io.IOException ; 24 import java.io.NotSerializableException ; 25 import java.io.ObjectInputStream ; 26 import java.io.ObjectOutputStream ; 27 import java.io.Serializable ; 28 import java.lang.reflect.Method ; 29 import java.security.AccessController ; 30 import java.security.Principal ; 31 import java.security.PrivilegedAction ; 32 import java.util.ArrayList ; 33 import java.util.Enumeration ; 34 import java.util.HashMap ; 35 import java.util.Hashtable ; 36 import java.util.Iterator ; 37 import java.util.Map ; 38 import java.util.concurrent.ConcurrentHashMap ; 39 import java.util.concurrent.atomic.AtomicInteger ; 40 41 import javax.servlet.ServletContext ; 42 import javax.servlet.http.HttpSession ; 43 import javax.servlet.http.HttpSessionActivationListener ; 44 import javax.servlet.http.HttpSessionAttributeListener ; 45 import javax.servlet.http.HttpSessionBindingEvent ; 46 import javax.servlet.http.HttpSessionBindingListener ; 47 import javax.servlet.http.HttpSessionContext ; 48 import javax.servlet.http.HttpSessionEvent ; 49 import javax.servlet.http.HttpSessionListener ; 50 51 import org.apache.catalina.Context; 52 import org.apache.catalina.Globals; 53 import org.apache.catalina.Manager; 54 import org.apache.catalina.Session; 55 import org.apache.catalina.SessionEvent; 56 import org.apache.catalina.SessionListener; 57 import org.apache.catalina.util.Enumerator; 58 import org.apache.catalina.util.StringManager; 59 60 import org.apache.catalina.security.SecurityUtil; 61 62 82 83 public class StandardSession 84 implements HttpSession , Session , Serializable { 85 86 87 protected static final boolean ACTIVITY_CHECK = 88 Globals.STRICT_SERVLET_COMPLIANCE 89 || Boolean.valueOf(System.getProperty("org.apache.catalina.session.StandardSession.ACTIVITY_CHECK", "false")).booleanValue(); 90 91 92 94 95 100 public StandardSession(Manager manager) { 101 102 super(); 103 this.manager = manager; 104 105 if (ACTIVITY_CHECK) { 107 accessCount = new AtomicInteger (); 108 } 109 110 } 111 112 113 115 116 119 protected static final String EMPTY_ARRAY[] = new String [0]; 120 121 122 126 protected static final String NOT_SERIALIZED = 127 "___NOT_SERIALIZABLE_EXCEPTION___"; 128 129 130 133 protected Map attributes = new ConcurrentHashMap (); 134 135 136 141 protected transient String authType = null; 142 143 144 152 protected transient Method containerEventMethod = null; 153 154 155 158 protected static final Class containerEventTypes[] = 159 { String .class, Object .class }; 160 161 162 166 protected long creationTime = 0L; 167 168 169 172 protected static final String [] excludedAttributes = { 173 Globals.SUBJECT_ATTR 174 }; 175 176 177 182 protected transient boolean expiring = false; 183 184 185 189 protected transient StandardSessionFacade facade = null; 190 191 192 195 protected String id = null; 196 197 198 201 protected static final String info = "StandardSession/1.0"; 202 203 204 207 protected long lastAccessedTime = creationTime; 208 209 210 213 protected transient ArrayList listeners = new ArrayList (); 214 215 216 219 protected transient Manager manager = null; 220 221 222 227 protected int maxInactiveInterval = -1; 228 229 230 233 protected boolean isNew = false; 234 235 236 239 protected boolean isValid = false; 240 241 242 247 protected transient Map notes = new Hashtable (); 248 249 250 255 protected transient Principal principal = null; 256 257 258 261 protected static StringManager sm = 262 StringManager.getManager(Constants.Package); 263 264 265 268 protected static HttpSessionContext sessionContext = null; 269 270 271 275 protected transient PropertyChangeSupport support = 276 new PropertyChangeSupport (this); 277 278 279 282 protected long thisAccessedTime = creationTime; 283 284 285 288 protected transient AtomicInteger accessCount = null; 289 290 291 293 294 298 public String getAuthType() { 299 300 return (this.authType); 301 302 } 303 304 305 311 public void setAuthType(String authType) { 312 313 String oldAuthType = this.authType; 314 this.authType = authType; 315 support.firePropertyChange("authType", oldAuthType, this.authType); 316 317 } 318 319 320 326 public void setCreationTime(long time) { 327 328 this.creationTime = time; 329 this.lastAccessedTime = time; 330 this.thisAccessedTime = time; 331 332 } 333 334 335 338 public String getId() { 339 340 return (this.id); 341 342 } 343 344 345 348 public String getIdInternal() { 349 350 return (this.id); 351 352 } 353 354 355 360 public void setId(String id) { 361 362 if ((this.id != null) && (manager != null)) 363 manager.remove(this); 364 365 this.id = id; 366 367 if (manager != null) 368 manager.add(this); 369 tellNew(); 370 } 371 372 373 377 public void tellNew() { 378 379 fireSessionEvent(Session.SESSION_CREATED_EVENT, null); 381 382 Context context = (Context ) manager.getContainer(); 384 Object listeners[] = context.getApplicationLifecycleListeners(); 385 if (listeners != null) { 386 HttpSessionEvent event = 387 new HttpSessionEvent (getSession()); 388 for (int i = 0; i < listeners.length; i++) { 389 if (!(listeners[i] instanceof HttpSessionListener )) 390 continue; 391 HttpSessionListener listener = 392 (HttpSessionListener ) listeners[i]; 393 try { 394 fireContainerEvent(context, 395 "beforeSessionCreated", 396 listener); 397 listener.sessionCreated(event); 398 fireContainerEvent(context, 399 "afterSessionCreated", 400 listener); 401 } catch (Throwable t) { 402 try { 403 fireContainerEvent(context, 404 "afterSessionCreated", 405 listener); 406 } catch (Exception e) { 407 ; 408 } 409 manager.getContainer().getLogger().error 410 (sm.getString("standardSession.sessionEvent"), t); 411 } 412 } 413 } 414 415 } 416 417 418 423 public String getInfo() { 424 425 return (info); 426 427 } 428 429 430 436 public long getLastAccessedTime() { 437 438 if (!isValidInternal()) { 439 throw new IllegalStateException  440 (sm.getString("standardSession.getLastAccessedTime.ise")); 441 } 442 443 return (this.lastAccessedTime); 444 } 445 446 450 public long getLastAccessedTimeInternal() { 451 return (this.lastAccessedTime); 452 } 453 454 457 public Manager getManager() { 458 459 return (this.manager); 460 461 } 462 463 464 469 public void setManager(Manager manager) { 470 471 this.manager = manager; 472 473 } 474 475 476 481 public int getMaxInactiveInterval() { 482 483 return (this.maxInactiveInterval); 484 485 } 486 487 488 495 public void setMaxInactiveInterval(int interval) { 496 497 this.maxInactiveInterval = interval; 498 if (isValid && interval == 0) { 499 expire(); 500 } 501 502 } 503 504 505 510 public void setNew(boolean isNew) { 511 512 this.isNew = isNew; 513 514 } 515 516 517 524 public Principal getPrincipal() { 525 526 return (this.principal); 527 528 } 529 530 531 539 public void setPrincipal(Principal principal) { 540 541 Principal oldPrincipal = this.principal; 542 this.principal = principal; 543 support.firePropertyChange("principal", oldPrincipal, this.principal); 544 545 } 546 547 548 552 public HttpSession getSession() { 553 554 if (facade == null){ 555 if (SecurityUtil.isPackageProtectionEnabled()){ 556 final StandardSession fsession = this; 557 facade = (StandardSessionFacade)AccessController.doPrivileged(new PrivilegedAction (){ 558 public Object run(){ 559 return new StandardSessionFacade(fsession); 560 } 561 }); 562 } else { 563 facade = new StandardSessionFacade(this); 564 } 565 } 566 return (facade); 567 568 } 569 570 571 574 public boolean isValid() { 575 576 if (this.expiring) { 577 return true; 578 } 579 580 if (!this.isValid) { 581 return false; 582 } 583 584 if (ACTIVITY_CHECK && accessCount.get() > 0) { 585 return true; 586 } 587 588 if (maxInactiveInterval >= 0) { 589 long timeNow = System.currentTimeMillis(); 590 int timeIdle = (int) ((timeNow - thisAccessedTime) / 1000L); 591 if (timeIdle >= maxInactiveInterval) { 592 expire(true); 593 } 594 } 595 596 return (this.isValid); 597 } 598 599 600 605 public void setValid(boolean isValid) { 606 this.isValid = isValid; 607 } 608 609 610 612 613 618 public void access() { 619 620 this.lastAccessedTime = this.thisAccessedTime; 621 this.thisAccessedTime = System.currentTimeMillis(); 622 623 if (ACTIVITY_CHECK) { 624 accessCount.incrementAndGet(); 625 } 626 627 } 628 629 630 633 public void endAccess() { 634 635 isNew = false; 636 637 if (ACTIVITY_CHECK) { 638 accessCount.decrementAndGet(); 639 } 640 641 } 642 643 644 647 public void addSessionListener(SessionListener listener) { 648 649 listeners.add(listener); 650 651 } 652 653 654 658 public void expire() { 659 660 expire(true); 661 662 } 663 664 665 672 public void expire(boolean notify) { 673 674 if (expiring) 676 return; 677 678 synchronized (this) { 679 680 if (manager == null) 681 return; 682 683 expiring = true; 684 685 Context context = (Context ) manager.getContainer(); 688 Object listeners[] = context.getApplicationLifecycleListeners(); 689 if (notify && (listeners != null)) { 690 HttpSessionEvent event = 691 new HttpSessionEvent (getSession()); 692 for (int i = 0; i < listeners.length; i++) { 693 int j = (listeners.length - 1) - i; 694 if (!(listeners[j] instanceof HttpSessionListener )) 695 continue; 696 HttpSessionListener listener = 697 (HttpSessionListener ) listeners[j]; 698 try { 699 fireContainerEvent(context, 700 "beforeSessionDestroyed", 701 listener); 702 listener.sessionDestroyed(event); 703 fireContainerEvent(context, 704 "afterSessionDestroyed", 705 listener); 706 } catch (Throwable t) { 707 try { 708 fireContainerEvent(context, 709 "afterSessionDestroyed", 710 listener); 711 } catch (Exception e) { 712 ; 713 } 714 manager.getContainer().getLogger().error 715 (sm.getString("standardSession.sessionEvent"), t); 716 } 717 } 718 } 719 if (ACTIVITY_CHECK) { 720 accessCount.set(0); 721 } 722 setValid(false); 723 724 728 long timeNow = System.currentTimeMillis(); 729 int timeAlive = (int) ((timeNow - creationTime)/1000); 730 synchronized (manager) { 731 if (timeAlive > manager.getSessionMaxAliveTime()) { 732 manager.setSessionMaxAliveTime(timeAlive); 733 } 734 int numExpired = manager.getExpiredSessions(); 735 numExpired++; 736 manager.setExpiredSessions(numExpired); 737 int average = manager.getSessionAverageAliveTime(); 738 average = ((average * (numExpired-1)) + timeAlive)/numExpired; 739 manager.setSessionAverageAliveTime(average); 740 } 741 742 manager.remove(this); 744 745 if (notify) { 747 fireSessionEvent(Session.SESSION_DESTROYED_EVENT, null); 748 } 749 750 expiring = false; 752 753 String keys[] = keys(); 755 for (int i = 0; i < keys.length; i++) 756 removeAttributeInternal(keys[i], notify); 757 758 } 759 760 } 761 762 763 767 public void passivate() { 768 769 fireSessionEvent(Session.SESSION_PASSIVATED_EVENT, null); 771 772 HttpSessionEvent event = null; 774 String keys[] = keys(); 775 for (int i = 0; i < keys.length; i++) { 776 Object attribute = attributes.get(keys[i]); 777 if (attribute instanceof HttpSessionActivationListener ) { 778 if (event == null) 779 event = new HttpSessionEvent (getSession()); 780 try { 781 ((HttpSessionActivationListener )attribute) 782 .sessionWillPassivate(event); 783 } catch (Throwable t) { 784 manager.getContainer().getLogger().error 785 (sm.getString("standardSession.attributeEvent"), t); 786 } 787 } 788 } 789 790 } 791 792 793 797 public void activate() { 798 799 if (ACTIVITY_CHECK) { 801 accessCount = new AtomicInteger (); 802 } 803 804 fireSessionEvent(Session.SESSION_ACTIVATED_EVENT, null); 806 807 HttpSessionEvent event = null; 809 String keys[] = keys(); 810 for (int i = 0; i < keys.length; i++) { 811 Object attribute = attributes.get(keys[i]); 812 if (attribute instanceof HttpSessionActivationListener ) { 813 if (event == null) 814 event = new HttpSessionEvent (getSession()); 815 try { 816 ((HttpSessionActivationListener )attribute) 817 .sessionDidActivate(event); 818 } catch (Throwable t) { 819 manager.getContainer().getLogger().error 820 (sm.getString("standardSession.attributeEvent"), t); 821 } 822 } 823 } 824 825 } 826 827 828 834 public Object getNote(String name) { 835 836 return (notes.get(name)); 837 838 } 839 840 841 845 public Iterator getNoteNames() { 846 847 return (notes.keySet().iterator()); 848 849 } 850 851 852 856 public void recycle() { 857 858 attributes.clear(); 860 setAuthType(null); 861 creationTime = 0L; 862 expiring = false; 863 id = null; 864 lastAccessedTime = 0L; 865 maxInactiveInterval = -1; 866 accessCount = null; 867 notes.clear(); 868 setPrincipal(null); 869 isNew = false; 870 isValid = false; 871 manager = null; 872 873 } 874 875 876 882 public void removeNote(String name) { 883 884 notes.remove(name); 885 886 } 887 888 889 892 public void removeSessionListener(SessionListener listener) { 893 894 listeners.remove(listener); 895 896 } 897 898 899 906 public void setNote(String name, Object value) { 907 908 notes.put(name, value); 909 910 } 911 912 913 916 public String toString() { 917 918 StringBuffer sb = new StringBuffer |