/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.security;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import org.geotools.data.Query;
import org.geotools.factory.CommonFactoryFinder;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;
import org.opengis.filter.expression.PropertyName;
/**
* Describes the access limits on a vector layer
*
* @author Andrea Aime - GeoSolutions
*/
public class VectorAccessLimits extends DataAccessLimits {
private static final long serialVersionUID = 1646981660625898503L;
private static FilterFactory2 FF = CommonFactoryFinder.getFilterFactory2(null);
/**
* The list of attributes the user is allowed to read (will be band names for raster data)
*/
transient List<PropertyName> readAttributes;
/**
* The set of attributes the user is allowed to write on
*/
transient List<PropertyName> writeAttributes;
/**
* Limits the features that can actually be written
*/
transient Filter writeFilter;
/**
* Builds a new vector access limits
*
* @param readAttributes
* The list of attributes that can be read
* @param readFilter
* Only matching features will be returned to the user
* @param writeAttributes
* The list of attributes that can be modified
* @param writeFilter
* Only matching features will be allowed to be created/modified/deleted
*/
public VectorAccessLimits(CatalogMode mode, List<PropertyName> readAttributes, Filter readFilter,
List<PropertyName> writeAttributes, Filter writeFilter) {
super(mode, readFilter);
this.readAttributes = readAttributes;
this.writeAttributes = writeAttributes;
this.writeFilter = writeFilter;
}
/**
* The list of attributes the user is allowed to read
*
* @return
*/
public List<PropertyName> getReadAttributes() {
return readAttributes;
}
/**
* The list of attributes the user is allowed to write
*
* @return
*/
public List<PropertyName> getWriteAttributes() {
return writeAttributes;
}
/**
* Identifies the features the user can write onto
*
* @return
*/
public Filter getWriteFilter() {
return writeFilter;
}
/**
* Returns a GeoTools query wrapping the read attributes and the read filter
* @return
*/
public Query getReadQuery() {
return buildQuery(readAttributes, readFilter);
}
/**
* Returns a GeoTools query wrapping the write attributes and the write filter
* @return
*/
public Query getWriteQuery() {
return buildQuery(writeAttributes, writeFilter);
}
/**
* Returns a GeoTools query build with the provided attributes and filters
* @return
*/
private Query buildQuery(List<PropertyName> attributes, Filter filter) {
if(attributes == null && (filter == null || filter == Filter.INCLUDE)) {
return Query.ALL;
} else {
Query q = new Query();
q.setFilter(filter);
// TODO: switch this to property names when possible
q.setPropertyNames(flattenNames(attributes));
return q;
}
}
/**
* Turns a list of {@link PropertyName} into a list of {@link String}
* @param names
* @return
*/
List<String> flattenNames(List<PropertyName> names) {
if(names == null) {
return null;
}
List<String> result = new ArrayList<String>(names.size());
for (PropertyName name : names) {
result.add(name.getPropertyName());
}
return result;
}
@Override
public String toString() {
return "VectorAccessLimits [readAttributes=" + readAttributes + ", writeAttributes="
+ writeAttributes + ", writeFilter=" + writeFilter + ", readFilter=" + readFilter
+ ", mode=" + mode + "]";
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
readAttributes = readProperties(in);
readFilter = readFilter(in);
writeAttributes = readProperties(in);
writeFilter = readFilter(in);
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
writeProperties(readAttributes, out);
writeFilter(readFilter, out);
writeProperties(writeAttributes, out);
writeFilter(writeFilter, out);
}
private void writeProperties(List<PropertyName> attributes, ObjectOutputStream oos)
throws IOException {
if (attributes == null) {
oos.writeInt(-1);
} else {
oos.writeInt(attributes.size());
for (PropertyName property : attributes) {
oos.writeObject(property.getPropertyName());
// TODO: write out the namespace support as well
}
}
}
private List<PropertyName> readProperties(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
int size = ois.readInt();
if (size == -1) {
return null;
} else {
List<PropertyName> properties = new ArrayList<PropertyName>();
for (int i = 0; i < size; i++) {
String name = (String) ois.readObject();
properties.add(FF.property(name));
// TODO: read out the namespace support as well
}
return properties;
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((readAttributes == null) ? 0 : readAttributes.hashCode());
result = prime * result + ((writeAttributes == null) ? 0 : writeAttributes.hashCode());
result = prime * result + ((writeFilter == null) ? 0 : writeFilter.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
VectorAccessLimits other = (VectorAccessLimits) obj;
if (readAttributes == null) {
if (other.readAttributes != null)
return false;
} else if (!readAttributes.equals(other.readAttributes))
return false;
if (writeAttributes == null) {
if (other.writeAttributes != null)
return false;
} else if (!writeAttributes.equals(other.writeAttributes))
return false;
if (writeFilter == null) {
if (other.writeFilter != null)
return false;
} else if (!writeFilter.equals(other.writeFilter))
return false;
return true;
}
}