package com.philmcrew.utility; import java.util.Enumeration; import java.util.Hashtable; /** */ public class SimpleXml { public StringBuffer currentText = null; public SimpleXml() { } public SimpleXml(StringBuffer currentText) { setCurrentText(currentText); } public SimpleXml(String currentText) { setCurrentText(currentText); } /** * Method used to replace the first copy of a particular substring with * another substring inside of a larger String object. * If the substring to be replaced is not found, then the * original String is returned without any changes. * * Should use replaceAll if needing to change all instances * * @param original The original String text * @param oldText The substring to be replaced * @param newText The new substring * * @return String The new string with the substring replace */ public String replaceString(String original, String oldText, String newText) { if ((original == null) || (oldText == null) || (newText == null)) { return original; } StringBuffer buffer = new StringBuffer(original); int index = original.indexOf(oldText); if (index == -1) { return original; } else { buffer.replace(index, index + oldText.length(), newText); } return buffer.toString(); } /** * @param original * @param oldText * @param newText * @return new string created from original in which oldText has been * replaced with newText */ public String replaceAll(String original, String oldText, String newText) { String changed = original; while (changed.indexOf(oldText) != -1) { changed = replaceString(changed, oldText, newText); } return changed; } protected static void logTrace(String logMessage) { System.out.println(logMessage); } protected static String logError(Throwable t, String logMessage) { StringBuffer buf = new StringBuffer(100); buf.append("Caught Throwable "); buf.append(t.getClass().getName()); buf.append(" - "); buf.append(t); buf.append(" - in "); buf.append(logMessage); System.err.println(buf); t.printStackTrace(); return buf.toString(); } public void setCurrentText(StringBuffer currentText) { this.currentText = currentText; } public void setCurrentText(String currentText) { setCurrentText(new StringBuffer(currentText)); } public StringBuffer getCurrentText() { if (null == this.currentText) this.currentText = new StringBuffer(128); return this.currentText; } /** * This method simplifies retrieval of the first instance of a specific tag * converted into an integer. * If it does not find the start or end tag or the tag contents cannot be made into * and integer, an exception is thrown * */ public int getXmlInt(String labelName) throws Exception { int iXmlInt = -1; String xmlString = ""; try { xmlString = getXmlString(labelName); iXmlInt = Integer.parseInt(xmlString); } catch (NumberFormatException e) { logError(e, "Invalid value for " + labelName + ": " + xmlString); throw e; } return iXmlInt; } public long getXmlLong(String labelName) throws Exception { long iXmlLong = -1; String xmlString = ""; try { xmlString = getXmlString(labelName); iXmlLong = Long.parseLong(xmlString); } catch (NumberFormatException e) { logError(e, "Invalid value for " + labelName + ": " + xmlString); throw e; } return iXmlLong; } public float getXmlFloat(String labelName) throws Exception { float iXmlFloat = -1; String xmlString = ""; try { xmlString = getXmlString(labelName); iXmlFloat = Float.parseFloat(xmlString); } catch (NumberFormatException e) { logError(e, "Invalid value for " + labelName + ": " + xmlString); throw e; } return iXmlFloat; } public double getXmlDouble(String labelName) throws Exception { double iXmlDouble = -1; String xmlString = ""; try { xmlString = getXmlString(labelName); iXmlDouble = Double.parseDouble(xmlString); } catch (NumberFormatException e) { logError(e, "Invalid value for " + labelName + ": " + xmlString); throw e; } return iXmlDouble; } /** * This method simplifies retrieval of the first instance of a specific tag. * If it does not find the start or end tag an exception is thrown * */ public String getXmlString(String labelName) throws Exception { StringBuffer startLabel = new StringBuffer("<"); startLabel.append(labelName); startLabel.append(">"); StringBuffer endLabel = new StringBuffer(""); int iStartLabelIndex = this.currentText.indexOf(startLabel.toString()); if (iStartLabelIndex == -1) throw new Exception("Missing Start Tag " + labelName); int iStartIndex = iStartLabelIndex + startLabel.length(); int iEndIndex = this.currentText.indexOf(endLabel.toString(), iStartIndex); if (iEndIndex == -1) throw new Exception("Missing End Tag " + labelName); try { return this.currentText.substring(iStartIndex, iEndIndex).trim(); } catch (IndexOutOfBoundsException e) { throw new Exception("Internal find error isi=" + iStartIndex + " iei=" + iEndIndex); } } /** * This method simplifies retrieval of the first instance of a specific tag. * If it does not find the start or end tag the default value is returned * * @param labelName The label name of the xml tag * @param defaultValue The value to return if the item is not found * @return The retrieved contents of the tag */ public String getXmlString(String labelName, String defaultValue) { String retString; try { retString = getXmlString(labelName); } catch (Exception e) { retString = defaultValue; } return retString; } /** * This method simplifies retrieval of the first instance of a specific tag. * If it does not find the start or end tag the default value is returned * * @param labelName The label name of the xml tag * @param defaultValue The value to return if the item is not found * @return The retrieved contents of the tag */ public int getXmlInt(String labelName, int defaultValue) { int ret; try { ret = getXmlInt(labelName); } catch (Exception e) { ret = defaultValue; } return ret; } public long getXmlLong(String labelName, long defaultValue) { long ret; try { ret = getXmlLong(labelName); } catch (Exception e) { ret = defaultValue; } return ret; } public float getXmlFloat(String labelName, float defaultValue) { float ret; try { ret = getXmlFloat(labelName); } catch (Exception e) { ret = defaultValue; } return ret; } public double getXmlDouble(String labelName, double defaultValue) { double ret; try { ret = getXmlDouble(labelName); } catch (Exception e) { ret = defaultValue; } return ret; } /** * Given a standard string, convert the <, >, and " characters to the * XML <, >, and " strings * @param data The string to convert * @return The converted string */ public String convertDisplayStringToXmlString(String data) { logTrace("convertDisplayStringToXmlString l=" + data.length()); int len = data.length(); StringBuffer buf = new StringBuffer(len * (int) 1.1); char ch; for (int ii = 0; ii < len; ii++) { ch = data.charAt(ii); switch (ch) { case'\'': { buf.append("'"); break; } case '<': { buf.append("<"); break; } case '>': { buf.append(">"); break; } case '"': { buf.append("\""); break; } case '&': { buf.append("&"); break; } default: { buf.append(ch); } } } return buf.toString(); } /** * Given a string containing anglebrackets (eg xml) this replaces the ampersand characters * with real ones, so it will display properly. * @param data The string to convert. * @return The converted string */ public String convertXmlStringToDisplayString(String data) { logTrace("convertXmlStringToDisplayString l=" + data.length()); data = replaceAll(data, "<", "<"); data = replaceAll(data, ">", ">"); data = replaceAll(data, "\"", "\\\""); data = replaceAll(data, "&", "&"); return data; } /** * * @param in * @return return tag contents minus the CData wrapper */ public static String removeCdata(String in) { String out = in; int len = in.length(); int startIndex = 0; int endIndex = in.length() - 1; if (in.startsWith("")) endIndex = in.length() - 3; if (endIndex > 0) out = in.substring(startIndex, endIndex); logTrace("removeCdata l=" + len + ";s=" + startIndex + ";e=" + endIndex); return out; } public void startTag(String tagName) { startTag(tagName, null); } public void startTag(String tagName, Hashtable attrs) { StringBuffer currentText = getCurrentText(); currentText.append("<"); currentText.append(tagName); if ((attrs != null) && !attrs.isEmpty()) { currentText.append(" "); String attr; for (Enumeration e = attrs.keys(); e.hasMoreElements(); ) { attr = (String) e.nextElement(); currentText.append(attr); currentText.append("=\""); currentText.append(attrs.get(attr)); currentText.append("\" "); } } currentText.append(">"); } /** * * @param tagName */ public void endTag(String tagName) { StringBuffer currentText = getCurrentText(); currentText.append(""); } /** * * @param tag * @param value */ public void forceBuildTag(String tag, String value) { startTag(tag, null); if (value != null && value.length() > 0) currentText.append(value); endTag(tag); } public void forceBuildTag(String tag, int value) { String valueString = Integer.toString(value); forceBuildTag(tag, valueString); } public void forceBuildTag(String tag, long value) { String valueString = Long.toString(value); forceBuildTag(tag, valueString); } public void forceBuildTag(String tag, float value) { String valueString = Float.toString(value); forceBuildTag(tag, valueString); } public void forceBuildTag(String tag, double value) { String valueString = Double.toString(value); forceBuildTag(tag, valueString); } public void forceBuildTag(String tag, boolean value) { String valueString = Boolean.toString(value); forceBuildTag(tag, valueString); } public void forceBuildTag(String tag, Boolean value) { String valueString = null; if (null != value) valueString = value.toString(); forceBuildTag(tag, valueString); } public void forceBuildTag(String tag, Double value) { String valueString = null; if (null != value) valueString = value.toString(); forceBuildTag(tag, valueString); } public void forceBuildTag(String tag, Float value) { String valueString = null; if (null != value) valueString = value.toString(); forceBuildTag(tag, valueString); } public void forceBuildTag(String tag, Long value) { String valueString = null; if (null != value) valueString = value.toString(); forceBuildTag(tag, valueString); } public void forceBuildTag(String tag, Integer value) { String valueString = null; if (null != value) valueString = value.toString(); forceBuildTag(tag, valueString); } public void buildTag(String tag, String value) { if (null != value && value.length() > 0) { forceBuildTag(tag, value); } } public void buildTag(String tag, int value) { if (0 != value) { forceBuildTag(tag, value); } } public void buildTag(String tag, long value) { if (0 != value) { forceBuildTag(tag, value); } } public void buildTag(String tag, float value) { if (0.0 != value) { forceBuildTag(tag, value); } } public void buildTag(String tag, double value) { if (0.0 != value) { forceBuildTag(tag, value); } } public void buildTag(String tag, Boolean value) { if (null != value) { forceBuildTag(tag, value); } } public void buildTag(String tag, Double value) { if (null != value && 0.0 != value.doubleValue()) { forceBuildTag(tag, value); } } public void buildTag(String tag, Float value) { if (null != value && 0.0 != value.floatValue()) { forceBuildTag(tag, value); } } public void buildTag(String tag, Long value) { if (null != value && 0l != value.longValue()) { forceBuildTag(tag, value); } } public void buildTag(String tag, Integer value) { if (null != value && 0l != value.intValue()) { forceBuildTag(tag, value); } } public void append(String newText) { StringBuffer currentText = getCurrentText(); currentText.append(newText); } public void append(int newText) { StringBuffer currentText = getCurrentText(); currentText.append(newText); } public void append(long newText) { StringBuffer currentText = getCurrentText(); currentText.append(newText); } public void append(float newText) { StringBuffer currentText = getCurrentText(); currentText.append(newText); } public void append(double newText) { StringBuffer currentText = getCurrentText(); currentText.append(newText); } public void append(Boolean newText) { StringBuffer currentText = getCurrentText(); currentText.append(newText); } public void append(Double newText) { StringBuffer currentText = getCurrentText(); currentText.append(newText); } public void append(Float newText) { StringBuffer currentText = getCurrentText(); currentText.append(newText); } public void append(Long newText) { StringBuffer currentText = getCurrentText(); currentText.append(newText); } public void append(Integer newText) { StringBuffer currentText = getCurrentText(); currentText.append(newText); } /** * Look for tag labelName. Replace contents of tag with newContents. Return complete new String. * Will not work for tags with attributes. Case of tag must match. * * @param xmlMessage * @param labelName * @param newContents * @return new string with tag contents replaced * @throws Exception if can't find start or end tag * @deprecated Use method that doesn't take message instead */ public String replaceXmlString(String xmlMessage, String labelName, String newContents) throws Exception { if (null == xmlMessage && null != labelName ) throw new Exception("Missing Start Tag " + labelName); setCurrentText(xmlMessage); replace(labelName, null, newContents); return getCurrentText().toString(); } public void replace(String labelName, String newAttributes, String newContents) throws Exception { StringBuffer xmlMessage = getCurrentText(); String retString = null; if (null == labelName && null != newContents) { logTrace("Cannot replace contents of a null tag"); return; } try { // TODO: would like to handle tags with attributes without going to SAX // SAX also doesn't handle mixed case and also changes spacing and so forth StringBuffer startLabel = new StringBuffer("<"); startLabel.append(labelName); startLabel.append(">"); StringBuffer endLabel = new StringBuffer(""); int iStartLabelIndex = xmlMessage.indexOf(startLabel.toString()); int iStartIndex; int iEndIndex; StringBuffer newMessage = new StringBuffer(xmlMessage.length()); if (iStartLabelIndex == -1) { // support case of StringBuffer startEndLabel = new StringBuffer("<"); startEndLabel.append(labelName); startEndLabel.append(" />"); iStartLabelIndex = xmlMessage.indexOf(startEndLabel.toString()); if (iStartLabelIndex == -1) throw new Exception("Missing Start Tag " + labelName); newMessage.append(xmlMessage.substring(0, iStartLabelIndex)); newMessage.append(startLabel); if (null != newContents) newMessage.append(newContents); newMessage.append(endLabel); iEndIndex = iStartLabelIndex + startEndLabel.length(); newMessage.append(xmlMessage.substring(iEndIndex)); } else { iStartIndex = iStartLabelIndex + startLabel.length(); iEndIndex = xmlMessage.indexOf(endLabel.toString(), iStartIndex); if (iEndIndex == -1) throw new Exception("Missing End Tag " + labelName); newMessage.append(xmlMessage.substring(0, iStartIndex)); if (null != newContents) newMessage.append(newContents); newMessage.append(xmlMessage.substring(iEndIndex)); } retString = newMessage.toString(); } catch (NullPointerException e) { logError(e, "Missing parameter xmlMessage=" + xmlMessage + ";labelName=" + labelName + ";newContents=" + newContents); throw e; } setCurrentText(retString); } public void replace(String labelName, String newContents) throws Exception { replace(labelName, null, newContents); } }