001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.compiler.util;
011:
012: import java.io.OutputStream;
013: import java.io.PrintWriter;
014: import java.io.Writer;
015: import java.util.Arrays;
016: import java.util.Comparator;
017: import java.util.HashMap;
018: import java.util.Map;
019:
020: public class GenericXMLWriter extends PrintWriter {
021: /* constants */
022: private static final String XML_VERSION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; //$NON-NLS-1$
023:
024: private static void appendEscapedChar(StringBuffer buffer, char c) {
025: String replacement = getReplacement(c);
026: if (replacement != null) {
027: buffer.append('&');
028: buffer.append(replacement);
029: buffer.append(';');
030: } else {
031: buffer.append(c);
032: }
033: }
034:
035: private static String getEscaped(String s) {
036: StringBuffer result = new StringBuffer(s.length() + 10);
037: for (int i = 0; i < s.length(); ++i)
038: appendEscapedChar(result, s.charAt(i));
039: return result.toString();
040: }
041:
042: private static String getReplacement(char c) {
043: // Encode special XML characters into the equivalent character references.
044: // These five are defined by default for all XML documents.
045: switch (c) {
046: case '<':
047: return "lt"; //$NON-NLS-1$
048: case '>':
049: return "gt"; //$NON-NLS-1$
050: case '"':
051: return "quot"; //$NON-NLS-1$
052: case '\'':
053: return "apos"; //$NON-NLS-1$
054: case '&':
055: return "amp"; //$NON-NLS-1$
056: }
057: return null;
058: }
059:
060: private String lineSeparator;
061: private int tab;
062:
063: public GenericXMLWriter(OutputStream stream, String lineSeparator,
064: boolean printXmlVersion) {
065: this (new PrintWriter(stream), lineSeparator, printXmlVersion);
066: }
067:
068: public GenericXMLWriter(Writer writer, String lineSeparator,
069: boolean printXmlVersion) {
070: super (writer);
071: this .tab = 0;
072: this .lineSeparator = lineSeparator;
073: if (printXmlVersion) {
074: print(XML_VERSION);
075: print(this .lineSeparator);
076: }
077: }
078:
079: public void endTag(String name, boolean insertTab,
080: boolean insertNewLine) {
081: this .tab--;
082: printTag('/' + name, null/*no parameters*/, insertTab,
083: insertNewLine, false/*don't close tag*/);
084: }
085:
086: /*
087: * External API
088: */
089: public void printString(String string, boolean insertTab,
090: boolean insertNewLine) {
091: if (insertTab) {
092: printTabulation();
093: }
094: print(string);
095: if (insertNewLine) {
096: print(this .lineSeparator);
097: }
098: }
099:
100: private void printTabulation() {
101: for (int i = 0; i < this .tab; i++)
102: this .print('\t');
103: }
104:
105: public void printTag(String name, HashMap parameters,
106: boolean insertTab, boolean insertNewLine, boolean closeTag) {
107: if (insertTab) {
108: this .printTabulation();
109: }
110: this .print('<');
111: this .print(name);
112: if (parameters != null) {
113: int length = parameters.size();
114: Map.Entry[] entries = new Map.Entry[length];
115: parameters.entrySet().toArray(entries);
116: Arrays.sort(entries, new Comparator() {
117: public int compare(Object o1, Object o2) {
118: Map.Entry entry1 = (Map.Entry) o1;
119: Map.Entry entry2 = (Map.Entry) o2;
120: return ((String) entry1.getKey())
121: .compareTo((String) entry2.getKey());
122: }
123: });
124: for (int i = 0; i < length; i++) {
125: this .print(' ');
126: this .print(entries[i].getKey());
127: this .print("=\""); //$NON-NLS-1$
128: this .print(getEscaped(String.valueOf(entries[i]
129: .getValue())));
130: this .print('\"');
131: }
132: }
133: if (closeTag) {
134: this .print("/>"); //$NON-NLS-1$
135: } else {
136: this .print(">"); //$NON-NLS-1$
137: }
138: if (insertNewLine) {
139: print(this .lineSeparator);
140: }
141: if (parameters != null && !closeTag)
142: this .tab++;
143:
144: }
145:
146: public void startTag(String name, boolean insertTab) {
147: printTag(name, null/*no parameters*/, insertTab,
148: true/*insert new line*/, false/*don't close tag*/);
149: this.tab++;
150: }
151: }
|