/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wps.security;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.builder.HashCodeBuilder;
/**
* Represents a data access rule: identifies a workspace, a layer, an access mode, and the set of
* roles that are allowed to access it
* <p>Mind, two rules are considered equal if the address the same data, if you need full
* comparison, use {@link #equalsExact(WpsAccessRule)}</p>
*/
@SuppressWarnings("serial")
public class WpsAccessRule implements Comparable<WpsAccessRule>, Serializable {
/**
* Any layer, or any workspace, or any role
*/
public static final String ANY = "*";
public static WpsAccessRule EXECUTE_ALL = new WpsAccessRule(ANY, ANY, ANY);
private String groupName;
private String wpsName;
private Set<String> roles;
/**
* Builds a new rule
*/
public WpsAccessRule(String groupName, String wpsName, Set<String> roles) {
super();
this.groupName = groupName;
this.wpsName = wpsName;
if (roles == null)
this.roles = new HashSet<String>();
else
this.roles = new HashSet<String>(roles);
}
/**
* Builds a new rule
*/
public WpsAccessRule(String groupName, String wpsName, String... roles) {
this(groupName, wpsName, roles == null ? null : new HashSet<String>(Arrays.asList(roles)));
}
/**
* Copy constructor
*/
public WpsAccessRule(WpsAccessRule other) {
this.groupName = other.groupName;
this.wpsName = other.wpsName;
this.roles = new HashSet<String>(other.roles);
}
/**
* Builds the default rule: *.*.r=*
*/
public WpsAccessRule() {
this(ANY, ANY);
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public String getWpsName() {
return wpsName;
}
public void setWpsName(String wpsName) {
this.wpsName = wpsName;
}
public void setRoles(Set<String> roles) {
this.roles = roles;
}
public Set<String> getRoles() {
return roles;
}
/**
* Returns the key for the current rule. No other rule should have the same
*
*
*/
public String getKey() {
return groupName + "." + wpsName ;
}
/**
* Returns the list of roles as a comma separated string for this rule
*
*/
public String getValue() {
if(roles.isEmpty()) {
return WpsAccessRule.ANY;
} else {
StringBuffer sb = new StringBuffer();
for (String role : roles) {
sb.append(role);
sb.append(",");
}
sb.setLength(sb.length() - 1);
return sb.toString();
}
}
/**
* Comparison implemented so that generic rules get first, specific one are compared by name,
* and if anything else is equal, read comes before write
*/
public int compareTo(WpsAccessRule other) {
int compareGroup = compareCatalogItems(groupName, other.groupName);
if (compareGroup != 0)
return compareGroup;
int compareName = compareCatalogItems(wpsName, other.wpsName);
return compareName;
}
/**
* Equality based on ws/layer/mode only
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof WpsAccessRule))
return false;
return 0 == compareTo((WpsAccessRule) obj);
}
/**
* Full equality, roles included
*/
public boolean equalsExact(WpsAccessRule obj) {
if(0 != compareTo(obj))
return false;
else
return roles.equals(obj.roles);
}
/**
* Hashcode based on wfs/layer/mode only
*/
@Override
public int hashCode() {
return new HashCodeBuilder().append(groupName).append(wpsName)
.toHashCode();
}
/**
* Generic string comparison that considers the use of {@link #ANY}
*/
public int compareCatalogItems(String item, String otherItem) {
if (item.equals(otherItem))
return 0;
else if (ANY.equals(item))
return -1;
else if (ANY.equals(otherItem))
return 1;
else
return item.compareTo(otherItem);
}
@Override
public String toString() {
return getKey() + "=" + getValue();
}
}