/* * Copyright 2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ratpack.session; import io.netty.util.AsciiString; import ratpack.exec.Operation; import ratpack.exec.Promise; import ratpack.func.Action; import ratpack.http.Response; import java.io.Serializable; import java.util.Optional; import java.util.Set; /** * A mechanism for associating semi persistent data with an individual user/client. * <p> * This object can be accessed via the context registry. * Access to the actual session data is provided by {@link #getData()} method this object. * <p> * The persistence mechanism used is determined by the implementation of {@link SessionStore} available. * * @see SessionModule */ public interface Session { /** * The unique ID for this session. * <p> * Call this method will provision a new ID if necessary. * Provisioning and tracking of the ID is provided by the bound {@link SessionId} implementation. * * @return the ID for this session */ String getId(); /** * The session data. * <p> * The data is available via a promise to support backing {@link SessionStore} implementations that load the data asynchronously. * * @return the session data */ Promise<SessionData> getData(); /** * A convenience shorthand for {@link SessionData#getKeys()}. * * @return the keys of all objects currently in the session */ default Promise<Set<SessionKey<?>>> getKeys() { return getData().map(SessionData::getKeys); } /** * A convenience shorthand for {@link SessionData#get(SessionKey)}. * * @param key the key * @param <T> the type of object * @return the value for the given key * @see #require(SessionKey) */ default <T> Promise<Optional<T>> get(SessionKey<T> key) { return getData().map(d -> d.get(key)); } /** * A convenience shorthand for {@link SessionData#get(SessionKey, SessionSerializer)}. * * @param key the key * @param serializer the serializer * @param <T> the type of object * @return the value for the given key * @see #require(SessionKey, SessionSerializer) */ default <T> Promise<Optional<T>> get(SessionKey<T> key, SessionSerializer serializer) { return getData().map(d -> d.get(key, serializer)); } /** * A convenience shorthand for {@link SessionData#get(String)}. * * @param name the object name * @return the value for the given key * @see #require(String) */ default Promise<Optional<?>> get(String name) { return getData().map(d -> d.get(name)); } /** * A convenience shorthand for {@link SessionData#get(String, SessionSerializer)}. * * @param name the object name * @param serializer the serializer * @return the value for the given key * @see #require(String, SessionSerializer) */ default Promise<Optional<?>> get(String name, SessionSerializer serializer) { return getData().map(d -> d.get(name, serializer)); } /** * A convenience shorthand for {@link SessionData#get(Class)}. * * @param type the type * @param <T> the type * @return the value for the given key * @see #require(Class) */ default <T> Promise<Optional<T>> get(Class<T> type) { return getData().map(d -> d.get(type)); } /** * A convenience shorthand for {@link SessionData#get(Class, SessionSerializer)}. * * @param type the type * @param serializer the serializer * @param <T> the type * @return the value for the given key * @see #require(Class, SessionSerializer) */ default <T> Promise<Optional<T>> get(Class<T> type, SessionSerializer serializer) { return getData().map(d -> d.get(type, serializer)); } /** * A convenience shorthand for {@link SessionData#require(SessionKey)}. * * @param key the object key * @param <T> the type * @return the value for the given key */ default <T> Promise<T> require(SessionKey<T> key) { return getData().map(d -> d.require(key)); } /** * A convenience shorthand for {@link SessionData#require(SessionKey, SessionSerializer)}. * * @param key the object key * @param serializer the serializer * @param <T> the type * @return the value for the given key */ default <T> Promise<T> require(SessionKey<T> key, SessionSerializer serializer) { return getData().map(d -> d.require(key, serializer)); } /** * A convenience shorthand for {@link SessionData#require(Class)}. * * @param type the type * @param <T> the type * @return the value for the given key */ default <T> Promise<T> require(Class<T> type) { return getData().map(d -> d.require(type)); } /** * A convenience shorthand for {@link SessionData#require(Class, SessionSerializer)}. * * @param type the type * @param serializer the serializer * @param <T> the type * @return the value for the given key */ default <T> Promise<T> require(Class<T> type, SessionSerializer serializer) { return getData().map(d -> d.require(type, serializer)); } /** * A convenience shorthand for {@link SessionData#require(String)}. * * @param name the object name * @return the value for the given key */ default Promise<?> require(String name) { return getData().map(d -> d.require(name)); } /** * A convenience shorthand for {@link SessionData#require(String, SessionSerializer)}. * * @param name the object name * @param serializer the serializer * @return the value for the given key */ default Promise<?> require(String name, SessionSerializer serializer) { return getData().map(d -> d.require(name, serializer)); } /** * A convenience shorthand for {@link SessionData#set(SessionKey, Object)}. * * @param key the key * @param value the value * @param <T> the type * @return the operation for setting the value */ default <T> Operation set(SessionKey<T> key, T value) { return getData().operation(d -> d.set(key, value)); } /** * A convenience shorthand for {@link SessionData#set(SessionKey, Object, SessionSerializer)}. * * @param key the key * @param value the value * @param serializer the serializer * @param <T> the type * @return the operation for setting the value */ default <T> Operation set(SessionKey<T> key, T value, SessionSerializer serializer) { return getData().operation(d -> d.set(key, value, serializer)); } /** * A convenience shorthand for {@link SessionData#set(Class, Object)}. * * @param type the type * @param value the value * @param <T> the type * @return the operation for setting the value */ default <T> Operation set(Class<T> type, T value) { return getData().operation(d -> d.set(type, value)); } /** * A convenience shorthand for {@link SessionData#set(Class, Object, SessionSerializer)}. * * @param type the type * @param value the value * @param serializer the serializer * @param <T> the type * @return the operation for setting the value */ default <T> Operation set(Class<T> type, T value, SessionSerializer serializer) { return getData().operation(d -> d.set(type, value, serializer)); } /** * A convenience shorthand for {@link SessionData#set(String, Object)}. * * @param name the name * @param value the value * @param <T> the type * @return the operation for setting the value */ default <T> Operation set(String name, T value) { return getData().operation(d -> d.set(name, value)); } /** * A convenience shorthand for {@link SessionData#set(String, Object, SessionSerializer)}. * * @param name the name * @param value the value * @param serializer the serializer * @param <T> the type * @return the operation for setting the value */ default <T> Operation set(String name, T value, SessionSerializer serializer) { return getData().operation(d -> d.set(name, value, serializer)); } /** * A convenience shorthand for {@link SessionData#set(Object)}. * * @param value the value * @param <T> the type * @return the operation for setting the value */ default <T> Operation set(T value) { return getData().operation(d -> d.set(value)); } /** * A convenience shorthand for {@link SessionData#set(Object, SessionSerializer)}. * * @param value the value * @param serializer the serializer * @param <T> the type * @return the operation for setting the value */ default <T> Operation set(T value, SessionSerializer serializer) { return getData().operation(d -> d.set(value, serializer)); } /** * A convenience shorthand for {@link SessionData#remove(SessionKey)}. * * @param key the key * @return the operation for removing the value */ default Operation remove(SessionKey<?> key) { return getData().operation(d -> d.remove(key)); } /** * A convenience shorthand for {@link SessionData#remove(Class)}. * * @param type the type * @return the operation for removing the value */ default Operation remove(Class<?> type) { return getData().operation(d -> d.remove(type)); } /** * A convenience shorthand for {@link SessionData#remove(String)}. * * @param name the name * @return the operation for removing the value */ default Operation remove(String name) { return getData().operation(d -> d.remove(name)); } /** * A convenience shorthand for {@link SessionData#clear()}. * * @return the operation for clearing the session */ default Operation clear() { return getData().operation(SessionData::clear); } /** * Whether or not any changes have been made to the session data since it was accessed. * * @return whether or not any changes have been made to the session data since it was accessed */ boolean isDirty(); /** * Persists the session data. * <p> * It is generally not necessary to call this method explicitly. * The {@link SessionModule} installs a {@link Response#beforeSend(Action) response finalizer} that will * call this method if the session {@link #isDirty() is dirty}. * <p> * This method is effectively a noop if the session data has not yet been accessed. * <p> * If the session data has been accessed, calling this method will initiate a store of the data regardless of whether the data is dirty or not. * <p> * The {@link #isDirty()} will always return {@code true} after calling this method, until changes are made to the session data. * * @return the save operation */ Operation save(); /** * Terminates the session and session id. * <p> * Calling this method will immediately reset the state of the session data, and initiate a call to {@link SessionStore#remove(AsciiString)} on the underlying store. * This effectively resets the state of this object. * <p> * This method also invokes the {@link SessionId#terminate()} method, which prevents the same ID from being used subsequently. * * @return the terminate operation */ Operation terminate(); /** * The value serializer that is guaranteed to be able to serialize/deserialize any Java object that implements {@link java.io.Serializable}. * <p> * Ratpack extensions, libraries etc. should explicitly use this serializer (e.g. with {@link SessionData#set(SessionKey, Object, SessionSerializer)} * when reading and writing to the session as it is not guaranteed that the {@link #getDefaultSerializer() default serializer} relies on Java serialization. * * @return a serializer for {@link Serializable} objects */ JavaSessionSerializer getJavaSerializer(); /** * The serializer that is used when a serializer is not explicitly given. * <p> * The default configuration of {@link SessionModule} configures this serializer to be the same as the {@link #getJavaSerializer() Java serializer}. * However, if you'd prefer to use a different serialization strategy by default in your application you can override this binding. * * @return the serializer to use by default */ SessionSerializer getDefaultSerializer(); }