| <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../../jacoco-resources/report.gif" type="image/gif"/><title>AbstractNativeSessionManager.java</title><link rel="stylesheet" href="../../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../../index.html" class="el_report">Apache Shiro :: Jar Bundle</a> > <a href="../index.html" class="el_bundle">shiro-core</a> > <a href="index.source.html" class="el_package">org.apache.shiro.session.mgt</a> > <span class="el_source">AbstractNativeSessionManager.java</span></div><h1>AbstractNativeSessionManager.java</h1><pre class="source lang-java linenums">/* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 org.apache.shiro.session.mgt; |
| |
| import org.apache.shiro.authz.AuthorizationException; |
| import org.apache.shiro.event.EventBus; |
| import org.apache.shiro.event.EventBusAware; |
| import org.apache.shiro.session.InvalidSessionException; |
| import org.apache.shiro.session.Session; |
| import org.apache.shiro.session.SessionException; |
| import org.apache.shiro.session.SessionListener; |
| import org.apache.shiro.session.UnknownSessionException; |
| import org.apache.shiro.util.CollectionUtils; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Date; |
| |
| /** |
| * Abstract implementation supporting the {@link NativeSessionManager NativeSessionManager} interface, supporting |
| * {@link SessionListener SessionListener}s and application of the |
| * {@link #getGlobalSessionTimeout() globalSessionTimeout}. |
| * |
| * @since 1.0 |
| */ |
| public abstract class AbstractNativeSessionManager extends AbstractSessionManager implements NativeSessionManager, EventBusAware { |
| |
| <span class="fc" id="L47"> private static final Logger log = LoggerFactory.getLogger(AbstractSessionManager.class);</span> |
| |
| private EventBus eventBus; |
| |
| private Collection<SessionListener> listeners; |
| |
| <span class="fc" id="L53"> public AbstractNativeSessionManager() {</span> |
| <span class="fc" id="L54"> this.listeners = new ArrayList<SessionListener>();</span> |
| <span class="fc" id="L55"> }</span> |
| |
| public void setSessionListeners(Collection<SessionListener> listeners) { |
| <span class="pc bpc" id="L58" title="1 of 2 branches missed."> this.listeners = listeners != null ? listeners : new ArrayList<SessionListener>();</span> |
| <span class="fc" id="L59"> }</span> |
| |
| @SuppressWarnings({"UnusedDeclaration"}) |
| public Collection<SessionListener> getSessionListeners() { |
| <span class="fc" id="L63"> return this.listeners;</span> |
| } |
| |
| /** |
| * Returns the EventBus used to publish SessionEvents. |
| * |
| * @return the EventBus used to publish SessionEvents. |
| * @since 1.3 |
| */ |
| protected EventBus getEventBus() { |
| <span class="nc" id="L73"> return eventBus;</span> |
| } |
| |
| /** |
| * Sets the EventBus to use to publish SessionEvents. |
| * |
| * @param eventBus the EventBus to use to publish SessionEvents. |
| * @since 1.3 |
| */ |
| public void setEventBus(EventBus eventBus) { |
| <span class="fc" id="L83"> this.eventBus = eventBus;</span> |
| <span class="fc" id="L84"> }</span> |
| |
| /** |
| * Publishes events on the event bus if the event bus is non-null, otherwise does nothing. |
| * |
| * @param event the event to publish on the event bus if the event bus exists. |
| * @since 1.3 |
| */ |
| protected void publishEvent(Object event) { |
| <span class="nc bnc" id="L93" title="All 2 branches missed."> if (this.eventBus != null) {</span> |
| <span class="nc" id="L94"> this.eventBus.publish(event);</span> |
| } |
| <span class="nc" id="L96"> }</span> |
| |
| public Session start(SessionContext context) { |
| <span class="fc" id="L99"> Session session = createSession(context);</span> |
| <span class="fc" id="L100"> applyGlobalSessionTimeout(session);</span> |
| <span class="fc" id="L101"> onStart(session, context);</span> |
| <span class="fc" id="L102"> notifyStart(session);</span> |
| //Don't expose the EIS-tier Session object to the client-tier: |
| <span class="fc" id="L104"> return createExposedSession(session, context);</span> |
| } |
| |
| /** |
| * Creates a new {@code Session Session} instance based on the specified (possibly {@code null}) |
| * initialization data. Implementing classes must manage the persistent state of the returned session such that it |
| * could later be acquired via the {@link #getSession(SessionKey)} method. |
| * |
| * @param context the initialization data that can be used by the implementation or underlying |
| * {@link SessionFactory} when instantiating the internal {@code Session} instance. |
| * @return the new {@code Session} instance. |
| * @throws org.apache.shiro.authz.HostUnauthorizedException |
| * if the system access control policy restricts access based |
| * on client location/IP and the specified hostAddress hasn't been enabled. |
| * @throws AuthorizationException if the system access control policy does not allow the currently executing |
| * caller to start sessions. |
| */ |
| protected abstract Session createSession(SessionContext context) throws AuthorizationException; |
| |
| protected void applyGlobalSessionTimeout(Session session) { |
| <span class="fc" id="L124"> session.setTimeout(getGlobalSessionTimeout());</span> |
| <span class="fc" id="L125"> onChange(session);</span> |
| <span class="fc" id="L126"> }</span> |
| |
| /** |
| * Template method that allows subclasses to react to a new session being created. |
| * <p/> |
| * This method is invoked <em>before</em> any session listeners are notified. |
| * |
| * @param session the session that was just {@link #createSession created}. |
| * @param context the {@link SessionContext SessionContext} that was used to start the session. |
| */ |
| protected void onStart(Session session, SessionContext context) { |
| <span class="fc" id="L137"> }</span> |
| |
| public Session getSession(SessionKey key) throws SessionException { |
| <span class="fc" id="L140"> Session session = lookupSession(key);</span> |
| <span class="fc bfc" id="L141" title="All 2 branches covered."> return session != null ? createExposedSession(session, key) : null;</span> |
| } |
| |
| private Session lookupSession(SessionKey key) throws SessionException { |
| <span class="pc bpc" id="L145" title="1 of 2 branches missed."> if (key == null) {</span> |
| <span class="nc" id="L146"> throw new NullPointerException("SessionKey argument cannot be null.");</span> |
| } |
| <span class="fc" id="L148"> return doGetSession(key);</span> |
| } |
| |
| private Session lookupRequiredSession(SessionKey key) throws SessionException { |
| <span class="fc" id="L152"> Session session = lookupSession(key);</span> |
| <span class="pc bpc" id="L153" title="1 of 2 branches missed."> if (session == null) {</span> |
| <span class="nc" id="L154"> String msg = "Unable to locate required Session instance based on SessionKey [" + key + "].";</span> |
| <span class="nc" id="L155"> throw new UnknownSessionException(msg);</span> |
| } |
| <span class="fc" id="L157"> return session;</span> |
| } |
| |
| protected abstract Session doGetSession(SessionKey key) throws InvalidSessionException; |
| |
| protected Session createExposedSession(Session session, SessionContext context) { |
| <span class="fc" id="L163"> return new DelegatingSession(this, new DefaultSessionKey(session.getId()));</span> |
| } |
| |
| protected Session createExposedSession(Session session, SessionKey key) { |
| <span class="nc" id="L167"> return new DelegatingSession(this, new DefaultSessionKey(session.getId()));</span> |
| } |
| |
| /** |
| * Returns the session instance to use to pass to registered {@code SessionListener}s for notification |
| * that the session has been invalidated (stopped or expired). |
| * <p/> |
| * The default implementation returns an {@link ImmutableProxiedSession ImmutableProxiedSession} instance to ensure |
| * that the specified {@code session} argument is not modified by any listeners. |
| * |
| * @param session the {@code Session} object being invalidated. |
| * @return the {@code Session} instance to use to pass to registered {@code SessionListener}s for notification. |
| */ |
| protected Session beforeInvalidNotification(Session session) { |
| <span class="fc" id="L181"> return new ImmutableProxiedSession(session);</span> |
| } |
| |
| /** |
| * Notifies any interested {@link SessionListener}s that a Session has started. This method is invoked |
| * <em>after</em> the {@link #onStart onStart} method is called. |
| * |
| * @param session the session that has just started that will be delivered to any |
| * {@link #setSessionListeners(java.util.Collection) registered} session listeners. |
| * @see SessionListener#onStart(org.apache.shiro.session.Session) |
| */ |
| protected void notifyStart(Session session) { |
| <span class="fc bfc" id="L193" title="All 2 branches covered."> for (SessionListener listener : this.listeners) {</span> |
| <span class="fc" id="L194"> listener.onStart(session);</span> |
| <span class="fc" id="L195"> }</span> |
| <span class="fc" id="L196"> }</span> |
| |
| protected void notifyStop(Session session) { |
| <span class="fc" id="L199"> Session forNotification = beforeInvalidNotification(session);</span> |
| <span class="fc bfc" id="L200" title="All 2 branches covered."> for (SessionListener listener : this.listeners) {</span> |
| <span class="fc" id="L201"> listener.onStop(forNotification);</span> |
| <span class="fc" id="L202"> }</span> |
| <span class="fc" id="L203"> }</span> |
| |
| protected void notifyExpiration(Session session) { |
| <span class="fc" id="L206"> Session forNotification = beforeInvalidNotification(session);</span> |
| <span class="fc bfc" id="L207" title="All 2 branches covered."> for (SessionListener listener : this.listeners) {</span> |
| <span class="fc" id="L208"> listener.onExpiration(forNotification);</span> |
| <span class="fc" id="L209"> }</span> |
| <span class="fc" id="L210"> }</span> |
| |
| public Date getStartTimestamp(SessionKey key) { |
| <span class="nc" id="L213"> return lookupRequiredSession(key).getStartTimestamp();</span> |
| } |
| |
| public Date getLastAccessTime(SessionKey key) { |
| <span class="nc" id="L217"> return lookupRequiredSession(key).getLastAccessTime();</span> |
| } |
| |
| public long getTimeout(SessionKey key) throws InvalidSessionException { |
| <span class="fc" id="L221"> return lookupRequiredSession(key).getTimeout();</span> |
| } |
| |
| public void setTimeout(SessionKey key, long maxIdleTimeInMillis) throws InvalidSessionException { |
| <span class="fc" id="L225"> Session s = lookupRequiredSession(key);</span> |
| <span class="fc" id="L226"> s.setTimeout(maxIdleTimeInMillis);</span> |
| <span class="fc" id="L227"> onChange(s);</span> |
| <span class="fc" id="L228"> }</span> |
| |
| public void touch(SessionKey key) throws InvalidSessionException { |
| <span class="fc" id="L231"> Session s = lookupRequiredSession(key);</span> |
| <span class="fc" id="L232"> s.touch();</span> |
| <span class="fc" id="L233"> onChange(s);</span> |
| <span class="fc" id="L234"> }</span> |
| |
| public String getHost(SessionKey key) { |
| <span class="fc" id="L237"> return lookupRequiredSession(key).getHost();</span> |
| } |
| |
| public Collection<Object> getAttributeKeys(SessionKey key) { |
| <span class="nc" id="L241"> Collection<Object> c = lookupRequiredSession(key).getAttributeKeys();</span> |
| <span class="nc bnc" id="L242" title="All 2 branches missed."> if (!CollectionUtils.isEmpty(c)) {</span> |
| <span class="nc" id="L243"> return Collections.unmodifiableCollection(c);</span> |
| } |
| <span class="nc" id="L245"> return Collections.emptySet();</span> |
| } |
| |
| public Object getAttribute(SessionKey sessionKey, Object attributeKey) throws InvalidSessionException { |
| <span class="fc" id="L249"> return lookupRequiredSession(sessionKey).getAttribute(attributeKey);</span> |
| } |
| |
| public void setAttribute(SessionKey sessionKey, Object attributeKey, Object value) throws InvalidSessionException { |
| <span class="pc bpc" id="L253" title="1 of 2 branches missed."> if (value == null) {</span> |
| <span class="nc" id="L254"> removeAttribute(sessionKey, attributeKey);</span> |
| } else { |
| <span class="fc" id="L256"> Session s = lookupRequiredSession(sessionKey);</span> |
| <span class="fc" id="L257"> s.setAttribute(attributeKey, value);</span> |
| <span class="fc" id="L258"> onChange(s);</span> |
| } |
| <span class="fc" id="L260"> }</span> |
| |
| public Object removeAttribute(SessionKey sessionKey, Object attributeKey) throws InvalidSessionException { |
| <span class="fc" id="L263"> Session s = lookupRequiredSession(sessionKey);</span> |
| <span class="fc" id="L264"> Object removed = s.removeAttribute(attributeKey);</span> |
| <span class="fc bfc" id="L265" title="All 2 branches covered."> if (removed != null) {</span> |
| <span class="fc" id="L266"> onChange(s);</span> |
| } |
| <span class="fc" id="L268"> return removed;</span> |
| } |
| |
| public boolean isValid(SessionKey key) { |
| try { |
| <span class="nc" id="L273"> checkValid(key);</span> |
| <span class="nc" id="L274"> return true;</span> |
| <span class="nc" id="L275"> } catch (InvalidSessionException e) {</span> |
| <span class="nc" id="L276"> return false;</span> |
| } |
| } |
| |
| public void stop(SessionKey key) throws InvalidSessionException { |
| <span class="fc" id="L281"> Session session = lookupRequiredSession(key);</span> |
| try { |
| <span class="pc bpc" id="L283" title="1 of 2 branches missed."> if (log.isDebugEnabled()) {</span> |
| <span class="fc" id="L284"> log.debug("Stopping session with id [" + session.getId() + "]");</span> |
| } |
| <span class="fc" id="L286"> session.stop();</span> |
| <span class="fc" id="L287"> onStop(session, key);</span> |
| <span class="fc" id="L288"> notifyStop(session);</span> |
| } finally { |
| <span class="pc" id="L290"> afterStopped(session);</span> |
| <span class="fc" id="L291"> }</span> |
| <span class="fc" id="L292"> }</span> |
| |
| protected void onStop(Session session, SessionKey key) { |
| <span class="fc" id="L295"> onStop(session);</span> |
| <span class="fc" id="L296"> }</span> |
| |
| protected void onStop(Session session) { |
| <span class="nc" id="L299"> onChange(session);</span> |
| <span class="nc" id="L300"> }</span> |
| |
| protected void afterStopped(Session session) { |
| <span class="nc" id="L303"> }</span> |
| |
| public void checkValid(SessionKey key) throws InvalidSessionException { |
| //just try to acquire it. If there is a problem, an exception will be thrown: |
| <span class="nc" id="L307"> lookupRequiredSession(key);</span> |
| <span class="nc" id="L308"> }</span> |
| |
| protected void onChange(Session s) { |
| <span class="fc" id="L311"> }</span> |
| } |
| </pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.7.7.201606060606</span></div></body></html> |