1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.archetype.common.util;
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 import javax.xml.transform.Result;
74
75 import java.io.BufferedOutputStream;
76 import java.io.BufferedWriter;
77 import java.io.IOException;
78 import java.io.OutputStream;
79 import java.io.OutputStreamWriter;
80 import java.io.StringWriter;
81 import java.io.Writer;
82 import java.util.List;
83
84 import org.codehaus.plexus.util.StringUtils;
85 import org.jdom2.Attribute;
86 import org.jdom2.CDATA;
87 import org.jdom2.Comment;
88 import org.jdom2.DocType;
89 import org.jdom2.Document;
90 import org.jdom2.Element;
91 import org.jdom2.EntityRef;
92 import org.jdom2.Namespace;
93 import org.jdom2.ProcessingInstruction;
94 import org.jdom2.Text;
95 import org.jdom2.output.EscapeStrategy;
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 public class XMLOutputter implements Cloneable {
148
149 private Format userFormat = Format.getRawFormat();
150
151
152 protected static final Format PRESERVE_FORMAT = Format.getRawFormat();
153
154
155 protected Format currentFormat = userFormat;
156
157
158
159
160
161 private boolean escapeOutput = true;
162
163
164
165
166
167
168
169
170 public XMLOutputter() {}
171
172
173
174
175
176
177 public XMLOutputter(Format format) {
178 userFormat = (Format) format.clone();
179 currentFormat = userFormat;
180 }
181
182
183
184
185
186
187
188
189
190 public XMLOutputter(XMLOutputter that) {
191 this.userFormat = (Format) that.userFormat.clone();
192 currentFormat = userFormat;
193 }
194
195
196
197
198
199
200
201
202
203
204 public void setFormat(Format newFormat) {
205 this.userFormat = (Format) newFormat.clone();
206 this.currentFormat = userFormat;
207 }
208
209
210
211
212
213 public Format getFormat() {
214 return (Format) userFormat.clone();
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228
229 public void output(Document doc, OutputStream out) throws IOException {
230 Writer writer = makeWriter(out);
231 output(doc, writer);
232 }
233
234
235
236
237
238
239
240 public void output(DocType doctype, OutputStream out) throws IOException {
241 Writer writer = makeWriter(out);
242 output(doctype, writer);
243 }
244
245
246
247
248
249
250
251
252
253 public void output(Element element, OutputStream out) throws IOException {
254 Writer writer = makeWriter(out);
255 output(element, writer);
256 }
257
258
259
260
261
262
263
264
265
266
267
268 public void outputElementContent(Element element, OutputStream out) throws IOException {
269 Writer writer = makeWriter(out);
270 outputElementContent(element, writer);
271 }
272
273
274
275
276
277
278
279
280
281
282 public void output(List<?> list, OutputStream out) throws IOException {
283 Writer writer = makeWriter(out);
284 output(list, writer);
285 }
286
287
288
289
290
291
292
293 public void output(CDATA cdata, OutputStream out) throws IOException {
294 Writer writer = makeWriter(out);
295 output(cdata, writer);
296 }
297
298
299
300
301
302
303
304
305 public void output(Text text, OutputStream out) throws IOException {
306 Writer writer = makeWriter(out);
307 output(text, writer);
308 }
309
310
311
312
313
314
315
316 public void output(Comment comment, OutputStream out) throws IOException {
317 Writer writer = makeWriter(out);
318 output(comment, writer);
319 }
320
321
322
323
324
325
326
327 public void output(ProcessingInstruction pi, OutputStream out) throws IOException {
328 Writer writer = makeWriter(out);
329 output(pi, writer);
330 }
331
332
333
334
335
336
337
338 public void output(EntityRef entity, OutputStream out) throws IOException {
339 Writer writer = makeWriter(out);
340 output(entity, writer);
341 }
342
343
344
345
346
347 private Writer makeWriter(OutputStream out) throws java.io.UnsupportedEncodingException {
348 return makeWriter(out, userFormat.encoding);
349 }
350
351
352 private static Writer makeWriter(OutputStream out, String enc) throws java.io.UnsupportedEncodingException {
353 return new BufferedWriter((new OutputStreamWriter(new BufferedOutputStream(out), enc)));
354 }
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371 public void output(Document doc, Writer out) throws IOException {
372
373 printDeclaration(out, doc, userFormat.encoding);
374
375
376
377
378 List<?> content = doc.getContent();
379 int size = content.size();
380 for (int i = 0; i < size; i++) {
381 Object obj = content.get(i);
382
383 if (obj instanceof Element) {
384 printElement(out, doc.getRootElement(), 0, createNamespaceStack());
385 } else if (obj instanceof Comment) {
386 printComment(out, (Comment) obj);
387 } else if (obj instanceof ProcessingInstruction) {
388 printProcessingInstruction(out, (ProcessingInstruction) obj);
389 } else if (obj instanceof DocType) {
390 printDocType(out, doc.getDocType());
391
392
393 out.write(currentFormat.lineSeparator);
394 } else {
395
396
397 }
398
399 newline(out);
400 indent(out, 0);
401 }
402
403
404
405 out.write(currentFormat.lineSeparator);
406 }
407
408
409
410
411
412
413
414 public void output(DocType doctype, Writer out) throws IOException {
415 printDocType(out, doctype);
416 }
417
418
419
420
421
422
423
424
425
426 public void output(Element element, Writer out) throws IOException {
427
428
429 printElement(out, element, 0, createNamespaceStack());
430 }
431
432
433
434
435
436
437
438
439
440
441
442 public void outputElementContent(Element element, Writer out) throws IOException {
443 List<?> content = element.getContent();
444 printContentRange(out, content, 0, content.size(), 0, createNamespaceStack());
445 }
446
447
448
449
450
451
452
453
454
455
456 public void output(List<?> list, Writer out) throws IOException {
457 printContentRange(out, list, 0, list.size(), 0, createNamespaceStack());
458 }
459
460
461
462
463
464
465
466 public void output(CDATA cdata, Writer out) throws IOException {
467 printCDATA(out, cdata);
468 }
469
470
471
472
473
474
475
476
477 public void output(Text text, Writer out) throws IOException {
478 printText(out, text);
479 }
480
481
482
483
484
485
486
487 public void output(Comment comment, Writer out) throws IOException {
488 printComment(out, comment);
489 }
490
491
492
493
494
495
496
497 public void output(ProcessingInstruction pi, Writer out) throws IOException {
498 boolean currentEscapingPolicy = currentFormat.ignoreTrAXEscapingPIs;
499
500
501 currentFormat.setIgnoreTrAXEscapingPIs(true);
502 printProcessingInstruction(out, pi);
503 currentFormat.setIgnoreTrAXEscapingPIs(currentEscapingPolicy);
504 }
505
506
507
508
509
510
511
512 public void output(EntityRef entity, Writer out) throws IOException {
513 printEntityRef(out, entity);
514 }
515
516
517
518
519
520
521
522
523
524
525
526 public String outputString(Document doc) {
527 StringWriter out = new StringWriter();
528 try {
529 output(doc, out);
530 } catch (IOException e) {
531 }
532 return out.toString();
533 }
534
535
536
537
538
539
540
541
542 public String outputString(DocType doctype) {
543 StringWriter out = new StringWriter();
544 try {
545 output(doctype, out);
546 } catch (IOException e) {
547 }
548 return out.toString();
549 }
550
551
552
553
554
555
556
557
558 public String outputString(Element element) {
559 StringWriter out = new StringWriter();
560 try {
561 output(element, out);
562 } catch (IOException e) {
563 }
564 return out.toString();
565 }
566
567
568
569
570
571
572
573 public String outputString(List<?> list) {
574 StringWriter out = new StringWriter();
575 try {
576 output(list, out);
577 } catch (IOException e) {
578 }
579 return out.toString();
580 }
581
582
583
584
585
586
587
588
589 public String outputString(CDATA cdata) {
590 StringWriter out = new StringWriter();
591 try {
592 output(cdata, out);
593 } catch (IOException e) {
594 }
595 return out.toString();
596 }
597
598
599
600
601
602
603
604
605 public String outputString(Text text) {
606 StringWriter out = new StringWriter();
607 try {
608 output(text, out);
609 } catch (IOException e) {
610 }
611 return out.toString();
612 }
613
614
615
616
617
618
619
620
621 public String outputString(Comment comment) {
622 StringWriter out = new StringWriter();
623 try {
624 output(comment, out);
625 } catch (IOException e) {
626 }
627 return out.toString();
628 }
629
630
631
632
633
634
635
636
637 public String outputString(ProcessingInstruction pi) {
638 StringWriter out = new StringWriter();
639 try {
640 output(pi, out);
641 } catch (IOException e) {
642 }
643 return out.toString();
644 }
645
646
647
648
649
650
651
652
653 public String outputString(EntityRef entity) {
654 StringWriter out = new StringWriter();
655 try {
656 output(entity, out);
657 } catch (IOException e) {
658 }
659 return out.toString();
660 }
661
662
663
664
665
666
667
668
669
670
671
672
673 protected void printDeclaration(Writer out, Document doc, String encoding) throws IOException {
674
675
676 if (!userFormat.omitDeclaration) {
677
678 out.write("<?xml version=\"1.0\"");
679 if (!userFormat.omitEncoding) {
680 out.write(" encoding=\"" + encoding + "\"");
681 }
682 out.write("?>");
683
684
685
686
687 out.write(currentFormat.lineSeparator);
688 }
689 }
690
691
692
693
694
695
696
697 protected void printDocType(Writer out, DocType docType) throws IOException {
698
699 String publicID = docType.getPublicID();
700 String systemID = docType.getSystemID();
701 String internalSubset = docType.getInternalSubset();
702 boolean hasPublic = false;
703
704 out.write("<!DOCTYPE ");
705 out.write(docType.getElementName());
706 if (publicID != null) {
707 out.write(" PUBLIC \"");
708 out.write(publicID);
709 out.write("\"");
710 hasPublic = true;
711 }
712 if (systemID != null) {
713 if (!hasPublic) {
714 out.write(" SYSTEM");
715 }
716 out.write(" \"");
717 out.write(systemID);
718 out.write("\"");
719 }
720 if ((internalSubset != null) && (!internalSubset.equals(""))) {
721 out.write(" [");
722 out.write(currentFormat.lineSeparator);
723 out.write(docType.getInternalSubset());
724 out.write("]");
725 }
726 out.write(">");
727 }
728
729
730
731
732
733
734
735 protected void printComment(Writer out, Comment comment) throws IOException {
736 out.write("<!--");
737 out.write(StringUtils.unifyLineSeparators(comment.getText(), currentFormat.lineSeparator));
738 out.write("-->");
739 }
740
741
742
743
744
745
746
747 protected void printProcessingInstruction(Writer out, ProcessingInstruction pi) throws IOException {
748 String target = pi.getTarget();
749 boolean piProcessed = false;
750
751 if (!currentFormat.ignoreTrAXEscapingPIs) {
752 if (target.equals(Result.PI_DISABLE_OUTPUT_ESCAPING)) {
753 escapeOutput = false;
754 piProcessed = true;
755 } else if (target.equals(Result.PI_ENABLE_OUTPUT_ESCAPING)) {
756 escapeOutput = true;
757 piProcessed = true;
758 }
759 }
760 if (!piProcessed) {
761 String rawData = pi.getData();
762
763
764 if (!"".equals(rawData)) {
765 out.write("<?");
766 out.write(target);
767 out.write(" ");
768 out.write(rawData);
769 out.write("?>");
770 } else {
771 out.write("<?");
772 out.write(target);
773 out.write("?>");
774 }
775 }
776 }
777
778
779
780
781
782
783
784
785
786
787 protected void printEntityRef(Writer out, EntityRef entity) throws IOException {
788 out.write("&");
789 out.write(entity.getName());
790 out.write(";");
791 }
792
793
794
795
796
797
798
799 protected void printCDATA(Writer out, CDATA cdata) throws IOException {
800 String str = (currentFormat.mode == Format.TextMode.NORMALIZE)
801 ? cdata.getTextNormalize()
802 : ((currentFormat.mode == Format.TextMode.TRIM)
803 ? cdata.getText().trim()
804 : cdata.getText());
805 out.write("<![CDATA[");
806 out.write(str);
807 out.write("]]>");
808 }
809
810
811
812
813
814
815
816 protected void printText(Writer out, Text text) throws IOException {
817 String str = (currentFormat.mode == Format.TextMode.NORMALIZE)
818 ? text.getTextNormalize()
819 : ((currentFormat.mode == Format.TextMode.TRIM) ? text.getText().trim() : text.getText());
820 out.write(escapeElementEntities(str));
821 }
822
823
824
825
826
827 private void printString(Writer out, String str) throws IOException {
828 if (currentFormat.mode == Format.TextMode.NORMALIZE) {
829 str = Text.normalizeString(str);
830 } else if (currentFormat.mode == Format.TextMode.TRIM) {
831 str = str.trim();
832 }
833 out.write(escapeElementEntities(str));
834 }
835
836
837
838
839
840
841
842
843
844
845
846 protected void printElement(Writer out, Element element, int level, NamespaceStack namespaces) throws IOException {
847
848 List<?> attributes = element.getAttributes();
849 List<?> content = element.getContent();
850
851
852 String space = null;
853 if (attributes != null) {
854 space = element.getAttributeValue("space", Namespace.XML_NAMESPACE);
855 }
856
857 Format previousFormat = currentFormat;
858
859 if ("default".equals(space)) {
860 currentFormat = userFormat;
861 } else if ("preserve".equals(space)) {
862 currentFormat = PRESERVE_FORMAT;
863 }
864
865
866
867 out.write("<");
868 printQualifiedName(out, element);
869
870
871 int previouslyDeclaredNamespaces = namespaces.size();
872
873
874 printElementNamespace(out, element, namespaces);
875
876
877 printAdditionalNamespaces(out, element, namespaces);
878
879
880 if (attributes != null) {
881 printAttributes(out, attributes, element, namespaces);
882 }
883
884
885
886
887
888
889 int start = skipLeadingWhite(content, 0);
890 int size = content.size();
891 if (start >= size) {
892
893 if (currentFormat.expandEmptyElements) {
894 out.write("></");
895 printQualifiedName(out, element);
896 out.write(">");
897 } else {
898 out.write(" />");
899 }
900 } else {
901 out.write(">");
902
903
904
905
906
907 if (nextNonText(content, start) < size) {
908
909 newline(out);
910 printContentRange(out, content, start, size, level + 1, namespaces);
911 newline(out);
912 indent(out, level);
913 } else {
914
915 printTextRange(out, content, start, size);
916 }
917 out.write("</");
918 printQualifiedName(out, element);
919 out.write(">");
920 }
921
922
923 while (namespaces.size() > previouslyDeclaredNamespaces) {
924 namespaces.pop();
925 }
926
927
928 currentFormat = previousFormat;
929 }
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944 private void printContentRange(
945 Writer out, List<?> content, int start, int end, int level, NamespaceStack namespaces) throws IOException {
946 boolean firstNode;
947 Object next;
948 int first, index;
949
950 index = start;
951 while (index < end) {
952 firstNode = index == start;
953 next = content.get(index);
954
955
956
957
958 if ((next instanceof Text) || (next instanceof EntityRef)) {
959 first = skipLeadingWhite(content, index);
960
961 index = nextNonText(content, first);
962
963
964 if (first < index) {
965 if (!firstNode) {
966 newline(out);
967 }
968 indent(out, level);
969 printTextRange(out, content, first, index);
970 }
971 continue;
972 }
973
974
975
976
977 if (!firstNode) {
978 newline(out);
979 }
980
981 indent(out, level);
982
983 if (next instanceof Comment) {
984 printComment(out, (Comment) next);
985 } else if (next instanceof Element) {
986 printElement(out, (Element) next, level, namespaces);
987 } else if (next instanceof ProcessingInstruction) {
988 printProcessingInstruction(out, (ProcessingInstruction) next);
989 } else {
990
991
992
993 }
994
995 index++;
996 }
997 }
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009 private void printTextRange(Writer out, List<?> content, int start, int end) throws IOException {
1010 String previous;
1011 Object node;
1012 String next;
1013
1014 previous = null;
1015
1016
1017 start = skipLeadingWhite(content, start);
1018
1019 int size = content.size();
1020 if (start < size) {
1021
1022 end = skipTrailingWhite(content, end);
1023
1024 for (int i = start; i < end; i++) {
1025 node = content.get(i);
1026
1027
1028
1029 if (node instanceof CDATA) {
1030 next = "<![CDATA[" + ((CDATA) node).getValue() + "]]>";
1031 } else if (node instanceof Text) {
1032 next = ((Text) node).getText();
1033 } else if (node instanceof EntityRef) {
1034 next = "&" + ((EntityRef) node).getValue() + ";";
1035 } else {
1036 throw new IllegalStateException("Should see only CDATA, Text, or EntityRef");
1037 }
1038
1039
1040 if (next == null || "".equals(next)) {
1041 continue;
1042 }
1043
1044
1045
1046 if (previous != null) {
1047 if (currentFormat.mode == Format.TextMode.NORMALIZE || currentFormat.mode == Format.TextMode.TRIM) {
1048 if ((endsWithWhite(previous)) || (startsWithWhite(next))) {
1049 out.write(" ");
1050 }
1051 }
1052 }
1053
1054
1055 if (node instanceof CDATA) {
1056 printCDATA(out, (CDATA) node);
1057 } else if (node instanceof EntityRef) {
1058 printEntityRef(out, (EntityRef) node);
1059 } else {
1060 printString(out, next);
1061 }
1062
1063 previous = next;
1064 }
1065 }
1066 }
1067
1068
1069
1070
1071
1072
1073
1074
1075 private void printNamespace(Writer out, Namespace ns, NamespaceStack namespaces) throws IOException {
1076 String prefix = ns.getPrefix();
1077 String uri = ns.getURI();
1078
1079
1080 if (uri.equals(namespaces.getURI(prefix))) {
1081 return;
1082 }
1083
1084 out.write(" xmlns");
1085 if (!prefix.equals("")) {
1086 out.write(":");
1087 out.write(prefix);
1088 }
1089 out.write("=\"");
1090 out.write(uri);
1091 out.write("\"");
1092 namespaces.push(ns);
1093 }
1094
1095
1096
1097
1098
1099
1100
1101 protected void printAttributes(Writer out, List<?> attributes, Element parent, NamespaceStack namespaces)
1102 throws IOException {
1103
1104
1105
1106
1107
1108
1109 for (int i = 0; i < attributes.size(); i++) {
1110 Attribute attribute = (Attribute) attributes.get(i);
1111 Namespace ns = attribute.getNamespace();
1112 if ((ns != Namespace.NO_NAMESPACE) && (ns != Namespace.XML_NAMESPACE)) {
1113 printNamespace(out, ns, namespaces);
1114 }
1115
1116 out.write(" ");
1117 printQualifiedName(out, attribute);
1118 out.write("=");
1119
1120 out.write("\"");
1121 out.write(escapeAttributeEntities(attribute.getValue()));
1122 out.write("\"");
1123 }
1124 }
1125
1126 private void printElementNamespace(Writer out, Element element, NamespaceStack namespaces) throws IOException {
1127
1128
1129
1130
1131 Namespace ns = element.getNamespace();
1132 if (ns == Namespace.XML_NAMESPACE) {
1133 return;
1134 }
1135 if (!((ns == Namespace.NO_NAMESPACE) && (namespaces.getURI("") == null))) {
1136 printNamespace(out, ns, namespaces);
1137 }
1138 }
1139
1140 private void printAdditionalNamespaces(Writer out, Element element, NamespaceStack namespaces) throws IOException {
1141 List<?> list = element.getAdditionalNamespaces();
1142 if (list != null) {
1143 for (int i = 0; i < list.size(); i++) {
1144 Namespace additional = (Namespace) list.get(i);
1145 printNamespace(out, additional, namespaces);
1146 }
1147 }
1148 }
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159 private void newline(Writer out) throws IOException {
1160 if (currentFormat.indent != null) {
1161 out.write(currentFormat.lineSeparator);
1162 }
1163 }
1164
1165
1166
1167
1168
1169
1170
1171
1172 private void indent(Writer out, int level) throws IOException {
1173 if (currentFormat.indent == null || currentFormat.indent.equals("")) {
1174 return;
1175 }
1176
1177 for (int i = 0; i < level; i++) {
1178 out.write(currentFormat.indent);
1179 }
1180 }
1181
1182
1183
1184
1185
1186 private int skipLeadingWhite(List<?> content, int start) {
1187 if (start < 0) {
1188 start = 0;
1189 }
1190
1191 int index = start;
1192 int size = content.size();
1193 if (currentFormat.mode == Format.TextMode.TRIM_FULL_WHITE
1194 || currentFormat.mode == Format.TextMode.NORMALIZE
1195 || currentFormat.mode == Format.TextMode.TRIM) {
1196 while (index < size) {
1197 if (!isAllWhitespace(content.get(index))) {
1198 return index;
1199 }
1200 index++;
1201 }
1202 }
1203 return index;
1204 }
1205
1206
1207
1208
1209
1210 private int skipTrailingWhite(List<?> content, int start) {
1211 int size = content.size();
1212 if (start > size) {
1213 start = size;
1214 }
1215
1216 int index = start;
1217 if (currentFormat.mode == Format.TextMode.TRIM_FULL_WHITE
1218 || currentFormat.mode == Format.TextMode.NORMALIZE
1219 || currentFormat.mode == Format.TextMode.TRIM) {
1220 while (index >= 0) {
1221 if (!isAllWhitespace(content.get(index - 1))) {
1222 break;
1223 }
1224 --index;
1225 }
1226 }
1227 return index;
1228 }
1229
1230
1231
1232
1233
1234 private static int nextNonText(List<?> content, int start) {
1235 if (start < 0) {
1236 start = 0;
1237 }
1238
1239 int index = start;
1240 int size = content.size();
1241 while (index < size) {
1242 Object node = content.get(index);
1243 if (!((node instanceof Text) || (node instanceof EntityRef))) {
1244 return index;
1245 }
1246 index++;
1247 }
1248 return size;
1249 }
1250
1251
1252 private boolean isAllWhitespace(Object obj) {
1253 String str = null;
1254
1255 if (obj instanceof String) {
1256 str = (String) obj;
1257 } else if (obj instanceof Text) {
1258 str = ((Text) obj).getText();
1259 } else {
1260 return false;
1261 }
1262
1263 for (int i = 0; i < str.length(); i++) {
1264 if (!isWhitespace(str.charAt(i))) {
1265 return false;
1266 }
1267 }
1268 return true;
1269 }
1270
1271
1272 private boolean startsWithWhite(String str) {
1273 return ((str != null) && (!str.isEmpty()) && isWhitespace(str.charAt(0)));
1274 }
1275
1276
1277 private boolean endsWithWhite(String str) {
1278 return ((str != null) && (!str.isEmpty()) && isWhitespace(str.charAt(str.length() - 1)));
1279 }
1280
1281
1282
1283 private static boolean isWhitespace(char c) {
1284 return (c == ' ' || c == '\n' || c == '\t' || c == '\r');
1285 }
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297 public String escapeAttributeEntities(String str) {
1298 StringBuilder buffer;
1299 char ch;
1300 String entity;
1301 EscapeStrategy strategy = currentFormat.escapeStrategy;
1302
1303 buffer = null;
1304 for (int i = 0; i < str.length(); i++) {
1305 ch = str.charAt(i);
1306 switch (ch) {
1307 case '<':
1308 entity = "<";
1309 break;
1310 case '>':
1311 entity = ">";
1312 break;
1313
1314
1315
1316
1317
1318 case '\"':
1319 entity = """;
1320 break;
1321 case '&':
1322 entity = "&";
1323 break;
1324 case '\r':
1325 entity = "
";
1326 break;
1327 case '\t':
1328 entity = "	";
1329 break;
1330 case '\n':
1331 entity = "
";
1332 break;
1333 default:
1334 if (strategy.shouldEscape(ch)) {
1335 entity = "&#x" + Integer.toHexString(ch) + ";";
1336 } else {
1337 entity = null;
1338 }
1339 break;
1340 }
1341 if (buffer == null) {
1342 if (entity != null) {
1343
1344
1345 buffer = new StringBuilder(str.length() + 20);
1346
1347
1348 buffer.append(str.substring(0, i));
1349 buffer.append(entity);
1350 }
1351 } else {
1352 if (entity == null) {
1353 buffer.append(ch);
1354 } else {
1355 buffer.append(entity);
1356 }
1357 }
1358 }
1359
1360
1361
1362
1363 return (buffer == null) ? str : buffer.toString();
1364 }
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375 public String escapeElementEntities(String str) {
1376 if (!escapeOutput) {
1377 return str;
1378 }
1379
1380 StringBuilder buffer;
1381 char ch;
1382 String entity;
1383 EscapeStrategy strategy = currentFormat.escapeStrategy;
1384
1385 buffer = null;
1386 for (int i = 0; i < str.length(); i++) {
1387 ch = str.charAt(i);
1388 switch (ch) {
1389 case '<':
1390 entity = "<";
1391 break;
1392 case '>':
1393 entity = ">";
1394 break;
1395 case '&':
1396 entity = "&";
1397 break;
1398 case '\r':
1399 entity = "
";
1400 break;
1401 case '\n':
1402 entity = currentFormat.lineSeparator;
1403 break;
1404 default:
1405 if (strategy.shouldEscape(ch)) {
1406 entity = "&#x" + Integer.toHexString(ch) + ";";
1407 } else {
1408 entity = null;
1409 }
1410 break;
1411 }
1412 if (buffer == null) {
1413 if (entity != null) {
1414
1415
1416 buffer = new StringBuilder(str.length() + 20);
1417
1418
1419 buffer.append(str.substring(0, i));
1420 buffer.append(entity);
1421 }
1422 } else {
1423 if (entity == null) {
1424 buffer.append(ch);
1425 } else {
1426 buffer.append(entity);
1427 }
1428 }
1429 }
1430
1431
1432
1433
1434 return (buffer == null) ? str : buffer.toString();
1435 }
1436
1437
1438 @Override
1439 public Object clone() {
1440
1441
1442
1443
1444
1445 try {
1446 return super.clone();
1447 } catch (java.lang.CloneNotSupportedException e) {
1448
1449
1450
1451
1452 throw new RuntimeException(e.toString());
1453 }
1454 }
1455
1456
1457
1458
1459
1460
1461
1462 @Override
1463 public String toString() {
1464 StringBuilder buffer = new StringBuilder();
1465 for (int i = 0; i < userFormat.lineSeparator.length(); i++) {
1466 char ch = userFormat.lineSeparator.charAt(i);
1467 switch (ch) {
1468 case '\r':
1469 buffer.append("\\r");
1470 break;
1471 case '\n':
1472 buffer.append("\\n");
1473 break;
1474 case '\t':
1475 buffer.append("\\t");
1476 break;
1477 default:
1478 buffer.append("[" + ((int) ch) + "]");
1479 break;
1480 }
1481 }
1482
1483 return ("XMLOutputter[omitDeclaration = " + userFormat.omitDeclaration + ", "
1484 + "encoding = " + userFormat.encoding + ", "
1485 + "omitEncoding = " + userFormat.omitEncoding + ", "
1486 + "indent = '" + userFormat.indent + "'" + ", "
1487 + "expandEmptyElements = " + userFormat.expandEmptyElements + ", "
1488 + "lineSeparator = '" + buffer + "', "
1489 + "textMode = " + userFormat.mode + "]");
1490 }
1491
1492
1493
1494
1495
1496
1497
1498 private NamespaceStack createNamespaceStack() {
1499
1500 return new NamespaceStack();
1501 }
1502
1503
1504
1505
1506
1507
1508
1509
1510 protected static class NamespaceStack extends org.apache.maven.archetype.common.util.NamespaceStack {}
1511
1512
1513
1514 private void printQualifiedName(Writer out, Element e) throws IOException {
1515 if (e.getNamespace().getPrefix().isEmpty()) {
1516 out.write(e.getName());
1517 } else {
1518 out.write(e.getNamespace().getPrefix());
1519 out.write(':');
1520 out.write(e.getName());
1521 }
1522 }
1523
1524
1525
1526 private void printQualifiedName(Writer out, Attribute a) throws IOException {
1527 String prefix = a.getNamespace().getPrefix();
1528 if ((prefix != null) && (!prefix.equals(""))) {
1529 out.write(prefix);
1530 out.write(':');
1531 out.write(a.getName());
1532 } else {
1533 out.write(a.getName());
1534 }
1535 }
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546 }