package org.plantuml.idea.rendering; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import org.apache.commons.lang.builder.ToStringBuilder; import org.plantuml.idea.plantuml.PlantUml; import org.plantuml.idea.plantuml.PlantUmlIncludes; import org.plantuml.idea.toolwindow.ExecutionStatusPanel; import java.io.File; import java.util.Map; public abstract class RenderCommand implements Runnable { public static final Logger logger = Logger.getInstance(RenderCommand.class); protected Reason reason; protected String sourceFilePath; protected final String source; protected final File baseDir; protected final int page; protected int zoom; protected RenderCacheItem cachedItem; protected int version; protected boolean renderUrlLinks; protected LazyApplicationPoolExecutor.Delay delay; protected ExecutionStatusPanel label; public enum Reason { INCLUDES, FILE_SWITCHED, REFRESH, CARET, MANUAL_UPDATE, /* no function*/ SOURCE_PAGE_ZOOM } public RenderCommand(Reason reason, String sourceFilePath, String source, File baseDir, int page, int zoom, RenderCacheItem cachedItem, int version, boolean renderUrlLinks, LazyApplicationPoolExecutor.Delay delay, ExecutionStatusPanel label) { this.reason = reason; this.sourceFilePath = sourceFilePath; this.source = source; this.baseDir = baseDir; this.page = page; this.zoom = zoom; this.cachedItem = cachedItem; this.version = version; this.renderUrlLinks = renderUrlLinks; this.delay = delay; this.label = label; } @Override public void run() { try { if (source.isEmpty()) { logger.debug("source is empty"); return; } long start = System.currentTimeMillis(); label.update(version, ExecutionStatusPanel.State.EXECUTING); final Map<File, Long> includedFiles = PlantUmlIncludes.commitIncludes(source, baseDir); logger.debug("includedFiles=", includedFiles); final RenderRequest renderRequest = new RenderRequest(baseDir, source, PlantUml.ImageFormat.PNG, page, zoom, version, renderUrlLinks, reason); final RenderResult result = PlantUmlRenderer.render(renderRequest, cachedItem); final RenderCacheItem newItem = new RenderCacheItem(renderRequest, sourceFilePath, source, baseDir, zoom, page, includedFiles, result, result.getImageItemsAsArray(), version); final long total = System.currentTimeMillis() - start; if (!Thread.currentThread().isInterrupted() && hasImages(newItem.getImageItems())) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { postRenderOnEDT(newItem, total, result); } }); } else { logger.debug("no images rendered"); label.update(version, ExecutionStatusPanel.State.DONE, total, result); } } catch (RenderingCancelledException e) { logger.info("command interrupted", e); label.update(version, ExecutionStatusPanel.State.CANCELLED); } catch (Throwable e) { label.update(version, ExecutionStatusPanel.State.ERROR); logger.error("Exception occurred rendering " + this, e); } } protected abstract void postRenderOnEDT(RenderCacheItem newItem, long total, RenderResult result); private boolean hasImages(ImageItem[] imageItems) { for (ImageItem imageItem : imageItems) { if (imageItem != null && imageItem.hasImage()) { return true; } } return false; } @Override public String toString() { return new ToStringBuilder(this) .append("reason", reason) .append("sourceFilePath", sourceFilePath) .append("selectedDir", baseDir.getName()) .append("page", page) .append("zoom", zoom) .append("cachedItem", cachedItem) .append("version", version) .toString(); } }