1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.shared.utils.xml;
20
21 import java.io.IOException;
22 import java.io.Writer;
23
24
25
26
27
28
29 final class XMLEncode {
30
31 private static final int CDATA_BLOCK_THRESHOLD_LENGTH = 12;
32
33 private static final char DEFAULT_QUOTE_CHAR = '"';
34
35 static void xmlEncodeText(String text, Writer writer) throws IOException {
36 if (text == null) {
37 return;
38 }
39
40 if (!needsEncoding(text)) {
41 writer.write(text);
42 return;
43 } else {
44
45 if (text.length() > CDATA_BLOCK_THRESHOLD_LENGTH) {
46 String cdata = xmlEncodeTextAsCDATABlock(text);
47 if (cdata != null) {
48 writer.write(cdata);
49 return;
50 }
51 }
52 }
53
54
55 xmlEncodeTextAsPCDATA(text, false, DEFAULT_QUOTE_CHAR, writer);
56 }
57
58 static void xmlEncodeTextAsPCDATA(String text, boolean forAttribute, char quoteChar, Writer n) throws IOException {
59 if (text == null) {
60 return;
61 }
62
63 int length = text.length();
64 if (forAttribute) {
65 n.append(quoteChar);
66 }
67
68 for (int i = 0; i < length; i++) {
69 char c = text.charAt(i);
70 switch (c) {
71 case '&':
72 n.append("&");
73 break;
74 case '<':
75 n.append("<");
76 break;
77 case '>':
78 n.append(">");
79 break;
80 case '"':
81 if (forAttribute) {
82 n.append(""");
83 } else {
84 n.append(c);
85 }
86 break;
87 case '\'':
88 if (forAttribute) {
89 n.append("'");
90 } else {
91 n.append(c);
92 }
93 break;
94 case '\r':
95 if (forAttribute) {
96 if (i == (length - 1) || text.charAt(i + 1) != '\n') {
97 n.append(" ");
98 }
99 } else {
100 n.append(c);
101 }
102
103
104 break;
105 case '\n':
106 if (forAttribute) {
107 n.append(" ");
108 }
109 break;
110
111 default:
112 n.append(c);
113 break;
114 }
115 }
116
117 if (forAttribute) {
118 n.append(quoteChar);
119 }
120 }
121
122
123
124
125 private static String xmlEncodeTextAsCDATABlock(String text) {
126 if (text == null) {
127 return null;
128 }
129 if (!text.contains("]]>")) {
130 return "<![CDATA[" + text + "]]>";
131 } else {
132 return null;
133 }
134 }
135
136
137
138
139 private static boolean needsEncoding(String text) {
140 if (text == null) {
141 return false;
142 }
143 for (int i = 0; i < text.length(); i++) {
144 char c = text.charAt(i);
145 if (c == '&' || c == '<') {
146 return true;
147 }
148 }
149 return false;
150 }
151 }