package uws.job.parameters; /* * This file is part of UWSLibrary. * * UWSLibrary 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. * * UWSLibrary 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 UWSLibrary. If not, see <http://www.gnu.org/licenses/>. * * Copyright 2012,2014 - UDS/Centre de DonnĂ©es astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ import java.io.Serializable; import java.text.ParseException; import java.util.Calendar; import java.util.Date; import uws.ISO8601Format; import uws.UWSException; /** * <p> * Let controlling the destruction time of all jobs managed by a UWS. Thus it is possible to set a default and a maximum value. * Moreover you can indicate whether the destruction time of jobs can be modified by the user or not. * </p> * * <p><i><u>Notes:</u> * <ul> * <li>By default, the destruction time can be modified by anyone without any limitation. * There is no default value (that means jobs may stay forever).</li> * <li>You can specify a destruction time (default or maximum value) in two ways: * by an exact date-time or by an interval of time from the initialization (expressed in the second, minutes, hours, days, months or years).</li> * </ul> * </i></p> * * <p>The logic of the destruction time is set in this class. Here it is:</p> * <ul> * <li>If no value is specified by the UWS client, the default value is returned.</li> * <li>If no default value is provided, the maximum destruction date is returned.</li> * <li>If no maximum value is provided, there is no destruction.</li> * </ul> * * @author Grégory Mantelet (CDS;ARI) * @version 4.1 (11/2014) */ public class DestructionTimeController implements InputParamController, Serializable { private static final long serialVersionUID = 1L; /** * Represents a date/time field. * * @author Grégory Mantelet (CDS) * @version 4.0 (02/2011) * * @see Calendar */ public static enum DateField{ SECOND(Calendar.SECOND), MINUTE(Calendar.MINUTE), HOUR(Calendar.HOUR), DAY(Calendar.DAY_OF_MONTH), MONTH(Calendar.MONTH), YEAR(Calendar.YEAR); private final int index; private DateField(int fieldIndex){ index = fieldIndex; } public final int getFieldIndex(){ return index; } } /** Default value of an interval: a null interval. */ public final static int NO_INTERVAL = 0; /** The default destruction time. */ protected Date defaultTime = null; /** The date-time field on which the default interval applies. */ protected DateField defaultIntervalField = null; /** The default interval from the initialization to the destruction of the concerned job. */ protected int defaultInterval = NO_INTERVAL; /** The maximum destruction time. */ protected Date maxTime = null; /** The date-time field on which the maximum interval applies. */ protected DateField maxIntervalField = null; /** The maximum interval from the initialization to the destruction of the concerned job. */ protected int maxInterval = NO_INTERVAL; /** Indicates whether the destruction time of jobs can be modified. */ protected boolean allowModification = true; @Override public Object check(final Object value) throws UWSException{ // If no value, return the default one: if (value == null) return getDefault(); // Otherwise, parse the date: Date date = null; if (value instanceof Date) date = (Date)value; else if (value instanceof String){ String strValue = (String)value; try{ date = ISO8601Format.parseToDate(strValue); }catch(ParseException pe){ throw new UWSException(UWSException.BAD_REQUEST, pe, "Wrong date format for the destruction time parameter: \"" + strValue + "\"! Dates must be formatted in ISO8601 (\"yyyy-MM-dd'T'hh:mm:ss[.sss]['Z'|[+|-]hh:mm]\", fields inside brackets are optional)."); } }else throw new UWSException(UWSException.INTERNAL_SERVER_ERROR, "Wrong type for the destruction time parameter: class \"" + value.getClass().getName() + "\"! It should be a Date or a string containing a date formatted in IS8601 (\"yyyy-MM-dd'T'hh:mm:ss[.sss]['Z'|[+|-]hh:mm]\", fields inside brackets are optional)."); // Compare it to the maximum destruction time: if after, set the date to the maximum allowed date: Date maxDate = getMaxDestructionTime(); if (maxDate != null && date.after(maxDate)) date = maxDate; // Return the parsed date: return date; } @Override public Object getDefault(){ Date defaultDate = getDefaultDestructionTime(); return (defaultDate == null) ? getMaxDestructionTime() : defaultDate; } /* ***************** */ /* GETTERS & SETTERS */ /* ***************** */ /** * Gets the default destruction time: either computed with an interval of time or obtained directly by a default destruction time. * * @return The default destruction time (<i>null</i> means that jobs may stay forever). */ public final Date getDefaultDestructionTime(){ if (defaultInterval > NO_INTERVAL){ Calendar date = Calendar.getInstance(); try{ date.add(defaultIntervalField.getFieldIndex(), defaultInterval); return date.getTime(); }catch(ArrayIndexOutOfBoundsException ex){ return null; } }else return defaultTime; } /** * <p>Sets the default destruction time.</p> * * <p> * <i><u>Note:</u> * If there was a default interval, it is reset and so the given destruction time will be used by {@link #getDefaultDestructionTime()}. * </i> * </p> * * @param defaultDestructionTime The default destruction time to set (<i>null</i> means jobs may stay forever). */ public final void setDefaultDestructionTime(Date defaultDestructionTime){ this.defaultTime = defaultDestructionTime; defaultInterval = NO_INTERVAL; defaultIntervalField = null; } /** * <p>Gets the default interval value.</p> * * <p><i><u>Note:</u> To get the corresponding unit, use {@link #getDefaultIntervalField()} and {@link DateField#name()}.</i></p> * * @return The default destruction interval. */ public final int getDefaultDestructionInterval(){ return defaultInterval; } /** * Gets the date-time field of the default interval. * * @return The default interval field. */ public final DateField getDefaultIntervalField(){ return defaultIntervalField; } /** * <p>Sets the default interval <b>in minutes</b> from the initialization to the destruction of the concerned job.</p> * * <p> * <i><u>Note:</u> * If there was a default destruction time, it is reset and so the given interval will be used by {@link #getDefaultDestructionTime()}. * </i> * </p> * * @param defaultDestructionInterval The default destruction interval ({@link #NO_INTERVAL}, 0 or a negative value mean the job may stay forever). * * @see #setDefaultDestructionInterval(int, DateField) */ public final void setDefaultDestructionInterval(int defaultDestructionInterval){ setDefaultDestructionInterval(defaultDestructionInterval, DateField.MINUTE); } /** * <p>Sets the default interval (in the given unit) from the initialization to the destruction of the concerned job.</p> * * <p> * <i><u>Note:</u> * If there was a default destruction time, it is reset and so the given interval will be used by {@link #getDefaultDestructionTime()}. * </i> * </p> * * @param defaultDestructionInterval The default destruction interval ({@link #NO_INTERVAL}, 0 or a negative value mean the job may stay forever). * @param timeField The unit of the interval (<i>null</i> means the job may stay forever). */ public final void setDefaultDestructionInterval(int defaultDestructionInterval, DateField timeField){ if (defaultDestructionInterval <= 0 || timeField == null){ defaultIntervalField = null; defaultInterval = NO_INTERVAL; }else{ defaultIntervalField = timeField; defaultInterval = defaultDestructionInterval; } defaultTime = null; } /** * Gets the maximum destruction time: either computed with an interval of time or obtained directly by a maximum destruction time. * * @return The maximum destruction time (<i>null</i> means that jobs may stay forever). */ public final Date getMaxDestructionTime(){ if (maxInterval > NO_INTERVAL){ Calendar date = Calendar.getInstance(); try{ date.add(maxIntervalField.getFieldIndex(), maxInterval); return date.getTime(); }catch(ArrayIndexOutOfBoundsException ex){ return null; } }else return maxTime; } /** * <p>Sets the maximum destruction time.</p> * * <p> * <i><u>Note:</u> * If there was a maximum interval, it is reset and so the given destruction time will be used by {@link #getMaxDestructionTime()}. * </i> * </p> * * @param maxDestructionTime The maximum destruction time to set (<i>null</i> means jobs may stay forever). */ public final void setMaxDestructionTime(Date maxDestructionTime){ this.maxTime = maxDestructionTime; maxInterval = NO_INTERVAL; maxIntervalField = null; } /** * <p>Gets the maximum interval value.</p> * * <p><i><u>Note:</u> To get the corresponding unit, use {@link #getMaxIntervalField()} and {@link DateField#name()}.</i></p> * * @return The maximum destruction interval. */ public final int getMaxDestructionInterval(){ return maxInterval; } /** * Gets the date-time field of the maximum interval. * * @return The maximum interval field. */ public final DateField getMaxIntervalField(){ return maxIntervalField; } /** * <p>Sets the maximum interval <b>in minutes</b> from the initialization to the destruction of the concerned job.</p> * * <p> * <i><u>Note:</u> * If there was a maximum destruction time, it is reset and so the given interval will be used by {@link #getMaxDestructionTime()}. * </i> * </p> * * @param maxDestructionInterval The maximum destruction interval ({@link #NO_INTERVAL}, 0 or a negative value mean the job may stay forever). * * @see #setMaxDestructionInterval(int, DateField) */ public final void setMaxDestructionInterval(int maxDestructionInterval){ setMaxDestructionInterval(maxDestructionInterval, DateField.MINUTE); } /** * <p>Sets the maximum interval (in the given unit) from the initialization to the destruction of the concerned job.</p> * * <p> * <i><u>Note:</u> * If there was a maximum destruction time, it is reset and so the given interval will be used by {@link #getMaxDestructionTime()}. * </i> * </p> * * @param maxDestructionInterval The maximum destruction interval ({@link #NO_INTERVAL}, 0 or a negative value mean the job may stay forever). * @param timeField The unit of the interval (<i>null</i> means the job may stay forever). */ public final void setMaxDestructionInterval(int maxDestructionInterval, DateField timeField){ if (maxDestructionInterval <= 0 || timeField == null){ this.maxInterval = NO_INTERVAL; maxIntervalField = null; maxTime = null; }else{ this.maxInterval = maxDestructionInterval; maxIntervalField = timeField; maxTime = null; } } /** * Tells whether the destruction time of any managed job can be modified. * * @return <i>true</i> if the destruction time can be modified, <i>false</i> otherwise. */ @Override public final boolean allowModification(){ return allowModification; } /** * Lets indicating whether the destruction time of any managed job can be modified. * * @param allowModification <i>true</i> if the destruction time can be modified, <i>false</i> otherwise. */ public final void allowModification(boolean allowModification){ this.allowModification = allowModification; } }