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

mybatis / generator / 1602

26 Feb 2025 05:58PM UTC coverage: 88.328% (-0.01%) from 88.339%
1602

push

github

web-flow
Merge pull request #1297 from jeffgbutler/java-17

Code Cleanup after Java 17 Update

2518 of 3412 branches covered (73.8%)

163 of 180 new or added lines in 53 files covered. (90.56%)

12 existing lines in 5 files now uncovered.

11192 of 12671 relevant lines covered (88.33%)

0.88 hits per line

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

63.64
/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
38
 * is very much based on the class dom.Writer from the Apache Xerces examples,
39
 * but I've simplified and updated it.
40
 *
41
 * @author Andy Clark, IBM (Original work)
42
 * @author Jeff Butler (derivation)
43
 */
44
public class DomWriter {
45

46
    protected PrintWriter printWriter;
47

48
    protected boolean isXML11;
49

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

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

62
    protected Attr[] sortAttributes(NamedNodeMap attrs) {
63

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

86
        return array;
1✔
87

88
    }
89

90
    protected void normalizeAndPrint(String s, boolean isAttValue) {
91

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

99
    protected void normalizeAndPrint(char c, boolean isAttValue) {
100

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

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

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

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

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

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

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

183
    private void handleLessThan() {
184
        printWriter.print("&lt;"); //$NON-NLS-1$
×
185
    }
×
186

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

199
        return document.getXmlVersion();
1✔
200
    }
201

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

208
        short type = node.getNodeType();
1✔
209
        switch (type) {
1!
210
        case Node.DOCUMENT_NODE:
211
            write((Document) node);
×
212
            break;
×
213

214
        case Node.DOCUMENT_TYPE_NODE:
215
            write((DocumentType) node);
×
216
            break;
×
217

218
        case Node.ELEMENT_NODE:
219
            write((Element) node);
1✔
220
            break;
1✔
221

222
        case Node.ENTITY_REFERENCE_NODE:
223
            write((EntityReference) node);
×
224
            break;
×
225

226
        case Node.CDATA_SECTION_NODE:
227
            write((CDATASection) node);
1✔
228
            break;
1✔
229

230
        case Node.TEXT_NODE:
231
            write((Text) node);
1✔
232
            break;
1✔
233

234
        case Node.PROCESSING_INSTRUCTION_NODE:
235
            write((ProcessingInstruction) node);
×
236
            break;
×
237

238
        case Node.COMMENT_NODE:
239
            write((Comment) node);
1✔
240
            break;
1✔
241

242
        default:
243
            throw new ShellException(getString(
×
244
                    "RuntimeError.18", Short.toString(type))); //$NON-NLS-1$
×
245
        }
246
    }
1✔
247

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

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

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

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

298
        if (node.getChildNodes().getLength() == 0) {
1✔
299
            printWriter.print(" />"); //$NON-NLS-1$
1✔
300
            printWriter.flush();
1✔
301
        } else {
302
            printWriter.print('>');
1✔
303
            printWriter.flush();
1✔
304

305
            Node child = node.getFirstChild();
1✔
306
            while (child != null) {
1✔
307
                writeAnyNode(child);
1✔
308
                child = child.getNextSibling();
1✔
309
            }
310

311
            printWriter.print("</"); //$NON-NLS-1$
1✔
312
            printWriter.print(node.getNodeName());
1✔
313
            printWriter.print('>');
1✔
314
            printWriter.flush();
1✔
315
        }
316
    }
1✔
317

318
    protected void write(EntityReference node) {
319
        printWriter.print('&');
×
320
        printWriter.print(node.getNodeName());
×
321
        printWriter.print(';');
×
322
        printWriter.flush();
×
323
    }
×
324

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

344
    protected void write(Text node) {
345
        normalizeAndPrint(node.getNodeValue(), false);
1✔
346
        printWriter.flush();
1✔
347
    }
1✔
348

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

361
    protected void write(Comment node) {
362
        printWriter.print("<!--"); //$NON-NLS-1$
1✔
363
        String comment = node.getNodeValue();
1✔
364
        if (comment != null && !comment.isEmpty()) {
1!
365
            normalizeAndPrint(comment, false);
1✔
366
        }
367
        printWriter.print("-->"); //$NON-NLS-1$
1✔
368
        printWriter.flush();
1✔
369
    }
1✔
370
}
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