1 package org.testng.reporters; 2 3 import org.testng.internal.Nullable; 4 5 import java.text.CharacterIterator; 6 import java.text.StringCharacterIterator; 7 import java.util.Map.Entry; 8 import java.util.Properties; 9 10 /** 11 * Static helpers for XML. 12 * 13 * @author Cedric Beust Jul 21, 2003 14 * 15 */ 16 public final class XMLUtils { 17 18 /** Platform specific end of line */ 19 private static final String EOL = System.getProperty("line.separator"); 20 XMLUtils()21 private XMLUtils() { 22 // Hide constructor 23 } 24 25 /** 26 * Generate tag. 27 * An opening and closing tag will be generated even if value is null. 28 * @param name name of the tag 29 * @param content content for this tag (or null) 30 * @param attributes tag attributes (or null) 31 */ xml(String indent, String name, @Nullable String content, @Nullable Properties attributes)32 static public String xml(String indent, 33 String name, 34 @Nullable String content, 35 @Nullable Properties attributes) { 36 IBuffer result = Buffer.create(); 37 xmlOpen(result, indent, name, attributes, true /* no newline */); 38 if (content != null) { 39 result.append(content); 40 } 41 xmlClose(result, "", name, XMLUtils.extractComment(name, attributes)); 42 43 return result.toString(); 44 } 45 extractComment(String tag, Properties properties)46 public static String extractComment(String tag, Properties properties) { 47 if (properties == null || "span".equals(tag)) return null; 48 49 String[] attributes = new String[] { "id", "name", "class" }; 50 for (String a : attributes) { 51 String comment = properties.getProperty(a); 52 if (comment != null) { 53 return " <!-- " + comment.replaceAll("[-]{2,}", "-") + " -->"; 54 } 55 } 56 57 return null; 58 } 59 xmlOptional(IBuffer result, String sp, String elementName, Boolean value, Properties attributes)60 public static void xmlOptional(IBuffer result, String sp, 61 String elementName, Boolean value, Properties attributes) { 62 if (null != value) { 63 xmlRequired(result, sp, elementName, value.toString(), attributes); 64 } 65 } 66 xmlOptional(IBuffer result, String sp, String elementName, @Nullable String value, Properties attributes)67 public static void xmlOptional(IBuffer result, String sp, 68 String elementName, @Nullable String value, Properties attributes) { 69 if (null != value) { 70 xmlRequired(result, sp, elementName, value, attributes); 71 } 72 } 73 xmlRequired(IBuffer result, String sp, String elementName, @Nullable String value, @Nullable Properties attributes)74 public static void xmlRequired(IBuffer result, String sp, 75 String elementName, @Nullable String value, @Nullable Properties attributes) { 76 result.append(xml(sp, elementName, value, attributes)); 77 } 78 xmlOpen(IBuffer result, String indent, String tag, Properties attributes)79 public static void xmlOpen(IBuffer result, String indent, String tag, 80 Properties attributes) { 81 xmlOpen(result, indent, tag, attributes, false /* no newline */); 82 } 83 84 /** 85 * Appends the attributes to result. The attributes are added on a single line 86 * as: key1="value1" key2="value2" ... (a space is added before the first key) 87 * 88 * @param result 89 * the buffer to append attributes to. 90 * @param attributes 91 * the attributes to append (may be null). 92 */ appendAttributes(IBuffer result, Properties attributes)93 public static void appendAttributes(IBuffer result, Properties attributes) { 94 if (null != attributes) { 95 for (Object element : attributes.entrySet()) { 96 Entry entry = (Entry) element; 97 String key = entry.getKey().toString(); 98 String value = escape(entry.getValue().toString()); 99 result.append(" ").append(key).append("=\"").append(value).append("\""); 100 } 101 } 102 } 103 xmlOpen(IBuffer result, String indent, String tag, Properties attributes, boolean noNewLine)104 public static void xmlOpen(IBuffer result, String indent, String tag, 105 Properties attributes, boolean noNewLine) { 106 result.append(indent).append("<").append(tag); 107 appendAttributes(result, attributes); 108 result.append(">"); 109 if (!noNewLine) { 110 result.append(EOL); 111 } 112 } 113 xmlClose(IBuffer result, String indent, String tag, String comment)114 public static void xmlClose(IBuffer result, String indent, String tag, String comment) { 115 result.append(indent).append("</").append(tag).append(">") 116 .append(comment != null ? comment : "") 117 .append(EOL); 118 } 119 escape(String input)120 public static String escape(String input) { 121 if (input == null) { 122 return null; 123 } 124 StringBuilder result = new StringBuilder(); 125 StringCharacterIterator iterator = new StringCharacterIterator(input); 126 char character = iterator.current(); 127 while (character != CharacterIterator.DONE) { 128 if (character == '<') { 129 result.append("<"); 130 } else if (character == '>') { 131 result.append(">"); 132 } else if (character == '\"') { 133 result.append("""); 134 } else if (character == '\'') { 135 result.append("'"); 136 } else if (character == '&') { 137 result.append("&"); 138 } else { 139 result.append(character); 140 } 141 character = iterator.next(); 142 } 143 return result.toString(); 144 } 145 } 146