• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mybatis / generator / 1646

21 Apr 2025 10:17PM UTC coverage: 88.157% (-0.2%) from 88.328%
1646

push

github

hazendaz
[ci] Run auto formatting

2518 of 3412 branches covered (73.8%)

994 of 1117 new or added lines in 164 files covered. (88.99%)

23 existing lines in 12 files now uncovered.

10578 of 11999 relevant lines covered (88.16%)

0.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

64.0
/core/mybatis-generator-core/src/main/java/org/mybatis/generator/internal/DomWriter.java
1
/*
2
 *    Copyright 2006-2025 the original author or authors.
3
 *
4
 *    Licensed under the Apache License, Version 2.0 (the "License");
5
 *    you may not use this file except in compliance with the License.
6
 *    You may obtain a copy of the License at
7
 *
8
 *       https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *    Unless required by applicable law or agreed to in writing, software
11
 *    distributed under the License is distributed on an "AS IS" BASIS,
12
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *    See the License for the specific language governing permissions and
14
 *    limitations under the License.
15
 */
16
package org.mybatis.generator.internal;
17

18
import static org.mybatis.generator.internal.util.messages.Messages.getString;
19

20
import java.io.PrintWriter;
21
import java.io.StringWriter;
22

23
import org.mybatis.generator.exception.ShellException;
24
import org.w3c.dom.Attr;
25
import org.w3c.dom.CDATASection;
26
import org.w3c.dom.Comment;
27
import org.w3c.dom.Document;
28
import org.w3c.dom.DocumentType;
29
import org.w3c.dom.Element;
30
import org.w3c.dom.EntityReference;
31
import org.w3c.dom.NamedNodeMap;
32
import org.w3c.dom.Node;
33
import org.w3c.dom.ProcessingInstruction;
34
import org.w3c.dom.Text;
35

36
/**
37
 * This class is used to generate a String representation of an XML document. It is very much based on the class
38
 * dom.Writer from the Apache Xerces examples, but I've simplified and updated it.
39
 *
40
 * @author Andy Clark, IBM (Original work)
41
 * @author Jeff Butler (derivation)
42
 */
