package net.sourceforge.plantuml.servlet; import java.io.IOException; import java.io.PrintWriter; import java.net.URL; import java.net.URLDecoder; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.sourceforge.plantuml.SourceStringReader; import net.sourceforge.plantuml.code.Transcoder; import net.sourceforge.plantuml.code.TranscoderUtil; import HTTPClient.CookieModule; import HTTPClient.HTTPConnection; import HTTPClient.HTTPResponse; import HTTPClient.ModuleException; import HTTPClient.ParseException; /* * Original idea from Achim Abeling for Confluence macro * See http://www.banapple.de/display/BANAPPLE/plantuml+user+macro * * Modified by Arnaud Roques * Packaged by Maxime Sinclair * */ public class PlantUmlServlet extends HttpServlet { private static final Pattern startumlPattern = Pattern .compile("/\\w+/uml/startuml/(.*)"); private static final Pattern imagePattern = Pattern .compile("/\\w+/uml/image/(.*)"); private static final Pattern proxyPattern = Pattern .compile("/\\w+/uml/proxy/((\\d+)/)?(http://.*)"); public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { final String uri = request.getRequestURI(); Matcher startumlMatcher = startumlPattern.matcher(uri); Matcher imageMatcher = imagePattern.matcher(uri); Matcher proxyMatcher = proxyPattern.matcher(uri); if (startumlMatcher.matches()) { String source = startumlMatcher.group(1); handleImage(response, source); } else if (imageMatcher.matches()) { String source = imageMatcher.group(1); handleImageDecompress(response, source); } else if (proxyMatcher.matches()) { String num = proxyMatcher.group(2); String source = proxyMatcher.group(3); handleImageProxy(response, num, source); } else { doPost(request, response); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.print(""); writer.print(""); writer .print(""); writer.print(""); writer.print(""); writer .print(""); writer .print(""); writer.print(""); writer.print(""); writer .print("

PlantUMLServer

This application provides a servlet which serves images createdby PlantUML.

"); String text = request.getParameter("text"); String url = request.getParameter("url"); String encode = ""; Transcoder transcoder = getTranscoder(); if (url != null) { Pattern p = Pattern.compile(".*/(.*)"); Matcher m = p.matcher(url); if (m.find()) { url = m.group(1); } text = transcoder.decode(url); } writer .print("

"); writer.print("
"); writer.print("You can enter here a previously generated URL:

"); String host = "http://" + request.getServerName() + ":" + request.getServerPort(); String total = host + "/plantuml/uml/image/" + encode; writer .print("

"); writer.print("
"); if (text != null) { writer.print("
"); writer.print("You can use the following URL:

"); String urlPart = "\"" + total + "\""; writer.print(""); writer.print(""); writer.print("<img src=" + urlPart + " >"); writer.print("

"); writer.print(""); writer.print(""); writer.print(""); } writer.print(""); writer.flush(); } private Transcoder getTranscoder() { return TranscoderUtil.getDefaultTranscoder(); } private void handleImage(HttpServletResponse response, String source) throws IOException { source = URLDecoder.decode(source, "UTF-8"); StringBuilder plantUmlSource = new StringBuilder(); StringTokenizer tokenizer = new StringTokenizer(source, "/@"); while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); plantUmlSource.append(token).append("\n"); } sendImage(response, plantUmlSource.toString()); } private void handleImageDecompress(HttpServletResponse response, String source) throws IOException { source = URLDecoder.decode(source, "UTF-8"); Transcoder transcoder = getTranscoder(); String text2 = transcoder.decode(source); sendImage(response, text2); } private void handleImageProxy(HttpServletResponse response, String num, String source) throws IOException { String s = getContent(source); SourceStringReader reader = new SourceStringReader(s); int n = num == null ? 0 : Integer.parseInt(num); // Write the first image to "os" reader.generateImage(response.getOutputStream(), n); } private void sendImage(HttpServletResponse response, String text) throws IOException { StringBuilder plantUmlSource = new StringBuilder(); plantUmlSource.append("@startuml\n"); plantUmlSource.append(text); plantUmlSource.append("\n@enduml"); SourceStringReader reader = new SourceStringReader(plantUmlSource .toString()); // Write the first image to "os" long today = System.currentTimeMillis(); response.addDateHeader("Expires", today + 31536000000L); // today + 1 year response.addDateHeader("Last-Modified", 1261440000000L); // 2009 dec 22 constant date in the past response.addHeader("Cache-Control", "public"); response.setContentType("image/png"); reader.generateImage(response.getOutputStream()); response.flushBuffer(); } public String getContent(String adress) throws IOException { // HTTPConnection.setProxyServer("proxy", 8080); CookieModule.setCookiePolicyHandler(null); final Pattern p = Pattern.compile("http://[^/]+(/?.*)"); final Matcher m = p.matcher(adress); if (m.find() == false) { throw new IOException(adress); } final URL url = new URL(adress); final HTTPConnection httpConnection = new HTTPConnection(url); try { final HTTPResponse resp = httpConnection.Get(m.group(1)); return resp.getText(); } catch (ModuleException e) { throw new IOException(e.toString()); } catch (ParseException e) { throw new IOException(e.toString()); } } }