1
2
3
4
5
6 package org.codehaus.modello.test.features.io.stax;
7
8
9
10
11
12 import javax.xml.namespace.NamespaceContext;
13 import javax.xml.stream.XMLStreamException;
14 import javax.xml.stream.XMLStreamWriter;
15
16
17
18
19
20
21 @SuppressWarnings( "all" )
22 class IndentingXMLStreamWriter
23 implements XMLStreamWriter
24 {
25
26
27
28
29
30
31
32
33 private XMLStreamWriter out;
34
35
36
37
38 private static final String NEW_LINE = "\n";
39
40
41
42
43 private String newLine = NEW_LINE;
44
45
46
47
48 private String indent = " ";
49
50
51
52
53 private char[] linePrefix = " ".toCharArray();
54
55
56
57
58 private int depth;
59
60
61
62
63 private byte[] states = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
64
65
66
67
68 private static final int ELEMENT_HAS_DATA = 0x1;
69
70
71
72
73 private static final int ELEMENT_HAS_MARKUP = 0x2;
74
75
76
77
78
79
80 public IndentingXMLStreamWriter(XMLStreamWriter out)
81 {
82 this.out = out;
83 }
84
85
86
87
88
89
90
91
92
93
94
95 public void close()
96 throws XMLStreamException
97 {
98 out.close();
99 }
100
101
102
103
104
105
106 public void flush()
107 throws XMLStreamException
108 {
109 out.flush();
110 }
111
112
113
114
115
116
117 public NamespaceContext getNamespaceContext()
118 {
119 return out.getNamespaceContext();
120 }
121
122
123
124
125
126
127
128
129 public String getPrefix( String uri )
130 throws XMLStreamException
131 {
132 return out.getPrefix( uri );
133 }
134
135
136
137
138
139
140
141
142
143 public Object getProperty( String name )
144 throws IllegalArgumentException
145 {
146 return out.getProperty( name );
147 }
148
149
150
151
152
153
154
155 public void setDefaultNamespace( String uri )
156 throws XMLStreamException
157 {
158 out.setDefaultNamespace( uri );
159 }
160
161
162
163
164
165
166
167 public void setNamespaceContext( NamespaceContext context )
168 throws XMLStreamException
169 {
170 out.setNamespaceContext( context );
171 }
172
173
174
175
176
177
178
179
180 public void setPrefix( String prefix, String uri )
181 throws XMLStreamException
182 {
183 out.setPrefix( prefix, uri );
184 }
185
186
187
188
189
190
191
192
193 public void writeAttribute( String localName, String value )
194 throws XMLStreamException
195 {
196 out.writeAttribute( localName, value );
197 }
198
199
200
201
202
203
204
205
206
207 public void writeAttribute( String namespaceURI, String localName, String value )
208 throws XMLStreamException
209 {
210 out.writeAttribute( namespaceURI, localName, value );
211 }
212
213
214
215
216
217
218
219
220
221
222 public void writeAttribute( String prefix, String namespaceURI, String localName, String value )
223 throws XMLStreamException
224 {
225 out.writeAttribute( prefix, namespaceURI, localName, value );
226 }
227
228
229
230
231
232
233
234 public void writeCData( String data )
235 throws XMLStreamException
236 {
237 out.writeCData( data );
238 afterData();
239 }
240
241
242
243
244
245
246
247 public void writeCharacters( String text )
248 throws XMLStreamException
249 {
250 out.writeCharacters( text );
251 afterData();
252 }
253
254
255
256
257
258
259
260
261
262 public void writeCharacters( char[] text, int start, int len )
263 throws XMLStreamException
264 {
265 out.writeCharacters( text, start, len );
266 afterData();
267 }
268
269
270
271
272
273
274
275 public void writeComment( String data )
276 throws XMLStreamException
277 {
278 beforeMarkup();
279 out.writeComment( data );
280 afterMarkup();
281 }
282
283
284
285
286
287
288
289 public void writeDTD( String dtd )
290 throws XMLStreamException
291 {
292 beforeMarkup();
293 out.writeDTD( dtd );
294 afterMarkup();
295 }
296
297
298
299
300
301
302
303 public void writeDefaultNamespace( String namespaceURI )
304 throws XMLStreamException
305 {
306 out.writeDefaultNamespace( namespaceURI );
307 }
308
309
310
311
312
313
314
315 public void writeEmptyElement( String localName )
316 throws XMLStreamException
317 {
318 beforeMarkup();
319 out.writeEmptyElement( localName );
320 afterMarkup();
321 }
322
323
324
325
326
327
328
329
330 public void writeEmptyElement( String namespaceURI, String localName )
331 throws XMLStreamException
332 {
333 beforeMarkup();
334 out.writeEmptyElement( namespaceURI, localName );
335 afterMarkup();
336 }
337
338
339
340
341
342
343
344
345
346 public void writeEmptyElement( String prefix, String namespaceURI, String localName )
347 throws XMLStreamException
348 {
349 beforeMarkup();
350 out.writeEmptyElement( prefix, namespaceURI, localName );
351 afterMarkup();
352 }
353
354
355
356
357
358
359 public void writeEndDocument()
360 throws XMLStreamException
361 {
362 out.writeEndDocument( );
363 }
364
365
366
367
368
369
370 public void writeEndElement()
371 throws XMLStreamException
372 {
373 beforeEndElement();
374 out.writeEndElement( );
375 afterEndElement();
376 }
377
378
379
380
381
382
383
384 public void writeEntityRef( String name )
385 throws XMLStreamException
386 {
387 out.writeEntityRef( name );
388 afterData();
389 }
390
391
392
393
394
395
396
397
398 public void writeNamespace( String prefix, String namespaceURI )
399 throws XMLStreamException
400 {
401 out.writeNamespace( prefix, namespaceURI );
402 }
403
404
405
406
407
408
409
410 public void writeProcessingInstruction( String target )
411 throws XMLStreamException
412 {
413 beforeMarkup();
414 out.writeProcessingInstruction( target );
415 afterMarkup();
416 }
417
418
419
420
421
422
423
424
425 public void writeProcessingInstruction( String target, String data )
426 throws XMLStreamException
427 {
428 beforeMarkup();
429 out.writeProcessingInstruction( target, data );
430 afterMarkup();
431 }
432
433
434
435
436
437
438 public void writeStartDocument()
439 throws XMLStreamException
440 {
441 beforeMarkup();
442 out.writeStartDocument( );
443 afterMarkup();
444 }
445
446
447
448
449
450
451
452 public void writeStartDocument( String version )
453 throws XMLStreamException
454 {
455 beforeMarkup();
456 out.writeStartDocument( version );
457 afterMarkup();
458 }
459
460
461
462
463
464
465
466
467 public void writeStartDocument( String encoding, String version )
468 throws XMLStreamException
469 {
470 beforeMarkup();
471 out.writeStartDocument( encoding, version );
472 afterMarkup();
473 }
474
475
476
477
478
479
480
481 public void writeStartElement( String localName )
482 throws XMLStreamException
483 {
484 beforeStartElement();
485 out.writeStartElement( localName );
486 afterStartElement();
487 }
488
489
490
491
492
493
494
495
496 public void writeStartElement( String namespaceURI, String localName )
497 throws XMLStreamException
498 {
499 beforeStartElement();
500 out.writeStartElement( namespaceURI, localName );
501 afterStartElement();
502 }
503
504
505
506
507
508
509
510
511
512 public void writeStartElement( String prefix, String localName, String namespaceURI )
513 throws XMLStreamException
514 {
515 beforeStartElement();
516 out.writeStartElement( prefix, localName, namespaceURI );
517 afterStartElement();
518 }
519
520
521
522
523 private void afterData()
524 {
525 states[depth] |= ELEMENT_HAS_DATA;
526 }
527
528
529
530
531 private void afterEndElement()
532 {
533 if ( depth > 0 )
534 {
535 depth--;
536 if ( depth <= 0 )
537 {
538 newLine( 0 );
539 }
540 }
541 }
542
543
544
545
546 private void afterMarkup()
547 {
548 states[depth] |= ELEMENT_HAS_MARKUP;
549 }
550
551
552
553
554 private void afterStartElement()
555 {
556 afterMarkup();
557 depth++;
558 }
559
560
561
562
563 private void beforeEndElement()
564 {
565 if ( depth > 0 && states[depth] == ELEMENT_HAS_MARKUP )
566 {
567 newLine( depth - 1 );
568 }
569 }
570
571
572
573
574 private void beforeMarkup()
575 {
576 int state = states[depth];
577 if ( ( state & ELEMENT_HAS_DATA ) == 0 && ( depth > 0 || state != 0 ) )
578 {
579 newLine( depth );
580 if ( depth > 0 && indent.length() > 0 )
581 {
582 afterMarkup();
583 }
584 }
585 }
586
587
588
589
590 private void beforeStartElement()
591 {
592 beforeMarkup();
593 if ( states.length <= depth + 1 )
594 {
595 byte[] tmp = new byte[states.length * 2];
596 System.arraycopy( states, 0, tmp, 0, states.length );
597 states = tmp;
598 }
599 states[depth + 1] = 0;
600 }
601
602
603
604
605
606
607 public String getLineSeparator()
608 {
609 try
610 {
611 return System.getProperty( "line.separator", NEW_LINE );
612 }
613 catch ( Exception e )
614 {
615 return NEW_LINE;
616 }
617 }
618
619
620
621
622
623
624 private void newLine( int depth )
625 {
626 try
627 {
628 out.writeCharacters( newLine );
629 int prefixLength = depth * indent.length();
630 while ( linePrefix.length < prefixLength )
631 {
632 char[] tmp = new char[linePrefix.length * 2];
633 System.arraycopy( linePrefix, 0, tmp, 0, linePrefix.length );
634 System.arraycopy( linePrefix, 0, tmp, linePrefix.length, linePrefix.length );
635 linePrefix = tmp;
636 }
637 out.writeCharacters( linePrefix, 0, prefixLength );
638 }
639 catch ( Exception e )
640 {
641 }
642 }
643
644
645
646
647
648
649 public void setNewLine( String newLine )
650 {
651 this.newLine = newLine;
652 }
653
654 }