43
public class DomWriter {
44

45
    protected PrintWriter printWriter;
46

47
    protected boolean isXML11;
48

49
    public DomWriter() {
50
        super();
1✔
51
    }
1✔
52

53
    public synchronized String toString(Document document) throws ShellException {
54
        StringWriter sw = new StringWriter();
1✔
55
        printWriter = new PrintWriter(sw);
1✔
56
        write(document);
1✔
57
        return sw.toString();
1✔
58
    }
59

60
    protected Attr[] sortAttributes(NamedNodeMap attrs) {
61

62
        int len = (attrs != null) ? attrs.getLength() : 0;
1!
63
        Attr[] array = new Attr[len];
1✔
64
        for (int i = 0; i < len; i++) {
1✔
65
            array[i] = (Attr) attrs.item(i);
1✔
66
        }
67
        for (int i = 0; i < len - 1; i++) {
1✔
68
            String name = array[i].getNodeName();
1✔
69
            int index = i;
1✔
70
            for (int j = i + 1; j < len; j++) {
1✔
71
                String curName = array[j].getNodeName();
1✔
72
                if (curName.compareTo(name) < 0) {
1!
73
                    name = curName;
×
74
                    index = j;
×
75
                }
76
            }
77
            if (index != i) {
1!
78
                Attr temp = array[i];
×
79
                array[i] = array[index];
×
80
                array[index] = temp;
×
81
            }
82
        }
83

84
        return array;
1✔
85

86
    }
87

88
    protected void normalizeAndPrint(String s, boolean isAttValue) {
89

90
        int len = (s != null) ? s.length() : 0;
1!
91
        for (int i = 0; i < len; i++) {
1✔
92
            char c = s.charAt(i);
1✔
93
            normalizeAndPrint(c, isAttValue);
1✔
94
        }
95
    }
1✔
96

97
    protected void normalizeAndPrint(char c, boolean isAttValue) {
98

99
        switch (c) {
1!
100
            case '<':
NEW
101
                handleLessThan();
×
NEW
102
                break;
×
103
            case '>':
NEW
104
                handleGreaterThan();
×
NEW
105
                break;
×
106
            case '&':
NEW
107
                handleAmpersand();
×
NEW
108
                break;
×
109
            case '"':
NEW
110
                handleDoubleQuote(isAttValue);
×
NEW
111
                break;
×
112
            case '\r':
NEW
113
                handleCarriageReturn();
×
NEW
114
                break;
×
115
            case '\n':
116
                handleLineFeed();
1✔
117
                break;
1✔
118
            default:
119
                handleDefault(c, isAttValue);
1✔
120
        }
121
    }
1✔
122

123
    private void handleDefault(char c, boolean isAttValue) {
124
        // In XML 1.1, control chars in the ranges [#x1-#x1F, #x7F-#x9F]
125
        // must be escaped.
126
        //
127
        // Escape space characters that would be normalized to #x20 in
128
        // attribute values
129
        // when the document is reparsed.
130
        //
131
        // Escape NEL (0x85) and LSEP (0x2028) that appear in content
132
        // if the document is XML 1.1, since they would be normalized to LF
133
        // when the document is reparsed.
134
        if (isXML11 && ((c >= 0x01 && c <= 0x1F && c != 0x09 && c != 0x0A) || (c >= 0x7F && c <= 0x9F) || c == 0x2028)
1!
135
                || isAttValue && (c == 0x09 || c == 0x0A)) {
136
            printWriter.print("&#x"); //$NON-NLS-1$
×
137
            printWriter.print(Integer.toHexString(c).toUpperCase());
×
138
            printWriter.print(';');
×
139
        } else {
140
            printWriter.print(c);
1✔
141
        }
142
    }
1✔
143

144
    private void handleLineFeed() {
145
        // If LF is part of the document's content, it
146
        // should be printed back out with the system default
147
        // line separator. XML parsing forces \n only after a parse,
148
        // but we should write it out as it was to avoid whitespace
149
        // commits on some version control systems.
150
        printWriter.print(System.lineSeparator());
1✔
151
    }
1✔
152

153
    private void handleCarriageReturn() {
154
        // If CR is part of the document's content, it
155
        // must be printed as a literal otherwise
156
        // it would be normalized to LF when the document
157
        // is reparsed.
158
        printWriter.print("&#xD;"); //$NON-NLS-1$
×
159
    }
×
160

161
    private void handleDoubleQuote(boolean isAttValue) {
162
        // A '"' that appears in character data
163
        // does not need to be escaped.
164
        if (isAttValue) {
×
165
            printWriter.print("&quot;"); //$NON-NLS-1$
×
166
        } else {
167
            printWriter.print('"');
×
168
        }
169
    }
×
170

171
    private void handleAmpersand() {
172
        printWriter.print("&amp;"); //$NON-NLS-1$
×
173
    }
×
174

175
    private void handleGreaterThan() {
176
        printWriter.print("&gt;"); //$NON-NLS-1$
×
177
    }
×
178

179
    private void handleLessThan() {
180
        printWriter.print("&lt;"); //$NON-NLS-1$
×
181
    }
×
182

183
    /**
184
     * Extracts the XML version from the Document.
185
     *
186
     * @param document
187
     *            the document
188
     *
189
     * @return the version
190
     */
191
    protected String getVersion(Document document) {
192
        if (document == null) {
1!
193
            return null;
×
194
        }
195

196
        return document.getXmlVersion();
1✔
197
    }
198

199
    protected void writeAnyNode(Node node) throws ShellException {
200
        // is there anything to do?
201
        if (node == null) {
1!
202
            return;
×
203
        }
204

205
        short type = node.getNodeType();
1✔
206
        switch (type) {
1!
207
            case Node.DOCUMENT_NODE:
NEW
208
                write((Document) node);
×
NEW
209
                break;
×
210

211
            case Node.DOCUMENT_TYPE_NODE:
NEW
212
                write((DocumentType) node);
×
NEW
213
                break;
×
214

215
            case Node.ELEMENT_NODE:
216
                write((Element) node);
1✔
217
                break;
1✔
218

219
            case Node.ENTITY_REFERENCE_NODE:
NEW
220
                write((EntityReference) node);
×
NEW
221
                break;
×
222

223
            case Node.CDATA_SECTION_NODE:
224
                write((CDATASection) node);
1✔
225
                break;
1✔
226

227
            case Node.TEXT_NODE:
228
                write((Text) node);
1✔
229
                break;
1✔
230

231
            case Node.PROCESSING_INSTRUCTION_NODE:
NEW
232
                write((ProcessingInstruction) node);
×
NEW
233
                break;
×
234

235
            case Node.COMMENT_NODE:
236
                write((Comment) node);
1✔
237
                break;
1✔
238

239
            default:
NEW
240
                throw new ShellException(getString("RuntimeError.18", Short.toString(type))); //$NON-NLS-1$
×
241
        }
242
    }
1✔
243

244
    protected void write(Document node) throws ShellException {
245
        isXML11 = "1.1".equals(getVersion(node)); //$NON-NLS-1$
1✔
246
        if (isXML11) {
1!
247
            printWriter.println("<?xml version=\"1.1\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$
×
248
        } else {
249
            printWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$
1✔
250
        }
251
        printWriter.flush();
1✔
252
        write(node.getDoctype());
1✔
253
        write(node.getDocumentElement());
1✔
254
    }
1✔
255

256
    protected void write(DocumentType node) {
257
        printWriter.print("<!DOCTYPE "); //$NON-NLS-1$
1✔
258
        printWriter.print(node.getName());
1✔
259
        String publicId = node.getPublicId();
1✔
260
        String systemId = node.getSystemId();
1✔
261
        if (publicId != null) {
1!
262
            printWriter.print(" PUBLIC \""); //$NON-NLS-1$
1✔
263
            printWriter.print(publicId);
1✔
264
            printWriter.print("\" \""); //$NON-NLS-1$
1✔
265
            printWriter.print(systemId);
1✔
266
            printWriter.print('\"');
1✔
267
        } else if (systemId != null) {
×
268
            printWriter.print(" SYSTEM \""); //$NON-NLS-1$
×
269
            printWriter.print(systemId);
×
270
            printWriter.print('"');
×
271
        }
272

273
        String internalSubset = node.getInternalSubset();
1✔
274
        if (internalSubset != null) {
1!
275
            printWriter.println(" ["); //$NON-NLS-1$
×
276
            printWriter.print(internalSubset);
×
277
            printWriter.print(']');
×
278
        }
279
        printWriter.println('>');
1✔
280
    }
1✔
281

282
    protected void write(Element node) throws ShellException {
283
        printWriter.print('<');
1✔
284
        printWriter.print(node.getNodeName());
1✔
285
        Attr[] attrs = sortAttributes(node.getAttributes());
1✔
286
        for (Attr attr : attrs) {
1✔
287
            printWriter.print(' ');
1✔
288
            printWriter.print(attr.getNodeName());
1✔
289
            printWriter.print("=\""); //$NON-NLS-1$
1✔
290
            normalizeAndPrint(attr.getNodeValue(), true);
1✔
291
            printWriter.print('"');
1✔
292
        }
293

294
        if (node.getChildNodes().getLength() == 0) {
1✔
295
            printWriter.print(" />"); //$NON-NLS-1$
1✔
296
            printWriter.flush();
1✔
297
        } else {
298
            printWriter.print('>');
1✔
299
            printWriter.flush();
1✔
300

301
            Node child = node.getFirstChild();
1✔
302
            while (child != null) {
1✔
303
                writeAnyNode(child);
1✔
304
                child = child.getNextSibling();
1✔
305
            }
306

307
            printWriter.print("</"); //$NON-NLS-1$
1✔
308
            printWriter.print(node.getNodeName());
1✔
309
            printWriter.print('>');
1✔
310
            printWriter.flush();
1✔
311
        }
312
    }
1✔
313

314
    protected void write(EntityReference node) {
315
        printWriter.print('&');
×
316
        printWriter.print(node.getNodeName());
×
317
        printWriter.print(';');
×
318
        printWriter.flush();
×
319
    }
×
320

321
    protected void write(CDATASection node) {
322
        printWriter.print("<![CDATA["); //$NON-NLS-1$
1✔
323
        String data = node.getNodeValue();
1✔
324
        // XML parsers normalize line endings to '\n'. We should write
325
        // it out as it was in the original to avoid whitespace commits
326
        // on some version control systems
327
        int len = (data != null) ? data.length() : 0;
1!
328
        for (int i = 0; i < len; i++) {
1✔
329
            char c = data.charAt(i);
1✔
330
            if (c == '\n') {
1✔
331
                handleLineFeed();
1✔
332
            } else {
333
                printWriter.print(c);
1✔
334
            }
335
        }
336
        printWriter.print("]]>"); //$NON-NLS-1$
1✔
337
        printWriter.flush();
1✔
338
    }
1✔
339

340
    protected void write(Text node) {
341
        normalizeAndPrint(node.getNodeValue(), false);
1✔
342
        printWriter.flush();
1✔
343
    }
1✔
344

345
    protected void write(ProcessingInstruction node) {
346
        printWriter.print("<?"); //$NON-NLS-1$
×
347
        printWriter.print(node.getNodeName());
×
348
        String data = node.getNodeValue();
×
349
        if (data != null && !data.isEmpty()) {
×
350
            printWriter.print(' ');
×
351
            printWriter.print(data);
×
352
        }
353
        printWriter.print("?>"); //$NON-NLS-1$
×
354
        printWriter.flush();
×
355
    }
×
356

357
    protected void write(Comment node) {
358
        printWriter.print("<!--"); //$NON-NLS-1$
1✔
359
        String comment = node.getNodeValue();
1✔
360
        if (comment != null && !comment.isEmpty()) {
1!
361
            normalizeAndPrint(comment, false);
1✔
362
        }
363
        printWriter.print("-->"); //$NON-NLS-1$
1✔
364
        printWriter.flush();
1✔
365
    }
1✔
366
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc