diff --git a/src/uws/UWSExceptionFactory.java b/src/uws/UWSExceptionFactory.java index c88fff2d2239b65b025ebc48e455387cf3519106..f5321c77c686d385c1466e38c5d310021db9e623 100644 --- a/src/uws/UWSExceptionFactory.java +++ b/src/uws/UWSExceptionFactory.java @@ -2,21 +2,21 @@ package uws; /* * 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), + * + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -25,10 +25,10 @@ import uws.job.user.JobOwner; /** * Let's creating the common exceptions of a UWS service. - * + * * @author Grégory Mantelet (CDS;ARI) - * @version 4.1 (09/2014) - * + * @version 4.3 (09/2017) + * * @see UWSException */ public final class UWSExceptionFactory { @@ -54,7 +54,7 @@ public final class UWSExceptionFactory { } public final static String incorrectPhaseTransition(final String jobID, final ExecutionPhase fromPhase, final ExecutionPhase toPhase, final String consequence){ - return "Incorrect phase transition ! => the job " + jobID + " is in the phase " + fromPhase + ". It can not go to " + toPhase + "." + appendMessage(consequence); + return "Incorrect phase transition! => the job " + jobID + " is in the phase " + fromPhase + ". It can not go to " + toPhase + "." + appendMessage(consequence); } public final static String readPermissionDenied(final JobOwner user, final boolean jobList, final String containerName){ @@ -62,7 +62,7 @@ public final class UWSExceptionFactory { } public final static String readPermissionDenied(final JobOwner user, final boolean jobList, final String containerName, final String consequence){ - return user.getID() + ((user.getPseudo() == null) ? "" : (" (alias " + user.getPseudo() + ")")) + " is not allowed to read the content of the " + (jobList ? "jobs list" : "job") + " \"" + containerName + "\" !" + appendMessage(consequence); + return user.getID() + ((user.getPseudo() == null) ? "" : (" (alias " + user.getPseudo() + ")")) + " is not allowed to read the content of the " + (jobList ? "jobs list" : "job") + " \"" + containerName + "\"!" + appendMessage(consequence); } public final static String writePermissionDenied(final JobOwner user, final boolean jobList, final String containerName){ @@ -70,7 +70,7 @@ public final class UWSExceptionFactory { } public final static String writePermissionDenied(final JobOwner user, final boolean jobList, final String containerName, final String consequence){ - return user.getID() + ((user.getPseudo() == null) ? "" : (" (alias " + user.getPseudo() + ")")) + " is not allowed to update the content of the " + (jobList ? "jobs list" : "job") + " \"" + containerName + "\" !" + appendMessage(consequence); + return user.getID() + ((user.getPseudo() == null) ? "" : (" (alias " + user.getPseudo() + ")")) + " is not allowed to update the content of the " + (jobList ? "jobs list" : "job") + " \"" + containerName + "\"!" + appendMessage(consequence); } public final static String executePermissionDenied(final JobOwner user, final String jobID){ @@ -78,7 +78,7 @@ public final class UWSExceptionFactory { } public final static String executePermissionDenied(final JobOwner user, final String jobID, final String consequence){ - return user.getID() + ((user.getPseudo() == null) ? "" : (" (alias " + user.getPseudo() + ")")) + " is not allowed to execute/abort the job \"" + jobID + "\" !" + appendMessage(consequence); + return user.getID() + ((user.getPseudo() == null) ? "" : (" (alias " + user.getPseudo() + ")")) + " is not allowed to execute/abort the job \"" + jobID + "\"!" + appendMessage(consequence); } public final static String jobModificationForbidden(final String jobId, final ExecutionPhase phase, final String parameter){ @@ -87,9 +87,9 @@ public final class UWSExceptionFactory { public final static String jobModificationForbidden(final String jobId, final ExecutionPhase phase, final String parameter, final String consequence){ if (parameter != null && !parameter.trim().isEmpty()) - return "Impossible to change the parameter \"" + parameter + "\" of the job " + jobId + ((phase != null) ? (" (phase: " + phase + ")") : "") + " !" + appendMessage(consequence); + return "Impossible to change the parameter \"" + parameter + "\" of the job " + jobId + ((phase != null) ? (" (phase: " + phase + ")") : "") + "!" + appendMessage(consequence); else - return "Impossible to change the parameters of the job " + jobId + ((phase != null) ? (" (phase: " + phase + ")") : "") + " !" + appendMessage(consequence); + return "Impossible to change the parameters of the job " + jobId + ((phase != null) ? (" (phase: " + phase + ")") : "") + "!" + appendMessage(consequence); } } diff --git a/src/uws/job/ExecutionPhase.java b/src/uws/job/ExecutionPhase.java index d803f829c6d71c21cd2e0ea182721901f14198fc..acfb95c427b94b86eb0434d2e5ed3b79c03af01d 100644 --- a/src/uws/job/ExecutionPhase.java +++ b/src/uws/job/ExecutionPhase.java @@ -2,70 +2,214 @@ package uws.job; /* * 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 - 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> - * - * <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> - * - * <li>{@link #EXECUTING}: the job has been assigned to a processor. Results may be produced - * at any time during this phase.</li> - * - * <li>{@link #COMPLETED}: the execution of the job is over. The Results may be collected.</li> - * - * <li>{@link #ERROR}: 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> + * 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 #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> + * The transitions of the state machine described by the IVOA are implemented + * in a different class: {@link JobPhase}. + * </p> * - * <li>{@link #UNKNOWN}: the job is in an unknown state.</li> + * @see JobPhase * - * <li>{@link #HELD}: The job is HELD pending execution and will not automatically be - * executed (cf pending).</li> - * - * <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> - * - * @see UWSJob - * - * @author Grégory Mantelet (CDS) - * @version 02/2011 + * @author Grégory Mantelet (CDS;ARI) + * @version 4.3 (09/2017) */ public enum ExecutionPhase{ - PENDING, QUEUED, EXECUTING, COMPLETED, ERROR, ABORTED, UNKNOWN, HELD, SUSPENDED; + /** + * 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> + * + * <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. + * + * <p><b>Allowed previous phases:</b> + * {@link #EXECUTING}, {@link #QUEUED} or {@link #PENDING}. + * </p> + * + * <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> + * + * <p><b>Possible next phases:</b> + * {@link #ARCHIVED}. + * </p> + */ + ABORTED, + /** + * The job is in an unknown state. + * + * <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> + * + * <p><b>Allowed previous phases:</b> <i>any</i>.</p> + * + * <p><b>Possible next phases:</b> <i>any</i>.</p> + */ + 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); diff --git a/src/uws/job/JobPhase.java b/src/uws/job/JobPhase.java index 1de05bbbd0b4428b265fdcc59ba75db0b54c2882..01926e48a8241d896fc1397110b2ed07433eb65c 100644 --- a/src/uws/job/JobPhase.java +++ b/src/uws/job/JobPhase.java @@ -2,21 +2,21 @@ package uws.job; /* * 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), + * + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -26,12 +26,12 @@ 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égory Mantelet (CDS;ARI) - * @version 4.1 (08/2014) - * + * @version 4.3 (09/2017) + * * @see ExecutionPhase * @see UWSJob */ @@ -46,9 +46,10 @@ 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>. */ public JobPhase(UWSJob j) throws NullPointerException{ @@ -59,7 +60,7 @@ public class JobPhase implements Serializable { /** * Gets the job whose the execution phase is represented by this object. - * + * * @return The associated job. */ public final UWSJob getJob(){ @@ -68,7 +69,7 @@ public class JobPhase implements Serializable { /** * Gets the current phase of the job. - * + * * @return The current job phase. */ public final ExecutionPhase getPhase(){ @@ -76,12 +77,14 @@ public class JobPhase implements Serializable { } /** - * 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. - * + * 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. + * * @see #setPhase(ExecutionPhase, boolean) */ public final void setPhase(ExecutionPhase p) throws UWSException{ @@ -89,17 +92,19 @@ 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 p The new phase. + * @param force <i>true</i> to ignore the phases order, + * <i>false</i> otherwise. + * * @throws UWSException If the phase transition is forbidden. - * + * * @see #setPendingPhase(boolean) * @see #setQueuedPhase(boolean) * @see #setExecutingPhase(boolean) @@ -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); @@ -149,172 +158,215 @@ 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. - * - * @throws UWSException If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase != PENDING or UNKNOWN)</i>. + * + * @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 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. - * - * @throws UWSException If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase != QUEUED or HELD or PENDING or UNKNOWN)</i>. + * + * @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, 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) - throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.QUEUED)); - - phase = ExecutionPhase.QUEUED; - } + 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. - * - * @throws UWSException If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase != EXECUTING or SUSPENDED or QUEUED or UNKNOWN)</i>. + * + * @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, 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) - throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.EXECUTING)); - - phase = ExecutionPhase.EXECUTING; - } + 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. - * - * @throws UWSException If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase != COMPLETED or EXECUTING or UNKNOWN)</i>. + * + * @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, 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) - throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.COMPLETED)); - - phase = ExecutionPhase.COMPLETED; - } + 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. - * - * @throws UWSException If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase = COMPLETED or ERROR)</i>. + * + * @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, ERROR + * or ARCHIVED)</i>. */ protected void setAbortedPhase(boolean force) throws UWSException{ - if (force) - phase = ExecutionPhase.ABORTED; - else{ - if (phase == ExecutionPhase.COMPLETED || phase == ExecutionPhase.ERROR) - throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.ABORTED)); - - phase = ExecutionPhase.ABORTED; - } + 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. - * - * @throws UWSException If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase = COMPLETED or ABORTED)</i>. + * + * @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, ABORTED + * or ARCHIVED)</i>. */ protected void setErrorPhase(boolean force) throws UWSException{ - if (force) - phase = ExecutionPhase.ERROR; - else{ - if (phase == ExecutionPhase.COMPLETED || phase == ExecutionPhase.ABORTED) - throw new UWSException(UWSException.BAD_REQUEST, UWSExceptionFactory.incorrectPhaseTransition(job.getJobId(), phase, ExecutionPhase.ERROR)); - - phase = ExecutionPhase.ERROR; - } + 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. - * - * @throws UWSException If this phase transition is forbidden <i>(by default: IF force=false AND currentPhase != HELD or PENDING or UNKNOWN)</i>. + * + * @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, 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; } /** * Changes the current phase to {@link ExecutionPhase#SUSPENDED SUSPENDED}. - * - * @param force <i>true</i> to ignore the phases order, <i>false</i> otherwise. - * - * @throws UWSException By default, never ! + * + * @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 != 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. - * - * @throws UWSException By default, never ! + * + * @param force <i>true</i> to ignore the phases order, + * <i>false</i> otherwise. + * + * @throws UWSException By default, never! */ protected void setUnknownPhase(boolean force) throws UWSException{ phase = ExecutionPhase.UNKNOWN; } /** - * <p>Indicates whether the job attributes (except errors and results) can be updated, considering its current phase.</p> - * - * <p><i><u>Note:</u> 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. + * Indicates whether the job attributes (except errors and results) can be + * updated, considering its current phase. + * + * <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. */ public boolean isJobUpdatable(){ return phase == ExecutionPhase.PENDING; } /** - * <p>Indicates whether the job is finished or not, considering its current phase.</p> - * - * <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> - * - * @return <i>true</i> if the job is finished, <i>false</i> otherwise. + * Indicates whether the job is finished or not, considering its current + * phase. + * + * <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. */ 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> - * - * <p><i><u>Note:</u> 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. + * Indicates whether the job is executing, considering its current phase. + * + * <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. */ public boolean isExecuting(){ return phase == ExecutionPhase.EXECUTING; diff --git a/src/uws/job/UWSJob.java b/src/uws/job/UWSJob.java index 35b45af8482721f533d094967f5983abcd7b16d2..ddf5504dea4af6bf3c1dc2db6e768f60c7390f1b 100644 --- a/src/uws/job/UWSJob.java +++ b/src/uws/job/UWSJob.java @@ -59,27 +59,35 @@ import uws.service.request.UploadFile; * * <ul> * <li> - * The job attributes <i>startTime</i> and <i>endTime</i> are automatically managed by {@link UWSJob}. You don't have to do anything ! - * The date/time format is managed automatically by the library and can not be customized since it is imposed by the UWS + * The job attributes <i>creationTime</i>, <i>startTime</i> and + * <i>endTime</i> are automatically managed by {@link UWSJob}. You don't + * have to do anything! The date/time format is managed automatically by + * the library and can not be customized since it is imposed by the UWS * protocol definition: ISO-8601. * </li> * <br /> - * <li>Once set, the <i>destruction</i> and the <i>executionDuration</i> attributes are automatically managed. That is to say: + * <li> + * Once set, the <i>destruction</i> and the <i>executionDuration</i> + * attributes are automatically managed. That is to say: * <ul> - * <li><u>if the destruction time is reached:</u> the job stops and it is destroyed by its job list</li> - * <li><u>if the execution duration is elapsed:</u> the job stops and the phase is put to {@link ExecutionPhase#ABORTED ABORTED}.</li> + * <li><u>if the destruction time is reached:</u> the job stops and it + * is destroyed by its job list</li> + * <li><u>if the execution duration is elapsed:</u> the job stops and + * the phase is put to {@link ExecutionPhase#ABORTED ABORTED}.</li> * </ul> * </li> * <br /> * <li> - * <u>The <i>owner</i> attribute is set at the job creation and can not be changed after</u> ! If no owner is given at the job creation, - * its default value is <i>null</i>. + * <u>The <i>owner</i> attribute is set at the job creation and can not be + * changed after</u> ! If no owner is given at the job creation, its + * default value is <i>null</i>. * </li> * <br /> * <li> - * 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). + * 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). * </li> * </ul> * @@ -88,29 +96,33 @@ import uws.service.request.UploadFile; * <ul> * <li> * <b>{@link #generateJobId()}:</b> - * This function is called at the construction of any {@link UWSJob}. It allows to generate a unique job ID. - * By default: time (in milliseconds) + a upper-case letter (A, B, C, ....). - * <u>If you want customizing the job ID of your jobs</u>, you need to override this function or to use the new function - * {@link #UWSJob(JobOwner, UWSParameters, String)}. + * This function is called at the construction of any {@link UWSJob}. It + * allows to generate a unique job ID. By default: + * time (in milliseconds) + a upper-case letter (A, B, C, ....). + * <u>If you want customizing the job ID of your jobs</u>, you need to + * override this function or to use the new function + * {@link #UWSJob(JobOwner, UWSParameters, String)}. * </li> * <br /> * <li> * <b>{@link #clearResources()}:</b> - * This method is called <u>only at the destruction of the job</u>. - * By default, the job is stopped (if running), thread resources are freed, - * the job is removed from its jobs list and result/error files are deleted. + * This method is called <u>only at the destruction of the job</u>. + * By default, the job is stopped (if running), thread resources are freed, + * the job is removed from its jobs list and result/error files are + * deleted. * </li> * <br /> * <li> * <b>{@link #setPhaseManager(JobPhase)}:</b> - * Lets customizing the default behaviors of all the execution phases for any job instance. - * For more details see {@link JobPhase}. + * Lets customizing the default behaviors of all the execution phases for + * any job instance. For more details see {@link JobPhase}. * </li> * <br /> * <li> * <b>{@link #addObserver(JobObserver)}:</b> - * An instance of any kind of AbstractJob can be observed by objects which implements {@link JobObserver} (i.e. {@link uws.service.UWSService}). - * Observers are notified at any change of the execution phase. + * An instance of any kind of AbstractJob can be observed by objects which + * implements {@link JobObserver} (i.e. {@link uws.service.UWSService}). + * Observers are notified at any change of the execution phase. * </li> * </ul> * @@ -196,44 +208,62 @@ public class UWSJob extends SerializableUWSObject { /* ********* */ /* VARIABLES */ /* ********* */ - /** The last generated job ID. <b>It SHOULD be used ONLY by the function {@link #generateJobId()} !</b> */ + /** The last generated job ID. <b>It SHOULD be used ONLY by the function + * {@link #generateJobId()} !</b> */ protected static String lastId = System.currentTimeMillis() + "A"; - /** The identifier of the job (it MUST be different from any other job).<BR /> - * <i><u>Note:</u> It is assigned automatically at the job creation in any job constructor - * by the function {@link #generateJobId()}. - * To change the way this ID is generated or its format you must override this function.</i> */ + /** The identifier of the job (it MUST be different from any other job). + * <p><i>Note: + * It is assigned automatically at the job creation in any job constructor + * by the function {@link #generateJobId()}. To change the way this ID is + * generated or its format you must override this function. + * </i></p> */ protected final String jobId; - /** Date of the initial creation of this job.<BR /> - * <i><u>Note:</u> This attribute can be set only automatically at creation - * by the UWS service and can not be set or changed by a user (even its - * owner).</i> + /** Date of the initial creation of this job. + * <p><i>Note: + * This attribute can be set only automatically at creation by the UWS + * service and can not be set or changed by a user (even its owner). + * </i></p> * @since 4.3 */ protected final Date creationTime; - /** The identifier of the creator of this job.<BR /> - * <i><u>Note:</u> This object will not exist for all invocations of the UWS conformant protocol, - * but only in cases where the access to the service is authenticated.</i> */ + /** The identifier of the creator of this job. + * <p><i>Note: + * This object will not exist for all invocations of the UWS conformant + * protocol, but only in cases where the access to the service is + * authenticated. + * </i></p> */ protected final JobOwner owner; /** The jobs list which is supposed to managed this job. */ private JobList myJobList = null; /** - * <p>The current phase of the job.</p> - * <i><u>Remember:</u> A job is treated as a state machine thanks to this attribute. + * The current phase of the job. + * <p><b>Remember:</b> + * A job is treated as a state machine thanks to this attribute. + * </p> * <ul> - * <li>A successful job will normally progress through the {@link ExecutionPhase#PENDING PENDING}, - * {@link ExecutionPhase#QUEUED QUEUED}, {@link ExecutionPhase#EXECUTING EXECUTING}, {@link ExecutionPhase#COMPLETED COMPLETED} - * phases in that order.</li> - * <li>At any time before the {@link ExecutionPhase#COMPLETED COMPLETED} phase a job may either be {@link ExecutionPhase#ABORTED ABORTED} - * or may suffer an {@link ExecutionPhase#ERROR ERROR}.</li> - * <li>If the UWS reports an {@link ExecutionPhase#UNKNOWN UNKNOWN} phase, then all the client can do is re-query the phase until a known phase is reported.</li> - * <li>A UWS may place a job in a {@link ExecutionPhase#HELD HELD} phase on receipt of a PHASE=RUN request it 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.</li> - * </ul></i> - */ + * <li>A successful job will normally progress through the + * {@link ExecutionPhase#PENDING PENDING}, + * {@link ExecutionPhase#QUEUED QUEUED}, + * {@link ExecutionPhase#EXECUTING EXECUTING}, + * {@link ExecutionPhase#COMPLETED COMPLETED} phases in that + * order.</li> + * <li>At any time before the + * {@link ExecutionPhase#COMPLETED COMPLETED} phase a job may + * either be {@link ExecutionPhase#ABORTED ABORTED} or may suffer + * an {@link ExecutionPhase#ERROR ERROR}.</li> + * <li>If the UWS reports an {@link ExecutionPhase#UNKNOWN UNKNOWN} + * phase, then all the client can do is re-query the phase until a + * known phase is reported.</li> + * <li>A UWS may place a job in a {@link ExecutionPhase#HELD HELD} + * phase on receipt of a PHASE=RUN request it 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.</li> + * </ul> */ private JobPhase phase; /** The used date formatter. @@ -242,9 +272,12 @@ 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.<br /> - * <b>It CAN NOT be changed after the job creation !<br /> - * <i>By default if no ID is given, {@link #quote} is set to {@link #QUOTE_NOT_KNOWN} (= {@value #QUOTE_NOT_KNOWN}).</i></b> + * 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 + * {@link #QUOTE_NOT_KNOWN} (= {@value #QUOTE_NOT_KNOWN}). + * </p> */ private long quote = QUOTE_NOT_KNOWN; @@ -254,9 +287,12 @@ public class UWSJob extends SerializableUWSObject { /** The time at which the job execution ended. */ private Date endTime = null; - /** <p>This error summary gives a human-readable error message for the underlying job.</p> - * <i><u>Note:</u> This object is intended to be a detailed error message, and consequently, - * might be a large piece of text such as a stack trace.</i> */ + /** This error summary gives a human-readable error message for the + * underlying job. + * <p><i>Note: + * This object is intended to be a detailed error message, and + * consequently, might be a large piece of text such as a stack trace. + * </i></p> */ protected ErrorSummary errorSummary = null; /** This is a list of all results of this job. */ @@ -275,20 +311,27 @@ public class UWSJob extends SerializableUWSObject { /** The time (in ms) to wait the end of the thread after an interruption. */ protected long waitForStop = 1000; - /** Objects which want to be notified at each modification of the execution phase of this job. */ + /** Objects which want to be notified at each modification of the execution + * phase of this job. */ private Vector<JobObserver> observers = new Vector<JobObserver>(); - /** If this job has been restored, this attribute should be set with the date of its restoration. */ + /** If this job has been restored, this attribute should be set with the + * date of its restoration. */ private final Date restorationDate; /* ************ */ /* CONSTRUCTORS */ /* ************ */ /** - * <p>Builds a job with no owner from a map of all parameters (UWS and additional parameters).</p> + * Builds a job with no owner from a map of all parameters (UWS and + * additional parameters). * - * <p><i><u>Note:</u> if the parameter {@link UWSJob#PARAM_PHASE} (</i>phase<i>) is given with the value {@link UWSJob#PHASE_RUN} - * the job execution starts immediately after the job has been added to a job list or after {@link #applyPhaseParam(JobOwner)} is called.</i></p> + * <p><i>Note: + * If the parameter {@link UWSJob#PARAM_PHASE} (</i>phase<i>) is given with + * the value {@link UWSJob#PHASE_RUN} the job execution starts immediately + * after the job has been added to a job list or after + * {@link #applyPhaseParam(JobOwner)} is called. + * </i></p> * * @param params UWS standard and non-standard parameters. * @@ -323,7 +366,7 @@ public class UWSJob extends SerializableUWSObject { results = new HashMap<String,Result>(); - inputParams = params; + inputParams = (params == null ? new UWSParameters() : params); inputParams.init(); jobId = generateJobId(); @@ -339,16 +382,23 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Builds a job of the given owner and from a map of all parameters (UWS and additional parameters). - * The given HTTP request ID will be used as Job ID if not already used by another job.</p> + * Builds a job of the given owner and from a map of all parameters (UWS and + * additional parameters). The given HTTP request ID will be used as Job ID + * if not already used by another job. * - * <p><i><u>Note:</u> if the parameter {@link #PARAM_PHASE} (</i>phase<i>) is given with the value {@link #PHASE_RUN} - * the job execution starts immediately after the job has been added to a job list or after {@link #applyPhaseParam(JobOwner)} is called.</i></p> + * <p><i>Note: + * If the parameter {@link #PARAM_PHASE} (</i>phase<i>) is given with the + * value {@link #PHASE_RUN} the job execution starts immediately after the + * job has been added to a job list or after + * {@link #applyPhaseParam(JobOwner)} is called. + * </i></p> * * @param owner Job.owner ({@link #PARAM_OWNER}). * @param params UWS standard and non-standard parameters. - * @param requestID ID of the HTTP request which has initiated the creation of this job. - * <i>Note: if NULL, empty or already used, a job ID will be generated thanks to {@link #generateJobId()}.</i> + * @param requestID ID of the HTTP request which has initiated the creation + * of this job. + * <i>Note: if NULL, empty or already used, a job ID will + * be generated thanks to {@link #generateJobId()}.</i> * * @see UWSParameters#init() * @@ -363,7 +413,7 @@ public class UWSJob extends SerializableUWSObject { results = new HashMap<String,Result>(); - inputParams = params; + inputParams = (params == null ? new UWSParameters() : params); inputParams.init(); // Set the Job ID with the value of the HTTP request ID (if not already used by a job): @@ -471,13 +521,21 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>This function lets generating a unique ID.</p> + * This function lets generating a unique ID. * - * <p><i><b>By default:</b> System.currentTimeMillis()+UpperCharacter (UpperCharacter: one upper-case character chosen in order to guarantee the unicity of the ID: A, B, C, ....)</i></p> + * <p><b>By default:</b> + * System.currentTimeMillis()+UpperCharacter (UpperCharacter: one + * upper-case character chosen in order to guarantee the unicity of the + * ID: A, B, C, ....) + * </p> * - * <p><i><u>note: </u> DO NOT USE in this function any of the following functions: {@link #getLogger()}, - * {@link #getFileManager()} and {@link #getFactory()}. All of them will return NULL, because this job does not - * yet know its jobs list (which is needed to know the UWS and so, all of the objects returned by these functions).</i></p> + * <p><i>Note: + * DO NOT USE in this function any of the following functions: + * {@link #getLogger()}, {@link #getFileManager()} and + * {@link #getFactory()}. All of them will return NULL, because this job + * does not yet know its jobs list (which is needed to know the UWS and so, + * all of the objects returned by these functions). + * </i></p> * * @return A unique job identifier. */ @@ -496,7 +554,7 @@ public class UWSJob extends SerializableUWSObject { /** * <p>Gets the value of the specified parameter.</p> * - * <p><i><u>note:</u> + * <p><i>Note: * No case sensitivity for the UWS parameters ON THE CONTRARY TO the names * of the additional parameters (which are case sensitive). * </i></p> @@ -532,17 +590,27 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Looks for an additional parameters which corresponds to the Execution Phase. If it exists and:</p> + * Looks for an additional parameters which corresponds to the Execution + * Phase. If it exists and: + * * <ul> - * <li> is equals to {@link UWSJob#PHASE_RUN RUN} => remove it from the attribute {@link #inputParams} and start the job.</li> - * <li> is equals to {@link UWSJob#PHASE_ABORT ABORT} => remove it from the attribute {@link #inputParams} and abort the job.</li> - * <li> is another value => the attribute is though removed from the attribute {@link #inputParams} but nothing is done.</li> + * <li>is equals to {@link UWSJob#PHASE_RUN RUN} + * => remove it from the attribute {@link #inputParams} + * and start the job.</li> + * <li>is equals to {@link UWSJob#PHASE_ABORT ABORT} + * => remove it from the attribute {@link #inputParams} + * and abort the job.</li> + * <li>is another value + * => the attribute is though removed from the attribute + * {@link #inputParams} but nothing is done.</li> * </ul> * - * @param user The user who asks to apply the phase parameter (start/abort). (may be NULL) + * @param user The user who asks to apply the phase parameter + * (start/abort). <i>May be NULL.</i> * - * @throws UWSException If it is impossible the state of this job (into EXECUTING or ABORTED) - * or if the given user is not allowed to execute this job. + * @throws UWSException If it is impossible the state of this job + * (into EXECUTING or ABORTED) or if the given user is + * not allowed to execute this job. * * @see UWSParameters#hasInputPhase() * @see UWSParameters#getInputPhase() @@ -574,7 +642,8 @@ public class UWSJob extends SerializableUWSObject { /** * Gets the file manager used in this job. * - * @return Its file manager or <i>null</i> if this job is not into a {@link JobList} or if this jobs list is not into a {@link UWS}. + * @return Its file manager or <i>null</i> if this job is not into a + * {@link JobList} or if this jobs list is not into a {@link UWS}. * * @see JobList#getUWS() * @see uws.service.UWS#getFileManager() @@ -587,7 +656,8 @@ public class UWSJob extends SerializableUWSObject { } /** - * Gets the logger of its UWS or a default one if the job list or the UWS is unknown. + * Gets the logger of its UWS or a default one if the job list or the UWS + * is unknown. * * @return A logger. * @@ -603,7 +673,8 @@ public class UWSJob extends SerializableUWSObject { } /** - * Gets the factory to use to create the thread to execute when this job starts. + * Gets the factory to use to create the thread to execute when this job + * starts. * * @return The factory to use to create a {@link JobThread}. */ @@ -635,18 +706,38 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Sets the current phase of this job.</p> + * Sets the current phase of this job. * - * <p><b><u>IMPORTANT:</u></b> - * <ul><li>The order of all phases must be respected:<i> BY DEFAULT</i> <BR /> {@link ExecutionPhase#PENDING PENDING} ---> {@link ExecutionPhase#QUEUED QUEUED} ---> {@link ExecutionPhase#EXECUTING EXECUTING} ---> {@link ExecutionPhase#COMPLETED COMPLETED}.</li> - * <li>The only way to go to the {@link ExecutionPhase#EXECUTING EXECUTING} phase is by sending a POST query with the value {@link UWSJob#PHASE_RUN RUN} for the parameter {@link UWSJob#PARAM_PHASE PHASE}.</li> - * <li>The only way to go to the {@link ExecutionPhase#ABORTED ABORTED} phase is by sending a POST query with the value {@link UWSJob#PHASE_ABORT ABORT} for the parameter {@link UWSJob#PARAM_PHASE PHASE}.</li> - * <li>The start time and the end time are set automatically when the phase is set to {@link ExecutionPhase#EXECUTING EXECUTING} and {@link ExecutionPhase#COMPLETED COMPLETED}, {@link ExecutionPhase#ABORTED ABORTED} or {@link ExecutionPhase#ERROR ERROR}</li> - *</ul></p> + * <p><b>IMPORTANT:</b></p> + * <ul> + * <li> + * The order of all phases must be respected. By default: + * {@link ExecutionPhase#PENDING PENDING} ---> + * {@link ExecutionPhase#QUEUED QUEUED} ---> + * {@link ExecutionPhase#EXECUTING EXECUTING} ---> + * {@link ExecutionPhase#COMPLETED COMPLETED}.</li> + * <li> + * The only way to go to the {@link ExecutionPhase#EXECUTING EXECUTING} + * phase is by sending a POST query with the value + * {@link UWSJob#PHASE_RUN RUN} for the parameter + * {@link UWSJob#PARAM_PHASE PHASE}.</li> + * <li> + * The only way to go to the {@link ExecutionPhase#ABORTED ABORTED} + * phase is by sending a POST query with the value + * {@link UWSJob#PHASE_ABORT ABORT} for the parameter + * {@link UWSJob#PARAM_PHASE PHASE}.</li> + * <li> + * The start time and the end time are set automatically when the phase + * is set to {@link ExecutionPhase#EXECUTING EXECUTING} and + * {@link ExecutionPhase#COMPLETED COMPLETED}, + * {@link ExecutionPhase#ABORTED ABORTED} + * or {@link ExecutionPhase#ERROR ERROR}</li> + * </ul> * - * @param p The phase to set for this job. + * @param p The phase to set for this job. * - * @throws UWSException If the given phase does not respect the job's phases order. + * @throws UWSException If the given phase does not respect the job's + * phases order. * * @see #setPhase(ExecutionPhase, boolean) */ @@ -655,19 +746,41 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Sets the current phase of this job, respecting or not the imposed order.</p> + * Sets the current phase of this job, respecting or not the imposed order. * - * <p><b><u>IMPORTANT:</u></b> - * <ul><li><b><u>If the parameter <i>force</i> is <i>false</i></u></b>, the order of all phases must be respected:<BR /> {@link ExecutionPhase#PENDING PENDING} ---> {@link ExecutionPhase#QUEUED QUEUED} ---> {@link ExecutionPhase#EXECUTING EXECUTING} ---> {@link ExecutionPhase#COMPLETED COMPLETED}.</li> - * <li>The only way to go to the {@link ExecutionPhase#EXECUTING EXECUTING} phase is by sending a POST query with the value {@link UWSJob#PHASE_RUN RUN} for the parameter {@link UWSJob#PARAM_PHASE PARAM_PHASE}.</li> - * <li>The only way to go to the {@link ExecutionPhase#ABORTED ABORTED} phase is by sending a POST query with the value {@link UWSJob#PHASE_ABORT ABORT} for the parameter {@link UWSJob#PARAM_PHASE PARAM_PHASE}.</li> - * <li>The start time and the end time are set automatically when the phase is set to {@link ExecutionPhase#EXECUTING EXECUTING} and {@link ExecutionPhase#COMPLETED COMPLETED}, {@link ExecutionPhase#ABORTED ABORTED} or {@link ExecutionPhase#ERROR ERROR}</li> - *</ul></p> - * - * @param p The phase to set for this job. - * @param force <i>true</i> to impose the given execution phase, <i>false</i> to take into account the order of all phases. - * - * @throws UWSException If the given phase does not respect the job's phases order. + * <p><b>IMPORTANT:</b></p> + * <ul> + * <li> + * <b><u>If the parameter <i>force</i> is <i>false</i></u></b>, + * the order of all phases must be respected: + * {@link ExecutionPhase#PENDING PENDING} ---> + * {@link ExecutionPhase#QUEUED QUEUED} ---> + * {@link ExecutionPhase#EXECUTING EXECUTING} ---> + * {@link ExecutionPhase#COMPLETED COMPLETED}.</li> + * <li> + * The only way to go to the {@link ExecutionPhase#EXECUTING EXECUTING} + * phase is by sending a POST query with the value + * {@link UWSJob#PHASE_RUN RUN} for the parameter + * {@link UWSJob#PARAM_PHASE PARAM_PHASE}.</li> + * <li> + * The only way to go to the {@link ExecutionPhase#ABORTED ABORTED} + * phase is by sending a POST query with the value + * {@link UWSJob#PHASE_ABORT ABORT} for the parameter + * {@link UWSJob#PARAM_PHASE PARAM_PHASE}.</li> + * <li> + * The start time and the end time are set automatically when the phase + * is set to {@link ExecutionPhase#EXECUTING EXECUTING} and + * {@link ExecutionPhase#COMPLETED COMPLETED}, + * {@link ExecutionPhase#ABORTED ABORTED} + * or {@link ExecutionPhase#ERROR ERROR}</li> + *</ul> + * + * @param p The phase to set for this job. + * @param force <i>true</i> to impose the given execution phase, + * <i>false</i> to take into account the order of all phases. + * + * @throws UWSException If the given phase does not respect the job's + * phases order. * * @see JobPhase#setPhase(ExecutionPhase, boolean) * @see JobPhase#isFinished() @@ -692,9 +805,12 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Gets the phase manager of this job.</p> + * Gets the phase manager of this job. * - * <p><i><u>Note:</u> The phase manager manages all the transitions between all the execution phases.</i></p> + * <p><i>Note: + * The phase manager manages all the transitions between all the execution + * phases. + * </i></p> * * @return Its phase manager. */ @@ -703,11 +819,15 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Sets the phase manager of this job.</p> + * Sets the phase manager of this job. * - * <p><i><u>Note:</u> The phase manager manages all the transitions between all the execution phases.</i></p> + * <p><i>Note: + * The phase manager manages all the transitions between all the execution + * phases. + * </i></p> * - * @param jobPhase Its new phase manager (if <i>null</i> this function does nothing). + * @param jobPhase Its new phase manager (if <i>null</i> this function does + * nothing). */ public final void setPhaseManager(JobPhase jobPhase){ if (jobPhase != null){ @@ -772,9 +892,13 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Sets the duration (in seconds) for which this job shall run ONLY IF the job can updated (considering its current execution phase, see {@link JobPhase#isJobUpdatable()}).</p> + * Sets the duration (in seconds) for which this job shall run ONLY IF the + * job can updated (considering its current execution phase, see + * {@link JobPhase#isJobUpdatable()}). * - * <p><i><u>Note:</u> A duration of 0 (or less) implies unlimited execution duration.</i></p> + * <p><i>Note: + * A duration of 0 (or less) implies unlimited execution duration. + * </i></p> * * @param executionDuration The execution duration of this job. * @@ -802,12 +926,13 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p> - * Sets the instant when the job shall be destroyed ONLY IF the job can updated (considering its current execution phase, see {@link JobPhase#isJobUpdatable()}). - * If known the jobs list is notify of this destruction time update. - * </p> + * Sets the instant when the job shall be destroyed ONLY IF the job can + * updated (considering its current execution phase, see + * {@link JobPhase#isJobUpdatable()}). If known the jobs list is notify of + * this destruction time update. * - * @param destructionTime The destruction time of this job. <i>MUST NOT be NULL</i> + * @param destructionTime The destruction time of this job. + * <i>MUST NOT be NULL</i> * * @see JobList#updateDestruction(UWSJob) * @see UWSParameters#set(String, Object) @@ -834,14 +959,20 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Sets the error that occurs during the execution of this job.</p> + * Sets the error that occurs during the execution of this job. * - * <p><b><u>IMPORTANT:</u> This function will have no effect if the job is finished, that is to say if the current phase is - * {@link ExecutionPhase#ABORTED ABORTED}, {@link ExecutionPhase#ERROR ERROR} or {@link ExecutionPhase#COMPLETED COMPLETED}.</i>.</b></p> + * <p><b>IMPORTANT:</b> + * This function will have no effect if the job is finished, that is to say + * if the current phase is {@link ExecutionPhase#ABORTED ABORTED}, + * {@link ExecutionPhase#ERROR ERROR}, + * {@link ExecutionPhase#COMPLETED COMPLETED} + * or {@link ExecutionPhase#ARCHIVED ARCHIVED}. + * </p> * * @param errorSummary A summary of the error. <i>MUST NOT be NULL</i> * - * @throws UWSException If the job execution is finished that is to say if the phase is ABORTED, ERROR or COMPLETED. + * @throws UWSException If the job execution is finished that is to say if + * the phase is ABORTED, ERROR, COMPLETED or ARCHIVED. * * @see #isFinished() */ @@ -866,10 +997,15 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Gets the RunID of this job given by the UWS user (presumed to be the owner of this job). - * This ID isn't the one used to access to this job thanks to the jobs list: it is more likely a label/name than an ID => it is not unique.</p> + * Gets the RunID of this job given by the UWS user (presumed to be the + * owner of this job). This ID isn't the one used to access to this job + * thanks to the jobs list: it is more likely a label/name than an ID + * => it is not unique. * - * <p><b><u>Warning:</u> This ID may be used by other jobs BUT their job id (cf {@link UWSJob#getJobId()}) must be different.</b></p> + * <p><b>WARNING:</b> + * This ID may be used by other jobs BUT their job id + * (cf {@link UWSJob#getJobId()}) must be different. + * </p> * * @return The Run ID (a kind of job name/label). * @@ -880,7 +1016,8 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Sets the RunID of this job ONLY IF the job can updated (considering its current execution phase, see {@link JobPhase#isJobUpdatable()}).</p> + * Sets the RunID of this job ONLY IF the job can updated (considering + * its current execution phase, see {@link JobPhase#isJobUpdatable()}). * * @param name Its name/label. * @@ -917,9 +1054,12 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Sets the quote attribute of this job ONLY IF the job can updated (considering its current execution phase, see {@link JobPhase#isJobUpdatable()}).</p> + * Sets the quote attribute of this job ONLY IF the job can updated + * (considering its current execution phase, see + * {@link JobPhase#isJobUpdatable()}). * - * @param nbSeconds The estimated duration of the job execution (in seconds). + * @param nbSeconds The estimated duration of the job execution + * (in seconds). * * @see JobPhase#isJobUpdatable() */ @@ -952,20 +1092,25 @@ public class UWSJob extends SerializableUWSObject { * Gets the value of the specified additional parameter. * * @param paramName The name of the parameter whose the value is wanted. - * @return The value of the specified parameter or <i>null</i> if it doesn't exist. + * + * @return The value of the specified parameter + * or <i>null</i> if it doesn't exist. */ public final Object getAdditionalParameterValue(String paramName){ return inputParams.getAdditionalParameters().get(paramName); } /** - * Adds or updates the specified parameter with the given value ONLY IF the job can be updated (considering its current execution phase, see {@link JobPhase#isJobUpdatable()}). + * Adds or updates the specified parameter with the given value ONLY IF the + * job can be updated (considering its current execution phase, see + * {@link JobPhase#isJobUpdatable()}). * * @param paramName The name of the parameter to add or to update. * @param paramValue The (new) value of the specified parameter. * - * @return <ul><li><i>true</i> if the parameter has been successfully added/updated,</li> - * <li><i>false</i> otherwise <i>(particularly if paramName=null or paramName="" or paramValue=null)</i>.</li></ul> + * @return <i>true</i> if the parameter has been successfully added/updated, + * <i>false</i> otherwise <i>(particularly if paramName=null or + * paramName="" or paramValue=null)</i>. * * @throws UWSException If a parameter value is incorrect. * @@ -976,14 +1121,17 @@ public class UWSJob extends SerializableUWSObject { } /** - * Adds or updates the specified parameter with the given value ONLY IF the job can be updated (considering its current execution phase, see {@link JobPhase#isJobUpdatable()}). + * Adds or updates the specified parameter with the given value ONLY IF the + * job can be updated (considering its current execution phase, see + * {@link JobPhase#isJobUpdatable()}). * * @param paramName The name of the parameter to add or to update. * @param paramValue The (new) value of the specified parameter. * @param user The user who asks for this update. * - * @return <ul><li><i>true</i> if the parameter has been successfully added/updated,</li> - * <li><i>false</i> otherwise <i>(particularly if paramName=null or paramName="" or paramValue=null)</i>.</li></ul> + * @return <i>true</i> if the parameter has been successfully added/updated, + * <i>false</i> otherwise <i>(particularly if paramName=null or + * paramName="" or paramValue=null)</i>. * * @throws UWSException If a parameter value is incorrect. * @@ -1021,18 +1169,31 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Adds or updates the given parameters ONLY IF the job can be updated (considering its current execution phase, see {@link JobPhase#isJobUpdatable()}).</p> + * Adds or updates the given parameters ONLY IF the job can be updated + * (considering its current execution phase, see + * {@link JobPhase#isJobUpdatable()}). * - * <p>At the end of this function, the method {@link #applyPhaseParam(JobOwner)} is called so that if there is an additional parameter {@link #PARAM_PHASE} with the value: + * <p> + * At the end of this function, the method + * {@link #applyPhaseParam(JobOwner)} is called so that if there is an + * additional parameter {@link #PARAM_PHASE} with the value: + * </p> * <ul> - * <li>{@link UWSJob#PHASE_RUN RUN} then the job is starting and the phase goes to {@link ExecutionPhase#EXECUTING EXECUTING}.</li> - * <li>{@link UWSJob#PHASE_ABORT ABORT} then the job is aborting.</li> - * <li>otherwise the parameter {@link UWSJob#PARAM_PHASE PARAM_PHASE} is removed from {@link UWSJob#inputParams inputParams} and nothing is done.</li> - * </ul></p> + * <li> + * {@link UWSJob#PHASE_RUN RUN} then the job is starting and the phase + * goes to {@link ExecutionPhase#EXECUTING EXECUTING}.</li> + * <li> + * {@link UWSJob#PHASE_ABORT ABORT} then the job is aborting.</li> + * <li> + * otherwise the parameter {@link UWSJob#PARAM_PHASE PARAM_PHASE} is + * removed from {@link UWSJob#inputParams inputParams} and nothing is + * done.</li> + * </ul> * - * @param params A list of parameters to add/update. - * @return <ul><li><i>true</i> if all the given parameters have been successfully added/updated,</li> - * <li><i>false</i> if some parameters have not been managed.</li></ul> + * @param params A list of parameters to add/update. + * @return <i>true</i> if all the given parameters have been successfully + * added/updated, + * <i>false</i> if some parameters have not been managed. * * @throws UWSException If a parameter value is incorrect. * @@ -1054,22 +1215,36 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Adds or updates the given parameters ONLY IF the job can be updated (considering its current execution phase, see {@link JobPhase#isJobUpdatable()}).</p> + * Adds or updates the given parameters ONLY IF the job can be updated + * (considering its current execution phase, see + * {@link JobPhase#isJobUpdatable()}). * - * <p>At the end of this function, the method {@link #applyPhaseParam(JobOwner)} is called so that if there is an additional parameter {@link #PARAM_PHASE} with the value: + * <p> + * At the end of this function, the method + * {@link #applyPhaseParam(JobOwner)} is called so that if there is an + * additional parameter {@link #PARAM_PHASE} with the value: + * </p> * <ul> - * <li>{@link UWSJob#PHASE_RUN RUN} then the job is starting and the phase goes to {@link ExecutionPhase#EXECUTING EXECUTING}.</li> - * <li>{@link UWSJob#PHASE_ABORT ABORT} then the job is aborting.</li> - * <li>otherwise the parameter {@link UWSJob#PARAM_PHASE PARAM_PHASE} is removed from {@link UWSJob#inputParams inputParams} and nothing is done.</li> + * <li> + * {@link UWSJob#PHASE_RUN RUN} then the job is starting and the phase + * goes to {@link ExecutionPhase#EXECUTING EXECUTING}.</li> + * <li> + * {@link UWSJob#PHASE_ABORT ABORT} then the job is aborting.</li> + * <li> + * otherwise the parameter {@link UWSJob#PARAM_PHASE PARAM_PHASE} is + * removed from {@link UWSJob#inputParams inputParams} and nothing is + * done.</li> * </ul></p> * - * @param params The UWS parameters to update. - * @param user The user who asks for this update. + * @param params The UWS parameters to update. + * @param user The user who asks for this update. * - * @return <ul><li><i>true</i> if all the given parameters have been successfully added/updated,</li> - * <li><i>false</i> if some parameters have not been managed.</li></ul> + * @return <i>true</i> if all the given parameters have been successfully + * added/updated, + * <i>false</i> if some parameters have not been managed. * - * @throws UWSException If a parameter value is incorrect or if the given user can not update or execute this job. + * @throws UWSException If a parameter value is incorrect or if the given + * user can not update or execute this job. * * @see JobPhase#isJobUpdatable() * @see #applyPhaseParam(JobOwner) @@ -1115,11 +1290,14 @@ public class UWSJob extends SerializableUWSObject { } /** - * Removes the specified additional parameter ONLY IF the job can be updated (considering its current execution phase, see {@link JobPhase#isJobUpdatable()}). + * Removes the specified additional parameter ONLY IF the job can be updated + * (considering its current execution phase, see + * {@link JobPhase#isJobUpdatable()}). * * @param paramName The name of the parameter to remove. * - * @return <i>true</i> if the parameter has been successfully removed, <i>false</i> otherwise. + * @return <i>true</i> if the parameter has been successfully removed, + * <i>false</i> otherwise. * * @see JobPhase#isJobUpdatable() * @see UWSParameters#remove(String) @@ -1172,15 +1350,20 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Adds the given result in the results list of this job.</p> + * Adds the given result in the results list of this job. * - * <p><b><u>IMPORTANT:</u> This function will throw an error if the job is finished.</b></p> + * <p><b>IMPORTANT:</b> + * This function will throw an error if the job is finished. + * </p> * - * @param res The result to add (<b>not null</b>). + * @param res The result to add (<b>not null</b>). * - * @return <i>true</i> if the result has been successfully added, <i>false</i> otherwise (for instance, if a result has the same ID). + * @return <i>true</i> if the result has been successfully added, + * <i>false</i> otherwise (for instance, if a result has the same + * ID). * - * @throws UWSException If the job execution is finished that is to say if the phase is ABORTED, ERROR or COMPLETED. + * @throws UWSException If the job execution is finished that is to say if + * the phase is ABORTED, ERROR, COMPLETED or ARCHIVED. * * @see #isFinished() */ @@ -1270,13 +1453,21 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Sets its jobs list.</p> + * Sets its jobs list. * - * <p><i><u>note 1:</u> a job can change its jobs list ONLY WHILE PENDING !</i></p> - * <p><i><u>note 2:</u> this job is removed from its previous job list, if there is one.</i></p> - * <p><i><u>note 3:</u> this job is NOT automatically added into the new jobs list. Indeed, this function should be called by {@link JobList#addNewJob(UWSJob)}.</i></p> + * <p><i>Note 1: + * A job can change its jobs list ONLY WHILE PENDING! + * </i></p> + * <p><i>Note 2: + * This job is removed from its previous job list, if there is one. + * </i></p> + * <p><i>Note 3: + * This job is NOT automatically added into the new jobs list. Indeed, this + * function should be called by {@link JobList#addNewJob(UWSJob)}. + * </i></p> * - * @param jobList Its new jobs list. <i><u>note:</u> if NULL, nothing is done !</i> + * @param jobList Its new jobs list. + * <i>Note: if NULL, nothing is done!</i> * * @throws IllegalStateException If this job is not PENDING. * @@ -1319,7 +1510,8 @@ public class UWSJob extends SerializableUWSObject { /** * Gets the time to wait for the end of the thread after an interruption. * - * @return The time to wait for the end of the thread (a negative or null value means no wait for the end of the thread). + * @return The time to wait for the end of the thread (a negative or null + * value means no wait for the end of the thread). */ public final long getTimeToWaitForEnd(){ return waitForStop; @@ -1328,14 +1520,16 @@ public class UWSJob extends SerializableUWSObject { /** * Sets the time to wait for the end of the thread after an interruption. * - * @param timeToWait The new time to wait for the end of the thread (a negative or null value means no wait for the end of the thread). + * @param timeToWait The new time to wait for the end of the thread (a + * negative or null value means no wait for the end of + * the thread). */ public final void setTimeToWaitForEnd(long timeToWait){ waitForStop = timeToWait; } /** - * <p>Starts the job by using the execution manager if any.</p> + * Starts the job by using the execution manager if any. * * @throws UWSException */ @@ -1344,14 +1538,24 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Starts the job.</p> + * Starts the job. * - * <p><i><u>Note:</u> This function does nothing if the job is already running !</i></p> + * <p><i>Note: + * This function does nothing if the job is already running! + * </i></p> * - * @param useManager <i>true</i> to let the execution manager deciding whether the job starts immediately or whether it must be put in a queue until enough resources are available, <i>false</i> to start the execution immediately. + * @param useManager <i>true</i> to let the execution manager deciding + * whether the job starts immediately or whether it + * must be put in a queue until enough resources are + * available, + * <i>false</i> to start the execution immediately. * - * @throws NullPointerException If this job is not associated with a job list or the associated job list is not part of a UWS service or if no thread is created. - * @throws UWSException If there is an error while changing the execution phase or when starting the corresponding thread. + * @throws NullPointerException If this job is not associated with a job + * list or the associated job list is not part + * of a UWS service or if no thread is created. + * @throws UWSException If there is an error while changing the + * execution phase or when starting the + * corresponding thread. * * @see #isRunning() * @see UWSFactory#createJobThread(UWSJob) @@ -1424,11 +1628,16 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Tells whether the job is still running.</p> + * Tells whether the job is still running. * - * <p><i><u>Note:</u> This function tests the execution phase (see {@link JobPhase#isExecuting()}) AND the status of the thread (see {@link #isStopped()}).</i></p> + * <p><i>Note: + * This function tests the execution phase (see + * {@link JobPhase#isExecuting()}) AND the status of the thread (see + * {@link #isStopped()}). + * </i></p> * - * @return <i>true</i> if the job is still running, <i>false</i> otherwise. + * @return <i>true</i> if the job is still running, + * <i>false</i> otherwise. * * @see JobPhase#isExecuting() * @see #isStopped() @@ -1438,11 +1647,17 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Tells whether the job is already finished (completed, aborted, error, ...).</p> + * Tells whether the job is already finished (completed, aborted, + * error, archived, ...). * - * <p><i><u>Note:</u> This function test the execution phase (see {@link JobPhase#isFinished()}) AND the status of the thread (see {@link #isStopped()})</i></p> + * <p><i>Note: + * This function test the execution phase (see + * {@link JobPhase#isFinished()}) AND the status of the thread (see + * {@link #isStopped()}). + * </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. * * @see JobPhase#isFinished() * @see #isStopped() @@ -1452,12 +1667,18 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Stops immediately the job, sets its phase to {@link ExecutionPhase#ABORTED ABORTED} and sets its end time.</p> + * Stops immediately the job, sets its phase to + * {@link ExecutionPhase#ABORTED ABORTED} and sets its end time. * - * <p><b><u>IMPORTANT:</u> If the thread does not stop immediately the phase and the end time are not modified. However it can be done by calling one more time {@link #abort()}. - * Besides you should check that you test regularly the interrupted flag of the thread in {@link JobThread#jobWork()} !</b></p> + * <p><b>IMPORTANT:</b> + * If the thread does not stop immediately the phase and the end time are + * not modified. However it can be done by calling one more time + * {@link #abort()}. Besides you should check that you test regularly the + * interrupted flag of the thread in {@link JobThread#jobWork()}! + * </p> * - * @throws UWSException If there is an error while changing the execution phase. + * @throws UWSException If there is an error while changing the execution + * phase. * * @see #stop() * @see #isStopped() @@ -1482,15 +1703,21 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Stops immediately the job, sets its error summary, sets its phase to {@link ExecutionPhase#ERROR} and sets its end time.</p> + * Stops immediately the job, sets its error summary, sets its phase to + * {@link ExecutionPhase#ERROR} and sets its end time. * - * <p><b><u>IMPORTANT:</u> If the thread does not stop immediately the phase, the error summary and the end time are not modified. - * However it can be done by calling one more time {@link #error(ErrorSummary)}. - * Besides you should check that you test regularly the interrupted flag of the thread in {@link JobThread#jobWork()} !</b></p> + * <p><b>IMPORTANT:</b> + * If the thread does not stop immediately the phase, the error summary and + * the end time are not modified. However it can be done by calling one + * more time {@link #error(ErrorSummary)}. Besides you should check that + * you test regularly the interrupted flag of the thread in + * {@link JobThread#jobWork()}! + * </p> * - * @param error The error that has interrupted this job. + * @param error The error that has interrupted this job. * - * @throws UWSException If there is an error while setting the error summary or while changing the phase. + * @throws UWSException If there is an error while setting the error summary + * or while changing the phase. * * @see #stop() * @see #isStopped() @@ -1519,7 +1746,8 @@ public class UWSJob extends SerializableUWSObject { getLogger().logJob(LogLevel.WARNING, this, "ERROR", "Stopping of the job \"" + getJobId() + "\" with error asked but not yet effective (after having waited " + waitForStop + "ms)!", null); } - /** Used by the thread to known whether the {@link #stop()} method has already been called, and so, that the job is stopping. */ + /** Used by the thread to known whether the {@link #stop()} method has + * already been called, and so, that the job is stopping. */ protected boolean stopping = false; /** @@ -1546,27 +1774,37 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>Tells whether the thread is different from <i>null</i>, is not alive or is finished (see {@link JobThread#isFinished()}).</p> + * Tells whether the thread is different from <i>null</i>, is not alive or + * is finished (see {@link JobThread#isFinished()}). * * <p><i><b>Important note:</b> - * Having the interrupted flag set to <code>true</code> is not enough to consider the job as stopped. - * So, if the job has been interrupted but is still running, it should mean that the {@link JobThread#jobWork()} does not - * check the interrupted flag of the thread often enough or not at the right moments. In such case, the job can not be - * considered as stopped/aborted - so the phase stays {@link ExecutionPhase#EXECUTING EXECUTING} - until the thread is "unblocked" - * and the interruption is detected. + * Having the interrupted flag set to <code>true</code> is not enough to + * consider the job as stopped. So, if the job has been interrupted but is + * still running, it should mean that the {@link JobThread#jobWork()} does + * not check the interrupted flag of the thread often enough or not at the + * right moments. In such case, the job can not be considered as + * stopped/aborted - so the phase stays + * {@link ExecutionPhase#EXECUTING EXECUTING} - until the thread is + * "unblocked" and the interruption is detected. * </i></p> * - * @return <i>true</i> if the thread is not still running, <i>false</i> otherwise. + * @return <i>true</i> if the thread is not still running, + * <i>false</i> otherwise. */ protected final boolean isStopped(){ return thread == null || !thread.isAlive() || thread.isFinished(); } /** - * <p>Stops the job if running, removes the job from the execution manager, stops the timer for the execution duration - * and may clear all files or any other resources associated to this job.</p> + * Stops the job if running, removes the job from the execution manager, + * stops the timer for the execution duration and may clear all files or any + * other resources associated to this job. * - * <p><i>By default the job is aborted, the {@link UWSJob#thread} attribute is set to null, the timers are stopped and uploaded files, results and the error summary are deleted and the jobInfo is destroyed.</i></p> + * <p><i>Note: + * By default the job is aborted, the {@link UWSJob#thread} attribute is + * set to null, the timers are stopped and uploaded files, results and the + * error summary are deleted and the jobInfo is destroyed. + * </i></p> */ public void clearResources(){ // If still running, abort/stop the job: @@ -1631,11 +1869,14 @@ public class UWSJob extends SerializableUWSObject { /* OBSERVER MANAGEMENT */ /* ******************* */ /** - * Lets adding an observer of this job. The observer will be notified each time the execution phase changes. + * Lets adding an observer of this job. The observer will be notified each + * time the execution phase changes. * * @param observer A new observer of this job. * - * @return <i>true</i> if the given object has been successfully added as observer of this job, <i>false</i> otherwise. + * @return <i>true</i> if the given object has been successfully added as + * observer of this job, + * <i>false</i> otherwise. */ public final boolean addObserver(JobObserver observer){ if (observer != null && !observers.contains(observer)){ @@ -1666,9 +1907,12 @@ public class UWSJob extends SerializableUWSObject { /** * Lets removing the given object from the list of observers of this job. * - * @param observer The object which must not be considered as observer of this job. + * @param observer The object which must not be considered as observer of + * this job. * - * @return <i>true</i> if the given object is not any more an observer of this job, <i>false</i> otherwise. + * @return <i>true</i> if the given object is not any more an observer of + * this job, + * <i>false</i> otherwise. */ public final boolean removeObserver(JobObserver observer){ return observers.remove(observer); @@ -1710,13 +1954,20 @@ public class UWSJob extends SerializableUWSObject { /* ERROR MANAGEMENT */ /* **************** */ /** - * <p>Gets the error (if any) which has occurred during the job execution.</p> + * Gets the error (if any) which has occurred during the job execution. * - * <p><i><u>Note:</u> In the case an error summary can not have been published, the job has no error summary. - * However the last {@link UWSException} caught during the execution of a {@link JobThread} is saved and is available thanks to {@link JobThread#getError()}. - * In that case, the {@link UWSJob#getWorkError() getWorkError()} method can be used to get back the occurred error.</i></p> + * <p><i>Note: + * In the case an error summary can not have been published, the job has no + * error summary. However the last {@link UWSException} caught during the + * execution of a {@link JobThread} is saved and is available thanks to + * {@link JobThread#getError()}. In that case, the + * {@link UWSJob#getWorkError() getWorkError()} method can be used to get + * back the occurred error. + * </i></p> * - * @return The error which interrupts the thread or <i>null</i> if there was no error or if the job is still running. + * @return The error which interrupts the thread + * or <i>null</i> if there was no error or if the job is still + * running. */ public final UWSException getWorkError(){ return (thread == null || !thread.isAlive()) ? null : thread.getError(); @@ -1734,14 +1985,18 @@ public class UWSJob extends SerializableUWSObject { } /** - * Serializes the specified attribute of this job by using the given serializer. + * Serializes the specified attribute of this job by using the given + * serializer. * - * @param attributes All the given attributes (may be <i>null</i> or empty). - * @param serializer The serializer to use. + * @param attributes All the given attributes. + * <i>May be <i>null</i> or empty.</i> + * @param serializer The serializer to use. * - * @return The serialized job attribute (or the whole job if <i>attributes</i> is an empty array or is <i>null</i>). + * @return The serialized job attribute (or the whole job if + * <i>attributes</i> is an empty array or is <i>null</i>). * - * @throws Exception If there is an unexpected error during the serialization. + * @throws Exception If there is an unexpected error during the + * serialization. * * @see UWSSerializer#getJob(UWSJob, String[], boolean) */ @@ -1750,13 +2005,17 @@ public class UWSJob extends SerializableUWSObject { } /** - * Serializes the specified attribute of this job in the given output stream by using the given serializer. + * Serializes the specified attribute of this job in the given output stream + * by using the given serializer. * - * @param output The output stream in which the job attribute must be serialized. - * @param attributes The name of the attribute to serialize (if <i>null</i>, the whole job will be serialized). - * @param serializer The serializer to use. + * @param output The output stream in which the job attribute must be + * serialized. + * @param attributes The name of the attribute to serialize (if + * <i>null</i>, the whole job will be serialized). + * @param serializer The serializer to use. * - * @throws Exception If there is an unexpected error during the serialization. + * @throws Exception If there is an unexpected error during the + * serialization. * * @see #serialize(String[], UWSSerializer) */ @@ -1791,9 +2050,11 @@ public class UWSJob extends SerializableUWSObject { } /** - * <p>2 instances of AbstractJob are equals ONLY IF their ID are equals.</p> + * 2 instances of AbstractJob are equals ONLY IF their ID are equals. * - * <p><i><u>Note:</u> If the given object is not an AbstractJob, FALSE is returned.</i></p> + * <p><i>Note: + * If the given object is not an AbstractJob, FALSE is returned. + * </i></p> * * @see java.lang.Object#equals(java.lang.Object) */ diff --git a/test/uws/job/TestJobPhase.java b/test/uws/job/TestJobPhase.java new file mode 100644 index 0000000000000000000000000000000000000000..f275d754999d5584fdb4806ba06d2421fa6f1fad --- /dev/null +++ b/test/uws/job/TestJobPhase.java @@ -0,0 +1,648 @@ +package uws.job; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Test; + +import uws.UWSException; + +public class TestJobPhase { + + @Test + public void testSetPhase(){ + /* + * Here, we just want to ensure that all Execution Phases are supported. + * So, we just test to test the phase with force=true. + * Tests with force=false, have to be done individually for each + * phase ; hence the other JUnit test functions of this JUnit test case. + */ + try{ + JobPhase jobPhase = (new UWSJob(null)).getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + jobPhase.setPhase(phase, true); + assertEquals(phase, jobPhase.getPhase()); + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting a phase with force=true must NEVER throw an error. See console for more details."); + } + } + + @Test + public void testSetPendingPhase(){ + /* + * The phase PENDING can be NEVER be set coming from another different + * (normal) phase. + */ + try{ + UWSJob job = new UWSJob(null); + JobPhase jobPhase = job.getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + + /* CASE: FORCE=TRUE */ + // set the phase to turn into PENDING: + jobPhase.setPhase(phase, true); + // try to set PENDING: + switch(phase){ + case PENDING: + case UNKNOWN: + try{ + jobPhase.setPhase(ExecutionPhase.PENDING, false); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the PENDING phase from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + break; + default: + try{ + jobPhase.setPhase(ExecutionPhase.PENDING, false); + fail("It is not allowed to go from " + phase + " to PENDING."); + }catch(Exception e){ + assertEquals(UWSException.class, e.getClass()); + assertEquals("Incorrect phase transition! => the job " + job.getJobId() + " is in the phase " + phase + ". It can not go to PENDING.", e.getMessage()); + } + break; + } + + /* CASE: FORCE=FALSE */ + // set the phase to turn into PENDING: + jobPhase.setPhase(phase, true); + // try to set PENDING: + try{ + jobPhase.setPhase(ExecutionPhase.PENDING, true); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the PENDING phase with force=true from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting a phase with force=true must NEVER throw an error. See console for more details."); + } + } + + @Test + public void testSetQueuedPhase(){ + /* + * The phase QUEUED can be set only if the current phase is + * HELD or PENDING. + */ + try{ + UWSJob job = new UWSJob(null); + JobPhase jobPhase = job.getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + + /* CASE: FORCE=TRUE */ + // set the phase to turn into QUEUED: + jobPhase.setPhase(phase, true); + // try to set QUEUED: + switch(phase){ + case QUEUED: + case HELD: + case PENDING: + case UNKNOWN: + try{ + jobPhase.setPhase(ExecutionPhase.QUEUED, false); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the QUEUED phase from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + break; + default: + try{ + jobPhase.setPhase(ExecutionPhase.QUEUED, false); + fail("It is not allowed to go from " + phase + " to QUEUED."); + }catch(Exception e){ + assertEquals(UWSException.class, e.getClass()); + assertEquals("Incorrect phase transition! => the job " + job.getJobId() + " is in the phase " + phase + ". It can not go to QUEUED.", e.getMessage()); + } + break; + } + + /* CASE: FORCE=FALSE */ + // set the phase to turn into QUEUED: + jobPhase.setPhase(phase, true); + // try to set QUEUED: + try{ + jobPhase.setPhase(ExecutionPhase.QUEUED, true); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the QUEUED phase with force=true from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting a phase with force=true must NEVER throw an error. See console for more details."); + } + } + + @Test + public void testSetExecutingPhase(){ + /* + * The phase EXECUTING can be set only if the current phase is + * HELD, SUSPENDED or QUEUED. + */ + try{ + UWSJob job = new UWSJob(null); + JobPhase jobPhase = job.getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + + /* CASE: FORCE=TRUE */ + // set the phase to turn into EXECUTING: + jobPhase.setPhase(phase, true); + // try to set EXECUTING: + switch(phase){ + case EXECUTING: + case HELD: + case SUSPENDED: + case QUEUED: + case UNKNOWN: + try{ + jobPhase.setPhase(ExecutionPhase.EXECUTING, false); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the EXECUTING phase from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + break; + default: + try{ + jobPhase.setPhase(ExecutionPhase.EXECUTING, false); + fail("It is not allowed to go from " + phase + " to EXECUTING."); + }catch(Exception e){ + assertEquals(UWSException.class, e.getClass()); + assertEquals("Incorrect phase transition! => the job " + job.getJobId() + " is in the phase " + phase + ". It can not go to EXECUTING.", e.getMessage()); + } + break; + } + + /* CASE: FORCE=FALSE */ + // set the phase to turn into EXECUTING: + jobPhase.setPhase(phase, true); + // try to set EXECUTING: + try{ + jobPhase.setPhase(ExecutionPhase.EXECUTING, true); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the EXECUTING phase with force=true from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting a phase with force=true must NEVER throw an error. See console for more details."); + } + } + + @Test + public void testSetCompletedPhase(){ + /* + * The phase COMPLETED can be set only if the current phase is + * EXECUTING. + */ + try{ + UWSJob job = new UWSJob(null); + JobPhase jobPhase = job.getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + + /* CASE: FORCE=TRUE */ + // set the phase to turn into COMPLETED: + jobPhase.setPhase(phase, true); + // try to set COMPLETED: + switch(phase){ + case COMPLETED: + case EXECUTING: + case UNKNOWN: + try{ + jobPhase.setPhase(ExecutionPhase.COMPLETED, false); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the COMPLETED phase from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + break; + default: + try{ + jobPhase.setPhase(ExecutionPhase.COMPLETED, false); + fail("It is not allowed to go from " + phase + " to COMPLETED."); + }catch(Exception e){ + assertEquals(UWSException.class, e.getClass()); + assertEquals("Incorrect phase transition! => the job " + job.getJobId() + " is in the phase " + phase + ". It can not go to COMPLETED.", e.getMessage()); + } + break; + } + + /* CASE: FORCE=FALSE */ + // set the phase to turn into COMPLETED: + jobPhase.setPhase(phase, true); + // try to set COMPLETED: + try{ + jobPhase.setPhase(ExecutionPhase.COMPLETED, true); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the COMPLETED phase with force=true from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting a phase with force=true must NEVER throw an error. See console for more details."); + } + } + + @Test + public void testSetAbortedPhase(){ + /* + * The phase ABORTED can be set if the current phase is none of the + * following phases: COMPLETED, ERROR and ARCHIVED. + */ + try{ + UWSJob job = new UWSJob(null); + JobPhase jobPhase = job.getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + + /* CASE: FORCE=TRUE */ + // set the phase to turn into ABORTED: + jobPhase.setPhase(phase, true); + // try to set ABORTED: + switch(phase){ + case COMPLETED: + case ERROR: + case ARCHIVED: + try{ + jobPhase.setPhase(ExecutionPhase.ABORTED, false); + fail("It is not allowed to go from " + phase + " to ABORTED."); + }catch(Exception e){ + assertEquals(UWSException.class, e.getClass()); + assertEquals("Incorrect phase transition! => the job " + job.getJobId() + " is in the phase " + phase + ". It can not go to ABORTED.", e.getMessage()); + } + break; + default: + try{ + jobPhase.setPhase(ExecutionPhase.ABORTED, false); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the ABORTED phase from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + break; + } + + /* CASE: FORCE=FALSE */ + // set the phase to turn into ABORTED: + jobPhase.setPhase(phase, true); + // try to set ABORTED: + try{ + jobPhase.setPhase(ExecutionPhase.ABORTED, true); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the ERROR phase with force=true from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting a phase with force=true must NEVER throw an error. See console for more details."); + } + } + + @Test + public void testSetErrorPhase(){ + /* + * The phase ERROR can be set if the current phase is none of the + * following phases: COMPLETED, ABORTED and ARCHIVED. + */ + try{ + UWSJob job = new UWSJob(null); + JobPhase jobPhase = job.getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + + /* CASE: FORCE=TRUE */ + // set the phase to turn into ERROR: + jobPhase.setPhase(phase, true); + // try to set ERROR: + switch(phase){ + case COMPLETED: + case ABORTED: + case ARCHIVED: + try{ + jobPhase.setPhase(ExecutionPhase.ERROR, false); + fail("It is not allowed to go from " + phase + " to ERROR."); + }catch(Exception e){ + assertEquals(UWSException.class, e.getClass()); + assertEquals("Incorrect phase transition! => the job " + job.getJobId() + " is in the phase " + phase + ". It can not go to ERROR.", e.getMessage()); + } + break; + default: + try{ + jobPhase.setPhase(ExecutionPhase.ERROR, false); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the ERROR phase from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + break; + } + + /* CASE: FORCE=FALSE */ + // set the phase to turn into ERROR: + jobPhase.setPhase(phase, true); + // try to set ERROR: + try{ + jobPhase.setPhase(ExecutionPhase.ERROR, true); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the ERROR phase with force=true from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting a phase with force=true must NEVER throw an error. See console for more details."); + } + } + + @Test + public void testSetHeldPhase(){ + /* + * The phase HELD can be set only if the current phase is + * PENDING or EXECUTING. + */ + try{ + UWSJob job = new UWSJob(null); + JobPhase jobPhase = job.getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + + /* CASE: FORCE=TRUE */ + // set the phase to turn into HELD: + jobPhase.setPhase(phase, true); + // try to set HELD: + switch(phase){ + case HELD: + case PENDING: + case EXECUTING: + case UNKNOWN: + try{ + jobPhase.setPhase(ExecutionPhase.HELD, false); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the HELD phase from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + break; + default: + try{ + jobPhase.setPhase(ExecutionPhase.HELD, false); + fail("It is not allowed to go from " + phase + " to HELD."); + }catch(Exception e){ + assertEquals(UWSException.class, e.getClass()); + assertEquals("Incorrect phase transition! => the job " + job.getJobId() + " is in the phase " + phase + ". It can not go to HELD.", e.getMessage()); + } + break; + } + + /* CASE: FORCE=FALSE */ + // set the phase to turn into HELD: + jobPhase.setPhase(phase, true); + // try to set HELD: + try{ + jobPhase.setPhase(ExecutionPhase.HELD, true); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the HELD phase with force=true from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting a phase with force=true must NEVER throw an error. See console for more details."); + } + } + + @Test + public void testSetSuspendedPhase(){ + /* + * The phase SUSPENDED can be set only if the current phase is + * EXECUTING. + */ + try{ + UWSJob job = new UWSJob(null); + JobPhase jobPhase = job.getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + + /* CASE: FORCE=TRUE */ + // set the phase to turn into SUSPENDED: + jobPhase.setPhase(phase, true); + // try to set SUSPENDED: + switch(phase){ + case SUSPENDED: + case EXECUTING: + case UNKNOWN: + try{ + jobPhase.setPhase(ExecutionPhase.SUSPENDED, false); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the SUSPENDED phase from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + break; + default: + try{ + jobPhase.setPhase(ExecutionPhase.SUSPENDED, false); + fail("It is not allowed to go from " + phase + " to SUSPENDED."); + }catch(Exception e){ + assertEquals(UWSException.class, e.getClass()); + assertEquals("Incorrect phase transition! => the job " + job.getJobId() + " is in the phase " + phase + ". It can not go to SUSPENDED.", e.getMessage()); + } + break; + } + + /* CASE: FORCE=FALSE */ + // set the phase to turn into SUSPENDED: + jobPhase.setPhase(phase, true); + // try to set SUSPENDED: + try{ + jobPhase.setPhase(ExecutionPhase.SUSPENDED, true); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the SUSPENDED phase with force=true from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting a phase with force=true must NEVER throw an error. See console for more details."); + } + } + + @Test + public void testSetArchivedPhase(){ + /* + * The phase ARCHIVED can be set only if the current phase is one of: + * ARCHIVED, COMPLETED, ABORTED and ERROR. + */ + try{ + UWSJob job = new UWSJob(null); + JobPhase jobPhase = job.getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + + /* CASE: FORCE=TRUE */ + // set the phase to turn into ARCHIVED: + jobPhase.setPhase(phase, true); + // try to set ARCHIVED: + switch(phase){ + case ARCHIVED: + case COMPLETED: + case ABORTED: + case ERROR: + case UNKNOWN: + try{ + jobPhase.setPhase(ExecutionPhase.ARCHIVED, false); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the ARCHIVED phase from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + break; + default: + try{ + jobPhase.setPhase(ExecutionPhase.ARCHIVED, false); + fail("It is not allowed to go from " + phase + " to ARCHIVED."); + }catch(Exception e){ + assertEquals(UWSException.class, e.getClass()); + assertEquals("Incorrect phase transition! => the job " + job.getJobId() + " is in the phase " + phase + ". It can not go to ARCHIVED.", e.getMessage()); + } + } + + /* CASE: FORCE=FALSE */ + // set the phase to turn into ARCHIVED: + jobPhase.setPhase(phase, true); + // try to set ARCHIVED: + try{ + jobPhase.setPhase(ExecutionPhase.ARCHIVED, true); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the ARCHIVED phase with force=true from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting a phase with force=true must NEVER throw an error. See console for more details."); + } + } + + @Test + public void testSetUnknownPhase(){ + /* + * The phase UNKNOWN is not really part of the Execution Phase state + * machine declared in the UWS standard. So, an exception can never be + * thrown when setting this phase, with force=true, or not. + */ + try{ + JobPhase jobPhase = (new UWSJob(null)).getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + + /* CASE: FORCE=TRUE */ + // set the phase to turn into UNKNOWN: + jobPhase.setPhase(phase, true); + // try to set UNKNOWN: + try{ + jobPhase.setPhase(ExecutionPhase.UNKNOWN, false); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the UNKNOWN phase from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + + /* CASE: FORCE=FALSE */ + // set the phase to turn into UNKNOWN: + jobPhase.setPhase(phase, true); + // try to set UNKNOWN: + try{ + jobPhase.setPhase(ExecutionPhase.UNKNOWN, true); + }catch(Exception e){ + e.printStackTrace(); + fail("Setting the UNKNOWN phase (especially with force=true) from any other phase (here: " + phase + ") MUST always be possible. See console for more details."); + } + + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting a phase with force=true must NEVER throw an error. See console for more details."); + } + } + + @Test + public void testIsJobUpdatable(){ + /* + * A UWS job can be updated in only one execution phase: PENDING. + */ + try{ + JobPhase jobPhase = (new UWSJob(null)).getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + // set the phase to test: + jobPhase.setPhase(phase, true); + // ensure isJobUpdatable(...) returns TRUE only for PENDING: + if (phase == ExecutionPhase.PENDING) + assertTrue(jobPhase.isJobUpdatable()); + else + assertFalse(jobPhase.isJobUpdatable()); + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting the phase with force=true must NEVER throw an error. See console for more details."); + } + } + + @Test + public void testIsFinished(){ + /* + * A UWS job is finished only if in the execution phase COMPLETED, + * ABORTED, ERROR or ARCHIVED. + */ + try{ + JobPhase jobPhase = (new UWSJob(null)).getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + // set the phase to test: + jobPhase.setPhase(phase, true); + // ensure isFinished(...) returns TRUE only for COMPLETED, + // ABORTED, ERROR and ARCHIVED: + switch(phase){ + case COMPLETED: + case ABORTED: + case ERROR: + case ARCHIVED: + assertTrue(jobPhase.isFinished()); + break; + default: + assertFalse(jobPhase.isFinished()); + break; + } + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting the phase with force=true must NEVER throw an error. See console for more details."); + } + } + + @Test + public void testIsExecuting(){ + /* + * A UWS job is executing if in only one execution phase: EXECUTING. + */ + try{ + JobPhase jobPhase = (new UWSJob(null)).getPhaseManager(); + for(ExecutionPhase phase : ExecutionPhase.values()){ + // set the phase to test: + jobPhase.setPhase(phase, true); + // ensure isExecuting(...) returns TRUE only for EXECUTING: + if (phase == ExecutionPhase.EXECUTING) + assertTrue(jobPhase.isExecuting()); + else + assertFalse(jobPhase.isExecuting()); + } + }catch(Exception ex){ + ex.printStackTrace(); + fail("Setting the phase with force=true must NEVER throw an error. See console for more details."); + } + } + +}