KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > jobs > InternalJob


1 /*******************************************************************************
2  * Copyright (c) 2003, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM - Initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.jobs;
12
13 import java.util.Map JavaDoc;
14 import org.eclipse.core.runtime.*;
15 import org.eclipse.core.runtime.jobs.*;
16
17 /**
18  * Internal implementation class for jobs. Clients must not implement this class
19  * directly. All jobs must be subclasses of the API <code>org.eclipse.core.runtime.jobs.Job</code> class.
20  */

21 public abstract class InternalJob extends PlatformObject implements Comparable JavaDoc {
22     /**
23      * Job state code (value 16) indicating that a job has been removed from
24      * the wait queue and is about to start running. From an API point of view,
25      * this is the same as RUNNING.
26      */

27     static final int ABOUT_TO_RUN = 0x10;
28
29     /**
30      * Job state code (value 32) indicating that a job has passed scheduling
31      * precondition checks and is about to be added to the wait queue. From an API point of view,
32      * this is the same as WAITING.
33      */

34     static final int ABOUT_TO_SCHEDULE = 0x20;
35     /**
36      * Job state code (value 8) indicating that a job is blocked by another currently
37      * running job. From an API point of view, this is the same as WAITING.
38      */

39     static final int BLOCKED = 0x08;
40
41     //flag mask bits
42
private static final int M_STATE = 0xFF;
43     private static final int M_SYSTEM = 0x0100;
44     private static final int M_USER = 0x0200;
45     
46     /*
47      * flag on a job indicating that it was about to run, but has been canceled
48      */

49     private static final int M_ABOUT_TO_RUN_CANCELED = 0x0400;
50
51     protected static final JobManager manager = JobManager.getInstance();
52     private static int nextJobNumber = 0;
53
54     /**
55      * Start time constant indicating a job should be started at
56      * a time in the infinite future, causing it to sleep forever.
57      */

58     static final long T_INFINITE = Long.MAX_VALUE;
59     /**
60      * Start time constant indicating that the job has no start time.
61      */

62     static final long T_NONE = -1;
63
64     private volatile int flags = Job.NONE;
65     private final int jobNumber = nextJobNumber++;
66     private ListenerList listeners = null;
67     private IProgressMonitor monitor;
68     private String JavaDoc name;
69     /**
70      * The job ahead of me in a queue or list.
71      */

72     private InternalJob next;
73     /**
74      * The job behind me in a queue or list.
75      */

76     private InternalJob previous;
77     private int priority = Job.LONG;
78     /**
79      * Arbitrary properties (key,value) pairs, attached
80      * to a job instance by a third party.
81      */

82     private ObjectMap properties;
83     private IStatus result;
84     private ISchedulingRule schedulingRule;
85     /**
86      * If the job is waiting, this represents the time the job should start by.
87      * If this job is sleeping, this represents the time the job should wake up.
88      * If this job is running, this represents the delay automatic rescheduling,
89      * or -1 if the job should not be rescheduled.
90      */

91     private long startTime;
92     /*
93      * The thread that is currently running this job
94      */

95     private volatile Thread JavaDoc thread = null;
96
97     protected InternalJob(String JavaDoc name) {
98         Assert.isNotNull(name);
99         this.name = name;
100     }
101
102     /* (non-Javadoc)
103      * @see Job#addJobListener(IJobChangeListener)
104      */

105     protected void addJobChangeListener(IJobChangeListener listener) {
106         if (listeners == null)
107             listeners = new ListenerList(ListenerList.IDENTITY);
108         listeners.add(listener);
109     }
110
111     /**
112      * Adds an entry at the end of the list of which this item is the head.
113      */

114     final void addLast(InternalJob entry) {
115         InternalJob last = this;
116         //find the end of the queue
117
while (last.previous != null)
118             last = last.previous;
119         //add the new entry to the end of the queue
120
last.previous = entry;
121         entry.next = last;
122         entry.previous = null;
123     }
124
125     /* (non-Javadoc)
126      * @see Job#belongsTo(Object)
127      */

128     protected boolean belongsTo(Object JavaDoc family) {
129         return false;
130     }
131
132     /* (non-Javadoc)
133      * @see Job#cancel()
134      */

135     protected boolean cancel() {
136         return manager.cancel(this);
137     }
138
139     /* (non-Javadoc)
140      * @see Job#canceling()
141      */

142     protected void canceling() {
143         //default implementation does nothing
144
}
145
146     /* (on-Javadoc)
147      * @see java.lang.Comparable#compareTo(java.lang.Object)
148      */

149     public final int compareTo(Object JavaDoc otherJob) {
150         return ((InternalJob) otherJob).startTime >= startTime ? 1 : -1;
151     }
152
153     /* (non-Javadoc)
154      * @see Job#done(IStatus)
155      */

156     protected void done(IStatus endResult) {
157         manager.endJob(this, endResult, true);
158     }
159
160     /**
161      * Returns the job listeners that are only listening to this job. Returns
162      * <code>null</code> if this job has no listeners.
163      */

164     final ListenerList getListeners() {
165         return listeners;
166     }
167
168     /* (non-Javadoc)
169      * @see Job#getName()
170      */

171     protected String JavaDoc getName() {
172         return name;
173     }
174
175     /* (non-Javadoc)
176      * @see Job#getPriority()
177      */

178     protected int getPriority() {
179         return priority;
180     }
181
182     /**
183      * Returns the job's progress monitor, or null if it is not running.
184      */

185     final IProgressMonitor getProgressMonitor() {
186         return monitor;
187     }
188
189     /* (non-Javadoc)
190      * @see Job#getProperty
191      */

192     protected Object JavaDoc getProperty(QualifiedName key) {
193         // thread safety: (Concurrency001 - copy on write)
194
Map JavaDoc temp = properties;
195         if (temp == null)
196             return null;
197         return temp.get(key);
198     }
199
200     /* (non-Javadoc)
201      * @see Job#getResult
202      */

203     protected IStatus getResult() {
204         return result;
205     }
206
207     /* (non-Javadoc)
208      * @see Job#getRule
209      */

210     protected ISchedulingRule getRule() {
211         return schedulingRule;
212     }
213
214     /**
215      * Returns the time that this job should be started, awakened, or
216      * rescheduled, depending on the current state.
217      * @return time in milliseconds
218      */

219     final long getStartTime() {
220         return startTime;
221     }
222
223     /* (non-Javadoc)
224      * @see Job#getState()
225      */

226     protected int getState() {
227         int state = flags & M_STATE;
228         switch (state) {
229             //blocked state is equivalent to waiting state for clients
230
case BLOCKED :
231                 return Job.WAITING;
232             case ABOUT_TO_RUN :
233                 return Job.RUNNING;
234             case ABOUT_TO_SCHEDULE :
235                 return Job.WAITING;
236             default :
237                 return state;
238         }
239     }
240
241     /* (non-javadoc)
242      * @see Job.getThread
243      */

244     protected Thread JavaDoc getThread() {
245         return thread;
246     }
247
248     /**
249      * Returns the raw job state, including internal states no exposed as API.
250      */

251     final int internalGetState() {
252         return flags & M_STATE;
253     }
254
255     /**
256      * Must be called from JobManager#setPriority
257      */

258     final void internalSetPriority(int newPriority) {
259         this.priority = newPriority;
260     }
261
262     /**
263      * Must be called from JobManager#setRule
264      */

265     final void internalSetRule(ISchedulingRule rule) {
266         this.schedulingRule = rule;
267     }
268
269     /**
270      * Must be called from JobManager#changeState
271      */

272     final void internalSetState(int i) {
273         flags = (flags & ~M_STATE) | i;
274     }
275
276     /**
277      * Returns whether this job was canceled when it was about to run
278      */

279     final boolean isAboutToRunCanceled(){
280         return (flags & M_ABOUT_TO_RUN_CANCELED) != 0;
281     }
282
283     /* (non-Javadoc)
284      * @see Job#isBlocking()
285      */

286     protected boolean isBlocking() {
287         return manager.isBlocking(this);
288     }
289
290     /**
291      * Returns true if this job conflicts with the given job, and false otherwise.
292      */

293     final boolean isConflicting(InternalJob otherJob) {
294         ISchedulingRule otherRule = otherJob.getRule();
295         if (schedulingRule == null || otherRule == null)
296             return false;
297         //if one of the rules is a compound rule, it must be asked the question.
298
if (schedulingRule.getClass() == MultiRule.class)
299             return schedulingRule.isConflicting(otherRule);
300         return otherRule.isConflicting(schedulingRule);
301     }
302
303     /* (non-javadoc)
304      * @see Job.isSystem()
305      */

306     protected boolean isSystem() {
307         return (flags & M_SYSTEM) != 0;
308     }
309
310     /* (non-javadoc)
311      * @see Job.isUser()
312      */

313     protected boolean isUser() {
314         return (flags & M_USER) != 0;
315     }
316
317     /* (non-Javadoc)
318      * @see Job#join()
319      */

320     protected void join() throws InterruptedException JavaDoc {
321         manager.join(this);
322     }
323
324     /**
325      * Returns the next entry (ahead of this one) in the list, or null if there is no next entry
326      */

327     final InternalJob next() {
328         return next;
329     }
330
331     /**
332      * Returns the previous entry (behind this one) in the list, or null if there is no previous entry
333      */

334     final InternalJob previous() {
335         return previous;
336     }
337
338     /**
339      * Removes this entry from any list it belongs to. Returns the receiver.
340      */

341     final InternalJob remove() {
342         if (next != null)
343             next.setPrevious(previous);
344         if (previous != null)
345             previous.setNext(next);
346         next = previous = null;
347         return this;
348     }
349
350     /* (non-Javadoc)
351      * @see Job#removeJobListener(IJobChangeListener)
352      */

353     protected void removeJobChangeListener(IJobChangeListener listener) {
354         if (listeners != null)
355             listeners.remove(listener);
356     }
357
358     /* (non-Javadoc)
359      * @see Job#run(IProgressMonitor)
360      */

361     protected abstract IStatus run(IProgressMonitor progressMonitor);
362
363     /* (non-Javadoc)
364      * @see Job#schedule(long)
365      */

366     protected void schedule(long delay) {
367         if (shouldSchedule())
368             manager.schedule(this, delay, false);
369     }
370     
371     /**
372      * Sets whether this job was canceled when it was about to run
373      */

374     final void setAboutToRunCanceled(boolean value) {
375         flags = value ? flags | M_ABOUT_TO_RUN_CANCELED : flags & ~M_ABOUT_TO_RUN_CANCELED;
376         
377     }
378
379     /* (non-Javadoc)
380      * @see Job#setName(String)
381      */

382     protected void setName(String JavaDoc name) {
383         Assert.isNotNull(name);
384         this.name = name;
385     }
386
387     /**
388      * Sets the next entry in this linked list of jobs.
389      * @param entry
390      */

391     final void setNext(InternalJob entry) {
392         this.next = entry;
393     }
394
395     /**
396      * Sets the previous entry in this linked list of jobs.
397      * @param entry
398      */

399     final void setPrevious(InternalJob entry) {
400         this.previous = entry;
401     }
402
403     /* (non-Javadoc)
404      * @see Job#setPriority(int)
405      */

406     protected void setPriority(int newPriority) {
407         switch (newPriority) {
408             case Job.INTERACTIVE :
409             case Job.SHORT :
410             case Job.LONG :
411             case Job.BUILD :
412             case Job.DECORATE :
413                 manager.setPriority(this, newPriority);
414                 break;
415             default :
416                 throw new IllegalArgumentException JavaDoc(String.valueOf(newPriority));
417         }
418     }
419
420     /* (non-Javadoc)
421      * @see Job#setProgressGroup(IProgressMonitor, int)
422      */

423     protected void setProgressGroup(IProgressMonitor group, int ticks) {
424         Assert.isNotNull(group);
425         IProgressMonitor pm = manager.createMonitor(this, group, ticks);
426         if (pm != null)
427             setProgressMonitor(pm);
428     }
429
430     /**
431      * Sets the progress monitor to use for the next execution of this job,
432      * or for clearing the monitor when a job completes.
433      * @param monitor a progress monitor
434      */

435     final void setProgressMonitor(IProgressMonitor monitor) {
436         this.monitor = monitor;
437     }
438
439     /* (non-Javadoc)
440      * @see Job#setProperty(QualifiedName,Object)
441      */

442     protected void setProperty(QualifiedName key, Object JavaDoc value) {
443         // thread safety: (Concurrency001 - copy on write)
444
if (value == null) {
445             if (properties == null)
446                 return;
447             ObjectMap temp = (ObjectMap) properties.clone();
448             temp.remove(key);
449             if (temp.isEmpty())
450                 properties = null;
451             else
452                 properties = temp;
453         } else {
454             ObjectMap temp = properties;
455             if (temp == null)
456                 temp = new ObjectMap(5);
457             else
458                 temp = (ObjectMap) properties.clone();
459             temp.put(key, value);
460             properties = temp;
461         }
462     }
463
464     /**
465      * Sets or clears the result of an execution of this job.
466      * @param result a result status, or <code>null</code>
467      */

468     final void setResult(IStatus result) {
469         this.result = result;
470     }
471
472     /* (non-Javadoc)
473      * @see Job#setRule(ISchedulingRule)
474      */

475     protected void setRule(ISchedulingRule rule) {
476         manager.setRule(this, rule);
477     }
478
479     /**
480      * Sets a time to start, wake up, or schedule this job,
481      * depending on the current state
482      * @param time a time in milliseconds
483      */

484     final void setStartTime(long time) {
485         startTime = time;
486     }
487
488     /* (non-javadoc)
489      * @see Job.setSystem
490      */

491     protected void setSystem(boolean value) {
492         if (getState() != Job.NONE)
493             throw new IllegalStateException JavaDoc();
494         flags = value ? flags | M_SYSTEM : flags & ~M_SYSTEM;
495     }
496
497     /* (non-javadoc)
498      * @see Job.setThread
499      */

500     protected void setThread(Thread JavaDoc thread) {
501         this.thread = thread;
502     }
503
504     /* (non-javadoc)
505      * @see Job.setUser
506      */

507     protected void setUser(boolean value) {
508         if (getState() != Job.NONE)
509             throw new IllegalStateException JavaDoc();
510         flags = value ? flags | M_USER : flags & ~M_USER;
511     }
512
513     /* (Non-javadoc)
514      * @see Job#shouldSchedule
515      */

516     protected boolean shouldSchedule() {
517         return true;
518     }
519
520     /* (non-Javadoc)
521      * @see Job#sleep()
522      */

523     protected boolean sleep() {
524         return manager.sleep(this);
525     }
526
527     /* (non-Javadoc)
528      * Prints a string-based representation of this job instance.
529      * For debugging purposes only.
530      */

531     public String JavaDoc toString() {
532         return getName() + "(" + jobNumber + ")"; //$NON-NLS-1$//$NON-NLS-2$
533
}
534
535     /* (non-Javadoc)
536      * @see Job#wakeUp(long)
537      */

538     protected void wakeUp(long delay) {
539         manager.wakeUp(this, delay);
540     }
541 }
542
Popular Tags