/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.security; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.apache.commons.io.output.ByteArrayOutputStream; import org.geotools.filter.v1_0.OGC; import org.geotools.filter.v1_1.OGCConfiguration; import org.geotools.xml.Encoder; import org.geotools.xml.Parser; import org.opengis.filter.Filter; /** * Base class for all AccessLimits declared by a {@link ResourceAccessManager} * * @author Andrea Aime - GeoSolutions */ public class DataAccessLimits extends AccessLimits { private static final OGCConfiguration CONFIGURATION = new OGCConfiguration(); private static final long serialVersionUID = 2594922992934373705L; /** * Used for vector reading, for raster if there is a read param taking an OGC filter, and in WMS * if the remote server supports CQL filters and on feature info requests. For workspaces it * will be just INCLUDE or EXCLUDE to allow or deny access to the workspace */ transient Filter readFilter; /** * Builds a generic DataAccessLimits * * @param readFilter * This filter will be merged with the request read filters to limit the * features/tiles that can be actually read */ public DataAccessLimits(CatalogMode mode, Filter readFilter) { super(mode); this.readFilter = readFilter; } /** * This filter will be merged with the request read filters to limit the features/tiles that can * be actually read * * */ public Filter getReadFilter() { return readFilter; } /** * The catalog mode for this layer * * */ public CatalogMode getMode() { return mode; } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); readFilter = readFilter(in); } private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); writeFilter(readFilter, out); } /** * Writes the non Serializable Filter object ot the ObjectOutputStream via a OGC Filter XML * encoding conversion * * @param filter * @param out * @throws IOException */ protected void writeFilter(Filter filter, ObjectOutputStream out) throws IOException { if (filter != null) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); Encoder encoder = new Encoder(CONFIGURATION); encoder.encode(filter, OGC.Filter, bos); out.writeObject(bos.toByteArray()); } else { out.writeObject(null); } } /** * Reads from the object input stream a string representing a filter in OGC XML encoding and * parses it back to a Filter object * * @param in * * @throws IOException * @throws ClassNotFoundException */ protected Filter readFilter(ObjectInputStream in) throws IOException, ClassNotFoundException { byte[] serializedReadFilter = (byte[]) in.readObject(); if (serializedReadFilter != null) { try { Parser p = new Parser(CONFIGURATION); return (Filter) p.parse(new ByteArrayInputStream(serializedReadFilter)); } catch (Exception e) { throw (IOException) new IOException("Failed to parse filter").initCause(e); } } else { return null; } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((readFilter == null) ? 0 : readFilter.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; DataAccessLimits other = (DataAccessLimits) obj; if (readFilter == null) { if (other.readFilter != null) return false; } else if (!readFilter.equals(other.readFilter)) return false; return true; } }