| /* |
| * 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.subject; |
| |
| import org.apache.shiro.util.CollectionUtils; |
| |
| import java.util.*; |
| |
| /** |
| * Default implementation of the {@link PrincipalMap} interface. |
| * |
| * *EXPERIMENTAL for Shiro 1.2 - DO NOT USE YET* |
| * |
| * @author Les Hazlewood |
| * @since 1.2 |
| */ |
| public class SimplePrincipalMap implements PrincipalMap { |
| |
| //Key: realm name, Value: map of principals specific to that realm |
| // internal map - key: principal name, value: principal |
| private Map<String, Map<String, Object>> realmPrincipals; |
| |
| //maintains the principals from all realms plus any that are modified via the Map modification methods |
| //this ensures a fast lookup of any named principal instead of needing to iterate over |
| //the realmPrincipals for each lookup. |
| private Map<String, Object> combinedPrincipals; |
| |
| public SimplePrincipalMap() { |
| this(null); |
| } |
| |
| public SimplePrincipalMap(Map<String, Map<String, Object>> backingMap) { |
| if (!CollectionUtils.isEmpty(backingMap)) { |
| this.realmPrincipals = backingMap; |
| for (Map<String, Object> principals : this.realmPrincipals.values()) { |
| if (!CollectionUtils.isEmpty(principals) ) { |
| ensureCombinedPrincipals().putAll(principals); |
| } |
| } |
| } |
| } |
| |
| public int size() { |
| return CollectionUtils.size(this.combinedPrincipals); |
| } |
| |
| protected Map<String, Object> ensureCombinedPrincipals() { |
| if (this.combinedPrincipals == null) { |
| this.combinedPrincipals = new HashMap<String, Object>(); |
| } |
| return this.combinedPrincipals; |
| } |
| |
| public boolean containsKey(Object o) { |
| return this.combinedPrincipals != null && this.combinedPrincipals.containsKey(o); |
| } |
| |
| public boolean containsValue(Object o) { |
| return this.combinedPrincipals != null && this.combinedPrincipals.containsKey(o); |
| } |
| |
| public Object get(Object o) { |
| return this.combinedPrincipals != null && this.combinedPrincipals.containsKey(o); |
| } |
| |
| public Object put(String s, Object o) { |
| return ensureCombinedPrincipals().put(s, o); |
| } |
| |
| public Object remove(Object o) { |
| return this.combinedPrincipals != null ? this.combinedPrincipals.remove(o) : null; |
| } |
| |
| public void putAll(Map<? extends String, ?> map) { |
| if (!CollectionUtils.isEmpty(map)) { |
| ensureCombinedPrincipals().putAll(map); |
| } |
| } |
| |
| public Set<String> keySet() { |
| return CollectionUtils.isEmpty(this.combinedPrincipals) ? |
| Collections.<String>emptySet() : |
| Collections.unmodifiableSet(this.combinedPrincipals.keySet()); |
| } |
| |
| public Collection<Object> values() { |
| return CollectionUtils.isEmpty(this.combinedPrincipals) ? |
| Collections.emptySet() : |
| Collections.unmodifiableCollection(this.combinedPrincipals.values()); |
| } |
| |
| public Set<Entry<String, Object>> entrySet() { |
| return CollectionUtils.isEmpty(this.combinedPrincipals) ? |
| Collections.<Entry<String,Object>>emptySet() : |
| Collections.unmodifiableSet(this.combinedPrincipals.entrySet()); |
| } |
| |
| public void clear() { |
| this.realmPrincipals = null; |
| this.combinedPrincipals = null; |
| } |
| |
| public Object getPrimaryPrincipal() { |
| //heuristic - just use the first one we come across: |
| return !CollectionUtils.isEmpty(this.combinedPrincipals) ? |
| this.combinedPrincipals.values().iterator().next() : |
| null; |
| } |
| |
| public <T> T oneByType(Class<T> type) { |
| if (CollectionUtils.isEmpty(this.combinedPrincipals)) { |
| return null; |
| } |
| for( Object value : this.combinedPrincipals.values()) { |
| if (type.isInstance(value) ) { |
| return type.cast(value); |
| } |
| } |
| return null; |
| } |
| |
| public <T> Collection<T> byType(Class<T> type) { |
| if (CollectionUtils.isEmpty(this.combinedPrincipals)) { |
| return Collections.emptySet(); |
| } |
| Collection<T> instances = null; |
| for( Object value : this.combinedPrincipals.values()) { |
| if (type.isInstance(value) ) { |
| if (instances == null) { |
| instances = new ArrayList<T>(); |
| } |
| instances.add(type.cast(value)); |
| } |
| } |
| return instances != null ? instances : Collections.<T>emptyList(); |
| } |
| |
| public List asList() { |
| if (CollectionUtils.isEmpty(this.combinedPrincipals)) { |
| return Collections.emptyList(); |
| } |
| List<Object> list = new ArrayList<Object>(this.combinedPrincipals.size()); |
| list.addAll(this.combinedPrincipals.values()); |
| return list; |
| } |
| |
| public Set asSet() { |
| if (CollectionUtils.isEmpty(this.combinedPrincipals)) { |
| return Collections.emptySet(); |
| } |
| Set<Object> set = new HashSet<Object>(this.combinedPrincipals.size()); |
| set.addAll(this.combinedPrincipals.values()); |
| return set; |
| } |
| |
| public Collection fromRealm(String realmName) { |
| if (CollectionUtils.isEmpty(this.realmPrincipals)) { |
| return Collections.emptySet(); |
| } |
| Map<String,Object> principals = this.realmPrincipals.get(realmName); |
| if (CollectionUtils.isEmpty(principals)) { |
| return Collections.emptySet(); |
| } |
| return Collections.unmodifiableCollection(principals.values()); |
| } |
| |
| public Set<String> getRealmNames() { |
| if (CollectionUtils.isEmpty(this.realmPrincipals)) { |
| return Collections.emptySet(); |
| } |
| return Collections.unmodifiableSet(this.realmPrincipals.keySet()); |
| } |
| |
| public boolean isEmpty() { |
| return CollectionUtils.isEmpty(this.combinedPrincipals); |
| } |
| |
| public Iterator iterator() { |
| return asList().iterator(); |
| } |
| |
| public Map<String, Object> getRealmPrincipals(String name) { |
| if (this.realmPrincipals == null) { |
| return null; |
| } |
| Map<String,Object> principals = this.realmPrincipals.get(name); |
| if (principals == null) { |
| return null; |
| } |
| return Collections.unmodifiableMap(principals); |
| } |
| |
| public Map<String,Object> setRealmPrincipals(String realmName, Map<String, Object> principals) { |
| if (realmName == null) { |
| throw new NullPointerException("realmName argument cannot be null."); |
| } |
| if (this.realmPrincipals == null) { |
| if (!CollectionUtils.isEmpty(principals)) { |
| this.realmPrincipals = new HashMap<String,Map<String,Object>>(); |
| return this.realmPrincipals.put(realmName, new HashMap<String,Object>(principals)); |
| } else { |
| return null; |
| } |
| } else { |
| Map<String,Object> existingPrincipals = this.realmPrincipals.remove(realmName); |
| if (!CollectionUtils.isEmpty(principals)) { |
| this.realmPrincipals.put(realmName, new HashMap<String,Object>(principals)); |
| } |
| return existingPrincipals; |
| } |
| } |
| |
| public Object setRealmPrincipal(String realmName, String principalName, Object principal) { |
| if (realmName == null) { |
| throw new NullPointerException("realmName argument cannot be null."); |
| } |
| if (principalName == null) { |
| throw new NullPointerException(("principalName argument cannot be null.")); |
| } |
| if (principal == null) { |
| return removeRealmPrincipal(realmName, principalName); |
| } |
| if (this.realmPrincipals == null) { |
| this.realmPrincipals = new HashMap<String,Map<String,Object>>(); |
| } |
| Map<String,Object> principals = this.realmPrincipals.get(realmName); |
| if (principals == null) { |
| principals = new HashMap<String,Object>(); |
| this.realmPrincipals.put(realmName, principals); |
| } |
| return principals.put(principalName, principal); |
| } |
| |
| public Object getRealmPrincipal(String realmName, String principalName) { |
| if (realmName == null) { |
| throw new NullPointerException("realmName argument cannot be null."); |
| } |
| if (principalName == null) { |
| throw new NullPointerException(("principalName argument cannot be null.")); |
| } |
| if (this.realmPrincipals == null) { |
| return null; |
| } |
| Map<String,Object> principals = this.realmPrincipals.get(realmName); |
| if (principals != null) { |
| return principals.get(principalName); |
| } |
| return null; |
| } |
| |
| public Object removeRealmPrincipal(String realmName, String principalName) { |
| if (realmName == null) { |
| throw new NullPointerException("realmName argument cannot be null."); |
| } |
| if (principalName == null) { |
| throw new NullPointerException(("principalName argument cannot be null.")); |
| } |
| if (this.realmPrincipals == null) { |
| return null; |
| } |
| Map<String,Object> principals = this.realmPrincipals.get(realmName); |
| if (principals != null) { |
| return principals.remove(principalName); |
| } |
| return null; |
| } |
| } |