diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsProcessor.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsProcessor.java index 95d3e7195f08..5f600e5ab20b 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsProcessor.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsProcessor.java @@ -16,70 +16,63 @@ package org.jetbrains.idea.maven.project; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; import com.intellij.util.concurrency.Semaphore; import org.jetbrains.idea.maven.embedder.MavenConsole; import org.jetbrains.idea.maven.execution.SoutMavenConsole; -import org.jetbrains.idea.maven.utils.*; +import org.jetbrains.idea.maven.utils.MavenProcessCanceledException; +import org.jetbrains.idea.maven.utils.MavenProgressIndicator; +import org.jetbrains.idea.maven.utils.MavenTask; +import org.jetbrains.idea.maven.utils.MavenUtil; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; +import java.util.LinkedList; +import java.util.Queue; public class MavenProjectsProcessor { - private static final int WAIT_TIMEOUT = 2000; - private final Project myProject; private final String myTitle; private final boolean myCancellable; private final MavenEmbeddersManager myEmbeddersManager; - private final Thread myThread; - private final BlockingQueue myQueue = new LinkedBlockingQueue(); + private final Queue myQueue = new LinkedList(); + private boolean isProcessing; + private volatile boolean isStopped; - private volatile MavenUtil.MavenTaskHandler myCurrentTaskHandler; public MavenProjectsProcessor(Project project, String title, boolean cancellable, MavenEmbeddersManager embeddersManager) { myProject = project; myTitle = title; myCancellable = cancellable; myEmbeddersManager = embeddersManager; - myThread = new Thread(new Runnable() { - public void run() { - try { - while (doRunCycle()) { /* nothing */ } - } - catch (Throwable e) { - MavenLog.LOG.error(e); - throw new RuntimeException(e); - } - } - }, getClass().getSimpleName() + ": " + title); - - if (isImmediateMode()) return; - - isStopped = false; - myThread.start(); // rework if make inheritance } public void scheduleTask(MavenProjectsProcessorTask task) { synchronized (myQueue) { + if (!isProcessing && !MavenUtil.isNoBackgroundMode()) { + isProcessing = true; + startProcessing(task); + return; + } if (myQueue.contains(task)) return; myQueue.add(task); - myQueue.notifyAll(); } } public void removeTask(MavenProjectsProcessorTask task) { synchronized (myQueue) { myQueue.remove(task); - myQueue.notifyAll(); } } public void waitForCompletion() { - if (isEmpty()) return; + if (isStopped) return; - if (isImmediateMode()) { - while (!isEmpty() && doRunCycle()) {/* do nothing */} + if (MavenUtil.isNoBackgroundMode()) { + synchronized (myQueue) { + while (!myQueue.isEmpty()) { + startProcessing(myQueue.poll()); + } + } return; } @@ -93,94 +86,67 @@ public class MavenProjectsProcessor { }); while (true) { - if (isStopped || isEmpty() || semaphore.waitFor(WAIT_TIMEOUT)) return; - } - } - - private boolean isEmpty() { - synchronized (myQueue) { - return myQueue.isEmpty(); - } - } - - private void cancelAllPendingRequests() { - synchronized (myQueue) { - myQueue.clear(); - myQueue.notifyAll(); + if (isStopped || semaphore.waitFor(1000)) return; } } public void stop() { - if (isImmediateMode()) return; - isStopped = true; synchronized (myQueue) { - myQueue.notifyAll(); + myQueue.clear(); } - cancelAllPendingRequests(); - - MavenUtil.MavenTaskHandler handler = myCurrentTaskHandler; - if (handler != null) handler.stop(); - - //myThread.join(); } - public boolean doRunCycle() { - try { - synchronized (myQueue) { - while (myQueue.isEmpty()) { - myQueue.wait(WAIT_TIMEOUT); - if (isStopped) return false; - } - } - } - catch (InterruptedException e) { - throw new RuntimeException(e); - } - if (isStopped) return false; - - myCurrentTaskHandler = MavenUtil.runInBackground(myProject, myTitle, myCancellable, new MavenTask() { + private void startProcessing(final MavenProjectsProcessorTask task) { + MavenUtil.runInBackground(myProject, myTitle, myCancellable, new MavenTask() { public void run(MavenProgressIndicator indicator) throws MavenProcessCanceledException { - int counter = 0; - while (true) { - MavenProjectsProcessorTask task; - int queueSize; - - synchronized (myQueue) { - task = myQueue.peek(); - queueSize = myQueue.size(); - } - if (isStopped || task == null) return; - try { - indicator.checkCanceled(); - - counter++; - indicator.setFraction(counter / (double)(counter + queueSize)); - - String text = myTitle; - if (queueSize > 0) text += " (" + (queueSize + 1) + " in queue)"; - indicator.setText(text); - - task.perform(myProject, myEmbeddersManager, new SoutMavenConsole(), indicator); - } - finally { - synchronized (myQueue) { - myQueue.remove(task); // remove the completed task from the queue - } + Condition condition = new Condition() { + public boolean value(MavenProgressIndicator mavenProgressIndicator) { + return isStopped; } + }; + indicator.addCancelCondition(condition); + try { + doProcessPendingTasks(indicator, task); + } + finally { + indicator.removeCancelCondition(condition); } } }); - myCurrentTaskHandler.waitFor(); - if (myCurrentTaskHandler.isCancelled()) { - cancelAllPendingRequests(); - } - myCurrentTaskHandler = null; - - return !isStopped; } - private boolean isImmediateMode() { - return MavenUtil.isNoBackgroundMode(); + private void doProcessPendingTasks(MavenProgressIndicator indicator, MavenProjectsProcessorTask task) + throws MavenProcessCanceledException { + int counter = 0; + try { + while (true) { + indicator.checkCanceled(); + counter++; + + int remained; + synchronized (myQueue) { + remained = myQueue.size(); + } + indicator.setFraction(counter / (double)(counter + remained)); + + task.perform(myProject, myEmbeddersManager, new SoutMavenConsole(), indicator); + + synchronized (myQueue) { + task = myQueue.poll(); + if (task == null) { + isProcessing = false; + return; + } + } + } + } + catch (MavenProcessCanceledException e) { + synchronized (myQueue) { + myQueue.clear(); + isProcessing = false; + } + throw e; + } } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenProblemFileHighlighter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenProblemFileHighlighter.java index a659efb12e5b..49eb62bdcaff 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenProblemFileHighlighter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenProblemFileHighlighter.java @@ -15,7 +15,9 @@ */ package org.jetbrains.idea.maven.utils; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; @@ -29,8 +31,12 @@ public class MavenProblemFileHighlighter implements Condition { myProject = project; } - public boolean value(VirtualFile file) { - PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file); - return psiFile != null && MavenDomUtil.isMavenFile(psiFile); + public boolean value(final VirtualFile file) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + public Boolean compute() { + PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file); + return psiFile != null && MavenDomUtil.isMavenFile(psiFile); + } + }); } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenProgressIndicator.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenProgressIndicator.java index 933be27a53d1..149bd3b6bdb4 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenProgressIndicator.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenProgressIndicator.java @@ -18,88 +18,65 @@ package org.jetbrains.idea.maven.utils; import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.util.containers.ContainerUtil; +import com.intellij.openapi.util.Condition; +import java.util.ArrayList; import java.util.List; public class MavenProgressIndicator { - private final List myIndicators = ContainerUtil.createEmptyCOWList(); - private String myText; - private String myText2; - private double myFraction; - private boolean myCanceled; + private ProgressIndicator myIndicator; + private List> myCancelConditions = new ArrayList>(); public MavenProgressIndicator() { + this(new EmptyProgressIndicator()); } public MavenProgressIndicator(ProgressIndicator i) { - myText = i.getText(); - myText2 = i.getText2(); - myFraction = i.getFraction(); - myCanceled = i.isCanceled(); - addIndicator(i); + myIndicator = i; } - public void addIndicator(ProgressIndicator i) { - synchronized (this) { - i.setText(myText); - i.setText2(myText2); - i.setFraction(myFraction); - if (myCanceled) i.cancel(); - } - myIndicators.add(i); + public synchronized void setIndicator(ProgressIndicator i) { + i.setText(myIndicator.getText()); + i.setText2(myIndicator.getText2()); + i.setFraction(myIndicator.getFraction()); + if (i.isCanceled()) i.cancel(); + myIndicator = i; } - public ProgressIndicator getIndicator() { - return myIndicators.isEmpty() ? new EmptyProgressIndicator() : myIndicators.get(0); + public synchronized ProgressIndicator getIndicator() { + return myIndicator; } - public void setText(String text) { - synchronized (this) { - myText = text; - } - for (ProgressIndicator each : myIndicators) { - each.setText(text); - } + public synchronized void setText(String text) { + myIndicator.setText(text); } - public void setText2(String text) { - synchronized (this) { - myText2 = text; - } - for (ProgressIndicator each : myIndicators) { - each.setText2(text); - } + public synchronized void setText2(String text) { + myIndicator.setText2(text); } - public void setFraction(double fraction) { - synchronized (this) { - myFraction = fraction; - } - for (ProgressIndicator each : myIndicators) { - each.setFraction(fraction); - } + public synchronized void setFraction(double fraction) { + myIndicator.setFraction(fraction); } - public void cancel() { - synchronized (this) { - myCanceled = true; - } - for (ProgressIndicator each : myIndicators) { - each.cancel(); - } + public synchronized void cancel() { + myIndicator.cancel(); } - public boolean isCanceled() { - for (ProgressIndicator each : myIndicators) { - if (each.isCanceled()) { - synchronized (this) { - myCanceled = true; - } - break; - } + public synchronized void addCancelCondition(Condition condition) { + myCancelConditions.add(condition); + } + + public synchronized void removeCancelCondition(Condition condition) { + myCancelConditions.remove(condition); + } + + public synchronized boolean isCanceled() { + if (myIndicator.isCanceled()) return true; + for (Condition each : myCancelConditions) { + if (each.value(this)) return true; } - return myCanceled; + return false; } public void checkCanceled() throws MavenProcessCanceledException { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java index 739042267bec..0f2ebbb8ff1c 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java @@ -432,14 +432,14 @@ public class MavenUtil { if (isNoBackgroundMode()) { runnable.run(); - return new MavenTaskHandler(indicator) { + return new MavenTaskHandler() { public void waitFor() { } }; } else { final Future future = ApplicationManager.getApplication().executeOnPooledThread(runnable); - final MavenTaskHandler handler = new MavenTaskHandler(indicator) { + final MavenTaskHandler handler = new MavenTaskHandler() { public void waitFor() { try { future.get(); @@ -457,7 +457,7 @@ public class MavenUtil { if (future.isDone()) return; new Task.Backgroundable(project, title, cancellable) { public void run(@NotNull ProgressIndicator i) { - indicator.addIndicator(i); + indicator.setIndicator(i); handler.waitFor(); } }.queue(); @@ -467,21 +467,7 @@ public class MavenUtil { } } - public static abstract class MavenTaskHandler { - private final MavenProgressIndicator myIndicator; - - private MavenTaskHandler(MavenProgressIndicator indicator) { - myIndicator = indicator; - } - - public void stop() { - myIndicator.cancel(); - } - - public abstract void waitFor(); - - public boolean isCancelled() { - return myIndicator.isCanceled(); - } + public interface MavenTaskHandler { + void waitFor(); } } diff --git a/plugins/maven/src/main/resources/ProjectBundle.properties b/plugins/maven/src/main/resources/ProjectBundle.properties index 1b43705f9190..24f592eea51f 100644 --- a/plugins/maven/src/main/resources/ProjectBundle.properties +++ b/plugins/maven/src/main/resources/ProjectBundle.properties @@ -2,17 +2,17 @@ maven.name=Maven maven.scanning.projects=Scanning Maven projects maven.locating.files=Locating Maven project files maven.searching.profiles=Looking for available profiles -maven.reading=Reading +maven.reading=Reading Maven projects maven.reading.pom=Reading {0} -maven.resolving=Resolving dependencies +maven.resolving=Resolving Maven dependencies maven.resolving.finished=Finished resolving dependencies maven.resolving.pom=Resolving dependencies of {0} -maven.updating.folders=Generating sources +maven.updating.folders=Generating Maven sources maven.updating.folders.finished=Finished Generating sources maven.updating.folders.pom=Generating sources for {0} -maven.downloading.plugins=Downloading plugins +maven.downloading.plugins=Downloading Maven plugins maven.downloading.pom.plugins=Downloading plugins for {0} -maven.downloading=Downloading sources and javadocs +maven.downloading=Downloading Maven sources and javadocs maven.downloading.finished=Finished downloading artifacts maven.downloading.artifact=Downloading {0} maven.transfer.progress={0}/{1}K [{2}] {3}