001/*
002 * #%L
003 * Netarchivesuite - harvester
004 * %%
005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library,
006 *             the National Library of France and the Austrian National Library.
007 * %%
008 * This program is free software: you can redistribute it and/or modify
009 * it under the terms of the GNU Lesser General Public License as
010 * published by the Free Software Foundation, either version 2.1 of the
011 * License, or (at your option) any later version.
012 * 
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Lesser Public License for more details.
017 * 
018 * You should have received a copy of the GNU General Lesser Public
019 * License along with this program.  If not, see
020 * <http://www.gnu.org/licenses/lgpl-2.1.html>.
021 * #L%
022 */
023
024package dk.netarkivet.harvester.datamodel;
025
026import java.util.Locale;
027
028import dk.netarkivet.common.exceptions.ArgumentNotValid;
029import dk.netarkivet.common.utils.I18n;
030
031/**
032 * Enumeration of the possible states (alt.: status) a Job can be in.
033 */
034public enum JobStatus {
035
036    /**
037     * Job status new is used for a job that has been created but not yet sent to a JMS queue.
038     */
039    NEW,
040    /**
041     * Job status submitted is used for a job that has been sent to a JMS queue, but not yet picked up by a harvester.
042     */
043    SUBMITTED,
044    /**
045     * Job status started is used for a job that a harvester has started.
046     */
047    STARTED,
048    /**
049     * Job status done is used for a job that a harvester has successfully finished.
050     */
051    DONE,
052    /**
053     * Job status failed is used for a job that has failed to execute correctly.
054     */
055    FAILED,
056    /**
057     * Job status resubmitted is used for a job that had failed and a new job with this jobs data has been submitted.
058     */
059    RESUBMITTED,
060    /**
061     * Job status for a job which has failed and which has been rejected for resubmission. A Job in this status can be
062     * returned to status FAILED if it has been rejected in error.
063     */
064    FAILED_REJECTED;
065
066    /** Internationalisation object. */
067    private static final I18n I18N = new I18n(dk.netarkivet.harvester.Constants.TRANSLATIONS_BUNDLE);
068
069    /** Constant representing ALL states. */
070    public static final int ALL_STATUS_CODE = -1;
071
072    /** Localization key for the NEW JobStatus. */
073    public static String JOBSTATUS_NEW_KEY = "status.job.new";
074    /** Localization key for the SUBMITTED JobStatus. */
075    public static String JOBSTATUS_SUBMITTED_KEY = "status.job.submitted";
076    /** Localization key for the STARTED JobStatus. */
077    public static String JOBSTATUS_STARTED_KEY = "status.job.started";
078    /** Localization key for the DONE JobStatus. */
079    public static String JOBSTATUS_DONE_KEY = "status.job.done";
080    /** Localization key for the FAILED JobStatus. */
081    public static String JOBSTATUS_FAILED_KEY = "status.job.failed";
082    /** Localization key for the RESUBMITTED JobStatus. */
083    public static String JOBSTATUS_RESUBMITTED_KEY = "status.job.resubmitted";
084    /** Localization key for a unknown JobStatus. */
085    public static String JOBSTATUS_UNKNOWN_KEY = "status.job.unknown";
086    /** Localization key for a JobStatus FAILED_REJECTED. */
087    public static String JOBSTATUS_FAILED_REJECTED_KEY = "status.job.failed_rejected";
088
089    /**
090     * Helper method that gives a proper object from e.g. a DB-stored value.
091     *
092     * @param status a certain integer
093     * @return the JobStatus related to a certain integer
094     * @throws ArgumentNotValid
095     */
096    public static JobStatus fromOrdinal(int status) {
097        switch (status) {
098        case 0:
099            return NEW;
100        case 1:
101            return SUBMITTED;
102        case 2:
103            return STARTED;
104        case 3:
105            return DONE;
106        case 4:
107            return FAILED;
108        case 5:
109            return RESUBMITTED;
110        case 6:
111            return FAILED_REJECTED;
112        default:
113            throw new ArgumentNotValid("Invalid job status '" + status + "'");
114        }
115    }
116
117    /**
118     * Helper method that gives a proper object from e.g. a DB-stored value.
119     *
120     * @param status a status string
121     * @return the JobStatus related to a string
122     * @throws ArgumentNotValid
123     */
124    public static JobStatus parse(String status) {
125        for (JobStatus s : values()) {
126            if (s.name().equals(status)) {
127                return s;
128            }
129        }
130        throw new ArgumentNotValid("Invalid job status '" + status + "'");
131    }
132
133    /**
134     * Return a localized human-readable string describing this status.
135     * <p>
136     * Strings are read from the harvester translation bundle found in Translation.properties in this module.
137     *
138     * @param l The locale
139     * @return A human readable string for that locale.
140     * @throws ArgumentNotValid on null locale.
141     */
142    public String getLocalizedString(Locale l) {
143        ArgumentNotValid.checkNotNull(l, "Locale l");
144        switch (this) {
145        case NEW:
146            return I18N.getString(l, JOBSTATUS_NEW_KEY);
147        case SUBMITTED:
148            return I18N.getString(l, JOBSTATUS_SUBMITTED_KEY);
149        case STARTED:
150            return I18N.getString(l, JOBSTATUS_STARTED_KEY);
151        case DONE:
152            return I18N.getString(l, JOBSTATUS_DONE_KEY);
153        case FAILED:
154            return I18N.getString(l, JOBSTATUS_FAILED_KEY);
155        case RESUBMITTED:
156            return I18N.getString(l, JOBSTATUS_RESUBMITTED_KEY);
157        case FAILED_REJECTED:
158            return I18N.getString(l, JOBSTATUS_FAILED_REJECTED_KEY);
159        default:
160            return I18N.getString(l, JOBSTATUS_UNKNOWN_KEY, this.toString());
161        }
162    }
163
164    /**
165     * True if it is legal to change from this status to a new status.
166     *
167     * @param newStatus a new JobStatus
168     * @return true if it is legal to go from the current status to this new status
169     */
170    public boolean legalChange(JobStatus newStatus) {
171        ArgumentNotValid.checkNotNull(newStatus, "JobStatus newStatus");
172        return newStatus.ordinal() >= ordinal()
173                || (newStatus.equals(FAILED) && fromOrdinal(ordinal()).equals(FAILED_REJECTED));
174    }
175
176}