From 855a805b49bae26467f199a948e87913aed186e0 Mon Sep 17 00:00:00 2001
From: gmantele <gmantele@ari.uni-heidelberg.de>
Date: Fri, 2 Mar 2018 12:25:29 +0100
Subject: [PATCH] [UWS] Fix the quote serialization.

The UWS-1.x standard defines the quote as an ISO-8601 date. UWS-Lib stores it
as a number of seconds (i.e. estimated job duration).

This fix ensures that this integer/long quote value is returned as a date.

Note: The backup and restoration processes are not affected by this change.
      The backup file format is still the same: a quote stored as a long value.
---
 src/org/json/Json4Uws.java                    | 12 ++++---
 src/uws/job/UWSJob.java                       | 33 ++++++++++++-------
 src/uws/job/serializer/JSONSerializer.java    | 11 +++++--
 src/uws/job/serializer/UWSSerializer.java     | 15 +++++++--
 src/uws/job/serializer/XMLSerializer.java     | 12 ++++---
 .../backup/DefaultUWSBackupManager.java       |  7 ++--
 6 files changed, 62 insertions(+), 28 deletions(-)

diff --git a/src/org/json/Json4Uws.java b/src/org/json/Json4Uws.java
index 25a85c6..11d64ae 100644
--- a/src/org/json/Json4Uws.java
+++ b/src/org/json/Json4Uws.java
@@ -16,7 +16,7 @@ package org.json;
  * 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-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2018 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -38,7 +38,7 @@ import uws.service.UWSUrl;
  * Useful conversion functions from UWS to JSON.
  *
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.3 (10/2017)
+ * @version 4.3 (03/2018)
  */
 public final class Json4Uws {
 
@@ -175,9 +175,13 @@ public final class Json4Uws {
 					json.put("href", jobsListUrl.getRequestURL());
 				}
 			}else{
-				json.put(UWSJob.PARAM_QUOTE, job.getQuote());
-				if (job.getStartTime() != null)
+				if (job.getStartTime() != null){
+					if (job.getQuote() > 0){
+						long quoteTime = job.getStartTime().getTime() + (1000 * job.getQuote());
+						json.put(UWSJob.PARAM_QUOTE, ISO8601Format.format(quoteTime));
+					}
 					json.put(UWSJob.PARAM_START_TIME, ISO8601Format.format(job.getStartTime()));
+				}
 				if (job.getEndTime() != null)
 					json.put(UWSJob.PARAM_END_TIME, ISO8601Format.format(job.getEndTime()));
 				if (job.getDestructionTime() != null)
diff --git a/src/uws/job/UWSJob.java b/src/uws/job/UWSJob.java
index 84c68ad..d13cc22 100644
--- a/src/uws/job/UWSJob.java
+++ b/src/uws/job/UWSJob.java
@@ -16,7 +16,7 @@ package uws.job;
  * 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-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2018 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -88,7 +88,9 @@ import uws.service.request.UploadFile;
  * 		If your job is executable, do not forget to set the <i>quote</i>
  * 		parameter ONLY by using the {@link #setQuote(long)} method (a negative
  * 		value or {@link #QUOTE_NOT_KNOWN} value indicates the quote is not
- * 		known ; {@link #QUOTE_NOT_KNOWN} is the default value).
+ * 		known ; {@link #QUOTE_NOT_KNOWN} is the default value). This duration in
+ * 		seconds will be added to the <i>startTime</i> and then automatically
+ * 		formatted into an ISO-8601 date by the used serializer.
  * 	</li>
  * </ul>
  *
@@ -128,7 +130,7 @@ import uws.service.request.UploadFile;
  * </ul>
  *
  * @author	Gr&eacute;gory Mantelet (CDS;ARI)
- * @version	4.3 (09/2017)
+ * @version	4.3 (03/2018)
  */
 public class UWSJob extends SerializableUWSObject {
 	private static final long serialVersionUID = 1L;
@@ -273,10 +275,13 @@ public class UWSJob extends SerializableUWSObject {
 	public static final DateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
 
 	/**
-	 * This time (in seconds) predicts when the job is likely to complete.
-	 * <p><b>WARNING:</b>
-	 * 	It CAN NOT be changed after the job creation!
-	 * 	By default if no ID is given, {@link #quote} is set to
+	 * This time predicts when the job is likely to complete.
+	 * <p>
+	 * 	It represents the estimated amount of time (in seconds) from the
+	 * 	job starting date-time to its successful end.
+	 * </p>
+	 * <p><i>Note:</i>
+	 * 	By default, if no ID is given, {@link #quote} is set to
 	 * 	{@link #QUOTE_NOT_KNOWN} (= {@value #QUOTE_NOT_KNOWN}).
 	 * </p>
 	 */
@@ -1055,14 +1060,18 @@ public class UWSJob extends SerializableUWSObject {
 	}
 
 	/**
-	 * Sets the quote attribute of this job ONLY IF the job can updated
-	 * (considering its current execution phase, see
-	 * {@link JobPhase#isJobUpdatable()}).
+	 * Sets the quote attribute of this job ONLY IF the job is not yet
+	 * finished according to its current status (i.e.
+	 * {@link JobPhase#isFinished()}).
+	 *
+	 * <p><i>Note:</i>
+	 * 	A negative or NULL value will be considered as 'no quote for this job'.
+	 * 	One could use the constant {@link #QUOTE_NOT_KNOWN}
+	 * 	(= {@value #QUOTE_NOT_KNOWN}) for this exact purpose.
+	 * </p>
 	 *
 	 * @param nbSeconds	The estimated duration of the job execution
 	 *                 	(in seconds).
-	 *
-	 * @see JobPhase#isJobUpdatable()
 	 */
 	public final void setQuote(long nbSeconds){
 		if (!phase.isFinished())
diff --git a/src/uws/job/serializer/JSONSerializer.java b/src/uws/job/serializer/JSONSerializer.java
index fbc30e9..e52a04c 100644
--- a/src/uws/job/serializer/JSONSerializer.java
+++ b/src/uws/job/serializer/JSONSerializer.java
@@ -16,7 +16,7 @@ package uws.job.serializer;
  * 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-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2018 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -37,7 +37,7 @@ import uws.service.UWSUrl;
  * Lets serializing any UWS resource in JSON.
  *
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.3 (10/2017)
+ * @version 4.3 (03/2018)
  *
  * @see Json4Uws
  */
@@ -94,7 +94,12 @@ public class JSONSerializer extends UWSSerializer {
 
 	@Override
 	public String getQuote(final UWSJob job, final boolean root) throws JSONException{
-		return Json4Uws.getJson(UWSJob.PARAM_QUOTE, job.getQuote()).toString();
+		String quoteDate = null;
+		if (job.getStartTime() != null && job.getQuote() > 0){
+			long quoteTime = job.getStartTime().getTime() + (1000 * job.getQuote());
+			quoteDate = ISO8601Format.format(quoteTime);
+		}
+		return Json4Uws.getJson(UWSJob.PARAM_QUOTE, quoteDate).toString();
 	}
 
 	@Override
diff --git a/src/uws/job/serializer/UWSSerializer.java b/src/uws/job/serializer/UWSSerializer.java
index f7cf1a8..bd7141d 100644
--- a/src/uws/job/serializer/UWSSerializer.java
+++ b/src/uws/job/serializer/UWSSerializer.java
@@ -343,9 +343,20 @@ public abstract class UWSSerializer implements Serializable {
 	/**
 	 * Serializes the quote of the given job.
 	 *
+	 * <p><b>Warning!</b>
+	 * 	{@link UWSJob#getQuote()} is a long, BUT the UWS standard explicitly
+	 * 	requires a quote as an ISO-8601 date (cf section "2.2.1. Resources and
+	 * 	URIs").<br/>
+	 * 	<b>This function MUST return a quote only when the job is
+	 * 	started/finished and MUST add the quote duration to the startTime and
+	 * 	format it as an ISO-8601 date.</b>
+	 * </p>
+	 *
 	 * @param job			The job whose the quote must be serialized.
-	 * @param root			<i>false</i> if the quote to serialize will be included
-	 * 						in a top level serialization (for a quote: job), <i>true</i> otherwise.
+	 * @param root			<i>false</i> if the quote to serialize will be
+	 *            			included in a top level serialization (for a quote:
+	 *            			job),
+	 *            			<i>true</i> otherwise.
 	 *
 	 * @return				The serialization of the quote.
 	 *
diff --git a/src/uws/job/serializer/XMLSerializer.java b/src/uws/job/serializer/XMLSerializer.java
index b44bdf3..289edc8 100644
--- a/src/uws/job/serializer/XMLSerializer.java
+++ b/src/uws/job/serializer/XMLSerializer.java
@@ -16,7 +16,7 @@ package uws.job.serializer;
  * 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-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2018 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -41,7 +41,7 @@ import uws.service.request.UploadFile;
  * Lets serializing any UWS resource in XML.
  *
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.3 (10/2017)
+ * @version 4.3 (03/2018)
  */
 public class XMLSerializer extends UWSSerializer {
 	private static final long serialVersionUID = 1L;
@@ -324,10 +324,12 @@ public class XMLSerializer extends UWSSerializer {
 	public String getQuote(final UWSJob job, final boolean root){
 		StringBuffer xml = new StringBuffer(root ? getHeader() : "");
 		xml.append("<quote").append(getUWSNamespace(root));
-		if (job.getQuote() <= 0)
+		if (job.getStartTime() == null || job.getQuote() <= 0)
 			xml.append(" xsi:nil=\"true\" />");
-		else
-			xml.append('>').append(job.getQuote()).append("</quote>");
+		else{
+			long quoteTime = job.getStartTime().getTime() + (1000 * job.getQuote());
+			xml.append('>').append(ISO8601Format.format(quoteTime)).append("</quote>");
+		}
 		return xml.toString();
 	}
 
diff --git a/src/uws/service/backup/DefaultUWSBackupManager.java b/src/uws/service/backup/DefaultUWSBackupManager.java
index 327f142..6b52b3c 100644
--- a/src/uws/service/backup/DefaultUWSBackupManager.java
+++ b/src/uws/service/backup/DefaultUWSBackupManager.java
@@ -16,7 +16,7 @@ package uws.service.backup;
  * 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-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2018 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -87,7 +87,7 @@ import uws.service.request.UploadFile;
  * <p>Another positive value will be considered as the frequency (in milliseconds) of the automatic backup (= {@link #saveAll()}).</p>
  *
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.3 (09/2017)
+ * @version 4.3 (03/2018)
  */
 public class DefaultUWSBackupManager implements UWSBackupManager {
 
@@ -549,6 +549,9 @@ public class DefaultUWSBackupManager implements UWSBackupManager {
 	protected JSONObject getJSONJob(final UWSJob job, final String jlName) throws UWSException, JSONException{
 		JSONObject jsonJob = Json4Uws.getJson(job);
 
+		// Only for the backup, the quote must be stored as a nb of seconds:
+		jsonJob.put(UWSJob.PARAM_QUOTE, job.getQuote());
+
 		// Re-Build the parameters map, by separating the uploads and the "normal" parameters:
 		JSONArray uploads = new JSONArray();
 		JSONObject params = new JSONObject();
-- 
GitLab