1 /******************************************************************************* 2 * Copyright (c) 2000, 2013 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.jdt.internal.compiler.util; 15 16 import java.io.OutputStream; 17 import java.io.PrintWriter; 18 import java.io.Writer; 19 import java.util.Arrays; 20 import java.util.Comparator; 21 import java.util.HashMap; 22 import java.util.Map; 23 24 @SuppressWarnings({"rawtypes", "unchecked"}) 25 public class GenericXMLWriter extends PrintWriter { 26 /* constants */ 27 private static final String XML_VERSION= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; //$NON-NLS-1$ appendEscapedChar(StringBuffer buffer, char c)28 private static void appendEscapedChar(StringBuffer buffer, char c) { 29 String replacement= getReplacement(c); 30 if (replacement != null) { 31 buffer.append('&'); 32 buffer.append(replacement); 33 buffer.append(';'); 34 } else { 35 buffer.append(c); 36 } 37 } getEscaped(String s)38 private static String getEscaped(String s) { 39 StringBuffer result= new StringBuffer(s.length() + 10); 40 for (int i= 0; i < s.length(); ++i) 41 appendEscapedChar(result, s.charAt(i)); 42 return result.toString(); 43 } getReplacement(char c)44 private static String getReplacement(char c) { 45 // Encode special XML characters into the equivalent character references. 46 // These five are defined by default for all XML documents. 47 switch (c) { 48 case '<' : 49 return "lt"; //$NON-NLS-1$ 50 case '>' : 51 return "gt"; //$NON-NLS-1$ 52 case '"' : 53 return "quot"; //$NON-NLS-1$ 54 case '\'' : 55 return "apos"; //$NON-NLS-1$ 56 case '&' : 57 return "amp"; //$NON-NLS-1$ 58 } 59 return null; 60 } 61 private String lineSeparator; 62 private int tab; GenericXMLWriter(OutputStream stream, String lineSeparator, boolean printXmlVersion)63 public GenericXMLWriter(OutputStream stream, String lineSeparator, boolean printXmlVersion) { 64 this(new PrintWriter(stream), lineSeparator, printXmlVersion); 65 } GenericXMLWriter(Writer writer, String lineSeparator, boolean printXmlVersion)66 public GenericXMLWriter(Writer writer, String lineSeparator, boolean printXmlVersion) { 67 super(writer); 68 this.tab= 0; 69 this.lineSeparator = lineSeparator; 70 if (printXmlVersion) { 71 print(XML_VERSION); 72 print(this.lineSeparator); 73 } 74 } endTag(String name, boolean insertTab, boolean insertNewLine)75 public void endTag(String name, boolean insertTab, boolean insertNewLine) { 76 this.tab --; 77 printTag('/' + name, null/*no parameters*/, insertTab, insertNewLine, false/*don't close tag*/); 78 } 79 /* 80 * External API 81 */ printString(String string, boolean insertTab, boolean insertNewLine)82 public void printString(String string, boolean insertTab, boolean insertNewLine) { 83 if (insertTab) { 84 printTabulation(); 85 } 86 print(string); 87 if (insertNewLine) { 88 print(this.lineSeparator); 89 } 90 } printTabulation()91 private void printTabulation() { 92 for (int i= 0; i < this.tab; i++) this.print('\t'); 93 } printTag(String name, HashMap parameters, boolean insertTab, boolean insertNewLine, boolean closeTag)94 public void printTag(String name, HashMap parameters, boolean insertTab, boolean insertNewLine, boolean closeTag) { 95 if (insertTab) { 96 printTabulation(); 97 } 98 this.print('<'); 99 this.print(name); 100 if (parameters != null) { 101 int length = parameters.size(); 102 Map.Entry[] entries = new Map.Entry[length]; 103 parameters.entrySet().toArray(entries); 104 Arrays.sort(entries, new Comparator() { 105 @Override 106 public int compare(Object o1, Object o2) { 107 Map.Entry entry1 = (Map.Entry) o1; 108 Map.Entry entry2 = (Map.Entry) o2; 109 return ((String) entry1.getKey()).compareTo((String) entry2.getKey()); 110 } 111 }); 112 for (int i = 0; i < length; i++) { 113 this.print(' '); 114 this.print(entries[i].getKey()); 115 this.print("=\""); //$NON-NLS-1$ 116 this.print(getEscaped(String.valueOf(entries[i].getValue()))); 117 this.print('\"'); 118 } 119 } 120 if (closeTag) { 121 this.print("/>"); //$NON-NLS-1$ 122 } else { 123 this.print(">"); //$NON-NLS-1$ 124 } 125 if (insertNewLine) { 126 print(this.lineSeparator); 127 } 128 if (parameters != null && !closeTag) 129 this.tab++; 130 131 } startTag(String name, boolean insertTab)132 public void startTag(String name, boolean insertTab) { 133 printTag(name, null/*no parameters*/, insertTab, true/*insert new line*/, false/*don't close tag*/); 134 this.tab++; 135 } 136 } 137