Commit 0467dbb1 authored by gmantele's avatar gmantele
Browse files

[UWS] Add the new Execution Phase `ARCHIVED` and check phase transitions.

A JUnit test case has been added in order to check that all possible phase
transitions are respecting the UWS-1.1 standard. However, there is anyway
a bit more freedom for some of them:

    - it is possible to go to and come from UNKNOWN at any time, whatever is
	  the source or target phase.

	- it is possible to go to ERROR or ABORTED from the phases HELD and
	  SUSPENDED. This fact was not specified in the State Machine figure of the
	  UWS standard but the following sentence at section
	  "2.1.3 Execution Phase" (page 7) should allow that:
	  "At any time before the COMPLETED phase a job may either be ABORTED or
	   may suffer an ERROR."

	- the UWS-1.1 document has an inconsistency about the HELD phase. At
	  section "2.1.3 Execution Phase" (page 7), the following sentence implies
	  that it is only possible to go to HELD from PENDING (because it would not
	  be possible to queue the job). And so, when PHASE=RUN is sent by the UWS
      client, if now possible, the job should go in phase QUEUED. However the
	  State Machine figure suggests that it is possible to go to HELD only from
	  EXECUTING and that a PHASE=RUN would make the job go back to EXECUTING (if
	  now possible). Because of this inconsistency, the UWSLibrary made possible
	  the following transitions: PENDING/EXECUTING->HELD->QUEUED/EXECUTING.

(note: a figure illustrating the phase transitions supported by the
       UWSLibrary-4.3 has been created in the directory `img` of the
	   UWS-Tutorial website under the file name `state_machine.png`...which of
	   course will be visible only when uwslib-4.3 will be released)

Besides, this commit also include almost a full rewriting of the Javadoc of
JobPhase and ExecutionPhase. The Javadoc of UWSJob has just been reformated
so that comments do not exceed 80 (+2) characters. This reformating aims to
improve the human reading of the Javadoc while looking at the source files ;
however this should not affect much the HTML version of the Javadoc.
parent a8d98f64
Loading
Loading
Loading
Loading
+14 −14
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ package uws;
 * 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),
 * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 *                       Astronomisches Rechen Institut (ARI)
 */

@@ -27,7 +27,7 @@ import uws.job.user.JobOwner;
 * Let's creating the common exceptions of a UWS service.
 *
 * @author Gr&eacute;gory Mantelet (CDS;ARI)
 * @version 4.1 (09/2014)
 * @version 4.3 (09/2017)
 *
 * @see UWSException
 */
+185 −41
Original line number Diff line number Diff line
@@ -16,56 +16,200 @@ 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
 * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 *                       Astronomisches Rechen Institut (ARI)
 */

/**
 * <p>A job is treated as a state machine where the Execution Phase is the job state. The phases are:</p>
 * <ul>
 *	<li>{@link #PENDING}: 	the job is accepted by the service but not yet committed for
 *          				execution by the client. In this state, the job quote can be read
 *          				and evaluated. This is the state into which a job enters when it
 *          				is first created.</li>
 * A job is treated as a state machine where the Execution Phase is the job
 * state. This enum class gathers all Execution Phases declared by the IVOA
 * since UWS-1.1.
 *
 *	<li>{@link #QUEUED}: 	the job is committed for execution by the client but the service
 *         					has not yet assigned it to a processor. No Results are produced in
 *         					this phase.</li>
 * <p>
 * 	The transitions of the state machine described by the IVOA are implemented
 * 	in a different class: {@link JobPhase}.
 * </p>
 *
 *	<li>{@link #EXECUTING}: the job has been assigned to a processor. Results may be produced
 *            				at any time during this phase.</li>
 * @see JobPhase
 *
 *	<li>{@link #COMPLETED}: the execution of the job is over. The Results may be collected.</li>
 * @author Gr&eacute;gory Mantelet (CDS;ARI)
 * @version 4.3 (09/2017)
 */
