blob: f52686640a7803c604ab8da9b1b655f510513764 [file] [log] [blame]
/*
* 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;
}
}