/* | |
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; | |
} | |
} |