001/**
002 *   GRANITE DATA SERVICES
003 *   Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S.
004 *
005 *   This file is part of the Granite Data Services Platform.
006 *
007 *                               ***
008 *
009 *   Community License: GPL 3.0
010 *
011 *   This file is free software: you can redistribute it and/or modify
012 *   it under the terms of the GNU General Public License as published
013 *   by the Free Software Foundation, either version 3 of the License,
014 *   or (at your option) any later version.
015 *
016 *   This file is distributed in the hope that it will be useful, but
017 *   WITHOUT ANY WARRANTY; without even the implied warranty of
018 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
019 *   GNU General Public License for more details.
020 *
021 *   You should have received a copy of the GNU General Public License
022 *   along with this program. If not, see <http://www.gnu.org/licenses/>.
023 *
024 *                               ***
025 *
026 *   Available Commercial License: GraniteDS SLA 1.0
027 *
028 *   This is the appropriate option if you are creating proprietary
029 *   applications and you are not prepared to distribute and share the
030 *   source code of your application under the GPL v3 license.
031 *
032 *   Please visit http://www.granitedataservices.com/license for more
033 *   details.
034 */
035package org.granite.client.tide.security;
036
037import java.util.ArrayList;
038import java.util.HashMap;
039import java.util.List;
040import java.util.Map;
041import java.util.Map.Entry;
042
043import org.granite.client.tide.BaseIdentity;
044import org.granite.client.tide.server.TideFaultEvent;
045import org.granite.client.tide.server.TideResponder;
046import org.granite.client.tide.server.TideResultEvent;
047
048/**
049 * @author William DRAI
050 */
051public class TideRoleCache {
052        
053        private final BaseIdentity identity;
054        private final String type;
055        private final Map<String, Object> cache = new HashMap<String, Object>();
056        
057        public TideRoleCache(BaseIdentity identity, String type) {
058                this.identity = identity;
059                this.type = type;
060        }
061        
062        public boolean get(String roleName, TideResponder<Boolean> tideResponder) {
063        Object cached = cache.get(roleName);
064        if (cached == null) {
065            if (this.identity.isLoggedIn()) {
066                TideResponder<Boolean> responder = new TideRoleResponder(roleName, tideResponder);
067                identity.call(type, roleName, responder);
068                cache.put(roleName, responder);
069            }
070            return false;
071        }
072        if (cached instanceof TideResponder) {
073                ((TideRoleResponder)cached).addResponder(tideResponder);
074                return false;
075        }
076        if (tideResponder != null) {
077            TideResultEvent<Boolean> event = identity.newResultEvent((Boolean)cached);
078            tideResponder.result(event);
079        }
080        return (Boolean)cached;
081        }    
082        
083        public void clear() {
084                for (Entry<String, Object> me : cache.entrySet()) {
085                        if (me.getValue() == Boolean.TRUE)
086                                identity.firePropertyChange(type, true, false);
087                }
088                        
089            cache.clear();
090        }
091        
092        
093        private class TideRoleResponder implements TideResponder<Boolean> {
094                
095                private final String roleName;
096                private final List<TideResponder<Boolean>> responders = new ArrayList<TideResponder<Boolean>>();
097                
098                public TideRoleResponder(String roleName, TideResponder<Boolean> tideResponder) {
099                        this.roleName = roleName;
100                        if (tideResponder != null)
101                                responders.add(tideResponder);
102                }
103                
104                public void addResponder(TideResponder<Boolean> tideResponder) {
105                        responders.add(tideResponder);
106                }
107                
108            public void result(TideResultEvent<Boolean> event) {
109                for (TideResponder<Boolean> responder : responders)
110                        responder.result(event);
111                Object cached = cache.get(roleName);
112                boolean oldValue = cached instanceof Boolean ? (Boolean)cached : false;
113                cache.put(roleName, event.getResult());
114                boolean newValue = event.getResult() != null ? event.getResult() : false;
115                if (event.getResult() != oldValue)
116                        identity.firePropertyChange(type, oldValue, newValue);
117            }
118            
119            public void fault(TideFaultEvent event) {
120                cache.remove(roleName);
121                for (TideResponder<Boolean> responder : responders)
122                        responder.fault(event);
123            }
124        }
125}