Move some basic string processing helpers into StringUtil.

This commit is contained in:
Erich Schubert 2018-10-21 17:01:37 +02:00
parent 1b4c97630d
commit 71f74d3093
2 changed files with 113 additions and 106 deletions

View File

@ -19,11 +19,18 @@
package org.umlgraph.doclet;
import static org.umlgraph.doclet.StringUtil.escape;
import static org.umlgraph.doclet.StringUtil.guilWrap;
import static org.umlgraph.doclet.StringUtil.guillemize;
import static org.umlgraph.doclet.StringUtil.htmlNewline;
import static org.umlgraph.doclet.StringUtil.removeTemplate;
import static org.umlgraph.doclet.StringUtil.tokenize;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
@ -33,7 +40,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.ConstructorDoc;
@ -159,89 +165,6 @@ class ClassGraph {
return buf.toString();
}
/**
* Escape <, >, and & characters in the string with
* the corresponding HTML entity code.
*/
private String escape(String s) {
final Pattern toEscape = Pattern.compile("[&<>]");
if (toEscape.matcher(s).find()) {
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.length();) {
switch (sb.charAt(i)) {
case '&':
sb.replace(i, i + 1, "&amp;");
i += "&amp;".length();
break;
case '<':
sb.replace(i, i + 1, "&lt;");
i += "&lt;".length();
break;
case '>':
sb.replace(i, i + 1, "&gt;");
i += "&gt;".length();
break;
default:
i++;
}
}
return sb.toString();
} else
return s;
}
/**
* Convert embedded newlines into HTML line breaks
*/
private String htmlNewline(String s) {
if (s.indexOf('\n') == -1)
return (s);
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.length();) {
if (sb.charAt(i) == '\n') {
sb.replace(i, i + 1, "<br/>");
i += "<br/>".length();
} else
i++;
}
return sb.toString();
}
/**
* Convert &lt; and &gt; characters in the string to the respective guillemot characters.
*/
private String guillemize(Options opt, String s) {
StringBuilder r = new StringBuilder(s);
for (int i = 0; i < r.length();)
switch (r.charAt(i)) {
case '<':
r.replace(i, i + 1, opt.guilOpen);
i += opt.guilOpen.length();
break;
case '>':
r.replace(i, i + 1, opt.guilClose);
i += opt.guilClose.length();
break;
default:
i++;
break;
}
return r.toString();
}
/**
* Wraps a string in Guillemot (or an ASCII substitute) characters.
*
* @param str the <code>String</code> to be wrapped.
* @return the wrapped <code>String</code>.
*/
private String guilWrap(Options opt, String str) {
return opt.guilOpen + str + opt.guilClose;
}
/**
* Print the visibility adornment of element e prefixed by
* any stereotypes
@ -397,7 +320,7 @@ class ClassGraph {
return;
for (Tag tag : tags) {
String t[] = StringUtil.tokenize(tag.text());
String t[] = tokenize(tag.text());
if (t.length != 2) {
System.err.println("@tagvalue expects two fields: " + tag.text());
continue;
@ -412,7 +335,7 @@ class ClassGraph {
*/
private void stereotype(Options opt, Doc c, Align align) {
for (Tag tag : c.tags("stereotype")) {
String t[] = StringUtil.tokenize(tag.text());
String t[] = tokenize(tag.text());
if (t.length != 1) {
System.err.println("@stereotype expects one field: " + tag.text());
continue;
@ -628,7 +551,7 @@ class ClassGraph {
private void allRelation(Options opt, RelationType rt, ClassDoc from) {
String tagname = rt.lower;
for (Tag tag : from.tags(tagname)) {
String t[] = StringUtil.tokenize(tag.text()); // l-src label l-dst target
String t[] = tokenize(tag.text()); // l-src label l-dst target
if (t.length != 4) {
System.err.println("Error in " + from + "\n" + tagname + " expects four fields (l-src label l-dst target): " + tag.text());
return;
@ -1013,24 +936,6 @@ class ClassGraph {
return null;
}
/** Removes the template specs from a class name. */
private String removeTemplate(String name) {
int openIdx = name.indexOf('<');
if(openIdx == -1)
return name;
StringBuilder buf = new StringBuilder(name.length());
for (int i = 0, depth = 0; i < name.length(); i++) {
char c = name.charAt(i);
if (c == '<')
depth++;
else if (c == '>')
depth--;
else if (depth == 0)
buf.append(c);
}
return buf.toString();
}
/** Convert the class name into a corresponding URL */
public String classToUrl(ClassDoc cd, boolean rootClass) {
// building relative path for context and package diagrams

View File

@ -20,9 +20,11 @@
package org.umlgraph.doclet;
import java.util.*;
import java.util.regex.Pattern;
/**
* String utility functions
*
* @version $Revision$
* @author <a href="http://www.spinellis.gr">Diomidis Spinellis</a>
*/
@ -62,4 +64,104 @@ class StringUtil {
return r.toArray(new String[0]);
}
private final static Pattern ESCAPE_BASIC_XML = Pattern.compile("[&<>]");
/**
* Escape &lt;, &gt;, and &amp; characters in the string with the corresponding
* HTML entity code.
*/
public static String escape(String s) {
if (ESCAPE_BASIC_XML.matcher(s).find()) {
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.length();) {
switch (sb.charAt(i)) {
case '&':
sb.replace(i, i + 1, "&amp;");
i += "&amp;".length();
break;
case '<':
sb.replace(i, i + 1, "&lt;");
i += "&lt;".length();
break;
case '>':
sb.replace(i, i + 1, "&gt;");
i += "&gt;".length();
break;
default:
i++;
}
}
return sb.toString();
} else
return s;
}
/**
* Convert embedded newlines into HTML line breaks
*/
public static String htmlNewline(String s) {
if (s.indexOf('\n') == -1)
return s;
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.length();) {
if (sb.charAt(i) == '\n') {
sb.replace(i, i + 1, "<br/>");
i += "<br/>".length();
} else
i++;
}
return sb.toString();
}
/**
* Convert &lt; and &gt; characters in the string to the respective guillemot
* characters.
*/
public static String guillemize(Options opt, String s) {
StringBuilder r = new StringBuilder(s);
for (int i = 0; i < r.length();)
switch (r.charAt(i)) {
case '<':
r.replace(i, i + 1, opt.guilOpen);
i += opt.guilOpen.length();
break;
case '>':
r.replace(i, i + 1, opt.guilClose);
i += opt.guilClose.length();
break;
default:
i++;
break;
}
return r.toString();
}
/**
* Wraps a string in Guillemot (or an ASCII substitute) characters.
*
* @param str the <code>String</code> to be wrapped.
* @return the wrapped <code>String</code>.
*/
public static String guilWrap(Options opt, String str) {
return opt.guilOpen + str + opt.guilClose;
}
/** Removes the template specs from a class name. */
public static String removeTemplate(String name) {
int openIdx = name.indexOf('<');
if (openIdx == -1)
return name;
StringBuilder buf = new StringBuilder(name.length());
for (int i = 0, depth = 0; i < name.length(); i++) {
char c = name.charAt(i);
if (c == '<')
depth++;
else if (c == '>')
depth--;
else if (depth == 0)
buf.append(c);
}
return buf.toString();
}
}