1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 module hunt.shiro.session.mgt.DelegatingSession;
20 
21 import hunt.shiro.session.mgt.NativeSessionManager;
22 import hunt.shiro.session.mgt.SessionKey;
23 
24 import hunt.shiro.Exceptions;
25 import hunt.shiro.session.Session;
26 
27 import hunt.Exceptions;
28 import hunt.collection;
29 import hunt.logging.Logger;
30 import hunt.util.Common;
31 
32 /**
33  * A DelegatingSession is a client-tier representation of a server side
34  * {@link hunt.shiro.session.Session Session}.
35  * This implementation is basically a proxy to a server-side {@link NativeSessionManager NativeSessionManager},
36  * which will return the proper results for each method call.
37  * <p/>
38  * <p>A <tt>DelegatingSession</tt> will cache data when appropriate to avoid a remote method invocation,
39  * only communicating with the server when necessary.
40  * <p/>
41  * <p>Of course, if used in-process with a NativeSessionManager business POJO, as might be the case in a
42  * web-based application where the web classes and server-side business pojos exist in the same
43  * JVM, a remote method call will not be incurred.
44  *
45  */
46 class DelegatingSession : Session {
47 
48     //TODO - complete JavaDoc
49 
50     private SessionKey key;
51 
52     //cached fields to avoid a server-side method call if out-of-process:
53     private Date startTimestamp; // = null;
54     private string host = null;
55 
56     /**
57      * Handle to the target NativeSessionManager that will support the delegate calls.
58      */
59     private NativeSessionManager sessionManager;
60 
61 
62     this(NativeSessionManager sessionManager, SessionKey key) {
63         if (sessionManager  is null) {
64             throw new IllegalArgumentException("sessionManager argument cannot be null.");
65         }
66         if (key  is null) {
67             throw new IllegalArgumentException("sessionKey argument cannot be null.");
68         }
69         if (key.getSessionId()  is null) {
70             string msg = "The " ~ typeid(DelegatingSession).name ~ " implementation requires that the " ~
71                     "SessionKey argument returns a non-null sessionId to support the " ~
72                     "Session.getId() invocations.";
73             throw new IllegalArgumentException(msg);
74         }
75         this.sessionManager = sessionManager;
76         this.key = key;
77     }
78 
79     /**
80      * @see hunt.shiro.session.Session#getId()
81      */
82     string getId() {
83         return key.getSessionId();
84     }
85 
86     /**
87      * @see hunt.shiro.session.Session#getStartTimestamp()
88      */
89     Date getStartTimestamp() {
90         // if (startTimestamp  is null) {
91         //     startTimestamp = sessionManager.getStartTimestamp(key);
92         // }
93         // return startTimestamp;
94         return sessionManager.getStartTimestamp(key);
95     }
96 
97     /**
98      * @see hunt.shiro.session.Session#getLastAccessTime()
99      */
100     Date getLastAccessTime() {
101         //can't cache - only business pojo knows the accurate time:
102         return sessionManager.getLastAccessTime(key);
103     }
104 
105      long getTimeout(){
106         return sessionManager.getTimeout(key);
107     }
108 
109      void setTimeout(long maxIdleTimeInMillis){
110         sessionManager.setTimeout(key, maxIdleTimeInMillis);
111     }
112 
113     string getHost() {
114         if (host  is null) {
115             host = sessionManager.getHost(key);
116         }
117         return host;
118     }
119 
120     /**
121      * @see hunt.shiro.session.Session#touch()
122      */
123     void touch(){
124         sessionManager.touch(key);
125     }
126 
127     /**
128      * @see hunt.shiro.session.Session#stop()
129      */
130     void stop(){
131         sessionManager.stop(key);
132     }
133 
134     /**
135      * @see hunt.shiro.session.Session#getAttributeKeys
136      */
137     Object[] getAttributeKeys(){
138         return sessionManager.getAttributeKeys(key);
139     }
140 
141     /**
142      * @see hunt.shiro.session.Session#getAttribute(Object key)
143      */
144     Object getAttribute(Object attributeKey) {
145         return sessionManager.getAttribute(this.key, attributeKey);
146     }
147 
148     /**
149      * @see Session#setAttribute(Object key, Object value)
150      */
151     void setAttribute(Object attributeKey, Object value){
152         if (value is null) {
153             removeAttribute(attributeKey);
154         } else {
155             sessionManager.setAttribute(this.key, attributeKey, value);
156         }
157     }
158 
159     /**
160      * @see Session#removeAttribute(Object key)
161      */
162     Object removeAttribute(Object attributeKey){
163         return sessionManager.removeAttribute(this.key, attributeKey);
164     }
165 }