1 package com.thoughtworks.xstream.io.xml; 2 3 import com.thoughtworks.xstream.core.util.QuickWriter; 4 import com.thoughtworks.xstream.core.util.StringStack; 5 import com.thoughtworks.xstream.io.HierarchicalStreamWriter; 6 7 import java.io.PrintWriter ; 8 import java.io.Writer ; 9 10 public class PrettyPrintWriter implements HierarchicalStreamWriter { 11 12 private final QuickWriter writer; 13 private final StringStack elementStack = new StringStack(16); 14 private final char[] lineIndenter; 15 16 private boolean tagInProgress; 17 private int depth; 18 private boolean readyForNewLine; 19 private boolean tagIsEmpty; 20 21 private static final char[] AMP = {'&', 'a', 'm', 'p', ';'}; 22 private static final char[] LT = {'&', 'l', 't', ';'}; 23 private static final char[] GT = {'&', 'g', 't', ';'}; 24 private static final char[] CLOSE = {'<', '/'}; 25 26 public PrettyPrintWriter(Writer writer, char[] lineIndenter) { 27 this.writer = new QuickWriter(writer); 28 this.lineIndenter = lineIndenter; 29 } 30 31 public PrettyPrintWriter(Writer writer, String lineIndenter) { 32 this(writer, lineIndenter.toCharArray()); 33 } 34 35 public PrettyPrintWriter(PrintWriter writer) { 36 this(writer, new char[]{' ', ' '}); 37 } 38 39 public PrettyPrintWriter(Writer writer) { 40 this(new PrintWriter (writer)); 41 } 42 43 public void startNode(String name) { 44 tagIsEmpty = false; 45 finishTag(); 46 writer.write('<'); 47 writer.write(name); 48 elementStack.push(name); 49 tagInProgress = true; 50 depth++; 51 readyForNewLine = true; 52 tagIsEmpty = true; 53 } 54 55 public void setValue(String text) { 56 readyForNewLine = false; 57 tagIsEmpty = false; 58 finishTag(); 59 60 final char[] chars = text.toCharArray(); 62 final int length = chars.length; 63 for (int i = 0; i < length; i++) { 64 final char c = chars[i]; 65 switch (c) { 66 case '&': 67 writer.write(AMP); 68 break; 69 case '<': 70 writer.write(LT); 71 break; 72 case '>': 73 writer.write(GT); 74 break; 75 default: 76 writer.write(c); 77 } 78 } 79 } 81 82 public void addAttribute(String key, String value) { 83 writer.write(' '); 84 writer.write(key); 85 writer.write('='); 86 writer.write('\"'); 87 writer.write(value); 88 writer.write('\"'); 89 } 90 91 public void endNode() { 92 depth--; 93 if (tagIsEmpty) { 94 writer.write('/'); 95 readyForNewLine = false; 96 finishTag(); 97 elementStack.popSilently(); 98 } else { 99 finishTag(); 100 writer.write(CLOSE); 101 writer.write(elementStack.pop()); 102 writer.write('>'); 103 } 104 readyForNewLine = true; 105 writer.flush(); 106 } 107 108 private void finishTag() { 109 if (tagInProgress) { 110 writer.write('>'); 111 } 112 tagInProgress = false; 113 if (readyForNewLine) { 114 endOfLine(); 115 } 116 readyForNewLine = false; 117 tagIsEmpty = false; 118 } 119 120 protected void endOfLine() { 121 writer.write('\n'); 122 for (int i = 0; i < depth; i++) { 123 writer.write(lineIndenter); 124 } 125 } 126 127 } 128 | Popular Tags |