001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.shiro.session.mgt; 020 021import org.apache.shiro.session.InvalidSessionException; 022import org.apache.shiro.session.Session; 023 024import java.io.Serializable; 025import java.util.Collection; 026import java.util.Date; 027 028/** 029 * A DelegatingSession is a client-tier representation of a server side 030 * {@link org.apache.shiro.session.Session Session}. 031 * This implementation is basically a proxy to a server-side {@link NativeSessionManager NativeSessionManager}, 032 * which will return the proper results for each method call. 033 * <p/> 034 * <p>A <tt>DelegatingSession</tt> will cache data when appropriate to avoid a remote method invocation, 035 * only communicating with the server when necessary. 036 * <p/> 037 * <p>Of course, if used in-process with a NativeSessionManager business POJO, as might be the case in a 038 * web-based application where the web classes and server-side business pojos exist in the same 039 * JVM, a remote method call will not be incurred. 040 * 041 * @since 0.1 042 */ 043public class DelegatingSession implements Session, Serializable { 044 045 //TODO - complete JavaDoc 046 047 private final SessionKey key; 048 049 //cached fields to avoid a server-side method call if out-of-process: 050 private Date startTimestamp = null; 051 private String host = null; 052 053 /** 054 * Handle to the target NativeSessionManager that will support the delegate calls. 055 */ 056 private final transient NativeSessionManager sessionManager; 057 058 059 public DelegatingSession(NativeSessionManager sessionManager, SessionKey key) { 060 if (sessionManager == null) { 061 throw new IllegalArgumentException("sessionManager argument cannot be null."); 062 } 063 if (key == null) { 064 throw new IllegalArgumentException("sessionKey argument cannot be null."); 065 } 066 if (key.getSessionId() == null) { 067 String msg = "The " + DelegatingSession.class.getName() + " implementation requires that the " + 068 "SessionKey argument returns a non-null sessionId to support the " + 069 "Session.getId() invocations."; 070 throw new IllegalArgumentException(msg); 071 } 072 this.sessionManager = sessionManager; 073 this.key = key; 074 } 075 076 /** 077 * @see org.apache.shiro.session.Session#getId() 078 */ 079 public Serializable getId() { 080 return key.getSessionId(); 081 } 082 083 /** 084 * @see org.apache.shiro.session.Session#getStartTimestamp() 085 */ 086 public Date getStartTimestamp() { 087 if (startTimestamp == null) { 088 startTimestamp = sessionManager.getStartTimestamp(key); 089 } 090 return startTimestamp; 091 } 092 093 /** 094 * @see org.apache.shiro.session.Session#getLastAccessTime() 095 */ 096 public Date getLastAccessTime() { 097 //can't cache - only business pojo knows the accurate time: 098 return sessionManager.getLastAccessTime(key); 099 } 100 101 public long getTimeout() throws InvalidSessionException { 102 return sessionManager.getTimeout(key); 103 } 104 105 public void setTimeout(long maxIdleTimeInMillis) throws InvalidSessionException { 106 sessionManager.setTimeout(key, maxIdleTimeInMillis); 107 } 108 109 public String getHost() { 110 if (host == null) { 111 host = sessionManager.getHost(key); 112 } 113 return host; 114 } 115 116 /** 117 * @see org.apache.shiro.session.Session#touch() 118 */ 119 public void touch() throws InvalidSessionException { 120 sessionManager.touch(key); 121 } 122 123 /** 124 * @see org.apache.shiro.session.Session#stop() 125 */ 126 public void stop() throws InvalidSessionException { 127 sessionManager.stop(key); 128 } 129 130 /** 131 * @see org.apache.shiro.session.Session#getAttributeKeys 132 */ 133 public Collection<Object> getAttributeKeys() throws InvalidSessionException { 134 return sessionManager.getAttributeKeys(key); 135 } 136 137 /** 138 * @see org.apache.shiro.session.Session#getAttribute(Object key) 139 */ 140 public Object getAttribute(Object attributeKey) throws InvalidSessionException { 141 return sessionManager.getAttribute(this.key, attributeKey); 142 } 143 144 /** 145 * @see Session#setAttribute(Object key, Object value) 146 */ 147 public void setAttribute(Object attributeKey, Object value) throws InvalidSessionException { 148 if (value == null) { 149 removeAttribute(attributeKey); 150 } else { 151 sessionManager.setAttribute(this.key, attributeKey, value); 152 } 153 } 154 155 /** 156 * @see Session#removeAttribute(Object key) 157 */ 158 public Object removeAttribute(Object attributeKey) throws InvalidSessionException { 159 return sessionManager.removeAttribute(this.key, attributeKey); 160 } 161}