fix CacheUpdateSession.updatingDone() assertion
[fedora-idea.git] / platform / platform-impl / src / com / intellij / openapi / project / CacheUpdateRunner.java
blob47100309d995df85f2f2f0c50b7d13806e4f44e8
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.openapi.project;
18 import com.intellij.ide.caches.CacheUpdater;
19 import com.intellij.ide.caches.FileContent;
20 import com.intellij.openapi.application.Application;
21 import com.intellij.openapi.application.ApplicationAdapter;
22 import com.intellij.openapi.application.ApplicationManager;
23 import com.intellij.openapi.progress.ProcessCanceledException;
24 import com.intellij.openapi.progress.ProgressIndicator;
25 import com.intellij.openapi.progress.ProgressManager;
26 import com.intellij.openapi.progress.util.ProgressIndicatorBase;
27 import com.intellij.openapi.vfs.VirtualFile;
28 import com.intellij.util.Consumer;
29 import gnu.trove.THashSet;
31 import java.util.Collection;
32 import java.util.Set;
34 class CacheUpdateRunner {
35 private final Project myProject;
36 private final Collection<CacheUpdater> myUpdaters;
37 private CacheUpdateSession mySession;
39 CacheUpdateRunner(Project project, Collection<CacheUpdater> updaters) {
40 myProject = project;
41 myUpdaters = updaters;
44 public int queryNeededFiles(ProgressIndicator indicator) {
45 // can be queried twice in DumbService
46 if (mySession == null) {
47 mySession = new CacheUpdateSession(myUpdaters, indicator);
49 return mySession.getFilesToUpdate().size();
52 public void processFiles(final ProgressIndicator indicator, boolean processInReadAction) {
53 FileContentQueue queue = new FileContentQueue();
54 try {
55 Collection<VirtualFile> files = mySession.getFilesToUpdate();
56 final double total = files.size();
57 queue.queue(files, indicator);
59 Consumer<VirtualFile> progressUpdater = new Consumer<VirtualFile>() {
60 // need set here to handle queue.pushbacks after checkCancelled() in order
61 // not to count the same file several times
62 final Set<VirtualFile> processed = new THashSet<VirtualFile>();
64 public void consume(VirtualFile virtualFile) {
65 indicator.checkCanceled();
66 processed.add(virtualFile);
67 indicator.setFraction(processed.size() / total);
68 if (virtualFile.isValid()) {
69 indicator.setText2(virtualFile.getPresentableUrl());
71 else {
72 indicator.setText2("");
77 while (!myProject.isDisposed()) {
78 indicator.checkCanceled();
79 // todo wait for the user...
80 if (processSomeFilesWhileUserIsInactive(queue, progressUpdater, mySession, processInReadAction)) {
81 break;
85 if (myProject.isDisposed()) {
86 indicator.cancel();
87 indicator.checkCanceled();
90 catch (ProcessCanceledException e) {
91 mySession.canceled();
92 throw e;
96 public void updatingDone() {
97 try {
98 mySession.updatingDone();
100 catch (ProcessCanceledException e) {
101 mySession.canceled();
102 throw e;
106 private boolean processSomeFilesWhileUserIsInactive(final FileContentQueue queue,
107 final Consumer<VirtualFile> progressUpdater,
108 final CacheUpdateSession session,
109 final boolean processInReadAction) {
110 final ProgressIndicatorBase innerIndicator = new ProgressIndicatorBase();
111 final ApplicationAdapter canceller = new ApplicationAdapter() {
112 @Override
113 public void beforeWriteActionStart(Object action) {
114 innerIndicator.cancel();
117 final Application application = ApplicationManager.getApplication();
118 application.addApplicationListener(canceller);
120 final boolean[] isFinished = new boolean[1];
121 try {
122 ProgressManager.getInstance().runProcess(new Runnable() {
123 public void run() {
124 while (true) {
125 if (myProject.isDisposed()) return;
126 if (innerIndicator.isCanceled()) return;
128 final FileContent fileContent = queue.take();
129 if (fileContent == null) {
130 isFinished[0] = true;
131 return;
134 try {
135 final Runnable action = new Runnable() {
136 public void run() {
137 innerIndicator.checkCanceled();
139 if (myProject.isDisposed()) return;
141 final VirtualFile file = fileContent.getVirtualFile();
142 progressUpdater.consume(file);
143 session.processFile(fileContent);
146 if (processInReadAction) {
147 application.runReadAction(action);
149 else {
150 action.run();
153 catch (ProcessCanceledException e) {
154 queue.pushback(fileContent);
155 return;
159 }, innerIndicator);
161 finally {
162 application.removeApplicationListener(canceller);
165 return isFinished[0];