| 1 16 17 package org.apache.catalina.cluster.session; 18 19 import java.beans.PropertyChangeSupport ; 20 import java.io.IOException ; 21 import java.io.NotSerializableException ; 22 import java.io.ObjectInputStream ; 23 import java.io.ObjectOutputStream ; 24 import java.io.Serializable ; 25 import java.lang.reflect.Method ; 26 import java.security.AccessController ; 27 import java.security.Principal ; 28 import java.security.PrivilegedAction ; 29 import java.util.ArrayList ; 30 import java.util.Enumeration ; 31 import java.util.HashMap ; 32 import java.util.Iterator ; 33 34 import javax.servlet.ServletContext ; 35 import javax.servlet.http.HttpSession ; 36 import javax.servlet.http.HttpSessionAttributeListener ; 37 import javax.servlet.http.HttpSessionBindingEvent ; 38 import javax.servlet.http.HttpSessionBindingListener ; 39 import javax.servlet.http.HttpSessionContext ; 40 import javax.servlet.http.HttpSessionEvent ; 41 import javax.servlet.http.HttpSessionListener ; 42 43 import org.apache.catalina.Context; 44 import org.apache.catalina.Manager; 45 import org.apache.catalina.Session; 46 import org.apache.catalina.SessionEvent; 47 import org.apache.catalina.SessionListener; 48 import org.apache.catalina.cluster.ClusterSession; 49 import org.apache.catalina.realm.GenericPrincipal; 50 import org.apache.catalina.util.Enumerator; 51 import org.apache.catalina.util.StringManager; 52 53 75 76 public class DeltaSession implements HttpSession , Session , Serializable , 77 ClusterSession { 78 79 public static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory 80 .getLog(DeltaManager.class); 81 82 85 protected static StringManager smp = StringManager 86 .getManager(Constants.Package); 87 88 90 96 public DeltaSession(Manager manager) { 97 98 super(); 99 this.manager = manager; 100 this.resetDeltaRequest(); 101 } 102 103 105 109 private static final String NOT_SERIALIZED = "___NOT_SERIALIZABLE_EXCEPTION___"; 110 111 114 private HashMap attributes = new HashMap (); 115 116 121 private transient String authType = null; 122 123 131 private transient Method containerEventMethod = null; 132 133 136 private static final Class containerEventTypes[] = { String .class, 137 Object .class }; 138 139 143 private long creationTime = 0L; 144 145 149 private transient int debug = 0; 150 151 156 private transient boolean expiring = false; 157 158 162 private transient DeltaSessionFacade facade = null; 163 164 167 private String id = null; 168 169 172 private static final String info = "DeltaSession/1.0"; 173 174 177 private long lastAccessedTime = creationTime; 178 179 182 private transient ArrayList listeners = new ArrayList (); 183 184 187 private transient Manager manager = null; 188 189 194 private int maxInactiveInterval = -1; 195 196 199 private boolean isNew = false; 200 201 204 private boolean isValid = false; 205 206 211 private transient HashMap notes = new HashMap (); 212 213 218 private transient Principal principal = null; 219 220 223 private static StringManager sm = StringManager 224 .getManager(Constants.Package); 225 226 229 private static HttpSessionContext sessionContext = null; 230 231 235 private transient PropertyChangeSupport support = new PropertyChangeSupport ( 236 this); 237 238 241 private long thisAccessedTime = creationTime; 242 243 249 private transient boolean isPrimarySession = true; 250 251 255 private transient DeltaRequest deltaRequest = null; 256 257 261 private transient long lastTimeReplicated = System.currentTimeMillis(); 262 263 266 protected transient int accessCount = 0; 267 268 270 274 public boolean isPrimarySession() { 275 return isPrimarySession; 276 } 277 278 284 public void setPrimarySession(boolean primarySession) { 285 this.isPrimarySession = primarySession; 286 } 287 288 292 public String getAuthType() { 293 294 return (this.authType); 295 296 } 297 298 305 public void setAuthType(String authType) { 306 307 String oldAuthType = this.authType; 308 this.authType = authType; 309 support.firePropertyChange("authType", oldAuthType, this.authType); 310 311 } 312 313 320 public void setCreationTime(long time) { 321 322 this.creationTime = time; 323 this.lastAccessedTime = time; 324 this.thisAccessedTime = time; 325 326 } 327 328 331 public String getId() { 332 333 return (this.id); 334 335 } 336 337 343 public void setId(String id) { 344 345 if ((this.id != null) && (manager != null)) 346 manager.remove(this); 347 348 this.id = id; 349 350 if (manager != null) 351 manager.add(this); 352 tellNew(); 353 if ( deltaRequest == null ) resetDeltaRequest(); 354 else deltaRequest.setSessionId(id); 355 } 356 357 361 public void tellNew() { 362 363 fireSessionEvent(Session.SESSION_CREATED_EVENT, null); 365 366 Context context = (Context ) manager.getContainer(); 368 if (context != null) { 370 Object listeners[] = context.getApplicationLifecycleListeners(); 371 if (listeners != null) { 372 HttpSessionEvent event = new HttpSessionEvent (getSession()); 373 for (int i = 0; i < listeners.length; i++) { 374 if (!(listeners[i] instanceof HttpSessionListener )) 375 continue; 376 HttpSessionListener listener = (HttpSessionListener ) listeners[i]; 377 try { 378 fireContainerEvent(context, "beforeSessionCreated", 379 listener); 380 listener.sessionCreated(event); 381 fireContainerEvent(context, "afterSessionCreated", 382 listener); 383 } catch (Throwable t) { 384 try { 385 fireContainerEvent(context, "afterSessionCreated", 386 listener); 387 } catch (Exception e) { 388 ; 389 } 390 log.error(sm.getString("standardSession.sessionEvent"), 392 t); 393 } 394 } 395 } 396 } 399 } 400 401 406 public String getInfo() { 407 408 return (info); 409 410 } 411 412 418 public long getLastAccessedTime() { 419 if (!isValid) { 420 throw new IllegalStateException (sm 421 .getString("standardSession.getLastAccessedTime")); 422 423 } 424 return (this.lastAccessedTime); 425 426 } 427 428 431 public Manager getManager() { 432 433 return (this.manager); 434 435 } 436 437 443 public void setManager(Manager manager) { 444 445 this.manager = manager; 446 447 } 448 449 454 public int getMaxInactiveInterval() { 455 456 return (this.maxInactiveInterval); 457 458 } 459 460 468 public void setMaxInactiveInterval(int interval) { 469 setMaxInactiveInterval(interval, true); 470 } 471 472 public void setMaxInactiveInterval(int interval, boolean addDeltaRequest) { 473 474 this.maxInactiveInterval = interval; 475 if (isValid && interval == 0) { 476 expire(); 477 } else { 478 if (addDeltaRequest && (deltaRequest != null)) 479 deltaRequest.setMaxInactiveInterval(interval); 480 } 481 482 } 483 484 490 public void setNew(boolean isNew) { 491 setNew(isNew, true); 492 } 493 494 public void setNew(boolean isNew, boolean addDeltaRequest) { 495 this.isNew = isNew; 496 if (addDeltaRequest && (deltaRequest != null)) 497 deltaRequest.setNew(isNew); 498 } 499 500 507 public Principal getPrincipal() { 508 509 return (this.principal); 510 511 } 512 513 522 public void setPrincipal(Principal principal) { 523 setPrincipal(principal, true); 524 } 525 526 public void setPrincipal(Principal principal, boolean addDeltaRequest) { 527 Principal oldPrincipal = this.principal; 528 this.principal = principal; 529 support.firePropertyChange("principal", oldPrincipal, this.principal); 530 if (addDeltaRequest && (deltaRequest != null)) 531 deltaRequest.setPrincipal(principal); 532 } 533 534 538 public HttpSession getSession() { 539 540 if (facade == null) { 541 if (System.getSecurityManager() != null) { 542 final DeltaSession fsession = this; 543 facade = (DeltaSessionFacade) AccessController 544 .doPrivileged(new PrivilegedAction () { 545 public Object run() { 546 return new DeltaSessionFacade(fsession); 547 } 548 }); 549 } else { 550 facade = new DeltaSessionFacade(this); 551 } 552 } 553 return (facade); 554 555 } 556 557 560 public boolean isValid() { 561 562 if (this.expiring) { 563 return true; 564 } 565 566 if (!this.isValid) { 567 return false; 568 } 569 570 if (accessCount > 0) { 571 return true; 572 } 573 574 if (maxInactiveInterval >= 0) { 575 long timeNow = System.currentTimeMillis(); 576 int timeIdle = (int) ((timeNow - lastAccessedTime) / 1000L); 577 if ((timeIdle >= maxInactiveInterval) && (isPrimarySession())) { 578 expire(true); 579 } else if (timeIdle >= (2 * maxInactiveInterval)) { 580 expire(true, false); 585 } 586 } 587 588 return (this.isValid); 589 } 590 591 597 public void setValid(boolean isValid) { 598 599 this.isValid = isValid; 600 } 601 602 604 609 public void access() { 610 611 this.lastAccessedTime = this.thisAccessedTime; 612 this.thisAccessedTime = System.currentTimeMillis(); 613 614 evaluateIfValid(); 615 616 accessCount++; 617 } 618 619 public void endAccess() { 620 isNew = false; 621 accessCount--; 622 } 623 624 627 public void addSessionListener(SessionListener listener) { 628 629 synchronized (listeners) { 630 listeners.add(listener); 631 } 632 633 } 634 635 639 public void expire() { 640 641 expire(true); 642 643 } 644 645 652 public void expire(boolean notify) { 653 expire(notify, true); 654 } 655 656 public void expire(boolean notify, boolean notifyCluster) { 657 658 if (expiring) 660 return; 661 String expiredId = getId(); 662 663 synchronized (this) { 664 665 if (manager == null) 666 return; 667 668 expiring = true; 669 670 Context context = (Context ) manager.getContainer(); 673 if (context != null) { 675 Object listeners[] = context.getApplicationLifecycleListeners(); 676 if (notify && (listeners != null)) { 677 HttpSessionEvent event = new HttpSessionEvent (getSession()); 678 for (int i = 0; i < listeners.length; i++) { 679 int j = (listeners.length - 1) - i; 680 if (!(listeners[j] instanceof HttpSessionListener )) 681 continue; 682 HttpSessionListener listener = (HttpSessionListener ) listeners[j]; 683 try { 684 fireContainerEvent(context, 685 "beforeSessionDestroyed", listener); 686 listener.sessionDestroyed(event); 687 fireContainerEvent(context, 688 "afterSessionDestroyed", listener); 689 } catch (Throwable t) { 690 try { 691 fireContainerEvent(context, 692 "afterSessionDestroyed", listener); 693 } catch (Exception e) { 694 ; 695 } 696 log.error(sm 698 .getString("standardSession.sessionEvent"), 699 t); 700 } 701 } 702 } 703 } accessCount = 0; 706 setValid(false); 707 708 if (manager != null) 710 manager.remove(this); 711 712 if (notify) { 714 fireSessionEvent(Session.SESSION_DESTROYED_EVENT, null); 715 } 716 717 expiring = false; 719 720 String keys[] = keys(); 722 for (int i = 0; i < keys.length; i++) 723 removeAttributeInternal(keys[i], notify, false); 724 725 if (notifyCluster) { 726 if (log.isDebugEnabled()) 727 log.debug(smp.getString("deltaSession.notifying", 728 ((DeltaManager) manager).getName(), new Boolean ( 729 isPrimarySession()), expiredId)); 730 ((DeltaManager) manager).sessionExpired(expiredId); 731 } 732 733 } 734 735 } 736 737 744 public Object getNote(String name) { 745 746 synchronized (notes) { 747 return (notes.get(name)); 748 } 749 750 } 751 752 756 public Iterator getNoteNames() { 757 758 synchronized (notes) { 759 return (notes.keySet().iterator()); 760 } 761 762 } 763 764 768 public void recycle() { 769 770 attributes.clear(); 772 setAuthType(null); 773 creationTime = 0L; 774 expiring = false; 775 id = null; 776 lastAccessedTime = 0L; 777 maxInactiveInterval = -1; 778 accessCount = 0; 779 notes.clear(); 780 setPrincipal(null); 781 isNew = false; 782 isValid = false; 783 manager = null; 784 deltaRequest.clear(); 785 786 } 787 788 795 public void removeNote(String name) { 796 797 synchronized (notes) { 798 notes.remove(name); 799 } 800 801 } 802 803 806 public void removeSessionListener(SessionListener listener) { 807 808 synchronized (listeners) { 809 listeners.remove(listener); 810 } 811 812 } 813 814 823 public void setNote(String name, Object value) { 824 825 synchronized (notes) { 826 notes.put(name, value); 827 } 828 829 } 830 831 834 public String toString() { 835 836 StringBuffer sb = new StringBuffer (); 837 sb.append("StandardSession["); 838 sb.append(id); 839 sb.append("]"); 840 return (sb.toString()); 841 842 } 843 844 846 859 public void readObjectData(ObjectInputStream stream) 860 throws ClassNotFoundException , IOException { 861 862 readObject(stream); 863 864 } 865 866 877 public void writeObjectData(ObjectOutputStream stream) throws IOException { 878 879 writeObject(stream); 880 881 } 882 883 public void resetDeltaRequest() { 884 if (deltaRequest == null) { 885 deltaRequest = new DeltaRequest(getId(), false); 886 } else { 887 deltaRequest.reset(); 888 deltaRequest.setSessionId(getId()); 889 } 890 } 891 892 public DeltaRequest getDeltaRequest() { 893 if (deltaRequest == null) 894 resetDeltaRequest(); 895 return deltaRequest; 896 } 897 898 900 |