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.util.Destroyable;
027import org.apache.shiro.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     * @since 1.3
050     */
051    private EventBus eventBus;
052
053    /**
054     * Default no-arg constructor that will automatically attempt to initialize a default cacheManager
055     */
056    public CachingSecurityManager() {
057        //use a default event bus:
058        setEventBus(new DefaultEventBus());
059    }
060
061    /**
062     * Returns the CacheManager used by this SecurityManager.
063     *
064     * @return the cacheManager used by this SecurityManager
065     */
066    public CacheManager getCacheManager() {
067        return cacheManager;
068    }
069
070    /**
071     * Sets the CacheManager used by this {@code SecurityManager} and potentially any of its
072     * children components.
073     * <p/>
074     * After the cacheManager attribute has been set, the template method
075     * {@link #afterCacheManagerSet afterCacheManagerSet()} is executed to allow subclasses to adjust when a
076     * cacheManager is available.
077     *
078     * @param cacheManager the CacheManager used by this {@code SecurityManager} and potentially any of its
079     *                     children components.
080     */
081    public void setCacheManager(CacheManager cacheManager) {
082        this.cacheManager = cacheManager;
083        afterCacheManagerSet();
084    }
085
086    /**
087     * Template callback to notify subclasses that a
088     * {@link org.apache.shiro.cache.CacheManager CacheManager} has been set and is available for use via the
089     * {@link #getCacheManager getCacheManager()} method.
090     */
091    protected void afterCacheManagerSet() {
092        applyEventBusToCacheManager();
093    }
094
095    /**
096     * Returns the {@code EventBus} used by this SecurityManager and potentially any of its children components.
097     *
098     * @return the {@code EventBus} used by this SecurityManager and potentially any of its children components.
099     * @since 1.3
100     */
101    public EventBus getEventBus() {
102        return eventBus;
103    }
104
105    /**
106     * Sets the EventBus used by this {@code SecurityManager} and potentially any of its
107     * children components.
108     * <p/>
109     * After the eventBus attribute has been set, the template method
110     * {@link #afterEventBusSet() afterEventBusSet()} is executed to allow subclasses to adjust when a
111     * eventBus is available.
112     *
113     * @param eventBus the EventBus used by this {@code SecurityManager} and potentially any of its
114     *                     children components.
115     * @since 1.3
116     */
117    public void setEventBus(EventBus eventBus) {
118        this.eventBus = eventBus;
119        afterEventBusSet();
120    }
121
122    /**
123     * @since 1.3
124     */
125    protected void applyEventBusToCacheManager() {
126        if (this.eventBus != null && this.cacheManager != null && this.cacheManager instanceof EventBusAware) {
127            ((EventBusAware)this.cacheManager).setEventBus(this.eventBus);
128        }
129    }
130
131    /**
132     * Template callback to notify subclasses that an {@link EventBus EventBus} has been set and is available for use
133     * via the {@link #getEventBus() getEventBus()} method.
134     *
135     * @since 1.3
136     */
137    protected void afterEventBusSet() {
138        applyEventBusToCacheManager();
139    }
140
141    /**
142     * Destroys the {@link #getCacheManager() cacheManager} via {@link LifecycleUtils#destroy LifecycleUtils.destroy}.
143     */
144    public void destroy() {
145        LifecycleUtils.destroy(getCacheManager());
146        this.cacheManager = null;
147        LifecycleUtils.destroy(getEventBus());
148        this.eventBus = new DefaultEventBus();
149    }
150
151}