public enum ExecutionPhase{
	/**
	 * The job is accepted by the service but not yet committed for execution by
	 * the client. In this state, the job quote can be read and evaluated. This
	 * is the state into which a job enters when it is first created.
	 *
	 * <p><b>Allowed previous phases:</b> <i>none</i>.</p>
	 *
	 * <p><b>Possible next phases:</b>
	 * 	{@link #HELD}, {@link #QUEUED}, {@link #ABORTED} or {@link #ERROR}.
	 * </p>
	 */
	PENDING,
	/**
	 * The job is committed for execution by the client but the service has not
	 * yet assigned it to a processor. No Results are produced in this phase.
	 *
	 * <p><b>Allowed previous phases:</b>
	 * 	{@link #PENDING} or {@link #HELD}.
	 * </p>
	 *
	 * <p><b>Possible next phases:</b>
	 * 	{@link #EXECUTING}, {@link #ABORTED} or {@link #ERROR}.
	 * </p>
	 */
	QUEUED,
	/**
	 * The job has been assigned to a processor. Results may be produced at any
	 * time during this phase.
	 *
	 * <p><b>Allowed previous phases:</b>
	 * 	{@link #QUEUED}, {@link #HELD} or {@link #SUSPENDED}.
	 * </p>
	 *
 *	<li>{@link #ERROR}: 	the job failed to complete. No further work will be done nor Results
	 * <p><b>Possible next phases:</b>
	 * 	{@link #HELD}, {@link #SUSPENDED}, {@link #COMPLETED}, {@link #ABORTED}
	 * 	or {@link #ERROR}.
	 * </p>
	 */
	EXECUTING,
	/**
	 * The execution of the job is over. The Results may be collected.
	 *
	 * <p><b>Allowed previous phases:</b>
	 * 	{@link #EXECUTING}.
	 * </p>
	 *
	 * <p><b>Possible next phases:</b>
	 * 	{@link #ARCHIVED}.
	 * </p>
	 */
	COMPLETED,
	/**
	 * The job failed to complete. No further work will be done nor Results
	 * produced. Results may be unavailable or available but invalid; either
 *        					way the Results should not be trusted.</li>
	 * way the Results should not be trusted.
	 *
 *	<li>{@link #ABORTED}: 	the job has been manually aborted by the user, or the system has
 *          				aborted the job due to lack of or overuse of resources.</li>
	 * <p><b>Allowed previous phases:</b>
	 * 	{@link #EXECUTING}, {@link #QUEUED} or {@link #PENDING}.
	 * </p>
	 *
 *	<li>{@link #UNKNOWN}: 	the job is in an unknown state.</li>
	 * <p><b>Possible next phases:</b>
	 * 	{@link #ARCHIVED}.
	 * </p>
	 */
	ERROR,
	/**
	 * The job has been manually aborted by the user, or the system has aborted
	 * the job due to lack of or overuse of resources.
	 *
	 * <p><b>Allowed previous phases:</b>
	 * 	{@link #PENDING}, {@link #QUEUED}, {@link #EXECUTING}, {@link #HELD} or
	 * 	{@link #SUSPENDED}.
	 * </p>
	 *
 *	<li>{@link #HELD}: 		The job is HELD pending execution and will not automatically be
 *      	 				executed (cf pending).</li>
	 * <p><b>Possible next phases:</b>
	 * 	{@link #ARCHIVED}.
	 * </p>
	 */
	ABORTED,
	/**
	 * The job is in an unknown state.
	 *
 *	<li>{@link #SUSPENDED}:	The job has been suspended by the system during execution. This might
 *							be because of temporary lack of resource. The UWS will automatically
 *							resume the job into the EXECUTING phase without any intervention
 *							when resource becomes available.</li>
 * </ul>
	 * <p><i>Note:
	 * 	If the UWS reports an UNKNOWN phase, then all the client can do is
	 * 	re-query the phase until a known phase is reported.
	 * </i></p>
	 *
 * @see UWSJob
	 * <p><b>Allowed previous phases:</b> <i>any</i>.</p>
	 *
 * @author Gr&eacute;gory Mantelet (CDS)
 * @version 02/2011
	 * <p><b>Possible next phases:</b> <i>any</i>.</p>
	 */
public enum ExecutionPhase{
	PENDING, QUEUED, EXECUTING, COMPLETED, ERROR, ABORTED, UNKNOWN, HELD, SUSPENDED;
	UNKNOWN,
	/**
	 * The job is HELD pending execution and will not automatically be executed
	 * (cf {@link #PENDING}).
	 *
	 * <p><i>Note:
	 * 	A UWS may place a job in a HELD phase on receipt of a PHASE=RUN request
	 * 	if for some reason the job cannot be immediately queued - in this case
	 * 	it is the responsibility of the client to request PHASE=RUN again at
	 * 	some later time.
	 * </i></p>
	 *
	 * <p><b>Allowed previous phases:</b>
	 * 	{@link #PENDING} or {@link #EXECUTING}.
	 * </p>
	 *
	 * <p><b>Possible next phases:</b>
	 * 	{@link #QUEUED}, {@link #EXECUTING}, {@link #ABORTED} or {@link #ERROR}.
	 * </p>
	 */
	HELD,
	/**
	 * The job has been suspended by the system during execution. This might be
	 * because of temporary lack of resource. The UWS will automatically resume
	 * the job into the EXECUTING phase without any intervention when resource
	 * becomes available.
	 *
	 * <p><b>Allowed previous phases:</b>
	 * 	{@link #EXECUTING}.
	 * </p>
	 *
	 * <p><b>Possible next phases:</b>
	 * 	{@link #EXECUTING}, {@link #ABORTED} or {@link #ERROR}.
	 * </p>
	 */
	SUSPENDED,
	/**
	 * At destruction time the results associated with a job have been deleted
	 * to free up resource, but the metadata associated with the job have been
	 * retained. This is an alternative that the server may choose in contrast
	 * to completely destroying all record of the job to allow a longer
	 * historical record of the existence of the job to be kept that would
	 * otherwise be the case if limited result storage resources forces
	 * destruction.
	 *
	 * <p><b>Allowed previous phases:</b>
	 * 	{@link #ABORTED}, {@link #COMPLETED} or {@link #ERROR}.
	 * </p>
	 *
	 * <p><b>Possible next phases:</b> <i>none</i>.</p>
	 *
	 * @since 4.3 */
	ARCHIVED;

