OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 174 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
174 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.xml;
15
 
180 ilm 16
import org.openconcerto.utils.Tuple2.List2;
17
 
174 ilm 18
import javax.xml.stream.XMLStreamConstants;
19
import javax.xml.stream.XMLStreamException;
20
import javax.xml.stream.XMLStreamReader;
21
 
22
public class XMLUtils {
23
 
24
    public static final String escapeAttribute(final String value) {
25
        final int len = value.length();
26
        int idx = 0;
27
 
28
        checkloop: while (idx < len) {
29
            final char ch = value.charAt(idx);
30
            if (ch == '<' || ch == '>' || ch == '&' || ch == '\r' || ch == '\n' || ch == '"' || ch == '\t') {
31
                break checkloop;
32
            }
33
            idx++;
34
        }
35
 
36
        if (idx == len) {
37
            return value;
38
        }
39
 
40
        final StringBuilder sb = new StringBuilder(len + 5);
41
        sb.append(value, 0, idx);
42
        while (idx < len) {
43
            final char ch = value.charAt(idx++);
44
            switch (ch) {
45
            case '<':
46
                sb.append("&lt;");
47
                break;
48
            case '>':
49
                sb.append("&gt;");
50
                break;
51
            case '&':
52
                sb.append("&amp;");
53
                break;
54
            case '\r':
55
                sb.append("&#xD;");
56
                break;
57
            case '"':
58
                sb.append("&quot;");
59
                break;
60
            case '\t':
61
                sb.append("&#x9;");
62
                break;
63
            case '\n':
64
                sb.append("&#xA;");
65
                break;
66
            default:
67
                sb.append(ch);
68
                break;
69
            }
70
        }
71
 
72
        return sb.toString();
73
    }
74
 
75
    public static final String escapeText(final String value) {
76
        final int right = value.length();
77
        int idx = 0;
78
        checkloop: while (idx < right) {
79
            final char ch = value.charAt(idx);
80
            if (ch == '<' || ch == '>' || ch == '&' || ch == '\r' || ch == '\n') {
81
                break checkloop;
82
            }
83
            idx++;
84
        }
85
 
86
        if (idx == right) {
87
            // no escape needed.
88
            return value;
89
        }
90
 
91
        final StringBuilder sb = new StringBuilder();
92
        if (idx > 0) {
93
            sb.append(value, 0, idx);
94
        }
95
 
96
        while (idx < right) {
97
            final char ch = value.charAt(idx++);
98
            switch (ch) {
99
            case '<':
100
                sb.append("&lt;");
101
                break;
102
            case '>':
103
                sb.append("&gt;");
104
                break;
105
            case '&':
106
                sb.append("&amp;");
107
                break;
108
            case '\r':
109
                sb.append("&#xD;");
110
                break;
111
            case '\n':
112
                sb.append('\n');
113
                break;
114
            default:
115
                sb.append(ch);
116
                break;
117
            }
118
        }
119
        return sb.toString();
120
    }
121
 
180 ilm 122
    /**
123
     * Split prefix and local name.
124
     *
125
     * @param qName a qualified name, e.g. "ns:foo" or "foo".
126
     * @return first the prefix (<code>null</code> if none), then the local name
127
     * @throws IllegalArgumentException if invalid syntax.
128
     * @see <a href="https://www.w3.org/TR/xml-names/#ns-qualnames">Qualified Names</a>
129
     */
130
    public static List2<String> splitQualifiedName(final String qName) throws IllegalArgumentException {
131
        final int indexOfColon = qName.indexOf(':');
132
        if (indexOfColon < 0)
133
            return new List2<>(null, qName);
134
 
135
        if (indexOfColon == 0)
136
            throw new IllegalArgumentException("Starts with colon : '" + qName + "'");
137
        final int l = qName.length();
138
        assert indexOfColon < l;
139
        if (indexOfColon == l - 1)
140
            throw new IllegalArgumentException("Ends with colon : '" + qName + "'");
141
        final int secondColon = qName.indexOf(':', indexOfColon + 1);
142
        if (secondColon >= 0)
143
            throw new IllegalArgumentException("Two colons : '" + qName + "'");
144
        return new List2<>(qName.substring(0, indexOfColon), qName.substring(indexOfColon + 1));
145
    }
146
 
174 ilm 147
    public static final void skipToEndElement(final XMLStreamReader reader) throws XMLStreamException {
148
        if (!reader.isStartElement())
149
            throw new IllegalStateException("Not at a start of an element : " + reader.getEventType() + ", " + reader.getLocation());
150
        final String name = reader.getLocalName();
151
        int depth = 1;
152
        while (!(depth == 0 && reader.isEndElement() && reader.getLocalName().equals(name))) {
153
            final int eventType = reader.next();
154
            if (eventType == XMLStreamConstants.START_ELEMENT)
155
                depth++;
156
            else if (eventType == XMLStreamConstants.END_ELEMENT)
157
                depth--;
158
        }
159
    }
160
}