/* 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.decorators; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import org.geoserver.data.util.CoverageUtils; import org.geoserver.security.CoverageAccessLimits; import org.geoserver.security.WrapperPolicy; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader; import org.geotools.coverage.processing.CoverageProcessor; import org.geotools.coverage.processing.operation.Crop; import org.geotools.factory.Hints; import org.geotools.geometry.jts.JTS; import org.geotools.geometry.jts.ReferencedEnvelope; import org.opengis.coverage.grid.Format; import org.opengis.filter.Filter; import org.opengis.parameter.GeneralParameterDescriptor; import org.opengis.parameter.GeneralParameterValue; import org.opengis.parameter.ParameterValueGroup; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.MultiPolygon; /** * Applies access limits policies around the wrapped reader * * @author Andrea Aime - GeoSolutions */ public class SecuredGridCoverage2DReader extends DecoratingGridCoverage2DReader { /** Parameters used to control the {@link Crop} operation. */ private static final ParameterValueGroup cropParams; /** * Cached crop factory */ private final static Crop coverageCropFactory = new Crop(); static { final CoverageProcessor processor = new CoverageProcessor(new Hints( Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE)); cropParams = processor.getOperation("CoverageCrop").getParameters(); } WrapperPolicy policy; public SecuredGridCoverage2DReader(AbstractGridCoverage2DReader delegate, WrapperPolicy policy) { super(delegate); this.policy = policy; } public Format getFormat() { Format format = delegate.getFormat(); if (format == null) { return null; } else { return (Format) SecuredObjects.secure(format, policy); } } public GridCoverage2D read(GeneralParameterValue[] parameters) throws IllegalArgumentException, IOException { MultiPolygon rasterFilter = null; if (policy.getLimits() instanceof CoverageAccessLimits) { CoverageAccessLimits limits = (CoverageAccessLimits) policy.getLimits(); // get the crop filter rasterFilter = limits.getRasterFilter(); Filter readFilter = limits.getReadFilter(); // update the read params final GeneralParameterValue[] limitParams = limits.getParams(); if (parameters == null) { parameters = limitParams; } else if (limitParams != null) { // scan the input params, add and overwrite with the limits params as needed List<GeneralParameterValue> params = new ArrayList<GeneralParameterValue>(Arrays .asList(parameters)); for (GeneralParameterValue lparam : limitParams) { // remove the overwritten param, if any final GeneralParameterDescriptor ldescriptor = lparam.getDescriptor(); for (Iterator it = params.iterator(); it.hasNext();) { GeneralParameterValue param = (GeneralParameterValue) it.next(); if (param.getDescriptor().equals(lparam.getDescriptor())) { it.remove(); break; } } // add the overwrite param (will be an overwrite if it was already there, an // addition otherwise) params.add(lparam); } parameters = (GeneralParameterValue[]) params .toArray(new GeneralParameterValue[params.size()]); } if(readFilter != null && !Filter.INCLUDE.equals(readFilter)) { ParameterValueGroup readParameters = delegate.getFormat().getReadParameters(); List<GeneralParameterDescriptor> descriptors = readParameters.getDescriptor().descriptors(); parameters = CoverageUtils.mergeParameter(descriptors, parameters, readFilter, "FILTER", "Filter"); } } GridCoverage2D grid = delegate.read(parameters); // crop if necessary if (rasterFilter != null) { Geometry coverageBounds = JTS.toGeometry((Envelope) new ReferencedEnvelope(grid.getEnvelope2D())); if(coverageBounds.intersects(rasterFilter)) { final ParameterValueGroup param = (ParameterValueGroup) cropParams.clone(); param.parameter("source").setValue(grid); param.parameter("ROI").setValue(rasterFilter); grid = (GridCoverage2D) coverageCropFactory.doOperation(param, hints); } else { return null; } } return grid; } }