	/**
	 * Get the label of the given Execution Phase.
	 *
	 * <p><i>Note:
	 * 	The reverse operation is {@link #getPhase(String)}.
	 * </i></p>
	 *
	 * @param ph	An Execution Phase.
	 *
	 * @return	The label of the given phase,
	 *        	or {@link #UNKNOWN} if NULL is given.
	 */
	public static final String getStr(ExecutionPhase ph){
		return (ph == null) ? ExecutionPhase.UNKNOWN.name() : ph.name();
	}

	/**
	 * Get the Execution Phase corresponding to the given label.
	 *
	 * <p><i>Note:
	 * 	The reverse operation is {@link #getStr(ExecutionPhase)}.
	 * </i></p>
	 *
	 * @param phStr	Label of the Execution Phase to resolve.
	 *
	 * @return	The corresponding {@link ExecutionPhase},
	 *        	or {@link #UNKNOWN} if the given String is NULL
	 *        	                    or does not match any legal Execution Phase.
	 */
	public static final ExecutionPhase getPhase(String phStr){
		try{
			return valueOf(phStr);
+175 −123
Original line number Diff line number Diff line
@@ -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,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
 *                       Astronomisches Rechen Institut (ARI)
 */

@@ -26,11 +26,11 @@ import uws.UWSException;
import uws.UWSExceptionFactory;

/**
 * An instance of this class represents the current execution phase of a given job,
 * and it describes the transitions between the different phases.
 * An instance of this class represents the current execution phase of a given
 * job, and it describes the transitions between the different phases.
 *
 * @author Gr&eacute;gory Mantelet (CDS;ARI)
 * @version 4.1 (08/2014)
 * @version 4.3 (09/2017)
 *
 * @see ExecutionPhase
 * @see UWSJob
@@ -47,7 +47,8 @@ public class JobPhase implements Serializable {
	/**
	 * Builds the phase manager of the given job.
	 *
	 * @param j				The job whose the execution phase must be represented by the built JobPhase instance.
	 * @param j	The job whose the execution phase must be represented by the
	 *         	built JobPhase instance.
	 *
	 * @throws NullPointerException	If the given job is <i>null</i>.
	 */
@@ -76,11 +77,13 @@ public class JobPhase implements Serializable {
	}

	/**
	 * Lets changing the current phase of the associated job considering the order of execution phases.
	 * Lets changing the current phase of the associated job considering the
	 * order of execution phases.
	 *
	 * @param p	The new execution phase.
	 *
	 * @throws UWSException	If the given phase is <i>null</i> or if the phase transition is forbidden.
	 * @throws UWSException	If the given phase is <i>null</i> or if the phase
	 *                     	transition is forbidden.
	 *
	 * @see #setPhase(ExecutionPhase, boolean)
	 */
@@ -89,14 +92,16 @@ public class JobPhase implements Serializable {
	}

	/**
	 * <p>Lets changing the current phase of the associated job considering or not the order of execution phases.</p>
	 * Lets changing the current phase of the associated job considering or
	 * not the order of execution phases.
	 *
	 * <p><i>Note:
	 * 	If the given phase is <i>null</i>, nothing is done.
	 * </i></p>
	 *
	 * @param p		The new phase.
	 * @param force			<i>true</i> to ignore the phases order, <i>false</i> otherwise.
	 * @param force	<i>true</i> to ignore the phases order,
	 *             	<i>false</i> otherwise.
	 *
	 * @throws UWSException	If the phase transition is forbidden.
	 *
@@ -108,6 +113,7 @@ public class JobPhase implements Serializable {
	 * @see #setErrorPhase(boolean)
	 * @see #setHeldPhase(boolean)
	 * @see #setSuspendedPhase(boolean)
	 * @see #setArchivedPhase(boolean)
	 * @see #setUnknownPhase(boolean)
	 */
	public void setPhase(ExecutionPhase p, boolean force) throws UWSException{
@@ -140,6 +146,9 @@ public class JobPhase implements Serializable {
			case SUSPENDED:
				setSuspendedPhase(force);
				break;
			case ARCHIVED:
				setArchivedPhase(force);
				break;
			case UNKNOWN:
			default:
				setUnknownPhase(force);
@@ -150,116 +159,117 @@ public class JobPhase implements Serializable {
	/**
	 * Changes the current phase to {@link ExecutionPhase#PENDING PENDING}.
	 *
	 * @param force			<i>true</i> to ignore the phases order, <i>false</i> otherwise.
	 * @param force	<i>true</i> to ignore the phases order,
	 *             	<i>false</i> otherwise.
	 *
	 * @throws UWSException	If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase != PENDING or UNKNOWN)</i>.
	 * @throws UWSException	If this phase transition is forbidden
	 *                     	<i>(by default: IF force=false
	 *                     	AND currentPhase != PENDING and UNKNOWN)</i>.
	 */
	protected void setPendingPhase(boolean force) throws UWSException{
		if (!force && phase != ExecutionPhase.PENDING && phase != ExecutionPhase.UNKNOWN)
			throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.PENDING));

		phase = ExecutionPhase.PENDING;
	}

	/**
	 * Changes the current phase to {@link ExecutionPhase#QUEUED QUEUED}.
	 *
	 * @param force			<i>true</i> to ignore the phases order, <i>false</i> otherwise.
	 * @param force	<i>true</i> to ignore the phases order,
	 *             	<i>false</i> otherwise.
	 *
	 * @throws UWSException	If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase != QUEUED or HELD or PENDING or UNKNOWN)</i>.
	 * @throws UWSException	If this phase transition is forbidden
	 *                     	<i>(by default: IF force=false
	 *                     	AND currentPhase != QUEUED, HELD, PENDING
	 *                     	                    and UNKNOWN)</i>.
	 */
	protected void setQueuedPhase(boolean force) throws UWSException{
		if (force)
			phase = ExecutionPhase.QUEUED;
		else{
			if (phase != ExecutionPhase.QUEUED && phase != ExecutionPhase.HELD && phase != ExecutionPhase.PENDING && phase != ExecutionPhase.UNKNOWN)
		if (!force && phase != ExecutionPhase.QUEUED && phase != ExecutionPhase.HELD && phase != ExecutionPhase.PENDING && phase != ExecutionPhase.UNKNOWN)
			throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.QUEUED));

		phase = ExecutionPhase.QUEUED;
	}
	}

	/**
	 * Changes the current phase to {@link ExecutionPhase#EXECUTING EXECUTING}.
	 *
	 * @param force			<i>true</i> to ignore the phases order, <i>false</i> otherwise.
	 * @param force	<i>true</i> to ignore the phases order,
	 *             	<i>false</i> otherwise.
	 *
	 * @throws UWSException	If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase != EXECUTING or SUSPENDED or QUEUED or UNKNOWN)</i>.
	 * @throws UWSException	If this phase transition is forbidden
	 *                     	<i>(by default: IF force=false
	 *                     	AND currentPhase != EXECUTING, HELD, SUSPENDED,
	 *                     	                    QUEUED and UNKNOWN)</i>.
	 */
	protected void setExecutingPhase(boolean force) throws UWSException{
		if (force)
			phase = ExecutionPhase.EXECUTING;
		else{
			if (phase != ExecutionPhase.EXECUTING && phase != ExecutionPhase.SUSPENDED && phase != ExecutionPhase.PENDING && phase != ExecutionPhase.QUEUED && phase != ExecutionPhase.UNKNOWN)
		if (!force && phase != ExecutionPhase.EXECUTING && phase != ExecutionPhase.HELD && phase != ExecutionPhase.SUSPENDED && phase != ExecutionPhase.QUEUED && phase != ExecutionPhase.UNKNOWN)
			throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.EXECUTING));

		phase = ExecutionPhase.EXECUTING;
	}
	}

