1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-11-26 14:56:28 +00:00

Improve URL management

This commit is contained in:
Arnaud Roques 2021-03-25 18:46:44 +01:00
parent 70a9b4c23f
commit 986393d90d
4 changed files with 226 additions and 91 deletions

View File

@ -51,9 +51,6 @@ public class Url implements EnsureVisible {
} }
public Url(String url, String tooltip, String label) { public Url(String url, String tooltip, String label) {
if (url.contains("{")) {
throw new IllegalArgumentException(url);
}
url = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(url, "\""); url = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(url, "\"");
this.url = url; this.url = url;
if (tooltip == null) { if (tooltip == null) {

View File

@ -45,24 +45,47 @@ public class UrlBuilder {
STRICT, ANYWHERE STRICT, ANYWHERE
} }
// private static String level0() { private static final String S_QUOTED = "\\[\\[[%s]*" + //
// return "(?:[^{}]|\\{[^{}]*\\})+"; "[%g]([^%g]+)[%g]" + // Quoted part
// } "(?:[%s]*\\{([^{}]*)\\})?" + // Optional tooltip
// "(?:[%s]([^%s\\{\\}\\[\\]][^\\[\\]]*))?" + // Optional label
// private static String levelN(int n) { "[%s]*\\]\\]";
// if (n == 0) {
// return level0();
// }
// return "(?:[^{}]|\\{" + levelN(n - 1) + "\\})+";
// }
// private static final String URL_PATTERN_OLD = private static final String S_ONLY_TOOLTIP = "\\[\\[[%s]*" + //
// "\\[\\[([%g][^%g]+[%g]|[^{}%s\\]\\[]*)(?:[%s]*\\{((?:[^{}]|\\{[^{}]*\\})+)\\})?(?:[%s]*([^\\]\\[]+))?\\]\\]"; "\\{(.*)\\}" + // Tooltip
private static final String URL_PATTERN = "\\[\\[([%g][^%g]+[%g])?([\\w\\W]*?)\\]\\]"; "[%s]*\\]\\]";
// private static final String URL_PATTERN_BAD = "\\[\\[([%g][^%g]+[%g]|[^{}%s\\]\\[]*)(?:[%s]*\\{" + "(" + private static final String S_ONLY_TOOLTIP_AND_LABEL = "\\[\\[[%s]*" + //
// levelN(3) "\\{([^{}]*)\\}" + // Tooltip
// + ")" + "\\})?(?:[%s]*([^\\]\\[]+))?\\]\\]"; "[%s]*" + //
"([^\\[%s\\{\\}\\[\\]][^\\[\\]]*)" // Label
+ "[%s]*\\]\\]";
private static final String S_LINK_TOOLTIP_NOLABEL = "\\[\\[[%s]*" + //
"([^\\s%g{}]+?)" + // Link
"[%s]*\\{(.+)\\}" + // Tooltip
"[%s]*\\]\\]";
private static final String S_LINK_WITH_OPTIONAL_TOOLTIP_WITH_OPTIONAL_LABEL = "\\[\\[[%s]*" + //
"([^%s%g]+?)" + // Link
"(?:[%s]*\\{([^{}]*)\\})?" + // Optional tooltip
"(?:[%s]([^%s\\{\\}\\[\\]][^\\[\\]]*))?" + // Optional label
"[%s]*\\]\\]";
public static String getRegexp() {
return S_QUOTED + "|" + //
S_ONLY_TOOLTIP + "|" + //
S_ONLY_TOOLTIP_AND_LABEL + "|" + //
S_LINK_TOOLTIP_NOLABEL + "|" + //
S_LINK_WITH_OPTIONAL_TOOLTIP_WITH_OPTIONAL_LABEL;
}
private static final Pattern2 QUOTED = MyPattern.cmpile(S_QUOTED);
private static final Pattern2 ONLY_TOOLTIP = MyPattern.cmpile(S_ONLY_TOOLTIP);
private static final Pattern2 ONLY_TOOLTIP_AND_LABEL = MyPattern.cmpile(S_ONLY_TOOLTIP_AND_LABEL);
private static final Pattern2 LINK_TOOLTIP_NOLABEL = MyPattern.cmpile(S_LINK_TOOLTIP_NOLABEL);
private static final Pattern2 LINK_WITH_OPTIONAL_TOOLTIP_WITH_OPTIONAL_LABEL = MyPattern
.cmpile(S_LINK_WITH_OPTIONAL_TOOLTIP_WITH_OPTIONAL_LABEL);
private final String topurl; private final String topurl;
private ModeUrl mode; private ModeUrl mode;
@ -73,67 +96,44 @@ public class UrlBuilder {
} }
public Url getUrl(String s) { public Url getUrl(String s) {
final Pattern2 p; Matcher2 m;
m = QUOTED.matcher(s);
if (matchesOrFind(m)) {
return new Url(withTopUrl(m.group(1)), m.group(2), m.group(3));
}
m = ONLY_TOOLTIP.matcher(s);
if (matchesOrFind(m)) {
return new Url("", m.group(1), null);
}
m = ONLY_TOOLTIP_AND_LABEL.matcher(s);
if (matchesOrFind(m)) {
return new Url("", m.group(1), m.group(2));
}
m = LINK_TOOLTIP_NOLABEL.matcher(s);
if (matchesOrFind(m)) {
return new Url(withTopUrl(m.group(1)), m.group(2), null);
}
m = LINK_WITH_OPTIONAL_TOOLTIP_WITH_OPTIONAL_LABEL.matcher(s);
if (matchesOrFind(m)) {
return new Url(withTopUrl(m.group(1)), m.group(2), m.group(3));
}
return null;
}
private boolean matchesOrFind(Matcher2 m) {
if (mode == ModeUrl.STRICT) { if (mode == ModeUrl.STRICT) {
p = MyPattern.cmpile("(?i)^" + URL_PATTERN + "$"); return m.matches();
} else if (mode == ModeUrl.ANYWHERE) { } else if (mode == ModeUrl.ANYWHERE) {
p = MyPattern.cmpile("(?i).*" + URL_PATTERN + ".*"); return m.find();
} else { } else {
throw new IllegalStateException(); throw new IllegalStateException();
} }
final Matcher2 m = p.matcher(StringUtils.trinNoTrace(s));
if (m.matches() == false) {
return null;
}
final String quotedPart = m.group(1);
final String fullpp = m.group(2).replaceAll("\\{scale=([0-9.]+)\\}", "\uE000scale=$1\uE001");
final int openBracket = openBracketBeforeSpace(fullpp);
final int closeBracket;
if (openBracket == -1) {
closeBracket = -1;
} else {
closeBracket = fullpp.lastIndexOf('}');
}
final String full = fullpp.replace('\uE000', '{').replace('\uE001', '}');
if (quotedPart == null) {
if (openBracket != -1 && closeBracket != -1) {
return new Url(withTopUrl(full.substring(0, openBracket)),
full.substring(openBracket + 1, closeBracket), full.substring(closeBracket + 1).trim());
}
final int firstSpace = full.indexOf(' ');
if (firstSpace == -1) {
return new Url(full, null, null);
}
return new Url(withTopUrl(full.substring(0, firstSpace)), null, full.substring(firstSpace + 1).trim());
}
if (openBracket != -1 && closeBracket != -1) {
return new Url(withTopUrl(quotedPart), full.substring(openBracket + 1, closeBracket), full.substring(
closeBracket + 1).trim());
}
return new Url(withTopUrl(quotedPart), null, null);
}
// private int openBracketBeforeSpace(final String full) {
// return full.indexOf('{');
// }
private int openBracketBeforeSpace(final String full) {
// final int firstSpace = full.indexOf(' ');
final int result = full.indexOf('{');
// if (result != -1 && full.substring(result).startsWith("{scale")) {
// return -1;
// }
// if (firstSpace == -1 || result == -1) {
// return result;
// }
// assert firstSpace >= 0;
// assert result >= 0;
// if (result > firstSpace + 1) {
// return -1;
// }
return result;
} }
private String withTopUrl(String url) { private String withTopUrl(String url) {
@ -143,19 +143,4 @@ public class UrlBuilder {
return url; return url;
} }
public static String getRegexp() {
return URL_PATTERN;
}
// private static String purgeUrl(final String label) {
// final Pattern2 p = MyPattern.cmpile("[%s]*" + URL_PATTERN + "[%s]*");
// final Matcher2 m = p.matcher(label);
// if (m.find() == false) {
// return label;
// }
// final String url = m.group(0);
// final int x = label.indexOf(url);
// return label.substring(0, x) + label.substring(x + url.length());
// }
} }

View File

@ -80,7 +80,7 @@ public class Version {
} }
public static int beta() { public static int beta() {
final int beta = 1; final int beta = 2;
return beta; return beta;
} }

