1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 package groovy.xml;
47
48 import groovy.util.BuilderSupport;
49 import groovy.util.IndentPrinter;
50
51 import java.io.PrintWriter;
52 import java.io.Writer;
53 import java.util.Iterator;
54 import java.util.Map;
55
56 /***
57 * A helper class for creating XML or HTML markup
58 *
59 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
60 * @author Stefan Matthias Aust
61 * @version $Revision: 1.7 $
62 */
63 public class MarkupBuilder extends BuilderSupport {
64
65 private IndentPrinter out;
66 private boolean nospace;
67 private int state;
68
69 public MarkupBuilder() {
70 this(new IndentPrinter());
71 }
72
73 public MarkupBuilder(PrintWriter writer) {
74 this(new IndentPrinter(writer));
75 }
76
77 public MarkupBuilder(Writer writer) {
78 this(new IndentPrinter(new PrintWriter(writer)));
79 }
80
81 public MarkupBuilder(IndentPrinter out) {
82 this.out = out;
83 }
84
85 protected void setParent(Object parent, Object child) {
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 protected Object createNode(Object name) {
102 toState(1, name);
103 return name;
104 }
105
106 protected Object createNode(Object name, Object value) {
107 toState(2, name);
108 out.print(">");
109 out.print(value.toString());
110 return name;
111 }
112
113 protected Object createNode(Object name, Map attributes, Object value) {
114 toState(1, name);
115 for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
116 Map.Entry entry = (Map.Entry) iter.next();
117 out.print(" ");
118 print(transformName(entry.getKey().toString()));
119 out.print("='");
120 print(transformValue(entry.getValue().toString()));
121 out.print("'");
122 }
123
124 return name;
125 }
126
127 protected Object createNode(Object name, Map attributes) {
128 return createNode(name, attributes, null);
129 }
130
131 protected void nodeCompleted(Object parent, Object node) {
132 toState(3, node);
133 out.flush();
134 }
135
136 protected void print(Object node) {
137 out.print(node == null ? "null" : node.toString());
138 }
139
140 protected Object getName(String methodName) {
141 return super.getName(transformName(methodName));
142 }
143
144 protected String transformName(String name) {
145 if (name.startsWith("_")) name = name.substring(1);
146 return name.replace('_', '-');
147 }
148
149 protected String transformValue(String value) {
150 return value.replaceAll("//'", """);
151 }
152
153 private void toState(int next, Object name) {
154 switch (state) {
155 case 0:
156 switch (next) {
157 case 1:
158 case 2:
159 out.print("<");
160 print(name);
161 break;
162 case 3:
163 throw new Error();
164 }
165 break;
166 case 1:
167 switch (next) {
168 case 1:
169 case 2:
170 out.print(">");
171 if (nospace) {
172 nospace = false;
173 } else {
174 out.println();
175 out.incrementIndent();
176 out.printIndent();
177 }
178 out.print("<");
179 print(name);
180 break;
181 case 3:
182 out.print(" />");
183 break;
184 }
185 break;
186 case 2:
187 switch (next) {
188 case 1:
189 case 2:
190 throw new Error();
191 case 3:
192 out.print("</");
193 print(name);
194 out.print(">");
195 break;
196 }
197 break;
198 case 3:
199 switch (next) {
200 case 1:
201 case 2:
202 if (nospace) {
203 nospace = false;
204 } else {
205 out.println();
206 out.printIndent();
207 }
208 out.print("<");
209 print(name);
210 break;
211 case 3:
212 if (nospace) {
213 nospace = false;
214 } else {
215 out.println();
216 out.decrementIndent();
217 out.printIndent();
218 }
219 out.print("</");
220 print(name);
221 out.print(">");
222 break;
223 }
224 break;
225 }
226 state = next;
227 }
228
229 }