	/**
	 * Changes the current phase to {@link ExecutionPhase#COMPLETED COMPLETED}.
	 *
	 * @param force			<i>true</i> to ignore the phases order, <i>false</i> otherwise.
	 * @param force	<i>true</i> to ignore the phases order,
	 *             	<i>false</i> otherwise.
	 *
	 * @throws UWSException	If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase != COMPLETED or EXECUTING or UNKNOWN)</i>.
	 * @throws UWSException	If this phase transition is forbidden
	 *                     	<i>(by default: IF force=false
	 *                     	AND currentPhase != COMPLETED, EXECUTING
	 *                     	                    and UNKNOWN)</i>.
	 */
	protected void setCompletedPhase(boolean force) throws UWSException{
		if (force)
			phase = ExecutionPhase.COMPLETED;
		else{
			if (phase != ExecutionPhase.COMPLETED && phase != ExecutionPhase.EXECUTING && phase != ExecutionPhase.UNKNOWN)
		if (!force && phase != ExecutionPhase.COMPLETED && phase != ExecutionPhase.EXECUTING && phase != ExecutionPhase.UNKNOWN)
			throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.COMPLETED));

		phase = ExecutionPhase.COMPLETED;
	}
	}

	/**
	 * Changes the current phase to {@link ExecutionPhase#ABORTED ABORTED}.
	 *
	 * @param force			<i>true</i> to ignore the phases order, <i>false</i> otherwise.
	 * @param force	<i>true</i> to ignore the phases order,
	 *             	<i>false</i> otherwise.
	 *
	 * @throws UWSException	If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase = COMPLETED or ERROR)</i>.
	 * @throws UWSException	If this phase transition is forbidden
	 *                     	<i>(by default: IF force=false
	 *                     	AND currentPhase = COMPLETED, ERROR
	 *                     	                   or ARCHIVED)</i>.
	 */
	protected void setAbortedPhase(boolean force) throws UWSException{
		if (force)
			phase = ExecutionPhase.ABORTED;
		else{
			if (phase == ExecutionPhase.COMPLETED || phase == ExecutionPhase.ERROR)
		if (!force && (phase == ExecutionPhase.COMPLETED || phase == ExecutionPhase.ERROR || phase == ExecutionPhase.ARCHIVED))
			throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.ABORTED));

		phase = ExecutionPhase.ABORTED;
	}
	}

	/**
	 * Changes the current phase to {@link ExecutionPhase#ERROR ERROR}.
	 *
	 * @param force			<i>true</i> to ignore the phases order, <i>false</i> otherwise.
	 * @param force	<i>true</i> to ignore the phases order,
	 *             	<i>false</i> otherwise.
	 *
	 * @throws UWSException	If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase = COMPLETED or ABORTED)</i>.
	 * @throws UWSException	If this phase transition is forbidden
	 *                     	<i>(by default: IF force=false
	 *                     	AND currentPhase = COMPLETED, ABORTED
	 *                     	                   or ARCHIVED)</i>.
	 */
	protected void setErrorPhase(boolean force) throws UWSException{
		if (force)
			phase = ExecutionPhase.ERROR;
		else{
			if (phase == ExecutionPhase.COMPLETED || phase == ExecutionPhase.ABORTED)
		if (!force && (phase == ExecutionPhase.COMPLETED || phase == ExecutionPhase.ABORTED || phase == ExecutionPhase.ARCHIVED))
			throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.ERROR));

		phase = ExecutionPhase.ERROR;
	}
	}

	/**
	 * Changes the current phase to {@link ExecutionPhase#HELD HELD}.
	 *
	 * @param force			<i>true</i> to ignore the phases order, <i>false</i> otherwise.
	 * @param force	<i>true</i> to ignore the phases order,
	 *             	<i>false</i> otherwise.
	 *
	 * @throws UWSException	If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase != HELD or PENDING or UNKNOWN)</i>.
	 * @throws UWSException	If this phase transition is forbidden
	 *                     	<i>(by default: IF force=false
	 *                     	AND currentPhase != HELD, PENDING, EXECUTING
	 *                     	                    and UNKNOWN)</i>.
	 */
	protected void setHeldPhase(boolean force) throws UWSException{
		if (!force && phase != ExecutionPhase.HELD && phase != ExecutionPhase.PENDING && phase != ExecutionPhase.UNKNOWN)
		if (!force && phase != ExecutionPhase.HELD && phase != ExecutionPhase.PENDING && phase != ExecutionPhase.EXECUTING && phase != ExecutionPhase.UNKNOWN)
			throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.HELD));
		phase = ExecutionPhase.HELD;
	}
