org.apache.shiro.subject.SimplePrincipalCollection Maven / Gradle / Ivy
The newest version!
/*
* 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 com.fasterxml.jackson.annotation.JsonFilter;
import org.apache.shiro.lang.util.StringUtils;
import org.apache.shiro.util.CollectionUtils;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.*;
/**
* A simple implementation of the {@link MutablePrincipalCollection} interface that tracks principals internally
* by storing them in a {@link LinkedHashMap}.
*
* @since 0.9
*/
@SuppressWarnings({"unchecked"})
@JsonFilter("rewrite-bean")
public class SimplePrincipalCollection implements MutablePrincipalCollection {
// Serialization reminder:
// You _MUST_ change this number if you introduce a change to this class
// that is NOT serialization backwards compatible. Serialization-compatible
// changes do not require a change to this number. If you need to generate
// a new number in this case, use the JDK's 'serialver' program to generate it.
private static final long serialVersionUID = -6305224034025797558L;
//TODO - complete JavaDoc
private Map realmPrincipals;
private transient String cachedToString; //cached toString() result, as this can be printed many times in logging
public SimplePrincipalCollection() {
}
public SimplePrincipalCollection(Object principal, String realmName) {
if (principal instanceof Collection) {
addAll((Collection) principal, realmName);
} else {
add(principal, realmName);
}
}
public SimplePrincipalCollection(Collection principals, String realmName) {
addAll(principals, realmName);
}
public SimplePrincipalCollection(PrincipalCollection principals) {
addAll(principals);
}
protected Collection getPrincipalsLazy(String realmName) {
if (realmPrincipals == null) {
realmPrincipals = new LinkedHashMap();
}
Set principals = realmPrincipals.get(realmName);
if (principals == null) {
principals = new LinkedHashSet();
realmPrincipals.put(realmName, principals);
}
return principals;
}
/**
* Returns the first available principal from any of the {@code Realm} principals, or {@code null} if there are
* no principals yet.
*
* The 'first available principal' is interpreted as the principal that would be returned by
* {@link #iterator() iterator()}.{@link java.util.Iterator#next() next()}.
*
* @inheritDoc
*/
public Object getPrimaryPrincipal() {
if (isEmpty()) {
return null;
}
return iterator().next();
}
public void add(Object principal, String realmName) {
if (realmName == null) {
throw new NullPointerException("realmName argument cannot be null.");
}
if (principal == null) {
throw new NullPointerException("principal argument cannot be null.");
}
this.cachedToString = null;
getPrincipalsLazy(realmName).add(principal);
}
public void addAll(Collection principals, String realmName) {
if (realmName == null) {
throw new NullPointerException("realmName argument cannot be null.");
}
if (principals == null) {
throw new NullPointerException("principals argument cannot be null.");
}
if (principals.isEmpty()) {
throw new IllegalArgumentException("principals argument cannot be an empty collection.");
}
this.cachedToString = null;
getPrincipalsLazy(realmName).addAll(principals);
}
public void addAll(PrincipalCollection principals) {
if (principals.getRealmNames() != null) {
for (String realmName : principals.getRealmNames()) {
for (Object principal : principals.fromRealm(realmName)) {
add(principal, realmName);
}
}
}
}
public T oneByType(Class type) {
if (realmPrincipals == null || realmPrincipals.isEmpty()) {
return null;
}
Collection values = realmPrincipals.values();
for (Set set : values) {
for (Object o : set) {
if (type.isAssignableFrom(o.getClass())) {
return (T) o;
}
}
}
return null;
}
public Collection byType(Class type) {
if (realmPrincipals == null || realmPrincipals.isEmpty()) {
return Collections.EMPTY_SET;
}
Set typed = new LinkedHashSet();
Collection values = realmPrincipals.values();
for (Set set : values) {
for (Object o : set) {
if (type.isAssignableFrom(o.getClass())) {
typed.add((T) o);
}
}
}
if (typed.isEmpty()) {
return Collections.EMPTY_SET;
}
return Collections.unmodifiableSet(typed);
}
public List asList() {
Set all = asSet();
if (all.isEmpty()) {
return Collections.EMPTY_LIST;
}
return Collections.unmodifiableList(new ArrayList(all));
}
public Set asSet() {
if (realmPrincipals == null || realmPrincipals.isEmpty()) {
return Collections.EMPTY_SET;
}
Set aggregated = new LinkedHashSet();
Collection values = realmPrincipals.values();
for (Set set : values) {
aggregated.addAll(set);
}
if (aggregated.isEmpty()) {
return Collections.EMPTY_SET;
}
return Collections.unmodifiableSet(aggregated);
}
public Collection fromRealm(String realmName) {
if (realmPrincipals == null || realmPrincipals.isEmpty()) {
return Collections.EMPTY_SET;
}
Set principals = realmPrincipals.get(realmName);
if (principals == null || principals.isEmpty()) {
principals = Collections.EMPTY_SET;
}
return Collections.unmodifiableSet(principals);
}
public Set getRealmNames() {
if (realmPrincipals == null) {
return null;
} else {
return realmPrincipals.keySet();
}
}
public boolean isEmpty() {
return realmPrincipals == null || realmPrincipals.isEmpty();
}
public void clear() {
this.cachedToString = null;
if (realmPrincipals != null) {
realmPrincipals.clear();
realmPrincipals = null;
}
}
public Iterator iterator() {
return asSet().iterator();
}
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o instanceof SimplePrincipalCollection) {
SimplePrincipalCollection other = (SimplePrincipalCollection) o;
return this.realmPrincipals != null ? this.realmPrincipals.equals(other.realmPrincipals) : other.realmPrincipals == null;
}
return false;
}
public int hashCode() {
if (this.realmPrincipals != null && !realmPrincipals.isEmpty()) {
return realmPrincipals.hashCode();
}
return super.hashCode();
}
/**
* Returns a simple string representation suitable for printing.
*
* @return a simple string representation suitable for printing.
* @since 1.0
*/
public String toString() {
if (this.cachedToString == null) {
Set