fit.Parse Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fitnesse Show documentation
Show all versions of fitnesse Show documentation
The fully integrated standalone wiki, and acceptance testing framework.
// Modified or written by Object Mentor, Inc. for inclusion with FitNesse.
// Copyright (c) 2002 Cunningham & Cunningham, Inc.
// Released under the terms of the GNU General Public License version 2 or later.
package fit;
// Copyright (c) 2002 Cunningham & Cunningham, Inc.
// Released under the terms of the GNU General Public License version 2 or later.
import java.io.PrintWriter;
import fit.exception.FitParseException;
public class Parse {
public String leader;
public String tag;
public String body;
public String end;
public String trailer;
public Parse more;
public Parse parts;
public Parse(String tag, String body, Parse parts, Parse more) {
this.leader = "\n";
this.tag = "<" + tag + ">";
this.body = body;
this.end = "" + tag + ">";
this.trailer = "";
this.parts = parts;
this.more = more;
}
public static final String[] tags = {"table", "tr", "td"};
public Parse(String text) throws FitParseException {
this(text, tags, 0, 0);
}
public Parse(String text, String[] tags) throws FitParseException {
this(text, tags, 0, 0);
}
public Parse(String text, String[] tags, int level, int offset) throws FitParseException {
String lc = text.toLowerCase();
int startTag = lc.indexOf("<" + tags[level]);
int endTag = lc.indexOf(">", startTag) + 1;
// int startEnd = lc.indexOf("" + tags[level], endTag);
int startEnd = findMatchingEndTag(lc, endTag, tags[level], offset);
int endEnd = lc.indexOf(">", startEnd) + 1;
int startMore = lc.indexOf("<" + tags[level], endEnd);
if (startTag < 0 || endTag < 0 || startEnd < 0 || endEnd < 0) {
throw new FitParseException("Can't find tag: " + tags[level], offset);
}
leader = text.substring(0, startTag);
tag = text.substring(startTag, endTag);
body = text.substring(endTag, startEnd);
end = text.substring(startEnd, endEnd);
trailer = text.substring(endEnd);
if (level + 1 < tags.length) {
parts = new Parse(body, tags, level + 1, offset + endTag);
body = null;
} else { // Check for nested table
int index = body.indexOf("<" + tags[0]);
if (index >= 0) {
parts = new Parse(body, tags, 0, offset + endTag);
body = "";
}
}
if (startMore >= 0) {
more = new Parse(trailer, tags, level, offset + endEnd);
trailer = null;
}
}
/* Added by Rick Mugridge, Feb 2005 */
protected static int findMatchingEndTag(String lc, int matchFromHere, String tag, int offset) throws FitParseException {
int fromHere = matchFromHere;
int count = 1;
int startEnd = 0;
while (count > 0) {
int embeddedTag = lc.indexOf("<" + tag, fromHere);
int embeddedTagEnd = lc.indexOf("" + tag, fromHere);
// Which one is closer?
if (embeddedTag < 0 && embeddedTagEnd < 0)
throw new FitParseException("Can't find tag: " + tag, offset);
if (embeddedTag < 0)
embeddedTag = Integer.MAX_VALUE;
if (embeddedTagEnd < 0)
embeddedTagEnd = Integer.MAX_VALUE;
if (embeddedTag < embeddedTagEnd) {
count++;
startEnd = embeddedTag;
fromHere = lc.indexOf(">", embeddedTag) + 1;
} else if (embeddedTagEnd < embeddedTag) {
count--;
startEnd = embeddedTagEnd;
fromHere = lc.indexOf(">", embeddedTagEnd) + 1;
}
}
return startEnd;
}
public int size() {
return more == null ? 1 : more.size() + 1;
}
public Parse last() {
return more == null ? this : more.last();
}
public Parse leaf() {
return parts == null ? this : parts.leaf();
}
public Parse at(int i) {
return i == 0 || more == null ? this : more.at(i - 1);
}
public Parse at(int i, int j) {
return at(i).parts.at(j);
}
public Parse at(int i, int j, int k) {
return at(i, j).parts.at(k);
}
public String text() {
return unescape(unformat(body)).trim();
}
public static String unformat(String s) {
int i = 0, j;
while ((i = s.indexOf('<', i)) >= 0) {
if ((j = s.indexOf('>', i + 1)) > 0) {
s = s.substring(0, i) + s.substring(j + 1);
} else
break;
}
return s;
}
public static String unescape(String s) {
StringBuilder sb = new StringBuilder(s);
int i = -1, j;
while ((i = sb.indexOf("&", i + 1)) >= 0) {
if ((j = sb.indexOf(";", i + 1)) > 0) {
String from = sb.substring(i + 1, j).toLowerCase();
String to = null;
if ((to = replacement(from)) != null) {
sb.replace(i, j + 1, to);
}
}
}
return sb.toString();
}
public static String replacement(String from) {
if (from.equals("lt"))
return "<";
else if (from.equals("gt"))
return ">";
else if (from.equals("amp"))
return "&";
else if (from.equals("nbsp"))
return " ";
else
return null;
}
public void addToTag(String text) {
int last = tag.length() - 1;
tag = tag.substring(0, last) + text + ">";
}
public void addToBody(String text) {
body = body + text;
}
public void print(PrintWriter out) {
out.print(leader);
out.print(tag);
if (parts != null) {
parts.print(out);
} else {
out.print(body);
}
out.print(end);
if (more != null) {
more.print(out);
} else {
out.print(trailer);
}
}
}