001    /*
002     * Copyright (c) 2002-2005 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://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, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.security.support;
017    
018    import java.util.HashMap;
019    import java.util.Iterator;
020    import java.util.Map;
021    
022    import org.springframework.beans.factory.NoSuchBeanDefinitionException;
023    import org.springframework.richclient.application.Application;
024    import org.springframework.richclient.security.SecurityController;
025    import org.springframework.richclient.security.SecurityControllerManager;
026    
027    /**
028     * Default implementation of the SecurityControllerManager. The controller map can be set
029     * during bean initialization. Also, if the map is not set, or does not contain an entry
030     * for a requested security controller Id, then an attempt to retrieve a bean instance
031     * with the given id will be made. Thus, no map entries are required for security
032     * controllers that are referenced by their application context bean id.
033     * <p>
034     * This implementation also provides for a <em>fallback</em> security controller. The
035     * fallback controller is registered with the
036     * {@link #setFallbackSecurityController(SecurityController)} method. Once registered, any
037     * call to {@link #getSecurityController(String)} that would have normally resulted in not
038     * finding a controller will instead return the fallback controller.
039     * <p>
040     * Here's an example configuration:
041     * 
042     * <pre>
043     *   &lt;bean id=&quot;securityControllerManager&quot; class=&quot;org.springframework.richclient.security.support.DefaultSecurityControllerManager&quot;&gt;
044     *       &lt;property name=&quot;fallbackSecurityController&quot; ref=&quot;writeController&quot; /&gt;
045     *       &lt;property name=&quot;securityControllerMap&quot;&gt;
046     *           &lt;map&gt;
047     *               &lt;entry key=&quot;contact.newContactCommand&quot; value-ref=&quot;adminController&quot;/&gt;
048     *               &lt;entry key=&quot;contact.deleteContactCommand&quot; value-ref=&quot;adminController&quot;/&gt;
049     *           &lt;/map&gt;
050     *       &lt;/property&gt;
051     *   &lt;/bean&gt;
052     * </pre>
053     * 
054     * @author Larry Streepy
055     * 
056     */
057    public class DefaultSecurityControllerManager implements SecurityControllerManager {
058    
059        private Map securityControllerMap = new HashMap();
060        private SecurityController fallbackController = null;
061    
062        /*
063         * (non-Javadoc)
064         * @see org.springframework.richclient.security.SecurityControllerManager#setSecurityControllerMap(java.util.Map)
065         */
066        public void setSecurityControllerMap(Map map) {
067            for( Iterator i = map.entrySet().iterator(); i.hasNext(); ) {
068                Map.Entry entry = (Map.Entry) i.next();
069                registerSecurityControllerAlias( (String) entry.getKey(), (SecurityController) entry.getValue() );
070            }
071        }
072    
073        /**
074         * Get the security controller for the given id. If the id is registered in our map,
075         * then return the registered controller. If not, then try to obtain a bean with the
076         * given id if it implements the SecurityController interface.
077         * @param id of controller to retrieve
078         * @return controller, null if not found
079         */
080        public SecurityController getSecurityController(String id) {
081            SecurityController sc = (SecurityController) securityControllerMap.get( id );
082            if( sc == null ) {
083                // Try for a named bean
084                try {
085                    sc = (SecurityController) Application.instance().getApplicationContext().getBean( id,
086                        SecurityController.class );
087                } catch( NoSuchBeanDefinitionException e ) {
088                    // Try for a fallback
089                    sc = getFallbackSecurityController();
090                }
091            }
092            return sc;
093        }
094    
095        /**
096         * Register an alias for a SecurityController.
097         * @param aliasId to register
098         * @param securityController to register under given alias Id
099         */
100        public void registerSecurityControllerAlias(String aliasId, SecurityController securityController) {
101            securityControllerMap.put( aliasId, securityController );
102        }
103    
104        /**
105         * Set the fallback security controller. This controller will be returned for any
106         * requested controller Id that is not found in the registry.
107         * @param fallbackController
108         */
109        public void setFallbackSecurityController(SecurityController fallbackController) {
110            this.fallbackController = fallbackController;
111        }
112    
113        /**
114         * Get the fallback security controller, if any.
115         * @return fallback security controller, null if not defined
116         */
117        public SecurityController getFallbackSecurityController() {
118            return fallbackController;
119        }
120    }