1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.onehippo.forge.hst.spring.support.session.servlet;
17
18 import java.io.Serializable;
19 import java.time.Duration;
20 import java.time.Instant;
21 import java.util.Collections;
22 import java.util.HashSet;
23 import java.util.Map;
24 import java.util.Set;
25 import java.util.concurrent.ConcurrentHashMap;
26
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.HttpSession;
29
30 import org.springframework.session.Session;
31
32
33
34
35 public class HttpSessionDelegatingSession implements Session, Serializable {
36
37 private static final long serialVersionUID = 1L;
38
39 static final String NAME = HttpSessionDelegatingSession.class.getName();
40
41 private static final String SESSION_ATTRS_MAP_KEY = HttpSessionDelegatingSession.class.getName() + ".sessionAttrsMap";
42
43 private transient HttpSession httpSession;
44 private Instant lastAccessedTime;
45
46 HttpSessionDelegatingSession(final HttpSession httpSession) {
47 this.httpSession = httpSession;
48 }
49
50 @Override
51 public String getId() {
52 return httpSession.getId();
53 }
54
55 @Override
56 public <T> T getAttribute(String attributeName) {
57 final Map<String, Object> sessionAttrs = (Map<String, Object>) httpSession.getAttribute(SESSION_ATTRS_MAP_KEY);
58 return (sessionAttrs != null) ? (T) sessionAttrs.get(attributeName) : null;
59 }
60
61 @Override
62 public Set<String> getAttributeNames() {
63 final Map<String, Object> sessionAttrs = (Map<String, Object>) httpSession.getAttribute(SESSION_ATTRS_MAP_KEY);
64
65 if (sessionAttrs == null) {
66 return Collections.emptySet();
67 }
68
69 Set<String> attrNames;
70
71 synchronized (sessionAttrs) {
72 attrNames = new HashSet<>(sessionAttrs.keySet());
73 }
74
75 return Collections.unmodifiableSet(attrNames);
76 }
77
78 @Override
79 public void setAttribute(String attributeName, Object attributeValue) {
80 Map<String, Object> sessionAttrs = (Map<String, Object>) httpSession.getAttribute(SESSION_ATTRS_MAP_KEY);
81
82 if (sessionAttrs == null) {
83 sessionAttrs = new ConcurrentHashMap<>();
84 httpSession.setAttribute(SESSION_ATTRS_MAP_KEY, sessionAttrs);
85 }
86
87 sessionAttrs.put(attributeName, attributeValue);
88 }
89
90 @Override
91 public void removeAttribute(String attributeName) {
92 final Map<String, Object> sessionAttrs = (Map<String, Object>) httpSession.getAttribute(SESSION_ATTRS_MAP_KEY);
93
94 if (sessionAttrs != null) {
95 sessionAttrs.remove(attributeName);
96 }
97 }
98
99 @Override
100 public Instant getCreationTime() {
101 return Instant.ofEpochMilli(httpSession.getCreationTime());
102 }
103
104 @Override
105 public void setLastAccessedTime(Instant lastAccessedTime) {
106 this.lastAccessedTime = lastAccessedTime;
107 }
108
109 @Override
110 public Instant getLastAccessedTime() {
111 if (lastAccessedTime != null) {
112 return lastAccessedTime;
113 }
114
115 return Instant.ofEpochMilli(httpSession.getLastAccessedTime());
116 }
117
118 @Override
119 public void setMaxInactiveInterval(Duration interval) {
120 httpSession.setMaxInactiveInterval((int) interval.getSeconds());
121 }
122
123 @Override
124 public Duration getMaxInactiveInterval() {
125 return Duration.ofSeconds(httpSession.getMaxInactiveInterval());
126 }
127
128 @Override
129 public boolean isExpired() {
130 final long lastAccessedTimeMillis = getLastAccessedTime().toEpochMilli();
131 final long maxInactiveIntervalSeconds = getMaxInactiveInterval().getSeconds();
132
133 if (System.currentTimeMillis() - lastAccessedTimeMillis > 1000L * maxInactiveIntervalSeconds) {
134 return true;
135 }
136
137 return false;
138 }
139
140 @Override
141 public String changeSessionId() {
142 final HttpServletRequest request = HttpSessionDelegatingContext.getCurrentServletRequest();
143 httpSession.invalidate();
144 httpSession = request.getSession(true);
145 return httpSession.getId();
146 }
147
148 }