/* (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.wcs;
import java.awt.image.RenderedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.jai.PlanarImage;
import org.geoserver.ows.AbstractDispatcherCallback;
import org.geoserver.ows.Request;
import org.geoserver.platform.Operation;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.resources.image.ImageUtilities;
import org.geotools.util.logging.Logging;
import org.opengis.coverage.grid.GridCoverage;
public class CoverageCleanerCallback extends AbstractDispatcherCallback {
static final Logger LOGGER = Logging.getLogger(CoverageCleanerCallback.class);
static final ThreadLocal<List<GridCoverage>> COVERAGES = new ThreadLocal<List<GridCoverage>>();
@Override
public Object operationExecuted(Request request, Operation operation, Object result) {
// collect the grid coverages that we'll have to dispose of at the
// end of the request
if (result instanceof GridCoverage) {
addCoverages((GridCoverage) result);
} else if (result instanceof GridCoverage[]) {
addCoverages((GridCoverage[]) result);
}
return result;
}
@Override
public void finished(Request request) {
clean();
}
/**
* Mark coverage for cleaning.
*
* @param coverages
*/
public static void addCoverages(GridCoverage... coverages) {
List<GridCoverage> list = COVERAGES.get();
if (list == null) {
list = new ArrayList<GridCoverage>();
COVERAGES.set(list);
}
list.addAll(Arrays.asList(coverages));
}
/**
* Cleans up a coverage and its internal rendered image
*
* @param coverage
*/
public static void disposeCoverage(GridCoverage coverage) {
RenderedImage ri = coverage.getRenderedImage();
if (coverage instanceof GridCoverage2D) {
((GridCoverage2D) coverage).dispose(true);
}
if (ri instanceof PlanarImage) {
ImageUtilities.disposePlanarImageChain((PlanarImage) ri);
}
}
/**
* Clean up any coverages collected by {@link #addCoverages(GridCoverage...)}
*/
public void clean() {
try {
List<GridCoverage> coverages = COVERAGES.get();
if (coverages != null) {
for (GridCoverage coverage : coverages) {
try {
disposeCoverage(coverage);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Failed to fully dispose coverage: " + coverage,
e);
}
}
}
} finally {
COVERAGES.remove();
}
}
}