1 package org.apache.maven.plugin.surefire.report;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.PrintWriter;
23 import java.util.LinkedList;
24
25 import org.apache.maven.shared.utils.xml.XMLWriter;
26
27 public class PrettyPrintXMLWriter
28 implements XMLWriter
29 {
30 private final PrintWriter writer;
31
32 private final LinkedList<String> elementStack = new LinkedList<String>();
33
34 private boolean tagInProgress;
35
36 private int depth;
37
38 private final String lineIndenter;
39
40 private final String encoding;
41
42 private final String docType;
43
44 private boolean readyForNewLine;
45
46 private boolean tagIsEmpty;
47
48 public PrettyPrintXMLWriter( PrintWriter writer )
49 {
50 this( writer, null, null );
51 }
52
53 private PrettyPrintXMLWriter( PrintWriter writer, String lineIndenter, String encoding, String doctype )
54 {
55 this.writer = writer;
56
57 this.lineIndenter = lineIndenter;
58
59 this.encoding = encoding;
60
61 this.docType = doctype;
62
63 if ( docType != null || encoding != null )
64 {
65 writeDocumentHeaders();
66 }
67 }
68
69 public void setEncoding( String encoding )
70 {
71 throw new RuntimeException( "Not Implemented" );
72 }
73
74 public void setDocType( String docType )
75 {
76 throw new RuntimeException( "Not Implemented" );
77 }
78
79 private PrettyPrintXMLWriter( PrintWriter writer, String encoding, String doctype )
80 {
81 this( writer, " ", encoding, doctype );
82 }
83
84 public void startElement( String name )
85 {
86 tagIsEmpty = false;
87
88 finishTag();
89
90 write( "<" );
91
92 write( name );
93
94 elementStack.addLast( name );
95
96 tagInProgress = true;
97
98 depth++;
99
100 readyForNewLine = true;
101
102 tagIsEmpty = true;
103 }
104
105 public void writeText( String text )
106 {
107 writeText( text, true );
108 }
109
110 public void writeMarkup( String text )
111 {
112 writeText( text, false );
113 }
114
115 private void writeText( String text, boolean escapeXml )
116 {
117 readyForNewLine = false;
118
119 tagIsEmpty = false;
120
121 finishTag();
122
123 if ( escapeXml )
124 {
125 text = escapeXml( text );
126 }
127
128 write( text );
129 }
130
131 private static String escapeXml( String text )
132 {
133 StringBuffer sb = new StringBuffer( text.length() * 2 );
134 for ( int i = 0; i < text.length(); i++ )
135 {
136 char c = text.charAt( i );
137 if ( c < 32 )
138 {
139 if ( c == '\n' || c == '\r' || c == '\t' )
140 {
141 sb.append( c );
142 }
143 else
144 {
145
146
147
148
149
150 sb.append( "&#" ).append( (int) c ).append( ';' );
151 }
152 }
153 else if ( c == '<' )
154 {
155 sb.append( "<" );
156 }
157 else if ( c == '>' )
158 {
159 sb.append( ">" );
160 }
161 else if ( c == '&' )
162 {
163 sb.append( "&" );
164 }
165 else if ( c == '"' )
166 {
167 sb.append( """ );
168 }
169 else if ( c == '\'' )
170 {
171 sb.append( "'" );
172 }
173 else
174 {
175 sb.append( c );
176 }
177 }
178 return sb.toString();
179 }
180
181 public void addAttribute( String key, String value )
182 {
183 write( " " );
184
185 write( key );
186
187 write( "=\"" );
188
189 write( escapeXml( value ) );
190
191 write( "\"" );
192 }
193
194 public void endElement()
195 {
196 depth--;
197
198 if ( tagIsEmpty )
199 {
200 write( "/" );
201
202 readyForNewLine = false;
203
204 finishTag();
205
206 elementStack.removeLast();
207 }
208 else
209 {
210 finishTag();
211
212 write( "</" + elementStack.removeLast() + ">" );
213 }
214
215 readyForNewLine = true;
216 }
217
218 private void write( String str )
219 {
220 writer.write( str );
221 }
222
223 private void finishTag()
224 {
225 if ( tagInProgress )
226 {
227 write( ">" );
228 }
229
230 tagInProgress = false;
231
232 if ( readyForNewLine )
233 {
234 endOfLine();
235 }
236 readyForNewLine = false;
237
238 tagIsEmpty = false;
239 }
240
241 protected void endOfLine()
242 {
243 write( "\n" );
244
245 for ( int i = 0; i < depth; i++ )
246 {
247 write( lineIndenter );
248 }
249 }
250
251 private void writeDocumentHeaders()
252 {
253 write( "<?xml version=\"1.0\"" );
254
255 if ( encoding != null )
256 {
257 write( " encoding=\"" + encoding + "\"" );
258 }
259
260 write( "?>" );
261
262 endOfLine();
263
264 if ( docType != null )
265 {
266 write( "<!DOCTYPE " );
267
268 write( docType );
269
270 write( ">" );
271
272 endOfLine();
273 }
274 }
275 }