package org.freertr.enc; import java.util.ArrayList; import java.util.List; import org.freertr.util.bits; /** * extensible markup language * * @author matecsaba */ public class encXml { /** * header string */ public final static String header = ""; /** * ignore */ public final static String ignore = "identifier-ignore"; /** * escapeds */ public final static String escape = "identifier-escape"; /** * values */ public final static String value = "identifier-value"; /** * original string */ public String orig; /** * self closing tags */ public String closed = ""; /** * elements */ public List data; /** * clear new instance */ public encXml() { clear(); } /** * unescape identifier * * @param s identifier * @return unescaped */ public static String unescId(String s) { return s.replaceAll(escape, ""); } private static boolean needEsc(char c, int p) { if ((c >= 'a') && (c <= 'z')) { return false; } if ((c >= 'A') && (c <= 'Z')) { return false; } if ((c >= '0') && (c <= '9')) { return p < 1; } switch (c) { //case ':': case '_': case '-': case '.': return p < 1; default: return true; } } /** * check if name needs escaping * * @param s string * @return true if yes, false if not */ public static boolean needEsc(String s) { for (int i = 0; i < s.length(); i++) { if (needEsc(s.charAt(i), i)) { return true; } } return false; } /** * unescape identifier * * @param s identifier * @return unescaped */ public static String escId(String s) { if (!needEsc(s)) { return s; } String res = escape; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (!needEsc(c, i)) { res += c; continue; } res += "&#" + (int) c + ";"; } return res; } /** * clear all data */ public void clear() { data = new ArrayList(); orig = ""; } /** * copy from other xml * * @param src original xml to copy */ public void copyBytes(encXml src) { clear(); orig = "" + src.orig; for (int i = 0; i < src.data.size(); i++) { data.add(src.data.get(i).copyBytes()); } } /** * convert strings to xml * * @param l list to parse * @param a separator to use * @return false on success, true on error */ public boolean fromString(List l, String a) { String s = ""; for (int i = 0; i < l.size(); i++) { s += l.get(i) + a; } return fromString(s); } /** * convert string to xml * * @param l list to parse * @return false on success, true on error */ public boolean fromString(List l) { String s = ""; for (int i = 0; i < l.size(); i++) { byte ch = l.get(i); s += (char) ch; } return fromString(s); } /** * convert string to xml * * @param s string to parse * @return false on success, true on error */ public boolean fromString(String s) { clear(); orig = "" + s; s = bits.trimE(s); String path = ""; encXmlEntry prnt = null; for (;;) { s = bits.trimB(s); if (s.length() < 1) { break; } int i = s.indexOf("<"); if (i < 0) { i = s.length(); } if (i > 0) { String a = s.substring(0, i); s = s.substring(i, s.length()); a = bits.trimE(a); if (a.length() < 1) { continue; } if (data.size() > 0) { encXmlEntry ntry = data.get(data.size() - 1); if (ntry.name.equals(path)) { ntry.value += a; continue; } } data.add(new encXmlEntry(prnt, path, "", a)); continue; } i = s.indexOf(">"); String a; if (i < 0) { a = s.substring(1, s.length()); s = ""; } else { a = s.substring(1, i); s = s.substring(i + 1, s.length()); } a = bits.trimB(a); a = bits.trimE(a); boolean nb = a.endsWith("/"); if (nb) { a = a.substring(0, a.length() - 1); a = bits.trimE(a); } i = a.indexOf(" "); String b = ""; if (i > 0) { b = a.substring(i + 1, a.length()); a = a.substring(0, i); b = bits.trimB(b); } if (a.startsWith("/")) { b = path + "/"; i = b.lastIndexOf(a + "/"); if (i < 0) { continue; } path = path.substring(0, i); for (; prnt != null;) { a = prnt.name; if (path.equals(a)) { break; } prnt = prnt.parent; } if (prnt == null) { data.add(new encXmlEntry(prnt, path, "", "")); } else { data.add(new encXmlEntry(prnt.parent, prnt.name, "", "")); } continue; } if (closed.indexOf("|" + a + "|") >= 0) { nb = true; } encXmlEntry curr = new encXmlEntry(prnt, path + "/" + a, b, ""); data.add(curr); if (nb) { if (prnt == null) { curr = null; } else { curr = prnt.parent; } data.add(new encXmlEntry(curr, path, "", "")); continue; } path += "/" + a; prnt = curr; } data.add(new encXmlEntry(null, "", "", "")); return false; } private String getPath(String tag, String add, boolean ord, String prm) { List lst = new ArrayList(); for (;;) { int i = tag.indexOf("/"); if (i < 0) { break; } lst.add(tag.substring(0, i)); tag = tag.substring(i + 1, tag.length()); } if (lst.size() > 0) { int i = lst.size() - 1; if (prm.length() > 0) { prm = " " + prm; } lst.set(i, lst.get(i) + prm); } tag = ""; for (int i = 0; i < lst.size(); i++) { prm = "<" + add + lst.get(i) + ">"; if (ord) { tag = prm + tag; } else { tag = tag + prm; } } return tag; } private String getMove(String src, String trg, String prm) { if (src.equals(trg)) { return ""; } src += "/"; trg += "/"; for (;;) { int i = src.indexOf("/"); int o = trg.indexOf("/"); if (i != o) { break; } if (!src.substring(0, i).equals(trg.substring(0, i))) { break; } src = src.substring(i + 1, src.length()); trg = trg.substring(i + 1, trg.length()); } return getPath(src, "/", true, "") + getPath(trg, "", false, prm); } /** * convert to xml * * @return xml format */ public List toXMLlst() { List lst = new ArrayList(); String path = ""; for (int pos = 0; pos < data.size(); pos++) { encXmlEntry ntry = data.get(pos); lst.add(getMove(path, ntry.name, ntry.param) + ntry.value); path = ntry.name; } lst.add(getMove(path, "", "")); return lst; } /** * convert to xml * * @return xml format */ public String toXMLstr() { List lst = toXMLlst(); String res = ""; for (int i = 0; i < lst.size(); i++) { res += bits.trimB(lst.get(i)); } return res; } /** * convert to string * * @return lines of string */ public List show() { List l = new ArrayList(); for (int i = 0; i < data.size(); i++) { l.add("" + data.get(i)); } return l; } /** * convert string to xml * * @param xml string to convert * @return converted xml */ public static encXml parseOne(String xml) { encXml res = new encXml(); res.fromString(xml); return res; } /** * setup for html parsing */ public void setup2html() { closed = "|br|p|img|dl|dt|dd|ul|ol|li|tr|td|table|input|button|link|meta|"; } /** * format for html * * @param txts text * @param lnks links * @param width screen size * @return false on success, true on error */ public boolean formatHtml(List txts, List> lnks, int width) { String txt = ""; List lnk = new ArrayList(); for (int num = 0; num < data.size(); num++) { encXmlEntry ntry = data.get(num); String str = ntry.value.trim(); String tag = "/" + ntry.name.trim().toLowerCase().replaceAll(" ", "") + "/"; if (tag.indexOf("/script/") > 0) { str = ""; } if (tag.indexOf("/style/") > 0) { str = ""; } tag = ntry.getTag().trim().toLowerCase(); int pos = 0; boolean br = "|br|p|ul|ol|tr|dl|dt|dd".indexOf("|" + tag + "|") >= 0; if (tag.equals("a")) { if (str.length() < 1) { str = ""; } pos = num; } if (tag.equals("link")) { if (str.length() < 1) { str = ""; } pos = num; } if (tag.equals("object")) { if (str.length() < 1) { str = ""; } pos = num; } if (tag.equals("applet")) { if (str.length() < 1) { str = ""; } pos = num; } if (tag.equals("title")) { str = "title: " + str; br = true; } if (tag.equals("td")) { str = str + " | "; } if (tag.equals("li")) { if (txt.length() > 0) { txts.add(txt); lnks.add(lnk); txt = ""; lnk = new ArrayList(); } str = " * " + str; } if (tag.equals("img")) { str = ""; pos = num; } if (tag.equals("frame")) { str = ""; pos = num; } if (tag.equals("iframe")) { str = "