@@ -267,18 +277,44 @@ public class JobPhase implements Serializable {
	/**
	 * Changes the current phase to {@link ExecutionPhase#SUSPENDED SUSPENDED}.
	 *
	 * @param force			<i>true</i> to ignore the phases order, <i>false</i> otherwise.
	 * @param force	<i>true</i> to ignore the phases order,
	 *             	<i>false</i> otherwise.
	 *
	 * @throws UWSException	By default, never !
	 * @throws UWSException	If this phase transition is forbidden
	 *                     	<i>(by default: IF force=false
	 *                     	AND currentPhase != SUSPENDED, EXECUTING
	 *                     	                    and UNKNOWN)</i>.
	 */
	protected void setSuspendedPhase(boolean force) throws UWSException{
		if (!force && phase != ExecutionPhase.SUSPENDED && phase != ExecutionPhase.EXECUTING && phase != ExecutionPhase.UNKNOWN)
			throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.SUSPENDED));
		phase = ExecutionPhase.SUSPENDED;
	}

	/**
	 * Changes the current phase to {@link ExecutionPhase#ARCHIVED ARCHIVED}.
	 *
	 * @param force	<i>true</i> to ignore the phases order,
	 *             	<i>false</i> otherwise.
	 *
	 * @throws UWSException	If this phase transition is forbidden
	 *                     	<i>(by default: IF force=false
	 *                     	AND currentPhase != ARCHIVED, COMPLETED, ABORTED,
	 *                     	                    and UNKNOWN)</i>.
	 *
	 * @since 4.3
	 */
	protected void setArchivedPhase(boolean force) throws UWSException{
		if (!force && phase != ExecutionPhase.ARCHIVED && phase != ExecutionPhase.COMPLETED && phase != ExecutionPhase.ABORTED && phase != ExecutionPhase.ERROR && phase != ExecutionPhase.UNKNOWN)
			throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.ARCHIVED));
		phase = ExecutionPhase.ARCHIVED;
	}

	/**
	 * Changes the current phase to {@link ExecutionPhase#UNKNOWN UNKNOWN}.
	 *
	 * @param force			<i>true</i> to ignore the phases order, <i>false</i> otherwise.
	 * @param force	<i>true</i> to ignore the phases order,
	 *             	<i>false</i> otherwise.
	 *
	 * @throws UWSException	By default, never!
	 */
