blob: 6ab8b0a5110c78a43bde4712a7da4c273105c4fc [file] [log] [blame]
/*
x * 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.chemistry.opencmis.inmemory.storedobj.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.chemistry.opencmis.commons.data.Ace;
import org.apache.chemistry.opencmis.commons.data.Acl;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl;
public class InMemoryAcl implements Cloneable {
private List<InMemoryAce> acl;
private int id;
@SuppressWarnings("serial")
private static class AceComparator<T extends InMemoryAce> implements Comparator<T> {
@Override
public int compare(T o1, T o2) {
if (null == o1 || null == o2) {
if (o1 == o2) { // NOSONAR
return 0;
} else if (o1 == null) {
return 1;
} else {
return -1;
}
}
int res = o1.getPrincipalId().compareTo(o2.getPrincipalId());
return res;
}
};
private static final Comparator<? super InMemoryAce> COMP = new AceComparator<InMemoryAce>();
private static final InMemoryAcl DEFAULT_ACL = new InMemoryAcl(new ArrayList<InMemoryAce>() {
{
add(InMemoryAce.getDefaultAce());
}
});
public static InMemoryAcl createFromCommonsAcl(Acl commonsAcl) {
InMemoryAcl acl = new InMemoryAcl();
for (Ace cace : commonsAcl.getAces()) {
if (acl.hasPrincipal(cace.getPrincipalId())) {
Permission perm = acl.getPermission(cace.getPrincipalId());
Permission newPerm = Permission.fromCmisString(cace.getPermissions().get(0));
if (perm.ordinal() > newPerm.ordinal()) {
acl.setPermission(cace.getPrincipalId(), newPerm);
}
} else {
acl.addAce(new InMemoryAce(cace));
}
}
return acl;
}
public static InMemoryAcl getDefaultAcl() {
return DEFAULT_ACL;
}
public InMemoryAcl() {
acl = new ArrayList<InMemoryAce>(3);
}
public InMemoryAcl(final List<InMemoryAce> arg) {
this.acl = new ArrayList<InMemoryAce>(arg);
Collections.sort(this.acl, COMP);
for (int i = 0; i < acl.size(); i++) {
InMemoryAce ace = acl.get(i);
if (ace == null) {
throw new IllegalArgumentException("Cannot create ACLs with a null principal id or permission.");
}
}
for (int i = 0; i < acl.size() - 1; i++) {
if (acl.get(i).equals(acl.get(i + 1))) {
throw new IllegalArgumentException("Cannot create ACLs with same principal id in more than one ACE.");
}
}
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public final List<InMemoryAce> getAces() {
return acl;
}
public boolean addAce(InMemoryAce ace) {
if (ace == null) {
return false;
}
for (InMemoryAce ace2 : acl) {
if (ace2.getPrincipalId().equals(ace.getPrincipalId())) {
return false;
}
}
acl.add(ace);
Collections.sort(acl, COMP);
return true;
}
public boolean removeAce(InMemoryAce ace) {
return acl.remove(ace);
}
public void mergeAcl(InMemoryAcl acl2) {
if (acl2 == null) {
return;
}
for (InMemoryAce ace : acl2.getAces()) {
InMemoryAce existingAce = getAce(ace.getPrincipalId());
if (existingAce == null) {
acl.add(ace);
} else if (existingAce.getPermission().ordinal() < ace.getPermission().ordinal()) {
existingAce.setPermission(ace.getPermission());
}
}
Collections.sort(this.acl, COMP);
}
public Permission getPermission(String principalId) {
InMemoryAce ace = getAce(principalId);
return ace == null ? Permission.NONE : ace.getPermission();
}
private InMemoryAce getAce(String principalId) {
if (null == principalId) {
return null;
}
for (InMemoryAce ace : acl) {
if (ace.getPrincipalId().equals(principalId)) {
return ace;
}
}
return null;
}
public boolean hasPermission(String principalId, Permission permission) {
if (null == permission) {
return false;
}
if (null == principalId) {
for (InMemoryAce ace : acl) {
if (ace.getPrincipalId().equals(InMemoryAce.getAnonymousUser())) {
return ace.hasPermission(permission);
}
}
}
for (InMemoryAce ace : acl) {
if (ace.getPrincipalId().equals(principalId) || ace.getPrincipalId().equals(InMemoryAce.getAnyoneUser())
|| ace.getPrincipalId().equals(InMemoryAce.getAnonymousUser())) {
return ace.hasPermission(permission);
}
}
return false;
}
public void setPermission(String principalId, Permission permission) {
for (InMemoryAce ace : acl) {
if (ace.getPrincipalId().equals(principalId)) {
ace.setPermission(permission);
}
}
throw new IllegalArgumentException("Unknown principalId in setPermission: " + principalId);
}
public int size() {
return acl.size();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((acl == null) ? 0 : acl.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
InMemoryAcl other = (InMemoryAcl) obj;
if (acl == null) {
if (other.acl != null) {
return false;
}
} else if (!acl.equals(other.acl)) {
return false;
}
return true;
}
@Override
public String toString() {
return "InMemoryAcl [acl=" + acl + "]";
}
private boolean hasPrincipal(String principalId) {
for (InMemoryAce ace : acl) {
if (ace.getPrincipalId().equals(principalId)) {
return true;
}
}
return false;
}
public Acl toCommonsAcl() {
List<Ace> commonsAcl = new ArrayList<Ace>();
for (InMemoryAce memAce : acl) {
commonsAcl.add(memAce.toCommonsAce());
}
return new AccessControlListImpl(commonsAcl);
}
@Override
public InMemoryAcl clone() throws CloneNotSupportedException {
InMemoryAcl newAcl = new InMemoryAcl(acl);
return newAcl;
}
}