package com.intellij.flex.uiDesigner;
import com.intellij.diagnostic.LogMessageEx;
import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.flex.uiDesigner.libraries.InitException;
import com.intellij.flex.uiDesigner.mxml.ProjectComponentReferenceCounter;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.ExceptionUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
abstract class DocumentTask extends Task.Backgroundable {
protected static final Logger LOG = Logger.getInstance(DesignerApplicationLauncher.class.getName());
protected ProgressIndicator indicator;
protected final ProblemsHolder problemsHolder = new ProblemsHolder();
protected final Module module;
protected final PostTask postTask;
public DocumentTask(@NotNull Module module, @NotNull PostTask postTask) {
this(module, false, postTask);
}
public DocumentTask(@NotNull Module module, boolean debug, @NotNull PostTask postTask) {
super(module.getProject(), DesignerApplicationManager.getOpenActionTitle(debug));
this.module = module;
this.postTask = postTask;
}
@Override
public final void run(@NotNull ProgressIndicator indicator) {
this.indicator = indicator;
try {
Throwable error = null;
beforeRun();
boolean result = false;
try {
result = doRun(indicator);
}
catch (ProcessCanceledException ignored) {
// don't log ProcessCanceledException
}
catch (Throwable e) {
error = e;
}
if (!result || indicator.isCanceled()) {
problemsHolder.disableLog();
processErrorOrCancel();
}
if (error != null) {
try {
LOG.error(error);
}
catch (AssertionError ignored) {
}
}
}
finally {
Disposer.dispose(postTask);
}
}
protected void beforeRun() {
}
abstract boolean doRun(ProgressIndicator indicator) throws
IOException, ExecutionException, InterruptedException,
TimeoutException;
protected abstract void processErrorOrCancel();
protected static void processInitException(InitException e, Module module, boolean debug) {
DesignerApplicationManager.notifyUser(debug, e.getMessage(), module);
if (e.attachments == null) {
LOG.error(e.getCause());
}
else {
final Collection<Attachment> attachments = new ArrayList<>(e.attachments.length);
for (Attachment attachment : e.attachments) {
if (attachment != null) {
attachments.add(attachment);
}
else {
break;
}
}
LOG.error(LogMessageEx.createEvent(e.getMessage(), e.technicalMessage + "\n" + ExceptionUtil.getThrowableText(e), e.getMessage(),
null, attachments));
}
}
abstract static class PostTask implements Disposable {
abstract boolean run(Module module,
@Nullable ProjectComponentReferenceCounter projectComponentReferenceCounter,
ProgressIndicator indicator,
ProblemsHolder problemsHolder);
@Override
public void dispose() {
}
}
}