@@ -287,34 +323,50 @@ public class JobPhase implements Serializable {
	}

	/**
	 * <p>Indicates whether the job attributes (except errors and results) can be updated, considering its current phase.</p>
	 * Indicates whether the job attributes (except errors and results) can be
	 * updated, considering its current phase.
	 *
	 * <p><i><u>Note:</u> By default, it returns TRUE only if the current phase is equals to {@link ExecutionPhase#PENDING PENDING} !</i></p>
	 * <p><i>Note:
	 * 	By default, it returns TRUE only if the current phase is equals to
	 * 	{@link ExecutionPhase#PENDING PENDING}!
	 * </i></p>
	 *
	 * @return	<i>true</i> if the job can be updated, <i>false</i> otherwise.
	 * @return	<i>true</i> if the job can be updated,
	 *        	<i>false</i> otherwise.
	 */
	public boolean isJobUpdatable(){
		return phase == ExecutionPhase.PENDING;
	}

	/**
	 * <p>Indicates whether the job is finished or not, considering its current phase.</p>
	 * Indicates whether the job is finished or not, considering its current
	 * phase.
	 *
	 * <p><i><u>Note:</u> By default, it returns TRUE only if the current phase is either {@link ExecutionPhase#COMPLETED COMPLETED},
	 * {@link ExecutionPhase#ABORTED ABORTED} or {@link ExecutionPhase#ERROR ERROR} !</i></p>
	 * <p><i>Note:
	 * 	By default, it returns TRUE only if the current phase is either
	 * 	{@link ExecutionPhase#COMPLETED COMPLETED},
	 * 	{@link ExecutionPhase#ABORTED ABORTED},
	 * 	{@link ExecutionPhase#ERROR ERROR}
	 * 	or {@link ExecutionPhase#ARCHIVED ARCHIVED}!
	 * </i></p>
	 *
	 * @return	<i>true</i> if the job is finished, <i>false</i> otherwise.
	 * @return	<i>true</i> if the job is finished,
	 *        	<i>false</i> otherwise.
	 */
	public boolean isFinished(){
		return phase == ExecutionPhase.COMPLETED || phase == ExecutionPhase.ABORTED || phase == ExecutionPhase.ERROR;
		return phase == ExecutionPhase.COMPLETED || phase == ExecutionPhase.ABORTED || phase == ExecutionPhase.ERROR || phase == ExecutionPhase.ARCHIVED;
	}

	/**
	 * <p>Indicates whether the job is executing, considering its current phase.</p>
	 * Indicates whether the job is executing, considering its current phase.
	 *
	 * <p><i><u>Note:</u> By default, it returns TRUE only if the current phase is {@link ExecutionPhase#EXECUTING EXECUTING} !</i></p>
	 * <p><i>Note:
	 * 	By default, it returns TRUE only if the current phase is
	 * 	{@link ExecutionPhase#EXECUTING EXECUTING}!
	 * </i></p>
	 *
	 * @return	<i>true</i> if the job is executing, <i>false</i> otherwise.
	 * @return	<i>true</i> if the job is executing,
	 *        	<i>false</i> otherwise.
	 */
	public boolean isExecuting(){
		return phase == ExecutionPhase.EXECUTING;
+478 −217

File changed.

Preview size limit exceeded, changes collapsed.

+648 −0

File added.

Preview size limit exceeded, changes collapsed.