From 85169a1baf81371cb2cec1354ac66b42fd22b098 Mon Sep 17 00:00:00 2001 From: Maxime Sinclair Date: Wed, 16 Feb 2011 09:18:23 +0100 Subject: [PATCH] Enhanced version with short URL scheme, http headers to take advantage of the browser cache, and a new structure with JSP files. --- .gitignore | 5 +- .../plantuml/servlet/PlantUmlServlet.java | 122 +++++++----------- WEB-INF/web.xml | 29 ++++- build.xml | 28 ++-- content/error.jsp | 32 +++++ favicon.ico => content/favicon.ico | Bin content/index.jsp | 72 +++++++++++ content/plantuml.css | 20 +++ 8 files changed, 221 insertions(+), 87 deletions(-) create mode 100644 content/error.jsp rename favicon.ico => content/favicon.ico (100%) create mode 100644 content/index.jsp create mode 100644 content/plantuml.css diff --git a/.gitignore b/.gitignore index d90f5b8..7d2c56a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ - +/user.property /WEB-INF/classes -/plantuml.war \ No newline at end of file +/plantuml.war +/.settings diff --git a/WEB-INF/src/net/sourceforge/plantuml/servlet/PlantUmlServlet.java b/WEB-INF/src/net/sourceforge/plantuml/servlet/PlantUmlServlet.java index bfc717b..ca77de9 100644 --- a/WEB-INF/src/net/sourceforge/plantuml/servlet/PlantUmlServlet.java +++ b/WEB-INF/src/net/sourceforge/plantuml/servlet/PlantUmlServlet.java @@ -1,21 +1,23 @@ 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.RequestDispatcher; 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.StringUtils; import net.sourceforge.plantuml.code.Transcoder; import net.sourceforge.plantuml.code.TranscoderUtil; + import HTTPClient.CookieModule; import HTTPClient.HTTPConnection; import HTTPClient.HTTPResponse; @@ -32,15 +34,14 @@ import HTTPClient.ParseException; */ 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://.*)"); + private static final Pattern startumlPattern = Pattern.compile("/\\w+/start/(.*)"); + private static final Pattern imagePattern = Pattern.compile("/\\w+/img/(.*)"); + private static final Pattern proxyPattern = Pattern.compile("/\\w+/proxy/((\\d+)/)?(http://.*)"); + private static final Pattern oldStartumlPattern = Pattern.compile("/\\w+/uml/startuml/(.*)"); + private static final Pattern oldImagePattern = Pattern.compile("/\\w+/uml/image/(.*)"); + private static final Pattern oldProxyPattern = Pattern.compile("/\\w+/uml/proxy/((\\d+)/)?(http://.*)"); + @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { @@ -48,7 +49,9 @@ public class PlantUmlServlet extends HttpServlet { Matcher startumlMatcher = startumlPattern.matcher(uri); Matcher imageMatcher = imagePattern.matcher(uri); Matcher proxyMatcher = proxyPattern.matcher(uri); - + Matcher oldStartumlMatcher = oldStartumlPattern.matcher(uri); + Matcher oldImageMatcher = oldImagePattern.matcher(uri); + Matcher oldProxyMatcher = oldProxyPattern.matcher(uri); if (startumlMatcher.matches()) { String source = startumlMatcher.group(1); handleImage(response, source); @@ -59,79 +62,51 @@ public class PlantUmlServlet extends HttpServlet { String num = proxyMatcher.group(2); String source = proxyMatcher.group(3); handleImageProxy(response, num, source); + } else if (oldStartumlMatcher.matches()) { + String source = oldStartumlMatcher.group(1); + handleImage(response, source); + } else if (oldImageMatcher.matches()) { + String source = oldImageMatcher.group(1); + handleImageDecompress(response, source); + } else if (oldProxyMatcher.matches()) { + String num = oldProxyMatcher.group(2); + String source = oldProxyMatcher.group(3); + handleImageProxy(response, num, source); } else { doPost(request, response); } } @Override - protected void doPost(HttpServletRequest request, HttpServletResponse resp) + protected void doPost(HttpServletRequest request, HttpServletResponse response) 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 = ""; + String encoded = ""; Transcoder transcoder = getTranscoder(); - if (url != null) { + // the URL form has been submitted + if ((url != null) && (!url.trim().isEmpty())) { + // TODO Verify the url is correct Pattern p = Pattern.compile(".*/(.*)"); Matcher m = p.matcher(url); if (m.find()) { url = m.group(1); + text = transcoder.decode(url); } - 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(); + request.setAttribute("net.sourceforge.plantuml.servlet.decoded", text); + request.setAttribute("net.sourceforge.plantuml.servlet.encoded", encoded); + + // forward to index.jsp + RequestDispatcher dispatcher = request.getRequestDispatcher("/index.jsp"); + dispatcher.forward(request, response); } private Transcoder getTranscoder() { @@ -162,8 +137,7 @@ public class PlantUmlServlet extends HttpServlet { private void handleImageProxy(HttpServletResponse response, String num, String source) throws IOException { - String s = getContent(source); - SourceStringReader reader = new SourceStringReader(s); + SourceStringReader reader = new SourceStringReader( getContent(source)); int n = num == null ? 0 : Integer.parseInt(num); // Write the first image to "os" reader.generateImage(response.getOutputStream(), n); @@ -175,16 +149,18 @@ public class PlantUmlServlet extends HttpServlet { plantUmlSource.append("@startuml\n"); plantUmlSource.append(text); plantUmlSource.append("\n@enduml"); - - SourceStringReader reader = new SourceStringReader(plantUmlSource - .toString()); + final String uml = plantUmlSource.toString(); + SourceStringReader reader = new SourceStringReader(uml); // 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"); + if ( StringUtils.isDiagramCacheable( uml)) { + // Add http headers to force the browser to cache the image + 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()); diff --git a/WEB-INF/web.xml b/WEB-INF/web.xml index 06353fe..c4f6dbe 100644 --- a/WEB-INF/web.xml +++ b/WEB-INF/web.xml @@ -5,11 +5,36 @@ plantumlservlet net.sourceforge.plantuml.servlet.PlantUmlServlet + plantumlservlet /uml/* + + plantumlservlet + /form + + + plantumlservlet + /img/* + + + plantumlservlet + /start/* + + + plantumlservlet + /proxy/* + - uml - + /index.jsp + + + java.lang.Throwable + /error.jsp + + + 500 + /error.jsp + diff --git a/build.xml b/build.xml index ed295cd..d7b8e8c 100644 --- a/build.xml +++ b/build.xml @@ -1,32 +1,40 @@ - - - - - - - + + + + + + + + + + + - - + + - + + + + + diff --git a/content/error.jsp b/content/error.jsp new file mode 100644 index 0000000..2a49c54 --- /dev/null +++ b/content/error.jsp @@ -0,0 +1,32 @@ +<%@ page isErrorPage="true" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> +<% +String contextRoot = request.getContextPath(); +%> + + + + + + + + + + + + PlantUMLServer Error + + +

