1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.exolab.castor.xml.parsing;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.exolab.castor.xml.AttributeSet;
20 import org.exolab.castor.xml.util.AttributeSetImpl;
21 import org.xml.sax.AttributeList;
22 import org.xml.sax.Attributes;
23 import org.xml.sax.SAXException;
24
25
26
27
28
29
30
31
32
33
34 public class AttributeSetBuilder {
35
36
37
38
39
40
41 private static final String XML_PREFIX = "xml";
42
43
44
45
46 private static final String XMLNS = "xmlns";
47
48
49
50
51 private final static String XMLNS_PREFIX = "xmlns:";
52
53
54
55
56 private final static int XMLNS_PREFIX_LENGTH = XMLNS_PREFIX.length();
57
58
59
60
61 private NamespaceHandling _namespaceHandling = null;
62
63
64
65
66
67
68
69 public AttributeSetBuilder(NamespaceHandling namespaceHandling) {
70 super();
71 _namespaceHandling = namespaceHandling;
72 }
73
74
75
76
77
78
79
80
81 private AttributeSetImpl prepareAttributeSetImpl(Attributes atts) {
82 if (atts != null) {
83 return new AttributeSetImpl(atts.getLength());
84 }
85 return new AttributeSetImpl();
86 }
87
88
89
90
91
92
93
94
95
96
97
98 public AttributeSet getAttributeSet(Attributes atts) throws SAXException {
99 AttributeSetImpl attributeSet = prepareAttributeSetImpl(atts);
100 return processAttributes(atts, attributeSet);
101 }
102
103
104
105
106
107
108
109
110
111
112 private AttributeSet processAttributes(Attributes atts, AttributeSetImpl attributeSet) {
113
114
115 if (atts == null || atts.getLength() == 0) {
116 return attributeSet;
117 }
118
119 boolean hasQNameAtts = false;
120
121
122
123 for (int i = 0; i < atts.getLength(); i++) {
124 String attName = atts.getQName(i);
125 if (StringUtils.isNotEmpty(attName)) {
126 if (!attName.equals(XMLNS) && !attName.startsWith(XMLNS_PREFIX)) {
127
128 if (attName.indexOf(':') < 0) {
129 attributeSet.setAttribute(attName, atts.getValue(i), atts
130 .getURI(i));
131 } else
132 hasQNameAtts = true;
133 }
134 } else {
135
136
137 attName = atts.getLocalName(i);
138 if (!XMLNS.equals(attName)) {
139 attributeSet.setAttribute(attName, atts.getValue(i), atts
140 .getURI(i));
141 }
142 }
143 }
144
145
146 if (!hasQNameAtts) {
147 return attributeSet;
148 }
149
150 for (int i = 0; i < atts.getLength(); i++) {
151 String attName = atts.getQName(i);
152 if (StringUtils.isNotEmpty(attName)) {
153
154 if ((!attName.equals(XMLNS))
155 && (!attName.startsWith(XMLNS_PREFIX))) {
156 int idx = attName.indexOf(':');
157 if (idx >= 0) {
158 String prefix = attName.substring(0, idx);
159 attName = attName.substring(idx + 1);
160 String nsURI = atts.getURI(i);
161 if (StringUtils.isEmpty(nsURI)) {
162 nsURI = _namespaceHandling.getNamespaceURI(prefix);
163 }
164 attributeSet.setAttribute(attName, atts.getValue(i), nsURI);
165 }
166 }
167 }
168
169 }
170 return attributeSet;
171 }
172
173
174
175
176
177
178
179
180
181
182
183
184 public AttributeSet getAttributeSet(AttributeList atts) throws SAXException {
185 AttributeSetImpl attributeSet = prepareAttributeSetImpl(atts);
186 return processAttributeList(atts, attributeSet);
187 }
188
189
190
191
192
193
194
195
196
197
198
199 private AttributeSet processAttributeList(AttributeList atts, AttributeSetImpl attributeSet) throws SAXException {
200 if (atts == null || atts.getLength() == 0)
201 return attributeSet;
202
203
204 int attCount = 0;
205 boolean[] validAtts = new boolean[atts.getLength()];
206 for (int i = 0; i < validAtts.length; i++) {
207 String attName = atts.getName(i);
208 if (attName.equals(XMLNS)) {
209 _namespaceHandling.addDefaultNamespace(atts.getValue(i));
210 } else if (attName.startsWith(XMLNS_PREFIX)) {
211 String prefix = attName.substring(XMLNS_PREFIX_LENGTH);
212 _namespaceHandling.addNamespace(prefix, atts.getValue(i));
213 } else {
214 validAtts[i] = true;
215 ++attCount;
216 }
217 }
218
219 for (int i = 0; i < validAtts.length; i++) {
220 if (!validAtts[i])
221 continue;
222 String namespace = null;
223 String attName = atts.getName(i);
224 int idx = attName.indexOf(':');
225 if (idx > 0) {
226 String prefix = attName.substring(0, idx);
227 if (!prefix.equals(XML_PREFIX)) {
228 attName = attName.substring(idx + 1);
229 namespace = _namespaceHandling.getNamespaceURI(prefix);
230 if (namespace == null) {
231 String error = "The namespace associated with "
232 + "the prefix '" + prefix
233 + "' could not be resolved.";
234 throw new SAXException(error);
235
236 }
237 }
238 }
239 attributeSet.setAttribute(attName, atts.getValue(i), namespace);
240 }
241 return attributeSet;
242 }
243
244
245
246
247
248
249
250
251
252 private AttributeSetImpl prepareAttributeSetImpl(AttributeList atts) {
253 if (atts == null) {
254 return new AttributeSetImpl();
255 }
256 return new AttributeSetImpl(atts.getLength());
257 }
258 }