001/*
002 * Copyright 2002-2018 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.lang.Nullable;
021import org.springframework.messaging.Message;
022
023/**
024 * Holder class to expose SiMP attributes associated with a session (e.g. WebSocket)
025 * in the form of a thread-bound {@link SimpAttributes} object.
026 *
027 * @author Rossen Stoyanchev
028 * @since 4.1
029 */
030public abstract class SimpAttributesContextHolder {
031
032        private static final ThreadLocal<SimpAttributes> attributesHolder =
033                        new NamedThreadLocal<>("SiMP session attributes");
034
035
036        /**
037         * Reset the SimpAttributes for the current thread.
038         */
039        public static void resetAttributes() {
040                attributesHolder.remove();
041        }
042
043        /**
044         * Bind the given SimpAttributes to the current thread.
045         * @param attributes the RequestAttributes to expose
046         */
047        public static void setAttributes(@Nullable SimpAttributes attributes) {
048                if (attributes != null) {
049                        attributesHolder.set(attributes);
050                }
051                else {
052                        resetAttributes();
053                }
054        }
055
056        /**
057         * Extract the SiMP session attributes from the given message, wrap them in
058         * a {@link SimpAttributes} instance and bind it to the current thread.
059         * @param message the message to extract session attributes from
060         */
061        public static void setAttributesFromMessage(Message<?> message) {
062                setAttributes(SimpAttributes.fromMessage(message));
063        }
064
065        /**
066         * Return the SimpAttributes currently bound to the thread.
067         * @return the attributes or {@code null} if not bound
068         */
069        @Nullable
070        public static SimpAttributes getAttributes() {
071                return attributesHolder.get();
072        }
073
074        /**
075         * Return the SimpAttributes currently bound to the thread or raise an
076         * {@link java.lang.IllegalStateException} if none are bound.
077         * @return the attributes, never {@code null}
078         * @throws java.lang.IllegalStateException if attributes are not bound
079         */
080        public static SimpAttributes currentAttributes() throws IllegalStateException {
081                SimpAttributes attributes = getAttributes();
082                if (attributes == null) {
083                        throw new IllegalStateException("No thread-bound SimpAttributes found. " +
084                                        "Your code is probably not processing a client message and executing in " +
085                                        "message-handling methods invoked by the SimpAnnotationMethodMessageHandler?");
086                }
087                return attributes;
088        }
089
090}