View File

@ -0,0 +1,153 @@
package net.sourceforge.plantuml;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import net.sourceforge.plantuml.UrlBuilder.ModeUrl;
class UrlBuilderTest {
@Test
public void testGetUrl10() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://foo", "http://foo", "http://foo", b.getUrl("[[http://foo]]"));
}
@Test
public void testGetUrl11() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://foo", "tooltip", "text", b.getUrl("[[http://foo{tooltip} text]]"));
}
@Test
public void testGetUrl12() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://foo", "tooltip", "text", b.getUrl("[[http://foo {tooltip} text]]"));
}
@Test
public void testGetUrl13() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://foo", "tooltip", "http://foo", b.getUrl("[[http://foo {tooltip}]]"));
}
@Test
public void testGetUrl15() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://foo", "http://foo", "text", b.getUrl("[[http://foo text]]"));
}
@Test
public void testGetUrl18() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://foo", "http://foo", "http://foo", b.getUrl("[[ http://foo ]]"));
}
@Test
public void testGetUrl20() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://foo test", "http://foo test", "http://foo test", b.getUrl("[[\"http://foo test\"]]"));
}
@Test
public void testGetUrl30() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.ANYWHERE);
assertUrl("http://foo test", "http://foo test", "http://foo test",
b.getUrl("start [[\"http://foo test\"]] end"));
}
@Test
public void testGetUrl40() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://google.com", "a nice toolip", "<img:HelloWorld.png{scale=2}>",
b.getUrl("[[http://google.com{a nice toolip} <img:HelloWorld.png{scale=2}>]]"));
}
@Test
public void testGetUrl41() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://google.com", "a nice toolip", "<img:HelloWorld.png{scale=2}>",
b.getUrl("[[http://google.com {a nice toolip} <img:HelloWorld.png{scale=2}>]]"));
}
@Test
public void testGetUrl42() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://google.com", "http://google.com", "<img:HelloWorld.png{scale=2}>",
b.getUrl("[[http://google.com <img:HelloWorld.png{scale=2}>]]"));
}
@Test
public void testGetUrl50() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://google.com", "http://google.com", "<img:HelloWorld.png{scale=2}>",
b.getUrl("[[http://google.com <img:HelloWorld.png{scale=2}>]]"));
}
@Test
public void testGetUrl60() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://foo?dummy={123}&action=edit", "http://foo?dummy={123}&action=edit",
"http://foo?dummy={123}&action=edit", b.getUrl("[[http://foo?dummy={123}&action=edit]]"));
}
@Test
public void testGetUrl70() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://www.plantuml.com", "Json: {\"firstName\":\"Bob\", \"lastName\":\"Smith\"}",
"http://www.plantuml.com",
b.getUrl("[[http://www.plantuml.com{Json: {\"firstName\":\"Bob\", \"lastName\":\"Smith\"}}]]"));
}
@Test
public void testGetUrl80() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://foo?dummy=", "123}z{", "http://foo?dummy=", b.getUrl("[[http://foo?dummy={123}z{}]]"));
}
@Test
public void testGetUrl90() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("", "tooltip", "some text", b.getUrl("[[{tooltip} some text]]"));
}
@Test
public void testGetUrl100() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.ANYWHERE);
assertUrl("www.google.com", "www.google.com", "POST /session/csrStart",
b.getUrl("fromor [[www.google.com POST /session/csrStart]] end"));
}
@Test
public void testGetUrl110() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("blaha(xyz,12)", " tooltip ", "blaha(xyz,12)", b.getUrl("[[ blaha(xyz,12){ tooltip } ]]"));
}
@Test
public void testGetUrl120() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("", "Json: {\"firstName\":\"Bob\", \"lastName\":\"Smith\"}", "",
b.getUrl("[[{Json: {\"firstName\":\"Bob\", \"lastName\":\"Smith\"}}]]"));
}
@Test
public void testGetUrl130() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://foo?dummy=", "123}{", "http://foo?dummy=", b.getUrl("[[http://foo?dummy={123}{}]]"));
}
@Test
public void testGetUrl140() {
final UrlBuilder b = new UrlBuilder(null, ModeUrl.STRICT);
assertUrl("http://foo?dummy={123}", "", "http://foo?dummy={123}", b.getUrl("[[\"http://foo?dummy={123}\"{}]]"));
}
public void assertUrl(String urlLink, String tooltip, String label, Url url) {
assertEquals(urlLink, url.getUrl(), "url");
assertEquals(tooltip, url.getTooltip(), "tooltip");
assertEquals(label, url.getLabel(), "label");
}
}