001/* 002 * JGrapes Event Driven Framework 003 * Copyright (C) 2017-2018 Michael N. Lipp 004 * 005 * This program is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU Affero General Public License as published by 007 * the Free Software Foundation; either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, but 011 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 012 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License 013 * for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License along 016 * with this program; if not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jgrapes.http; 020 021import java.io.Serializable; 022import java.time.Instant; 023import java.util.Map; 024import java.util.concurrent.ConcurrentHashMap; 025 026/** 027 * Implements the {@link Session} interface using a {@link ConcurrentHashMap}. 028 */ 029@SuppressWarnings("serial") 030public class InMemorySession 031 extends ConcurrentHashMap<Serializable, Serializable> 032 implements Session { 033 034 @SuppressWarnings("PMD.ShortVariable") 035 private final String id; 036 private final Instant createdAt; 037 private Instant lastUsedAt; 038 private final Map<Object, Object> transientData = new ConcurrentHashMap<>(); 039 private boolean beingDiscarded; 040 041 /** 042 * Create a new session. 043 */ 044 @SuppressWarnings("PMD.ShortVariable") 045 public InMemorySession(String id) { 046 this.id = id; 047 createdAt = Instant.now(); 048 lastUsedAt = createdAt; 049 } 050 051 /** 052 * Returns the session id. 053 * 054 * @return the id 055 */ 056 @SuppressWarnings("PMD.ShortMethodName") 057 public String id() { 058 return id; 059 } 060 061 /** 062 * Returns the creation time stamp. 063 * 064 * @return the creation time stamp 065 */ 066 public Instant createdAt() { 067 return createdAt; 068 } 069 070 /** 071 * Returns the last used (referenced in request) time stamp. 072 * 073 * @return the last used timestamp 074 */ 075 public Instant lastUsedAt() { 076 return lastUsedAt; 077 } 078 079 /** 080 * Updates the last used time stamp. 081 */ 082 public void updateLastUsedAt() { 083 this.lastUsedAt = Instant.now(); 084 } 085 086 /* 087 * (non-Javadoc) 088 * 089 * @see org.jgrapes.http.Session#transientData() 090 */ 091 @Override 092 public Map<Object, Object> transientData() { 093 return transientData; 094 } 095 096 /* 097 * (non-Javadoc) 098 * 099 * @see java.lang.Object#hashCode() 100 */ 101 @Override 102 public int hashCode() { 103 return id.hashCode(); 104 } 105 106 /** 107 * Marks the session as to be removed. 108 * 109 * @return false, if called before (session is already being discarded) 110 */ 111 public boolean setBeingDiscarded() { 112 boolean result = !beingDiscarded; 113 beingDiscarded = true; 114 return result; 115 } 116 117 /* 118 * (non-Javadoc) 119 * 120 * @see java.lang.Object#equals(java.lang.Object) 121 */ 122 @Override 123 public boolean equals(Object obj) { 124 if (obj == null) { 125 return false; 126 } 127 if (getClass() != obj.getClass()) { 128 return false; 129 } 130 @SuppressWarnings("PMD.LooseCoupling") 131 InMemorySession other = (InMemorySession) obj; 132 if (id == null) { 133 if (other.id != null) { 134 return false; 135 } 136 } else if (!id.equals(other.id)) { 137 return false; 138 } 139 return true; 140 } 141 142 /* 143 * (non-Javadoc) 144 * 145 * @see java.lang.Object#toString() 146 */ 147 @Override 148 public String toString() { 149 StringBuilder builder = new StringBuilder(50); 150 builder.append("InMemorySession ["); 151 if (id != null) { 152 builder.append("id=").append(id).append(", "); 153 } 154 if (createdAt != null) { 155 builder.append("createdAt=").append(createdAt).append(", "); 156 } 157 if (lastUsedAt != null) { 158 builder.append("lastUsedAt=").append(lastUsedAt); 159 } 160 builder.append(']'); 161 return builder.toString(); 162 } 163 164}