/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2013, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.map; import java.util.logging.Level; import java.util.logging.Logger; import org.geotoolkit.storage.coverage.DefaultCoverageReference; import org.geotoolkit.coverage.grid.GridCoverage2D; import org.geotoolkit.coverage.io.GridCoverageReader; import org.geotoolkit.coverage.memory.MemoryCoverageReader; import org.geotoolkit.util.NamesExt; import org.geotoolkit.process.ProcessDescriptor; import org.geotoolkit.process.Process; import org.apache.sis.util.logging.Logging; import org.geotoolkit.coverage.io.CoverageStoreException; import org.opengis.parameter.ParameterNotFoundException; import org.opengis.parameter.ParameterValueGroup; /** * A collection which is calculated on the fly by a process. * * @author Johann Sorel (Geomatys) */ public class ProcessedCoverageReference extends DefaultCoverageReference{ private static final Logger LOGGER = Logging.getLogger("org.geotoolkit.map"); private ProcessDescriptor processDescriptor; private ParameterValueGroup inputParam; private String resultParam; private long lifespan = 0; private ParameterValueGroup result; private long lastCall = 0; public ProcessedCoverageReference(){ super(null, NamesExt.create("Processed")); } /** * Get ProcessDescriptor called to obtain the result collection. * @return ProcessDescriptor */ public ProcessDescriptor getProcessDescriptor() { return processDescriptor; } /** * Set ProcessDescriptor called to obtain the result collection. * @return ProcessDescriptor */ public void setProcessDescriptor(ProcessDescriptor processDescriptor) { this.processDescriptor = processDescriptor; } /** * Get ParameterValueGroup used when executing the process. * @return ProcessDescriptor */ public ParameterValueGroup getInputParameters() { return inputParam; } /** * Set ParameterValueGroup used when executing the process. * @return ProcessDescriptor */ public void setInputParameters(ParameterValueGroup inputParam) { this.inputParam = inputParam; } /** * Get name of the parameter is the result parameterValueGroup to use * as a Collection. * @return String parameter name */ public String getResultParameter() { return resultParam; } /** * Set name of the parameter is the result parameterValueGroup to use * as a Collection. * @return String parameter name */ public void setResultParameter(String resultParam) { this.resultParam = resultParam; } /** * Lapse of time the result of the process is valid. * A negative value means the lifespan is infinite. * A value of zero will cause the process to be executed on each access. * It is recommanded to have a value superior to 5.000 milliseconds to avoid * to much processing, yet this higly depends on the process itself. * * @return long lifespan in millisecond */ public long getLifespan() { return lifespan; } /** * {@see ProcessedCollection.getLifespan} * @param lifespan */ public void setLifespan(long lifespan) { this.lifespan = lifespan; } private GridCoverage2D getResult(){ if(processDescriptor == null || inputParam == null || resultParam == null){ LOGGER.log(Level.WARNING, "ProcessedCollection not configured."); return null; } //check lifespan if(result != null && lifespan>=0 && (System.currentTimeMillis()-lastCall)>lifespan ){ result = null; } //execute process if requiered if(result == null){ lastCall = System.currentTimeMillis(); try{ final Process process = processDescriptor.createProcess(inputParam); result = process.call(); }catch(Exception ex){ //we should not catch exception, but we don't want to break the stack because of a //uncorrect process script (groovy, javascript,...) LOGGER.log(Level.WARNING, "Processing failed : "+ex.getMessage(), ex); } } if(result == null){ return null; }else{ Object cov = null; try{ cov = result.parameter(resultParam).getValue(); }catch(ParameterNotFoundException ex){ LOGGER.log(Level.WARNING, "Parameter "+resultParam+" is not in the result parameters."); } if(cov instanceof GridCoverage2D){ //do nothing }else{ //unsupported type LOGGER.log(Level.WARNING, "Parameter "+resultParam+" is not a coverage type : "+cov); cov = null; } return (GridCoverage2D)cov; } } @Override public GridCoverageReader acquireReader() throws CoverageStoreException { GridCoverage2D cov = getResult(); if(cov != null){ return new MemoryCoverageReader(cov); } return null; } }