package com.trendmicro.tme.grapheditor; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.StreamingOutput; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class GraphvizStreamingOutput implements StreamingOutput { private static final Logger logger = LoggerFactory.getLogger(GraphvizStreamingOutput.class); private String dot; private String type; public GraphvizStreamingOutput(String dot, String type) { this.dot = dot; this.type = type; } @Override public void write(final OutputStream outputStream) throws IOException, WebApplicationException { Process p = null; try { p = Runtime.getRuntime().exec(String.format("dot -T%s", type).split(" ")); final InputStream resultStream = p.getInputStream(); final InputStream errorStream = p.getErrorStream(); final OutputStream toDotStream = p.getOutputStream(); new Thread() { @Override public void run() { try { toDotStream.write(dot.getBytes()); toDotStream.close(); } catch(IOException e) { logger.error(e.getMessage(), e); } } }.start(); final ByteArrayOutputStream bos = new ByteArrayOutputStream(); new Thread() { @Override public void run() { try { IOUtils.copy(errorStream, bos); } catch(IOException e) { logger.error(e.getMessage(), e); } } }.start(); IOUtils.copy(resultStream, outputStream); if(p.waitFor() != 0) { String errorMsg = bos.toString(); logger.error("dot render error: {}", errorMsg); logger.error("\n======== input to dot =========\n{}\n===============================", dot); throw new Exception("dot render error: " + errorMsg); } } catch(Exception e) { logger.error(e.getMessage(), e); throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR.getStatusCode()); } finally { p.destroy(); } } }