jsr-299 libs and facets
[idea/community.git] / platform / platform-api / src / com / intellij / openapi / progress / BackgroundTaskQueue.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.intellij.openapi.progress;
18
19 import com.intellij.openapi.application.ApplicationManager;
20 import com.intellij.openapi.application.ModalityState;
21 import com.intellij.openapi.project.Project;
22 import org.jetbrains.annotations.NotNull;
23
24 import java.util.LinkedList;
25 import java.util.Queue;
26
27 /**
28  * @author yole
29  */
30 public class BackgroundTaskQueue {
31   private final Project myProject;
32   private final Queue<Task> myQueue = new LinkedList<Task>();
33   private boolean myHasActiveTask = false;
34   private Task.Backgroundable myRunnerTask;
35
36   public BackgroundTaskQueue(String title) {
37     this(null, title);
38   }
39
40   public BackgroundTaskQueue(Project project, String title) {
41     myProject = project;
42     myRunnerTask = new Task.Backgroundable(project, title) {
43       public void run(@NotNull final ProgressIndicator indicator) {
44         while (true) {
45           final Task task;
46
47           synchronized(myQueue) {
48             myHasActiveTask = true;
49             task = myQueue.poll();
50             if (task == null) {
51               myHasActiveTask = false;
52               return;
53             }
54           }
55
56           indicator.setText(task.getTitle());
57           try {
58             task.run(indicator);
59           } catch (ProcessCanceledException e) {
60             //ok
61           }
62
63           ApplicationManager.getApplication().invokeLater(new Runnable() {
64             public void run() {
65               if (myProject == null || !myProject.isDisposed()) {
66                 task.onSuccess();
67               }
68             }
69           }, ModalityState.NON_MODAL);
70         }
71       }
72     };
73   }
74
75   public void run(Task.Backgroundable task) {
76     if (ApplicationManager.getApplication().isUnitTestMode()) {
77       task.run(new EmptyProgressIndicator());
78       task.onSuccess();
79     }
80     else if (task.isConditionalModal() && !task.shouldStartInBackground()) {
81       ProgressManager.getInstance().run(task);
82     }
83     else {
84       boolean hadActiveTask;
85       synchronized (myQueue) {
86         hadActiveTask = myHasActiveTask;
87         myQueue.offer(task);
88         myHasActiveTask = true;
89       }
90       if (!hadActiveTask) {
91         if (ApplicationManager.getApplication().isDispatchThread()) {
92           ProgressManager.getInstance().run(myRunnerTask);
93         }
94         else {
95           ApplicationManager.getApplication().invokeLater(new Runnable() {
96             public void run() {
97               if (myProject == null || !myProject.isDisposed()) {
98                 ProgressManager.getInstance().run(myRunnerTask);
99               }
100             }
101           });
102         }
103       }
104     }
105   }
106 }