package tap.parameters;
/*
* This file is part of TAPLibrary.
*
* TAPLibrary 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, either version 3 of the License, or
* (at your option) any later version.
*
* TAPLibrary 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2012-2016 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
* Astronomisches Rechen Institut (ARI)
*/
import tap.ServiceConnection;
import tap.TAPJob;
import uws.UWSException;
import uws.job.parameters.InputParamController;
/**
* <p>Let controlling the execution duration of all jobs managed by a TAP service.
* The maximum and default values are provided by the service connection.</p>
*
* <p><i>Note:
* By default, the execution duration can be modified by anyone without any limitation.
* The default value is {@link TAPJob#UNLIMITED_DURATION}.
* </i></p>
*
* <p>The logic of the execution duration is set in this class. Here it is:</p>
* <ul>
* <li>If no value is specified by the TAP client, the default value is returned.</li>
* <li>If no default value is provided, the maximum duration is returned.</li>
* <li>If no maximum value is provided, there is no limit (={@link TAPJob#UNLIMITED_DURATION}).</li>
* </ul>
*
* @author Grégory Mantelet (CDS;ARI)
* @version 2.1 (09/2016)
*/
public class TAPExecutionDurationController implements InputParamController {
/** Connection to the service which knows the maximum and default value of this parameter. */
protected final ServiceConnection service;
/** Indicate whether the execution duration of jobs can be modified. */
protected boolean allowModification = true;
/**
* Build a controller for the ExecutionDuration parameter.
*
* @param service Connection to the TAP service.
*/
public TAPExecutionDurationController(final ServiceConnection service){
this.service = service;
}
@Override
public final boolean allowModification(){
return allowModification;
}
/**
* Let indicate whether the execution duration of any managed job can be modified.
*
* @param allowModif <i>true</i> if the execution duration can be modified, <i>false</i> otherwise.
*/
public final void allowModification(final boolean allowModif){
allowModification = allowModif;
}
@Override
public final Object getDefault(){
// Get the default value from the service connection:
long defaultVal = TAPJob.UNLIMITED_DURATION;
if (service.getExecutionDuration() != null && service.getExecutionDuration().length >= 2)
defaultVal = service.getExecutionDuration()[0] / 1000; // ServiceConnection keeps limits in MILLISECONDS, but the controller MUST work in SECONDS (TAP input and output for this parameter are always in seconds)
// The default value is also limited by the maximum value if any:
long maxVal = getMaxDuration();
return (defaultVal <= 0 || (maxVal > 0 && defaultVal > maxVal)) ? maxVal : defaultVal;
}
/**
* Gets the maximum execution duration.
*
* @return The maximum execution duration <i>(0 or less mean an unlimited duration)</i>.
*/
public final long getMaxDuration(){
if (service.getExecutionDuration() != null && service.getExecutionDuration().length >= 2){
if (service.getExecutionDuration()[1] > 0)
return service.getExecutionDuration()[1] / 1000; // ServiceConnection keeps limits in MILLISECONDS, but the controller MUST work in SECONDS (TAP input and output for this parameter are always in seconds)
}
return TAPJob.UNLIMITED_DURATION;
}
@Override
public Object check(final Object value) throws UWSException{
// If no value, return the default one:
if (value == null)
return getDefault();
// Get the default and maximum durations for comparison:
long defaultDuration = (Long)getDefault(),
maxDuration = getMaxDuration();
// Parse the given duration:
Long duration;
if (value instanceof Long)
duration = (Long)value;
else if (value instanceof Integer)
duration = (long)((Integer)value).intValue();
else if (value instanceof String){
try{
duration = Long.parseLong((String)value);
}catch(NumberFormatException nfe){
throw new UWSException(UWSException.BAD_REQUEST, "Wrong format for the parameter \"executionduration\": \"" + value.toString() + "\"! It should be a long numeric value between " + TAPJob.UNLIMITED_DURATION + " and " + maxDuration + " (Default value: " + defaultDuration + ").");
}
}else
throw new UWSException(UWSException.INTERNAL_SERVER_ERROR, "Wrong type for the parameter \"executionduration\": class \"" + value.getClass().getName() + "\"! It should be long or a string containing only a long value.");
// A negative value must be considered as an unlimited duration:
if (duration <= 0)
duration = TAPJob.UNLIMITED_DURATION;
// Ensure the given value is less than the maximum duration:
if (maxDuration > 0 && (duration > maxDuration || duration <= 0))
duration = maxDuration;
return duration;
}
}