1 package nginx.unit; 2 3 import java.io.Serializable; 4 5 import javax.servlet.ServletContext; 6 import javax.servlet.http.HttpSession; 7 import javax.servlet.http.HttpSessionAttributeListener; 8 import javax.servlet.http.HttpSessionBindingEvent; 9 import javax.servlet.http.HttpSessionBindingListener; 10 11 import java.util.Collections; 12 import java.util.Date; 13 import java.util.Enumeration; 14 import java.util.HashMap; 15 import java.util.Map; 16 17 /** 18 * @author Andrey Kazankov 19 */ 20 public class Session implements HttpSession, Serializable 21 { 22 private final Map<String, Object> attributes = new HashMap<>(); 23 private final long creation_time = new Date().getTime(); 24 private long last_access_time = creation_time; 25 private long access_time = creation_time; 26 private int max_inactive_interval; 27 private String id; 28 private final Context context; 29 private boolean is_new = true; 30 private final HttpSessionAttributeListener attr_listener; 31 Session(Context context, String id, HttpSessionAttributeListener al, int max_inactive_interval)32 public Session(Context context, String id, 33 HttpSessionAttributeListener al, int max_inactive_interval) 34 { 35 this.id = id; 36 this.context = context; 37 attr_listener = al; 38 this.max_inactive_interval = max_inactive_interval; 39 } 40 setId(String id)41 public void setId(String id) 42 { 43 this.id = id; 44 } 45 46 @Override getCreationTime()47 public long getCreationTime() 48 { 49 return creation_time; 50 } 51 52 @Override getId()53 public String getId() 54 { 55 return id; 56 } 57 58 @Override getLastAccessedTime()59 public long getLastAccessedTime() 60 { 61 return last_access_time; 62 } 63 64 @Override getServletContext()65 public ServletContext getServletContext() 66 { 67 return context; 68 } 69 70 @Override setMaxInactiveInterval(int i)71 public void setMaxInactiveInterval(int i) 72 { 73 max_inactive_interval = i; 74 } 75 76 @Override getMaxInactiveInterval()77 public int getMaxInactiveInterval() 78 { 79 return max_inactive_interval; 80 } 81 82 @Deprecated 83 @Override getSessionContext()84 public javax.servlet.http.HttpSessionContext getSessionContext() 85 { 86 return null; 87 } 88 89 @Override getAttribute(String s)90 public Object getAttribute(String s) 91 { 92 synchronized (attributes) { 93 return attributes.get(s); 94 } 95 } 96 97 @Deprecated 98 @Override getValue(String s)99 public Object getValue(String s) 100 { 101 return getAttribute(s); 102 } 103 104 @Override getAttributeNames()105 public Enumeration<String> getAttributeNames() 106 { 107 synchronized (attributes) { 108 return Collections.enumeration(attributes.keySet()); 109 } 110 } 111 112 @Deprecated 113 @Override getValueNames()114 public String[] getValueNames() 115 { 116 synchronized (attributes) { 117 return attributes.keySet().toArray(new String[attributes.keySet().size()]); 118 } 119 } 120 121 @Override setAttribute(String s, Object o)122 public void setAttribute(String s, Object o) 123 { 124 Object old; 125 126 if (o != null && o instanceof HttpSessionBindingListener) { 127 HttpSessionBindingListener l = (HttpSessionBindingListener) o; 128 HttpSessionBindingEvent e = new HttpSessionBindingEvent(this, s); 129 130 l.valueBound(e); 131 } 132 133 synchronized (attributes) { 134 if (o != null) { 135 old = attributes.put(s, o); 136 } else { 137 old = attributes.remove(s); 138 } 139 } 140 141 if (old != null && old instanceof HttpSessionBindingListener) { 142 HttpSessionBindingListener l = (HttpSessionBindingListener) old; 143 HttpSessionBindingEvent e = new HttpSessionBindingEvent(this, s); 144 145 l.valueUnbound(e); 146 } 147 148 if (attr_listener == null) { 149 return; 150 } 151 152 if (o == null) { 153 if (old != null) { 154 HttpSessionBindingEvent e = new HttpSessionBindingEvent(this, s, old); 155 attr_listener.attributeRemoved(e); 156 } 157 158 return; 159 } 160 161 if (old != null) { 162 HttpSessionBindingEvent e = new HttpSessionBindingEvent(this, s, old); 163 attr_listener.attributeReplaced(e); 164 } else { 165 HttpSessionBindingEvent e = new HttpSessionBindingEvent(this, s, o); 166 attr_listener.attributeAdded(e); 167 } 168 } 169 170 @Deprecated 171 @Override putValue(String s, Object o)172 public void putValue(String s, Object o) 173 { 174 setAttribute(s,o); 175 } 176 177 @Override removeAttribute(String s)178 public void removeAttribute(String s) 179 { 180 Object o; 181 182 synchronized (attributes) { 183 o = attributes.remove(s); 184 } 185 186 if (o != null && o instanceof HttpSessionBindingListener) { 187 HttpSessionBindingListener l = (HttpSessionBindingListener) o; 188 HttpSessionBindingEvent e = new HttpSessionBindingEvent(this, s); 189 190 l.valueUnbound(e); 191 } 192 193 if (attr_listener == null || o == null) { 194 return; 195 } 196 197 HttpSessionBindingEvent e = new HttpSessionBindingEvent(this, s, o); 198 attr_listener.attributeRemoved(e); 199 } 200 201 @Deprecated 202 @Override removeValue(String s)203 public void removeValue(String s) 204 { 205 removeAttribute(s); 206 } 207 208 @Override invalidate()209 public void invalidate() 210 { 211 context.invalidateSession(this); 212 213 unboundAttributes(); 214 } 215 unboundAttributes()216 private void unboundAttributes() 217 { 218 for (Map.Entry<String, Object> a : attributes.entrySet()) { 219 Object o = a.getValue(); 220 if (o != null && o instanceof HttpSessionBindingListener) { 221 HttpSessionBindingListener l = (HttpSessionBindingListener) o; 222 HttpSessionBindingEvent e = new HttpSessionBindingEvent(this, a.getKey()); 223 224 l.valueUnbound(e); 225 } 226 } 227 228 attributes.clear(); 229 } 230 231 @Override isNew()232 public boolean isNew() 233 { 234 return is_new; 235 } 236 accessed()237 public void accessed() { 238 synchronized (this) { 239 is_new = false; 240 241 last_access_time = access_time; 242 access_time = new Date().getTime(); 243 } 244 } 245 checkTimeOut()246 public boolean checkTimeOut() 247 { 248 return (max_inactive_interval > 0) && 249 (access_time - last_access_time > max_inactive_interval * 1000); 250 } 251 }