blob: c8109dce3d291bc1df0941d1326744a654d8e759 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.remoteServer.util;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Progressive;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Disposer;
import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.concurrent.atomic.AtomicReference;
public abstract class CloudRuntimeTask<
T,
DC extends DeploymentConfiguration,
SR extends CloudServerRuntimeInstance<DC, ?, ?>> {
private static final Logger LOG = Logger.getInstance("#" + CloudRuntimeTask.class.getName());
private final Project myProject;
private final String myTitle;
private final AtomicReference<Boolean> mySuccess = new AtomicReference<Boolean>();
private final AtomicReference<String> myErrorMessage = new AtomicReference<String>();
public CloudRuntimeTask(Project project, String title) {
myProject = project;
myTitle = title;
}
public T performSync() {
return perform(true, null);
}
public void performAsync() {
performAsync(null);
}
public void performAsync(Disposable disposable) {
perform(false, disposable);
}
private T perform(boolean modal, final Disposable disposable) {
final Semaphore semaphore = new Semaphore();
semaphore.down();
final AtomicReference<T> result = new AtomicReference<T>();
final Progressive progressive = new Progressive() {
@Override
public void run(@NotNull ProgressIndicator indicator) {
indicator.setIndeterminate(true);
while (!indicator.isCanceled()) {
if (semaphore.waitFor(500)) {
if (mySuccess.get()) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
if (disposable == null || !Disposer.isDisposed(disposable)) {
postPerform(result.get());
}
}
});
}
break;
}
}
}
};
Task task;
boolean cancellable = isCancellable(modal);
if (modal) {
task = new Task.Modal(myProject, myTitle, cancellable) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
progressive.run(indicator);
}
};
}
else {
task = new Task.Backgroundable(myProject, myTitle, cancellable) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
progressive.run(indicator);
}
@Override
public boolean shouldStartInBackground() {
return CloudRuntimeTask.this.shouldStartInBackground();
}
};
}
mySuccess.set(false);
myErrorMessage.set(null);
run(semaphore, result);
task.queue();
return result.get();
}
protected boolean shouldStartInBackground() {
return true;
}
protected void postPerform(T result) {
}
protected boolean isCancellable(boolean modal) {
return modal;
}
protected void run(final Semaphore semaphore, final AtomicReference<T> result) {
run(getServerRuntime(), semaphore, result);
}
protected void run(final SR serverRuntime, final Semaphore semaphore, final AtomicReference<T> result) {
serverRuntime.getTaskExecutor().submit(new Runnable() {
@Override
public void run() {
try {
result.set(CloudRuntimeTask.this.run(serverRuntime));
mySuccess.set(true);
}
catch (ServerRuntimeException e) {
runtimeErrorOccurred(e.getMessage());
}
finally {
semaphore.up();
}
}
});
}
protected void runtimeErrorOccurred(@NotNull String errorMessage) {
myErrorMessage.set(errorMessage);
LOG.info(errorMessage);
}
public void showMessageDialog(JComponent component, String successMessage, String title) {
if (mySuccess.get()) {
Messages.showInfoMessage(component, successMessage, title);
return;
}
String errorMessage = myErrorMessage.get();
if (errorMessage != null) {
Messages.showErrorDialog(component, errorMessage, title);
}
}
protected abstract SR getServerRuntime();
protected abstract T run(SR serverRuntime) throws ServerRuntimeException;
}