001/*
002 * Copyright 2002-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.messaging.simp;
018
019import org.springframework.core.NamedThreadLocal;
020import org.springframework.messaging.Message;
021
022/**
023 * Holder class to expose SiMP attributes associated with a session (e.g. WebSocket)
024 * in the form of a thread-bound {@link SimpAttributes} object.
025 *
026 * @author Rossen Stoyanchev
027 * @since 4.1
028 */
029public abstract class SimpAttributesContextHolder {
030
031        private static final ThreadLocal<SimpAttributes> attributesHolder =
032                        new NamedThreadLocal<SimpAttributes>("SiMP session attributes");
033
034
035        /**
036         * Reset the SimpAttributes for the current thread.
037         */
038        public static void resetAttributes() {
039                attributesHolder.remove();
040        }
041
042        /**
043         * Bind the given SimpAttributes to the current thread,
044         * @param attributes the RequestAttributes to expose
045         */
046        public static void setAttributes(SimpAttributes attributes) {
047                if (attributes != null) {
048                        attributesHolder.set(attributes);
049                }
050                else {
051                        resetAttributes();
052                }
053        }
054
055        /**
056         * Extract the SiMP session attributes from the given message, wrap them in
057         * a {@link SimpAttributes} instance and bind it to the current thread,
058         * @param message the message to extract session attributes from
059         */
060        public static void setAttributesFromMessage(Message<?> message) {
061                setAttributes(SimpAttributes.fromMessage(message));
062        }
063
064        /**
065         * Return the SimpAttributes currently bound to the thread.
066         * @return the attributes or {@code null} if not bound
067         */
068        public static SimpAttributes getAttributes() {
069                return attributesHolder.get();
070        }
071
072        /**
073         * Return the SimpAttributes currently bound to the thread or raise an
074         * {@link java.lang.IllegalStateException} if none are bound..
075         * @return the attributes, never {@code null}
076         * @throws java.lang.IllegalStateException if attributes are not bound
077         */
078        public static SimpAttributes currentAttributes() throws IllegalStateException {
079                SimpAttributes attributes = getAttributes();
080                if (attributes == null) {
081                        throw new IllegalStateException("No thread-bound SimpAttributes found. " +
082                                        "Your code is probably not processing a client message and executing in " +
083                                        "message-handling methods invoked by the SimpAnnotationMethodMessageHandler?");
084                }
085                return attributes;
086        }
087
088}