View Javadoc

1   /*
2    * Copyright (c) 2005, London e-Science Centre, Imperial College London, UK
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6    *
7    * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8    * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9    * - Neither the name of the London e-Science Centre nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10   *
11   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12   */
13  package org.icenigrid.gridsam.core;
14  
15  import java.io.Serializable;
16  import java.util.ArrayList;
17  import java.util.Arrays;
18  import java.util.HashMap;
19  import java.util.List;
20  import java.util.Map;
21  
22  /**
23   * Enumeration class representing Job States
24   */
25  public class JobState implements Serializable {
26  
27      /**
28       * state map
29       */
30      private static final Map sStateMap = new HashMap();
31  
32      /**
33       * The job is waiting for resource to become available in order to run
34       */
35      public static final JobState PENDING = new JobState("pending");
36  
37      /**
38       * The job's data are staging into the job execution environment
39       */
40      public static final JobState STAGING_IN = new JobState("staging-in");
41  
42      /**
43       * The job's data have been staged into the job execution environment
44       */
45      public static final JobState STAGED_IN = new JobState("staged-in");
46  
47      /**
48       * The job's data are staging out from the job execution environment
49       */
50      public static final JobState STAGING_OUT = new JobState("staging-out");
51  
52      /**
53       * The job's data have been staged out from the job execution environment
54       */
55      public static final JobState STAGED_OUT = new JobState("staged-out");
56  
57      /**
58       * The job has received resource, and the application is executing
59       */
60      public static final JobState ACTIVE = new JobState("active");
61  
62      /**
63       * The job has received resource, and the application is queued
64       */
65      
66      public static final JobState ACTIVE_QUEUED = new JobState("active-queued");
67      
68      /**
69       * The job has received resource, and the application is running
70       */
71      public static final JobState ACTIVE_RUNNING = new JobState("active-running");
72      
73      /**
74       * The job has received resource, but the application is held/suspended ?
75       */
76      public static final JobState ACTIVE_HELD = new JobState("active-held");
77      
78      /**
79       * The job has been executed (i.e. exit code is available), however not yet
80       * completed
81       */
82      public static final JobState EXECUTED = new JobState("executed");
83  
84      /**
85       * The job terminated before completion because of an error, user-triggered
86       * cancel, or system-triggered cancel
87       */
88      public static final JobState FAILED = new JobState("failed");
89  
90      /**
91       * The job has completed successfully
92       */
93      public static final JobState DONE = new JobState("done");
94  
95      /**
96       * The job is being terminated by user
97       */
98      public static final JobState TERMINATING = new JobState("terminating");
99  
100     /**
101      * The job has been terminated by user
102      */
103     public static final JobState TERMINATED = new JobState("terminated");
104 
105     /**
106      * The job state is undefined
107      */
108     public static final JobState UNDEFINED = new JobState("undefined");
109 
110     /**
111      * backing value of the constant
112      */
113     private String oStateValue;
114 
115     /**
116      * private constructor
117      * 
118      * @param pValue
119      */
120     private JobState(String pValue) {
121         oStateValue = pValue;
122         sStateMap.put(pValue, this);
123     }
124 
125     /**
126      * transition definition
127      */
128     private static final Map TRANSITIONS = new HashMap();
129 
130     static {
131         TRANSITIONS.put(JobState.PENDING, Arrays.asList(new JobState[] {
132                 JobState.FAILED, JobState.STAGING_IN, JobState.ACTIVE,
133                 JobState.ACTIVE_HELD, JobState.ACTIVE_QUEUED, JobState.ACTIVE_RUNNING,
134                 JobState.UNDEFINED, JobState.TERMINATING }));
135         TRANSITIONS.put(JobState.STAGING_IN, Arrays.asList(new JobState[] {
136                 JobState.STAGED_IN, JobState.FAILED, JobState.UNDEFINED,
137                 JobState.TERMINATING }));
138         TRANSITIONS.put(JobState.STAGED_IN, Arrays.asList(new JobState[] {
139                 JobState.ACTIVE, JobState.ACTIVE_HELD, JobState.ACTIVE_QUEUED,
140                 JobState.ACTIVE_RUNNING, JobState.STAGING_OUT, 
141                 JobState.UNDEFINED, JobState.FAILED, JobState.TERMINATING }));
142         TRANSITIONS.put(JobState.ACTIVE, Arrays.asList(new JobState[] {
143                 JobState.ACTIVE_HELD, JobState.ACTIVE_QUEUED, JobState.ACTIVE_RUNNING,
144                 JobState.FAILED, JobState.EXECUTED, JobState.UNDEFINED,
145                 JobState.TERMINATING }));
146         TRANSITIONS.put(JobState.ACTIVE_HELD, Arrays.asList(new JobState[] {
147                 JobState.ACTIVE_QUEUED, JobState.ACTIVE_RUNNING, JobState.FAILED,
148                 JobState.EXECUTED, JobState.UNDEFINED, JobState.TERMINATING }));
149         TRANSITIONS.put(JobState.ACTIVE_QUEUED, Arrays.asList(new JobState[] {
150                 JobState.ACTIVE_HELD, JobState.ACTIVE_RUNNING, JobState.FAILED,
151                 JobState.EXECUTED, JobState.UNDEFINED, JobState.TERMINATING }));
152         TRANSITIONS.put(JobState.ACTIVE_RUNNING, Arrays.asList(new JobState[] {
153                 JobState.ACTIVE_HELD, JobState.FAILED, JobState.EXECUTED, 
154                 JobState.UNDEFINED, JobState.TERMINATING }));
155         TRANSITIONS.put(JobState.EXECUTED, Arrays.asList(new JobState[] {
156                 JobState.STAGING_OUT, JobState.UNDEFINED, JobState.DONE, JobState.FAILED, 
157                 JobState.TERMINATING }));
158         TRANSITIONS.put(JobState.STAGING_OUT, Arrays.asList(new JobState[] {
159                 JobState.FAILED, JobState.STAGED_OUT, JobState.UNDEFINED,
160                 JobState.TERMINATING }));
161         TRANSITIONS.put(JobState.STAGED_OUT, Arrays.asList(new JobState[] {
162                 JobState.DONE, JobState.UNDEFINED, JobState.TERMINATING }));
163         TRANSITIONS.put(JobState.TERMINATING, Arrays.asList(new JobState[] {
164                 JobState.TERMINATED, JobState.UNDEFINED }));
165 
166         // terminal state
167         TRANSITIONS.put(JobState.FAILED, new ArrayList());
168         TRANSITIONS.put(JobState.DONE, new ArrayList());
169         TRANSITIONS.put(JobState.UNDEFINED, new ArrayList());
170         TRANSITIONS.put(JobState.TERMINATED, new ArrayList());
171     }
172 
173     /**
174      * get a list of JobState this state can advance to
175      * 
176      * @return List of JobState that are directly the advance state of the
177      *         current state
178      */
179     public List getPossibleNextState() {
180         if (!TRANSITIONS.containsKey(this)) {
181             throw new IllegalArgumentException("unknown state " + this);
182         }
183         return (List) TRANSITIONS.get(this);
184     }
185 
186     /**
187      * test whether this state is a terminal state
188      * 
189      * @return true if this state is terminal, false otherwise
190      */
191     public boolean isTerminal() {
192         return getPossibleNextState().isEmpty();
193     }
194 
195     /**
196      * parse a state value into a JobState object
197      * 
198      * @param pValue
199      *            state value
200      * @return JobState the job state
201      * 
202      * @throws IllegalArgumentException
203      *             if pValue is not a known state identifier
204      */
205     public static final JobState parse(String pValue) {
206         JobState xState = (JobState) sStateMap.get(pValue);
207         if (xState == null) {
208             xState = (JobState) sStateMap.get(pValue.toUpperCase());
209         }
210         if (xState == null) {
211             throw new IllegalArgumentException(pValue + " or "
212                     + pValue.toUpperCase() + " is not a valid state");
213         }
214         return xState;
215     }
216 
217     /**
218      * equality check
219      * 
220      * @param o
221      *            object to test with
222      * @return boolean true to indicate equality, false otherwise
223      */
224     public boolean equals(Object o) {
225         if (this == o)
226             return true;
227         if (!(o instanceof JobState))
228             return false;
229 
230         final JobState xJobState = (JobState) o;
231 
232         if (!oStateValue.equals(xJobState.oStateValue))
233             return false;
234 
235         return true;
236     }
237 
238     /**
239      * get the hashcode of this object
240      * 
241      * @return int hash code
242      */
243     public int hashCode() {
244         return oStateValue.hashCode();
245     }
246 
247     /**
248      * Returns a string representation of the object. In general, the
249      * <code>toString</code> method returns a string that "textually
250      * represents" this object. The result should be a concise but informative
251      * representation that is easy for a person to read. It is recommended that
252      * all subclasses override this method. <p/> The <code>toString</code>
253      * method for class <code>Object</code> returns a string consisting of the
254      * name of the class of which the object is an instance, the at-sign
255      * character `<code>@</code>', and the unsigned hexadecimal
256      * representation of the hash code of the object. In other words, this
257      * method returns a string equal to the value of: <blockquote>
258      * 
259      * <pre>
260      * getClass().getName() + '@' + Integer.toHexString(hashCode())
261      * </pre>
262      * 
263      * </blockquote>
264      * 
265      * @return a string representation of the object.
266      */
267     public String toString() {
268         return oStateValue;
269     }
270 }