001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.shiro.mgt;
020
021import org.apache.shiro.cache.CacheManager;
022import org.apache.shiro.cache.CacheManagerAware;
023import org.apache.shiro.event.EventBus;
024import org.apache.shiro.event.EventBusAware;
025import org.apache.shiro.event.support.DefaultEventBus;
026import org.apache.shiro.lang.util.Destroyable;
027import org.apache.shiro.lang.util.LifecycleUtils;
028
029
030/**
031 * A very basic starting point for the SecurityManager interface that merely provides logging and caching
032 * support.  All actual {@code SecurityManager} method implementations are left to subclasses.
033 * <p/>
034 * <b>Change in 1.0</b> - a default {@code CacheManager} instance is <em>not</em> created by default during
035 * instantiation.  As caching strategies can vary greatly depending on an application's needs, a {@code CacheManager}
036 * instance must be explicitly configured if caching across the framework is to be enabled.
037 *
038 * @since 0.9
039 */
040public abstract class CachingSecurityManager implements SecurityManager, Destroyable, CacheManagerAware, EventBusAware {
041
042    /**
043     * The CacheManager to use to perform caching operations to enhance performance.  Can be null.
044     */
045    private CacheManager cacheManager;
046
047    /**
048     * The EventBus to use to use to publish and receive events of interest during Shiro's lifecycle.
049     *
050     * @since 1.3
051     */
052    private EventBus eventBus;
053
054    /**
055     * Default no-arg constructor that will automatically attempt to initialize a default cacheManager
056     */
057    public CachingSecurityManager() {
058        //use a default event bus:
059        setEventBus(new DefaultEventBus());
060    }
061
062    /**
063     * Returns the CacheManager used by this SecurityManager.
064     *
065     * @return the cacheManager used by this SecurityManager
066     */
067    public CacheManager getCacheManager() {
068        return cacheManager;
069    }
070
071    /**
072     * Sets the CacheManager used by this {@code SecurityManager} and potentially any of its
073     * children components.
074     * <p/>
075     * After the cacheManager attribute has been set, the template method
076     * {@link #afterCacheManagerSet afterCacheManagerSet()} is executed to allow subclasses to adjust when a
077     * cacheManager is available.
078     *
079     * @param cacheManager the CacheManager used by this {@code SecurityManager} and potentially any of its
080     *                     children components.
081     */
082    public void setCacheManager(CacheManager cacheManager) {
083        this.cacheManager = cacheManager;
084        afterCacheManagerSet();
085    }
086
087    /**
088     * Template callback to notify subclasses that a
089     * {@link org.apache.shiro.cache.CacheManager CacheManager} has been set and is available for use via the
090     * {@link #getCacheManager getCacheManager()} method.
091     */
092    protected void afterCacheManagerSet() {
093        applyEventBusToCacheManager();
094    }
095
096    /**
097     * Returns the {@code EventBus} used by this SecurityManager and potentially any of its children components.
098     *
099     * @return the {@code EventBus} used by this SecurityManager and potentially any of its children components.
100     * @since 1.3
101     */
102    public EventBus getEventBus() {
103        return eventBus;
104    }
105
106    /**
107     * Sets the EventBus used by this {@code SecurityManager} and potentially any of its
108     * children components.
109     * <p/>
110     * After the eventBus attribute has been set, the template method
111     * {@link #afterEventBusSet() afterEventBusSet()} is executed to allow subclasses to adjust when a
112     * eventBus is available.
113     *
114     * @param eventBus the EventBus used by this {@code SecurityManager} and potentially any of its
115     *                 children components.
116     * @since 1.3
117     */
118    public void setEventBus(EventBus eventBus) {
119        this.eventBus = eventBus;
120        afterEventBusSet();
121    }
122
123    /**
124     * @since 1.3
125     */
126    protected void applyEventBusToCacheManager() {
127        if (this.eventBus != null && this.cacheManager != null && this.cacheManager instanceof EventBusAware) {
128            ((EventBusAware) this.cacheManager).setEventBus(this.eventBus);
129        }
130    }
131
132    /**
133     * Template callback to notify subclasses that an {@link EventBus EventBus} has been set and is available for use
134     * via the {@link #getEventBus() getEventBus()} method.
135     *
136     * @since 1.3
137     */
138    protected void afterEventBusSet() {
139        applyEventBusToCacheManager();
140    }
141
142    /**
143     * Destroys the {@link #getCacheManager() cacheManager} via {@link LifecycleUtils#destroy LifecycleUtils.destroy}.
144     */
145    public void destroy() {
146        LifecycleUtils.destroy(getCacheManager());
147        this.cacheManager = null;
148        LifecycleUtils.destroy(getEventBus());
149        this.eventBus = new DefaultEventBus();
150    }
151
152}