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