mirror of
https://github.com/octoleo/plantuml-server.git
synced 2024-12-22 08:48:54 +00:00
Improve multipage (index) handling
This commit is contained in:
parent
db31315485
commit
3763ee737e
@ -34,6 +34,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.sourceforge.plantuml.FileFormat;
|
||||
import net.sourceforge.plantuml.servlet.utility.UmlExtractor;
|
||||
import net.sourceforge.plantuml.servlet.utility.UrlDataExtractor;
|
||||
|
||||
/**
|
||||
* Check servlet of the webapp.
|
||||
@ -46,7 +47,8 @@ public class CheckSyntaxServlet extends HttpServlet {
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
|
||||
// build the UML source from the compressed request parameter
|
||||
String uml = UmlExtractor.getUmlSource(getSource(request.getRequestURI()));
|
||||
final String url = request.getRequestURI();
|
||||
final String uml = UmlExtractor.getUmlSource(UrlDataExtractor.getEncodedDiagram(url, ""));
|
||||
|
||||
// generate the response
|
||||
DiagramResponse dr = new DiagramResponse(response, getOutputFormat(), request);
|
||||
@ -55,23 +57,6 @@ public class CheckSyntaxServlet extends HttpServlet {
|
||||
} catch (IIOException e) {
|
||||
// Browser has closed the connection, do nothing
|
||||
}
|
||||
dr = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract UML source from URI.
|
||||
*
|
||||
* @param uri the complete URI as returned by `request.getRequestURI()`
|
||||
*
|
||||
* @return the encoded UML text
|
||||
*/
|
||||
public String getSource(String uri) {
|
||||
String[] result = uri.split("/check/", 2);
|
||||
if (result.length != 2) {
|
||||
return "";
|
||||
} else {
|
||||
return result[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -166,10 +166,14 @@ public class DiagramResponse {
|
||||
* Produce and send the image map of the uml diagram in HTML format.
|
||||
*
|
||||
* @param uml textual UML diagram source
|
||||
* @param idx diagram index of {@code uml} to send
|
||||
*
|
||||
* @throws IOException if an input or output exception occurred
|
||||
*/
|
||||
public void sendMap(String uml) throws IOException {
|
||||
public void sendMap(String uml, int idx) throws IOException {
|
||||
if (idx < 0) {
|
||||
idx = 0;
|
||||
}
|
||||
response.setContentType(getContentType());
|
||||
SourceStringReader reader = new SourceStringReader(uml);
|
||||
final BlockUml blockUml = reader.getBlocks().get(0);
|
||||
@ -177,7 +181,7 @@ public class DiagramResponse {
|
||||
addHeaderForCache(blockUml);
|
||||
}
|
||||
final Diagram diagram = blockUml.getDiagram();
|
||||
ImageData map = diagram.exportDiagram(new NullOutputStream(), 0,
|
||||
ImageData map = diagram.exportDiagram(new NullOutputStream(), idx,
|
||||
new FileFormatOption(FileFormat.PNG, false));
|
||||
if (map.containsCMapData()) {
|
||||
PrintWriter httpOut = response.getWriter();
|
||||
@ -237,7 +241,7 @@ public class DiagramResponse {
|
||||
*
|
||||
* @param response http response
|
||||
*/
|
||||
public static void addHeaders(HttpServletResponse response) {
|
||||
private static void addHeaders(HttpServletResponse response) {
|
||||
response.addHeader("X-Powered-By", POWERED_BY);
|
||||
response.addHeader("X-Patreon", "Support us on https://plantuml.com/patreon");
|
||||
response.addHeader("X-Donate", "https://plantuml.com/paypal");
|
||||
|
@ -34,6 +34,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.sourceforge.plantuml.FileFormat;
|
||||
import net.sourceforge.plantuml.servlet.utility.UmlExtractor;
|
||||
import net.sourceforge.plantuml.servlet.utility.UrlDataExtractor;
|
||||
|
||||
/**
|
||||
* MAP servlet of the webapp.
|
||||
@ -46,32 +47,17 @@ public class MapServlet extends HttpServlet {
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
|
||||
// build the UML source from the compressed request parameter
|
||||
String uml = UmlExtractor.getUmlSource(getSource(request.getRequestURI()));
|
||||
final String url = request.getRequestURI();
|
||||
final String uml = UmlExtractor.getUmlSource(UrlDataExtractor.getEncodedDiagram(url, ""));
|
||||
final int idx = UrlDataExtractor.getIndex(url, 0);
|
||||
|
||||
// generate the response
|
||||
DiagramResponse dr = new DiagramResponse(response, getOutputFormat(), request);
|
||||
try {
|
||||
dr.sendMap(uml);
|
||||
dr.sendMap(uml, idx);
|
||||
} catch (IIOException e) {
|
||||
// Browser has closed the connection, do nothing
|
||||
}
|
||||
dr = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract UML source from URI.
|
||||
*
|
||||
* @param uri the complete URI as returned by `request.getRequestURI()`
|
||||
*
|
||||
* @return the encoded UML text
|
||||
*/
|
||||
public String getSource(String uri) {
|
||||
String[] result = uri.split("/map/", 2);
|
||||
if (result.length != 2) {
|
||||
return "";
|
||||
} else {
|
||||
return result[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,6 +45,7 @@ import net.sourceforge.plantuml.code.TranscoderUtil;
|
||||
import net.sourceforge.plantuml.png.MetadataTag;
|
||||
import net.sourceforge.plantuml.servlet.utility.Configuration;
|
||||
import net.sourceforge.plantuml.servlet.utility.UmlExtractor;
|
||||
import net.sourceforge.plantuml.servlet.utility.UrlDataExtractor;
|
||||
|
||||
/**
|
||||
* Original idea from Achim Abeling for Confluence macro.
|
||||
@ -69,10 +70,6 @@ public class PlantUmlServlet extends HttpServlet {
|
||||
* Regex pattern to fetch last part of the URL.
|
||||
*/
|
||||
private static final Pattern URL_PATTERN = Pattern.compile("^.*[^a-zA-Z0-9\\-\\_]([a-zA-Z0-9\\-\\_]+)");
|
||||
/**
|
||||
* Regex pattern to fetch encoded uml text from an "uml" URL.
|
||||
*/
|
||||
private static final Pattern RECOVER_UML_PATTERN = Pattern.compile("/uml/(.*)");
|
||||
|
||||
static {
|
||||
OptionFlags.ALLOW_INCLUDE = false;
|
||||
@ -94,8 +91,11 @@ public class PlantUmlServlet extends HttpServlet {
|
||||
return;
|
||||
}
|
||||
|
||||
// diagram index to render
|
||||
final int idx = UrlDataExtractor.getIndex(request.getRequestURI());
|
||||
|
||||
// forward to index.jsp
|
||||
prepareRequestForDispatch(request, text);
|
||||
prepareRequestForDispatch(request, text, idx);
|
||||
final RequestDispatcher dispatcher = request.getRequestDispatcher("/index.jsp");
|
||||
dispatcher.forward(request, response);
|
||||
}
|
||||
@ -107,6 +107,9 @@ public class PlantUmlServlet extends HttpServlet {
|
||||
) throws ServletException, IOException {
|
||||
request.setCharacterEncoding("UTF-8");
|
||||
|
||||
// diagram index to render
|
||||
final int idx = UrlDataExtractor.getIndex(request.getRequestURI());
|
||||
|
||||
// encoded diagram source
|
||||
String encoded;
|
||||
try {
|
||||
@ -117,7 +120,7 @@ public class PlantUmlServlet extends HttpServlet {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
redirectNow(request, response, encoded);
|
||||
redirectNow(request, response, encoded, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,15 +177,16 @@ public class PlantUmlServlet extends HttpServlet {
|
||||
* @throws IOException if an input or output exception occurred
|
||||
*/
|
||||
private String getTextFromUrl(HttpServletRequest request) throws IOException {
|
||||
final Matcher recoverUml = RECOVER_UML_PATTERN.matcher(
|
||||
request.getRequestURI().substring(request.getContextPath().length())
|
||||
);
|
||||
// the URL form has been submitted
|
||||
if (recoverUml.matches()) {
|
||||
final String data = recoverUml.group(1);
|
||||
return getTranscoder().decode(data);
|
||||
// textual diagram source from request URI
|
||||
String url = request.getRequestURI();
|
||||
if (url.contains("/uml/") && !url.endsWith("/uml/")) {
|
||||
final String encoded = UrlDataExtractor.getEncodedDiagram(request.getRequestURI(), "");
|
||||
if (!encoded.isEmpty()) {
|
||||
return getTranscoder().decode(encoded);
|
||||
}
|
||||
String url = request.getParameter("url");
|
||||
}
|
||||
// textual diagram source from "url" parameter
|
||||
url = request.getParameter("url");
|
||||
if (url != null && !url.trim().isEmpty()) {
|
||||
// Catch the last part of the URL if necessary
|
||||
final Matcher matcher = URL_PATTERN.matcher(url);
|
||||
@ -203,11 +207,12 @@ public class PlantUmlServlet extends HttpServlet {
|
||||
*
|
||||
* @throws IOException if an input or output exception occurred
|
||||
*/
|
||||
private void prepareRequestForDispatch(HttpServletRequest request, String text) throws IOException {
|
||||
// diagram sources
|
||||
private void prepareRequestForDispatch(HttpServletRequest request, String text, int idx) throws IOException {
|
||||
final String encoded = getTranscoder().encode(text);
|
||||
final String index = (idx < 0) ? "" : idx + "/";
|
||||
// diagram sources
|
||||
request.setAttribute("decoded", text);
|
||||
request.setAttribute("encoded", encoded);
|
||||
request.setAttribute("index", idx);
|
||||
// properties
|
||||
request.setAttribute("showSocialButtons", Configuration.get("SHOW_SOCIAL_BUTTONS"));
|
||||
request.setAttribute("showGithubRibbon", Configuration.get("SHOW_GITHUB_RIBBON"));
|
||||
@ -217,10 +222,10 @@ public class PlantUmlServlet extends HttpServlet {
|
||||
// image URLs
|
||||
final boolean hasImg = !text.isEmpty();
|
||||
request.setAttribute("hasImg", hasImg);
|
||||
request.setAttribute("imgurl", hostpath + "/png/" + encoded);
|
||||
request.setAttribute("svgurl", hostpath + "/svg/" + encoded);
|
||||
request.setAttribute("txturl", hostpath + "/txt/" + encoded);
|
||||
request.setAttribute("mapurl", hostpath + "/map/" + encoded);
|
||||
request.setAttribute("imgurl", hostpath + "/png/" + index + encoded);
|
||||
request.setAttribute("svgurl", hostpath + "/svg/" + index + encoded);
|
||||
request.setAttribute("txturl", hostpath + "/txt/" + index + encoded);
|
||||
request.setAttribute("mapurl", hostpath + "/map/" + index + encoded);
|
||||
// map for diagram source if necessary
|
||||
final boolean hasMap = PlantumlUtils.hasCMapData(text);
|
||||
request.setAttribute("hasMap", hasMap);
|
||||
@ -276,7 +281,32 @@ public class PlantUmlServlet extends HttpServlet {
|
||||
HttpServletResponse response,
|
||||
String encoded
|
||||
) throws IOException {
|
||||
final String result = request.getContextPath() + "/uml/" + encoded;
|
||||
redirectNow(request, response, encoded, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send redirect response to encoded uml text.
|
||||
*
|
||||
* @param request http request
|
||||
* @param response http response
|
||||
* @param encoded encoded uml text
|
||||
* @param index diagram index
|
||||
*
|
||||
* @throws IOException if an input or output exception occurred
|
||||
*/
|
||||
private void redirectNow(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
String encoded,
|
||||
Integer index
|
||||
) throws IOException {
|
||||
final String result;
|
||||
if (index == null || index < 0) {
|
||||
result = request.getContextPath() + "/uml/" + encoded;
|
||||
} else {
|
||||
result = request.getContextPath() + "/uml/" + index + "/" + encoded;
|
||||
}
|
||||
|
||||
response.sendRedirect(result);
|
||||
}
|
||||
|
||||
|
@ -25,8 +25,6 @@ package net.sourceforge.plantuml.servlet;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
|
||||
@ -34,9 +32,11 @@ import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.sourceforge.plantuml.FileFormat;
|
||||
import net.sourceforge.plantuml.OptionFlags;
|
||||
import net.sourceforge.plantuml.servlet.utility.UmlExtractor;
|
||||
import net.sourceforge.plantuml.servlet.utility.UrlDataExtractor;
|
||||
|
||||
/**
|
||||
* Common service servlet to produce diagram from compressed UML source contained in the end part of the requested URI.
|
||||
@ -44,11 +44,6 @@ import net.sourceforge.plantuml.servlet.utility.UmlExtractor;
|
||||
@SuppressWarnings("SERIAL")
|
||||
public abstract class UmlDiagramService extends HttpServlet {
|
||||
|
||||
/**
|
||||
* Regex pattern to fetch encoded uml text from an URL.
|
||||
*/
|
||||
private static final Pattern RECOVER_UML_PATTERN = Pattern.compile("/\\w+/(\\d+/)?(.*)");
|
||||
|
||||
static {
|
||||
OptionFlags.ALLOW_INCLUDE = false;
|
||||
if ("true".equalsIgnoreCase(System.getenv("ALLOW_PLANTUML_INCLUDE"))) {
|
||||
@ -58,12 +53,14 @@ public abstract class UmlDiagramService extends HttpServlet {
|
||||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||
final String url = request.getRequestURI();
|
||||
final String encoded = UrlDataExtractor.getEncodedDiagram(url, "");
|
||||
final int idx = UrlDataExtractor.getIndex(url, 0);
|
||||
|
||||
// build the UML source from the compressed request parameter
|
||||
final String[] sourceAndIdx = getSourceAndIdx(request);
|
||||
final int idx = Integer.parseInt(sourceAndIdx[1]);
|
||||
final String uml;
|
||||
try {
|
||||
uml = UmlExtractor.getUmlSource(sourceAndIdx[0]);
|
||||
uml = UmlExtractor.getUmlSource(encoded);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Bad Request");
|
||||
@ -75,19 +72,16 @@ public abstract class UmlDiagramService extends HttpServlet {
|
||||
|
||||
@Override
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
// build the UML source from the compressed request parameter
|
||||
final String[] sourceAndIdx = getSourceAndIdx(request);
|
||||
final int idx = Integer.parseInt(sourceAndIdx[1]);
|
||||
final int idx = UrlDataExtractor.getIndex(request.getRequestURI(), 0);
|
||||
|
||||
// read textual diagram source from request body
|
||||
final StringBuilder uml = new StringBuilder();
|
||||
final BufferedReader in = request.getReader();
|
||||
while (true) {
|
||||
final String line = in.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
try (BufferedReader in = request.getReader()) {
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
uml.append(line).append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
doDiagramResponse(request, response, uml.toString(), idx);
|
||||
}
|
||||
@ -118,33 +112,6 @@ public abstract class UmlDiagramService extends HttpServlet {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the UML source text and its index from the HTTP request.
|
||||
*
|
||||
* @param request http request
|
||||
*
|
||||
* @return the UML source text and its index
|
||||
*/
|
||||
public final String[] getSourceAndIdx(HttpServletRequest request) {
|
||||
final Matcher recoverUml = RECOVER_UML_PATTERN.matcher(
|
||||
request.getRequestURI().substring(
|
||||
request.getContextPath().length()));
|
||||
// the URL form has been submitted
|
||||
if (recoverUml.matches()) {
|
||||
final String data = recoverUml.group(2);
|
||||
if (data.length() >= 4) {
|
||||
String idx = recoverUml.group(1);
|
||||
if (idx == null) {
|
||||
idx = "0";
|
||||
} else {
|
||||
idx = idx.substring(0, idx.length() - 1);
|
||||
}
|
||||
return new String[]{data, idx };
|
||||
}
|
||||
}
|
||||
return new String[]{"", "0"};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the wished output format of the diagram. This value is used by the DiagramResponse class.
|
||||
*
|
||||
|
@ -6,26 +6,33 @@ hide empty members
|
||||
hide empty methods
|
||||
hide empty fields
|
||||
abstract class UmlDiagramService {
|
||||
public void doGet(HttpServletRequest rq, HttpServletResponse rsp)
|
||||
abstract public String getSource( String uri)
|
||||
abstract FileFormat getOutputFormat()
|
||||
+ doGet(request: HttpServletRequest, response: HttpServletResponse) : void
|
||||
+ doPost(request: HttpServletRequest, response: HttpServletResponse) : void
|
||||
+ {abstract} getOutputFormat() : FileFormat
|
||||
}
|
||||
class DiagramResponse {
|
||||
DiagramResponse( HttpServletResponse r, FileFormat f)
|
||||
void sendDiagram( String uml)
|
||||
void sendMap( String uml)
|
||||
+ DiagramResponse(res: HttpServletResponse, fmt: FileFormat, req: HttpServletRequest)
|
||||
+ sendDiagram(uml: String, idx: int) : void
|
||||
+ sendMap(uml: String, idx: int) : void
|
||||
+ sendCheck(uml: String) : void
|
||||
}
|
||||
abstract HttpServlet <|-- UmlDiagramService
|
||||
abstract HttpServlet <|-- MapServlet
|
||||
abstract HttpServlet <|-- ProxyServlet
|
||||
UmlDiagramService <|-- PngServlet
|
||||
UmlDiagramService <|-- SvgServlet
|
||||
HttpServlet <|-- CheckSyntaxServlet
|
||||
HttpServlet <|-- LanguageServlet
|
||||
HttpServlet <|-- MapServlet
|
||||
HttpServlet <|-- PlantUmlServlet
|
||||
HttpServlet <|-- ProxyServlet
|
||||
HttpServlet <|-- OldProxyServlet
|
||||
HttpServlet <|-- UmlDiagramService
|
||||
UmlDiagramService <|-- AsciiServlet
|
||||
UmlDiagramService <|-- Base64Servlet
|
||||
UmlDiagramService <|-- EpsServlet
|
||||
UmlDiagramService <|-- EpsTextServlet
|
||||
UmlDiagramService <|-- AsciiServlet
|
||||
UmlDiagramService o- DiagramResponse
|
||||
MapServlet o-- DiagramResponse
|
||||
ProxyServlet o-- DiagramResponse
|
||||
UmlDiagramService <|-- ImgServlet
|
||||
UmlDiagramService <|-- SvgServlet
|
||||
UmlDiagramService o-- DiagramResponse
|
||||
DiagramResponse --o CheckSyntaxServlet
|
||||
DiagramResponse --o MapServlet
|
||||
DiagramResponse --o ProxyServlet
|
||||
@enduml
|
||||
|
||||
## Sequence diagram ##
|
||||
@ -33,14 +40,17 @@ ProxyServlet o-- DiagramResponse
|
||||
|
||||
@startuml
|
||||
title Generation of a PNG image illustrated
|
||||
PngServlet -> PngServlet : getSource()
|
||||
PngServlet -> UmlExtractor : getUmlSource()
|
||||
UmlExtractor --> PngServlet
|
||||
PngServlet -> PngServlet : getOutputFormat()
|
||||
PngServlet -> DiagramResponse : <<create>>
|
||||
PngServlet -> DiagramResponse : sendDiagram()
|
||||
ImgServlet -> UrlDataExtractor : getEncodedDiagram()
|
||||
UrlDataExtractor --> ImgServlet : encoded
|
||||
ImgServlet -> UrlDataExtractor : getIndex()
|
||||
UrlDataExtractor --> ImgServlet : index
|
||||
ImgServlet -> UmlExtractor : getUmlSource()
|
||||
UmlExtractor --> ImgServlet : decoded
|
||||
ImgServlet -> ImgServlet : getOutputFormat()
|
||||
ImgServlet -> "dr:DiagramResponse" as dr ** : <<create>>
|
||||
ImgServlet -> dr : sendDiagram()
|
||||
participant "PlantUML library" as Lib #99FF99
|
||||
DiagramResponse -> Lib : generateImage()
|
||||
Lib --> DiagramResponse
|
||||
DiagramResponse --> PngServlet
|
||||
dr -> Lib : generateImage()
|
||||
Lib --> dr
|
||||
dr --> ImgServlet
|
||||
@enduml
|
@ -0,0 +1,102 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* Project Info: https://plantuml.com
|
||||
*
|
||||
* This file is part of PlantUML.
|
||||
*
|
||||
* PlantUML is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PlantUML distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
package net.sourceforge.plantuml.servlet.utility;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Utility class to extract the index and diagram source from an URL, e.g., returned by `request.getRequestURI()`.
|
||||
*/
|
||||
public abstract class UrlDataExtractor {
|
||||
|
||||
/**
|
||||
* URL regex pattern to easily extract index and encoded diagram.
|
||||
*/
|
||||
private static final Pattern URL_PATTERN = Pattern.compile(
|
||||
"/\\w+(?:/(?<idx>\\d+))?(?:/(?<encoded>[^/]+))?/?$"
|
||||
);
|
||||
|
||||
/**
|
||||
* Get diagram index from URL.
|
||||
*
|
||||
* @param url URL to analyse, e.g., returned by `request.getRequestURI()`
|
||||
*
|
||||
* @return if exists diagram index; otherwise -1
|
||||
*/
|
||||
public static int getIndex(final String url) {
|
||||
return getIndex(url, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get diagram index from URL.
|
||||
*
|
||||
* @param url URL to analyse, e.g., returned by `request.getRequestURI()`
|
||||
* @param fallback fallback index if no index exists in {@code url}
|
||||
*
|
||||
* @return if exists diagram index; otherwise {@code fallback}
|
||||
*/
|
||||
public static int getIndex(final String url, final int fallback) {
|
||||
final Matcher matcher = URL_PATTERN.matcher(url);
|
||||
if (!matcher.find()) {
|
||||
return fallback;
|
||||
}
|
||||
String idx = matcher.group("idx");
|
||||
if (idx == null) {
|
||||
return fallback;
|
||||
}
|
||||
return Integer.parseInt(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get encoded diagram source from URL.
|
||||
*
|
||||
* @param url URL to analyse, e.g., returned by `request.getRequestURI()`
|
||||
*
|
||||
* @return if exists diagram index; otherwise `null`
|
||||
*/
|
||||
public static String getEncodedDiagram(final String url) {
|
||||
return getEncodedDiagram(url, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get encoded diagram source from URL.
|
||||
*
|
||||
* @param url URL to analyse, e.g., returned by `request.getRequestURI()`
|
||||
* @param fallback fallback if no encoded diagram source exists in {@code url}
|
||||
*
|
||||
* @return if exists diagram index; otherwise {@code fallback}
|
||||
*/
|
||||
public static String getEncodedDiagram(final String url, final String fallback) {
|
||||
final Matcher matcher = URL_PATTERN.matcher(url);
|
||||
if (!matcher.find()) {
|
||||
return fallback;
|
||||
}
|
||||
String encoded = matcher.group("encoded");
|
||||
if (encoded == null) {
|
||||
return fallback;
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@
|
||||
<%
|
||||
// diagram sources
|
||||
String decoded = request.getAttribute("decoded").toString();
|
||||
String encoded = request.getAttribute("encoded").toString();
|
||||
// properties
|
||||
boolean showSocialButtons = (boolean)request.getAttribute("showSocialButtons");
|
||||
boolean showGithubRibbon = (boolean)request.getAttribute("showGithubRibbon");
|
||||
|
@ -216,4 +216,88 @@ public class TestForm extends WebappTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that an multipage diagram renders correct given index.
|
||||
*
|
||||
* Bob -> Alice : hello
|
||||
* newpage
|
||||
* Bob <- Alice : hello
|
||||
* Bob -> Alice : let's talk
|
||||
* Bob <- Alice : better not
|
||||
* Bob -> Alice : <&rain> bye
|
||||
* newpage
|
||||
* Bob <- Alice : bye
|
||||
*/
|
||||
public void testIndexPage() throws IOException {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
HtmlPage page = webClient.getPage(
|
||||
getServerUrl() + "/uml/1/" +
|
||||
"SyfFKj2rKt3CoKnELR1Io4ZDoSddoaijBqXCJ-Lo0ahQwA99Eg7go4ajKIzMA4dCoKPNdfHQKf9Qf92NNuAknqQjA34ppquXgJ8Lbrr0AG00"
|
||||
);
|
||||
// Analyze response
|
||||
List<HtmlForm> forms = page.getForms();
|
||||
assertEquals(2, forms.size());
|
||||
// Ensure the Text field is correct
|
||||
String text = ((HtmlTextArea)(forms.get(0).getFirstByXPath("//textarea[contains(@name, 'text')]"))).getTextContent();
|
||||
assertEquals(
|
||||
"@startuml\nBob -> Alice : hello\nnewpage\nBob <- Alice : hello\nBob -> Alice : let's talk\nBob <- Alice : better not\nBob -> Alice : <&rain> bye\nnewpage\nBob <- Alice : bye\n@enduml",
|
||||
text
|
||||
);
|
||||
// Ensure the URL field is correct
|
||||
HtmlInput url = forms.get(1).getInputByName("url");
|
||||
assertNotNull(url);
|
||||
assertTrue(url.getAttribute("value").endsWith("/png/1/SyfFKj2rKt3CoKnELR1Io4ZDoSddoaijBqXCJ-Lo0ahQwA99Eg7go4ajKIzMA4dCoKPNdfHQKf9Qf92NNuAknqQjA34ppquXgJ8Lbrr0AG00"));
|
||||
// Ensure the generated image is present
|
||||
HtmlImage img = page.getFirstByXPath("//img[contains(@alt, 'PlantUML diagram')]");
|
||||
int height = img.getImageReader().getHeight(0);
|
||||
assertNotEquals(0, height); // 222
|
||||
assertNotEquals(0, img.getImageReader().getWidth(0)); // 152
|
||||
// Ensure the correct index was generated
|
||||
assertTrue(height > 200); // 222
|
||||
assertTrue(height < 250); // 222
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that an multipage diagram renders correct even if no index is specified.
|
||||
*
|
||||
* Bob -> Alice : hello
|
||||
* newpage
|
||||
* Bob <- Alice : hello
|
||||
* Bob -> Alice : let's talk
|
||||
* Bob <- Alice : better not
|
||||
* Bob -> Alice : <&rain> bye
|
||||
* newpage
|
||||
* Bob <- Alice : bye
|
||||
*/
|
||||
public void testIndexPageWithNoDefinedIndex() throws IOException {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
HtmlPage page = webClient.getPage(
|
||||
getServerUrl() + "/uml/" +
|
||||
"SyfFKj2rKt3CoKnELR1Io4ZDoSddoaijBqXCJ-Lo0ahQwA99Eg7go4ajKIzMA4dCoKPNdfHQKf9Qf92NNuAknqQjA34ppquXgJ8Lbrr0AG00"
|
||||
);
|
||||
// Analyze response
|
||||
List<HtmlForm> forms = page.getForms();
|
||||
assertEquals(2, forms.size());
|
||||
// Ensure the Text field is correct
|
||||
String text = ((HtmlTextArea)(forms.get(0).getFirstByXPath("//textarea[contains(@name, 'text')]"))).getTextContent();
|
||||
assertEquals(
|
||||
"@startuml\nBob -> Alice : hello\nnewpage\nBob <- Alice : hello\nBob -> Alice : let's talk\nBob <- Alice : better not\nBob -> Alice : <&rain> bye\nnewpage\nBob <- Alice : bye\n@enduml",
|
||||
text
|
||||
);
|
||||
// Ensure the URL field is correct
|
||||
HtmlInput url = forms.get(1).getInputByName("url");
|
||||
assertNotNull(url);
|
||||
assertTrue(url.getAttribute("value").endsWith("/png/SyfFKj2rKt3CoKnELR1Io4ZDoSddoaijBqXCJ-Lo0ahQwA99Eg7go4ajKIzMA4dCoKPNdfHQKf9Qf92NNuAknqQjA34ppquXgJ8Lbrr0AG00"));
|
||||
// Ensure the generated image is present
|
||||
HtmlImage img = page.getFirstByXPath("//img[contains(@alt, 'PlantUML diagram')]");
|
||||
int height = img.getImageReader().getHeight(0);
|
||||
assertNotEquals(0, height); // 132
|
||||
assertNotEquals(0, img.getImageReader().getWidth(0)); // 152
|
||||
// Ensure the correct index was generated
|
||||
assertTrue(height > 100); // 132
|
||||
assertTrue(height < 150); // 132
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,199 @@
|
||||
package net.sourceforge.plantuml.servlet;
|
||||
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
|
||||
public class TestMultipageUml extends WebappTestCase {
|
||||
|
||||
/**
|
||||
* Encoded/compressed diagram source to text multipage uml diagrams.
|
||||
*
|
||||
* Bob -> Alice : hello
|
||||
* newpage
|
||||
* Bob <- Alice : hello
|
||||
* Bob -> Alice : let's talk [[tel:0123456789]]
|
||||
* Bob <- Alice : better not
|
||||
* Bob -> Alice : <&rain> bye
|
||||
* newpage
|
||||
* Bob <- Alice : bye
|
||||
*/
|
||||
private static final String ENCODED = "SoWkIImgAStDuNBAJrBGjLDmpCbCJbMmKiX8pSd9vyfBBIz8J4y5IzheeagYwyX9BL4lLYX9pCbMY8ukISsnCZ0qCZOnDJEti8oDHJSXARMa9BL88I-_1DqO6xMYnCmyEuMaobGSreEb75BpKe3E1W00";
|
||||
|
||||
/**
|
||||
* Verifies that an multipage diagram renders correct given index (PNG).
|
||||
*/
|
||||
public void testPngIndexPage() throws IOException {
|
||||
final URL url = new URL(getServerUrl() + "/png/1/" + ENCODED);
|
||||
final URLConnection conn = url.openConnection();
|
||||
// Analyze response
|
||||
// Verifies the Content-Type header
|
||||
assertEquals(
|
||||
"Response content type is not PNG",
|
||||
"image/png",
|
||||
conn.getContentType().toLowerCase()
|
||||
);
|
||||
// Get the image and verify its size
|
||||
byte[] inMemoryImage = getContentAsBytes(conn);
|
||||
int diagramLen = inMemoryImage.length; // 7525
|
||||
assertTrue(diagramLen > 6000);
|
||||
assertTrue(diagramLen < 9000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that an multipage diagram renders correct even if no index is specified (PNG).
|
||||
*/
|
||||
public void testPngIndexPageNoIndex() throws IOException {
|
||||
final URL url = new URL(getServerUrl() + "/png/" + ENCODED);
|
||||
final URLConnection conn = url.openConnection();
|
||||
// Analyze response
|
||||
// Verifies the Content-Type header
|
||||
assertEquals(
|
||||
"Response content type is not PNG",
|
||||
"image/png",
|
||||
conn.getContentType().toLowerCase()
|
||||
);
|
||||
// Get the image and verify its size
|
||||
byte[] inMemoryImage = getContentAsBytes(conn);
|
||||
int diagramLen = inMemoryImage.length; // 4196
|
||||
assertTrue(diagramLen > 3000);
|
||||
assertTrue(diagramLen < 5000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that an multipage diagram renders correct given index (SVG).
|
||||
*/
|
||||
public void testSvgIndexPage() throws IOException {
|
||||
final URL url = new URL(getServerUrl() + "/svg/1/" + ENCODED);
|
||||
final URLConnection conn = url.openConnection();
|
||||
// Analyze response
|
||||
// Verifies the Content-Type header
|
||||
assertEquals(
|
||||
"Response content type is not SVG",
|
||||
"image/svg+xml",
|
||||
conn.getContentType().toLowerCase()
|
||||
);
|
||||
// Get the content and verify its size
|
||||
String diagram = getContentText(conn);
|
||||
int diagramLen = diagram.length(); // 5834
|
||||
assertTrue(diagramLen > 5500);
|
||||
assertTrue(diagramLen < 7000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that an multipage diagram renders correct even if no index is specified (SVG).
|
||||
*/
|
||||
public void testSvgIndexPageNoIndex() throws IOException {
|
||||
final URL url = new URL(getServerUrl() + "/svg/" + ENCODED);
|
||||
final URLConnection conn = url.openConnection();
|
||||
// Analyze response
|
||||
// Verifies the Content-Type header
|
||||
assertEquals(
|
||||
"Response content type is not SVG",
|
||||
"image/svg+xml",
|
||||
conn.getContentType().toLowerCase()
|
||||
);
|
||||
// Get the content and verify its size
|
||||
String diagram = getContentText(conn);
|
||||
int diagramLen = diagram.length(); // 2970
|
||||
assertTrue(diagramLen > 1500);
|
||||
assertTrue(diagramLen < 4000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that an multipage diagram renders correct given index (AsciiArt).
|
||||
*/
|
||||
public void testAsciiArtIndexPage() throws IOException {
|
||||
final URL url = new URL(getServerUrl() + "/txt/1/" + ENCODED);
|
||||
final URLConnection conn = url.openConnection();
|
||||
// Analyze response
|
||||
// Verifies the Content-Type header
|
||||
assertEquals(
|
||||
"Response content type is not TEXT PLAIN or UTF-8",
|
||||
"text/plain;charset=utf-8",
|
||||
conn.getContentType().toLowerCase()
|
||||
);
|
||||
// Get the content and verify its size
|
||||
String diagram = getContentText(conn);
|
||||
int diagramLen = diagram.length();
|
||||
assertNotEquals(0, diagramLen);
|
||||
// BUG/Missing Feature: plantuml renders always whole AsciiArt diagram
|
||||
//assertTrue(diagramLen > ??);
|
||||
//assertTrue(diagramLen < ??);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that an multipage diagram renders correct even if no index is specified (AsciiArt).
|
||||
*/
|
||||
public void testAsciiArtIndexPageNoIndex() throws IOException {
|
||||
final URL url = new URL(getServerUrl() + "/txt/" + ENCODED);
|
||||
final URLConnection conn = url.openConnection();
|
||||
// Analyze response
|
||||
// Verifies the Content-Type header
|
||||
assertEquals(
|
||||
"Response content type is not TEXT PLAIN or UTF-8",
|
||||
"text/plain;charset=utf-8",
|
||||
conn.getContentType().toLowerCase()
|
||||
);
|
||||
// Get the content and verify its size
|
||||
String diagram = getContentText(conn);
|
||||
int diagramLen = diagram.length();
|
||||
assertNotEquals(0, diagramLen);
|
||||
// BUG/Missing Feature: plantuml renders always whole AsciiArt diagram
|
||||
//assertTrue(diagramLen > ??);
|
||||
//assertTrue(diagramLen < ??);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that an multipage diagram renders correct given index (Map).
|
||||
*/
|
||||
public void testMapIndexPage() throws IOException {
|
||||
final URL url = new URL(getServerUrl() + "/map/1/" + ENCODED);
|
||||
final URLConnection conn = url.openConnection();
|
||||
// Analyze response
|
||||
// Verifies the Content-Type header
|
||||
assertEquals(
|
||||
"Response content type is not TEXT PLAIN or UTF-8",
|
||||
"text/plain;charset=utf-8",
|
||||
conn.getContentType().toLowerCase()
|
||||
);
|
||||
// Get the data contained in the XML
|
||||
String map = getContentText(url);
|
||||
// map contains "tel:0123456789"
|
||||
assertTrue(
|
||||
"Response does not contain 'tel:0123456789'",
|
||||
map.contains("tel:0123456789")
|
||||
);
|
||||
// Verify shape:
|
||||
// <map id="..." name="...">
|
||||
// <area shape="..." id="..." href="..." ... />
|
||||
// </map>
|
||||
assertTrue(
|
||||
"Response doesn't match shape",
|
||||
map.matches("^<map id=\".+\" name=\".+\">\n(<area shape=\".+\" id=\".+\" href=\".+\".*/>\n)</map>\n*$")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that an multipage diagram renders correct even if no index is specified (Map).
|
||||
*/
|
||||
public void testMapIndexPageNoIndex() throws IOException {
|
||||
final URL url = new URL(getServerUrl() + "/map/" + ENCODED);
|
||||
final URLConnection conn = url.openConnection();
|
||||
// Analyze response
|
||||
// Verifies the Content-Type header
|
||||
assertEquals(
|
||||
"Response content type is not TEXT PLAIN or UTF-8",
|
||||
"text/plain;charset=utf-8",
|
||||
conn.getContentType().toLowerCase()
|
||||
);
|
||||
// Get the data contained in the XML
|
||||
String diagram = getContentText(conn);
|
||||
int diagramLen = diagram.length();
|
||||
assertEquals(0, diagramLen);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user