+Sorry, but things didn't work out as planned. +

+
+ + +
+ + \ No newline at end of file diff --git a/favicon.ico b/content/favicon.ico similarity index 100% rename from favicon.ico rename to content/favicon.ico diff --git a/content/index.jsp b/content/index.jsp new file mode 100644 index 0000000..e0ffc31 --- /dev/null +++ b/content/index.jsp @@ -0,0 +1,72 @@ +<%@ page info="index" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> + +<% +String contextRoot = request.getContextPath(); +String host = "http://" + request.getServerName() + ":" + request.getServerPort(); +String encoded = ""; +String umltext = ""; +String imgurl = ""; +Object encodedAttribute = request.getAttribute("net.sourceforge.plantuml.servlet.encoded"); +if (encodedAttribute != null) { + encoded = encodedAttribute.toString(); + if (!encoded.isEmpty()) { + imgurl = host + contextRoot + "/img/" + encoded; + } +} +Object decodedAttribute = request.getAttribute("net.sourceforge.plantuml.servlet.decoded"); +if (decodedAttribute != null) { + umltext = decodedAttribute.toString(); +} +%> + + + + + + + + + + + + PlantUMLServer + + + +
+ <%-- CONTENT --%> +
+

+ +
+ +

+
+
+ You can enter here a previously generated URL: +
+

+ +
+ +

+
+ <% if ( !imgurl.isEmpty()) { %> +
+

You can use the following URL: +
+ <img src="<%=imgurl %>" /> +

+ PlantUML diagram +

+ <% } //endif %> +
+ +<%-- FOOTER +<%@ include file="util/footer.jspf" %> --%> + + diff --git a/content/plantuml.css b/content/plantuml.css new file mode 100644 index 0000000..6da9fdc --- /dev/null +++ b/content/plantuml.css @@ -0,0 +1,20 @@ +/****************************** +* PlantUMLServlet style sheet * +******************************/ + +/* Header */ +#header { + margin-left: auto; + margin-right: auto; + text-align: center; +} + +/* Form inputs */ +#content textarea, #content input[type=text] { + width: 900px; +} + +/* Diagram */ +#content img#diagram { + border: thin solid green; +}