author | joehw |
Wed, 18 Oct 2017 13:25:49 -0700 | |
changeset 47359 | e1a6c0168741 |
parent 47216 | 71c04702a3d5 |
child 48409 | 5ab69533994b |
permissions | -rw-r--r-- |
12005 | 1 |
/* |
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
2 |
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
3 |
* @LastModified: Oct 2017 |
12005 | 4 |
*/ |
5 |
/* |
|
44797
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
6 |
* Licensed to the Apache Software Foundation (ASF) under one or more |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
7 |
* contributor license agreements. See the NOTICE file distributed with |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
8 |
* this work for additional information regarding copyright ownership. |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
9 |
* The ASF licenses this file to You under the Apache License, Version 2.0 |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
10 |
* (the "License"); you may not use this file except in compliance with |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
11 |
* the License. You may obtain a copy of the License at |
12005 | 12 |
* |
13 |
* http://www.apache.org/licenses/LICENSE-2.0 |
|
14 |
* |
|
15 |
* Unless required by applicable law or agreed to in writing, software |
|
16 |
* distributed under the License is distributed on an "AS IS" BASIS, |
|
17 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
18 |
* See the License for the specific language governing permissions and |
|
19 |
* limitations under the License. |
|
20 |
*/ |
|
21 |
||
22 |
package com.sun.org.apache.xerces.internal.dom; |
|
23 |
||
24 |
import java.util.ArrayList; |
|
25 |
import java.util.List; |
|
26 |
import org.w3c.dom.DOMException; |
|
27 |
import org.w3c.dom.Node; |
|
28 |
||
29 |
/** |
|
30 |
* AttributeMap inherits from NamedNodeMapImpl and extends it to deal with the |
|
31 |
* specifics of storing attributes. These are: |
|
32 |
* <ul> |
|
33 |
* <li>managing ownership of attribute nodes |
|
34 |
* <li>managing default attributes |
|
35 |
* <li>firing mutation events |
|
36 |
* </ul> |
|
37 |
* <p> |
|
38 |
* This class doesn't directly support mutation events, however, it notifies |
|
39 |
* the document when mutations are performed so that the document class do so. |
|
40 |
* |
|
41 |
* @xerces.internal |
|
42 |
* |
|
43 |
*/ |
|
44 |
public class AttributeMap extends NamedNodeMapImpl { |
|
45 |
||
46 |
/** Serialization version. */ |
|
47 |
static final long serialVersionUID = 8872606282138665383L; |
|
48 |
||
49 |
// |
|
50 |
// Constructors |
|
51 |
// |
|
52 |
||
53 |
/** Constructs a named node map. */ |
|
54 |
protected AttributeMap(ElementImpl ownerNode, NamedNodeMapImpl defaults) { |
|
55 |
super(ownerNode); |
|
56 |
if (defaults != null) { |
|
57 |
// initialize map with the defaults |
|
58 |
cloneContent(defaults); |
|
59 |
if (nodes != null) { |
|
60 |
hasDefaults(true); |
|
61 |
} |
|
62 |
} |
|
63 |
} |
|
64 |
||
65 |
/** |
|
66 |
* Adds an attribute using its nodeName attribute. |
|
67 |
* @see org.w3c.dom.NamedNodeMap#setNamedItem |
|
68 |
* @return If the new Node replaces an existing node the replaced Node is |
|
69 |
* returned, otherwise null is returned. |
|
70 |
* @param arg |
|
71 |
* An Attr node to store in this map. |
|
72 |
* @exception org.w3c.dom.DOMException The exception description. |
|
73 |
*/ |
|
74 |
public Node setNamedItem(Node arg) |
|
75 |
throws DOMException { |
|
76 |
||
77 |
boolean errCheck = ownerNode.ownerDocument().errorChecking; |
|
78 |
if (errCheck) { |
|
79 |
if (isReadOnly()) { |
|
80 |
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null); |
|
81 |
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg); |
|
82 |
} |
|
83 |
if (arg.getOwnerDocument() != ownerNode.ownerDocument()) { |
|
84 |
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null); |
|
85 |
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg); |
|
86 |
} |
|
87 |
if (arg.getNodeType() != Node.ATTRIBUTE_NODE) { |
|
88 |
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null); |
|
89 |
throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, msg); |
|
90 |
} |
|
91 |
} |
|
92 |
AttrImpl argn = (AttrImpl)arg; |
|
93 |
||
94 |
if (argn.isOwned()){ |
|
95 |
if (errCheck && argn.getOwnerElement() != ownerNode) { |
|
96 |
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INUSE_ATTRIBUTE_ERR", null); |
|
97 |
throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, msg); |
|
98 |
} |
|
99 |
// replacing an Attribute with itself does nothing |
|
100 |
return arg; |
|
101 |
} |
|
102 |
||
103 |
||
104 |
// set owner |
|
105 |
argn.ownerNode = ownerNode; |
|
106 |
argn.isOwned(true); |
|
107 |
||
108 |
int i = findNamePoint(argn.getNodeName(),0); |
|
109 |
AttrImpl previous = null; |
|
110 |
if (i >= 0) { |
|
111 |
previous = (AttrImpl) nodes.get(i); |
|
112 |
nodes.set(i, arg); |
|
113 |
previous.ownerNode = ownerNode.ownerDocument(); |
|
114 |
previous.isOwned(false); |
|
115 |
// make sure it won't be mistaken with defaults in case it's reused |
|
116 |
previous.isSpecified(true); |
|
117 |
} else { |
|
118 |
i = -1 - i; // Insert point (may be end of list) |
|
119 |
if (null == nodes) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
120 |
nodes = new ArrayList<>(5); |
12005 | 121 |
} |
122 |
nodes.add(i, arg); |
|
123 |
} |
|
124 |
||
125 |
// notify document |
|
126 |
ownerNode.ownerDocument().setAttrNode(argn, previous); |
|
127 |
||
128 |
// If the new attribute is not normalized, |
|
129 |
// the owning element is inherently not normalized. |
|
130 |
if (!argn.isNormalized()) { |
|
131 |
ownerNode.isNormalized(false); |
|
132 |
} |
|
133 |
return previous; |
|
134 |
||
135 |
} // setNamedItem(Node):Node |
|
136 |
||
137 |
/** |
|
138 |
* Adds an attribute using its namespaceURI and localName. |
|
139 |
* @see org.w3c.dom.NamedNodeMap#setNamedItem |
|
140 |
* @return If the new Node replaces an existing node the replaced Node is |
|
141 |
* returned, otherwise null is returned. |
|
142 |
* @param arg A node to store in a named node map. |
|
143 |
*/ |
|
144 |
public Node setNamedItemNS(Node arg) |
|
145 |
throws DOMException { |
|
146 |
||
147 |
boolean errCheck = ownerNode.ownerDocument().errorChecking; |
|
148 |
if (errCheck) { |
|
149 |
if (isReadOnly()) { |
|
150 |
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null); |
|
151 |
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg); |
|
152 |
} |
|
153 |
if(arg.getOwnerDocument() != ownerNode.ownerDocument()) { |
|
154 |
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null); |
|
155 |
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg); |
|
156 |
} |
|
157 |
if (arg.getNodeType() != Node.ATTRIBUTE_NODE) { |
|
158 |
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null); |
|
159 |
throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, msg); |
|
160 |
} |
|
161 |
} |
|
162 |
AttrImpl argn = (AttrImpl)arg; |
|
163 |
||
164 |
if (argn.isOwned()){ |
|
165 |
if (errCheck && argn.getOwnerElement() != ownerNode) { |
|
166 |
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INUSE_ATTRIBUTE_ERR", null); |
|
167 |
throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, msg); |
|
168 |
} |
|
169 |
// replacing an Attribute with itself does nothing |
|
170 |
return arg; |
|
171 |
} |
|
172 |
||
173 |
// set owner |
|
174 |
argn.ownerNode = ownerNode; |
|
175 |
argn.isOwned(true); |
|
176 |
||
177 |
int i = findNamePoint(argn.getNamespaceURI(), argn.getLocalName()); |
|
178 |
AttrImpl previous = null; |
|
179 |
if (i >= 0) { |
|
180 |
previous = (AttrImpl) nodes.get(i); |
|
181 |
nodes.set(i, arg); |
|
182 |
previous.ownerNode = ownerNode.ownerDocument(); |
|
183 |
previous.isOwned(false); |
|
184 |
// make sure it won't be mistaken with defaults in case it's reused |
|
185 |
previous.isSpecified(true); |
|
186 |
} else { |
|
187 |
// If we can't find by namespaceURI, localName, then we find by |
|
188 |
// nodeName so we know where to insert. |
|
189 |
i = findNamePoint(arg.getNodeName(),0); |
|
190 |
if (i >=0) { |
|
191 |
previous = (AttrImpl) nodes.get(i); |
|
192 |
nodes.add(i, arg); |
|
193 |
} else { |
|
194 |
i = -1 - i; // Insert point (may be end of list) |
|
195 |
if (null == nodes) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
196 |
nodes = new ArrayList<>(5); |
12005 | 197 |
} |
198 |
nodes.add(i, arg); |
|
199 |
} |
|
200 |
} |
|
201 |
// changed(true); |
|
202 |
||
203 |
// notify document |
|
204 |
ownerNode.ownerDocument().setAttrNode(argn, previous); |
|
205 |
||
206 |
// If the new attribute is not normalized, |
|
207 |
// the owning element is inherently not normalized. |
|
208 |
if (!argn.isNormalized()) { |
|
209 |
ownerNode.isNormalized(false); |
|
210 |
} |
|
211 |
return previous; |
|
212 |
||
213 |
} // setNamedItemNS(Node):Node |
|
214 |
||
215 |
/** |
|
216 |
* Removes an attribute specified by name. |
|
217 |
* @param name |
|
218 |
* The name of a node to remove. If the |
|
219 |
* removed attribute is known to have a default value, an |
|
220 |
* attribute immediately appears containing the default value |
|
221 |
* as well as the corresponding namespace URI, local name, |
|
222 |
* and prefix when applicable. |
|
223 |
* @return The node removed from the map if a node with such a name exists. |
|
224 |
* @throws NOT_FOUND_ERR: Raised if there is no node named |
|
225 |
* name in the map. |
|
226 |
*/ |
|
227 |
/***/ |
|
228 |
public Node removeNamedItem(String name) |
|
229 |
throws DOMException { |
|
230 |
return internalRemoveNamedItem(name, true); |
|
231 |
} |
|
232 |
||
233 |
/** |
|
234 |
* Same as removeNamedItem except that it simply returns null if the |
|
235 |
* specified name is not found. |
|
236 |
*/ |
|
237 |
Node safeRemoveNamedItem(String name) { |
|
238 |
return internalRemoveNamedItem(name, false); |
|
239 |
} |
|
240 |
||
241 |
||
242 |
/** |
|
243 |
* NON-DOM: Remove the node object |
|
244 |
* |
|
245 |
* NOTE: Specifically removes THIS NODE -- not the node with this |
|
246 |
* name, nor the node with these contents. If node does not belong to |
|
247 |
* this named node map, we throw a DOMException. |
|
248 |
* |
|
249 |
* @param item The node to remove |
|
250 |
* @param addDefault true -- magically add default attribute |
|
251 |
* @return Removed node |
|
252 |
* @exception DOMException |
|
253 |
*/ |
|
254 |
protected Node removeItem(Node item, boolean addDefault) |
|
255 |
throws DOMException { |
|
256 |
||
257 |
int index = -1; |
|
258 |
if (nodes != null) { |
|
259 |
final int size = nodes.size(); |
|
260 |
for (int i = 0; i < size; ++i) { |
|
261 |
if (nodes.get(i) == item) { |
|
262 |
index = i; |
|
263 |
break; |
|
264 |
} |
|
265 |
} |
|
266 |
} |
|
267 |
if (index < 0) { |
|
268 |
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null); |
|
269 |
throw new DOMException(DOMException.NOT_FOUND_ERR, msg); |
|
270 |
} |
|
271 |
||
272 |
return remove((AttrImpl)item, index, addDefault); |
|
273 |
} |
|
274 |
||
275 |
/** |
|
276 |
* Internal removeNamedItem method allowing to specify whether an exception |
|
277 |
* must be thrown if the specified name is not found. |
|
278 |
*/ |
|
279 |
final protected Node internalRemoveNamedItem(String name, boolean raiseEx){ |
|
280 |
if (isReadOnly()) { |
|
281 |
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null); |
|
282 |
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg); |
|
283 |
} |
|
284 |
int i = findNamePoint(name,0); |
|
285 |
if (i < 0) { |
|
286 |
if (raiseEx) { |
|
287 |
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null); |
|
288 |
throw new DOMException(DOMException.NOT_FOUND_ERR, msg); |
|
289 |
} else { |
|
290 |
return null; |
|
291 |
} |
|
292 |
} |
|
293 |
||
294 |
return remove((AttrImpl)nodes.get(i), i, true); |
|
295 |
||
296 |
} // internalRemoveNamedItem(String,boolean):Node |
|
297 |
||
298 |
private final Node remove(AttrImpl attr, int index, |
|
299 |
boolean addDefault) { |
|
300 |
||
301 |
CoreDocumentImpl ownerDocument = ownerNode.ownerDocument(); |
|
302 |
String name = attr.getNodeName(); |
|
303 |
if (attr.isIdAttribute()) { |
|
304 |
ownerDocument.removeIdentifier(attr.getValue()); |
|
305 |
} |
|
306 |
||
307 |
if (hasDefaults() && addDefault) { |
|
308 |
// If there's a default, add it instead |
|
309 |
NamedNodeMapImpl defaults = |
|
310 |
((ElementImpl) ownerNode).getDefaultAttributes(); |
|
311 |
||
312 |
Node d; |
|
313 |
if (defaults != null && |
|
314 |
(d = defaults.getNamedItem(name)) != null && |
|
315 |
findNamePoint(name, index+1) < 0) { |
|
316 |
NodeImpl clone = (NodeImpl)d.cloneNode(true); |
|
317 |
if (d.getLocalName() !=null){ |
|
318 |
// we must rely on the name to find a default attribute |
|
319 |
// ("test:attr"), but while copying it from the DOCTYPE |
|
320 |
// we should not loose namespace URI that was assigned |
|
321 |
// to the attribute in the instance document. |
|
322 |
((AttrNSImpl)clone).namespaceURI = attr.getNamespaceURI(); |
|
323 |
} |
|
324 |
clone.ownerNode = ownerNode; |
|
325 |
clone.isOwned(true); |
|
326 |
clone.isSpecified(false); |
|
327 |
||
328 |
nodes.set(index, clone); |
|
329 |
if (attr.isIdAttribute()) { |
|
330 |
ownerDocument.putIdentifier(clone.getNodeValue(), |
|
331 |
(ElementImpl)ownerNode); |
|
332 |
} |
|
333 |
} else { |
|
334 |
nodes.remove(index); |
|
335 |
} |
|
336 |
} else { |
|
337 |
nodes.remove(index); |
|
338 |
} |
|
339 |
||
340 |
// changed(true); |
|
341 |
||
342 |
// remove reference to owner |
|
343 |
attr.ownerNode = ownerDocument; |
|
344 |
attr.isOwned(false); |
|
345 |
||
346 |
// make sure it won't be mistaken with defaults in case it's |
|
347 |
// reused |
|
348 |
attr.isSpecified(true); |
|
349 |
attr.isIdAttribute(false); |
|
350 |
||
351 |
// notify document |
|
352 |
ownerDocument.removedAttrNode(attr, ownerNode, name); |
|
353 |
||
354 |
return attr; |
|
355 |
} |
|
356 |
||
357 |
/** |
|
358 |
* Introduced in DOM Level 2. <p> |
|
359 |
* Removes an attribute specified by local name and namespace URI. |
|
360 |
* @param namespaceURI |
|
361 |
* The namespace URI of the node to remove. |
|
362 |
* When it is null or an empty string, this |
|
363 |
* method behaves like removeNamedItem. |
|
364 |
* @param name The local name of the node to remove. If the |
|
365 |
* removed attribute is known to have a default |
|
366 |
* value, an attribute immediately appears |
|
367 |
* containing the default value. |
|
368 |
* @return Node The node removed from the map if a node with such |
|
369 |
* a local name and namespace URI exists. |
|
370 |
* @throws NOT_FOUND_ERR: Raised if there is no node named |
|
371 |
* name in the map. |
|
372 |
*/ |
|
373 |
public Node removeNamedItemNS(String namespaceURI, String name) |
|
374 |
throws DOMException { |
|
375 |
return internalRemoveNamedItemNS(namespaceURI, name, true); |
|
376 |
} |
|
377 |
||
378 |
/** |
|
379 |
* Same as removeNamedItem except that it simply returns null if the |
|
380 |
* specified local name and namespace URI is not found. |
|
381 |
*/ |
|
382 |
Node safeRemoveNamedItemNS(String namespaceURI, String name) { |
|
383 |
return internalRemoveNamedItemNS(namespaceURI, name, false); |
|
384 |
} |
|
385 |
||
386 |
/** |
|
387 |
* Internal removeNamedItemNS method allowing to specify whether an |
|
388 |
* exception must be thrown if the specified local name and namespace URI |
|
389 |
* is not found. |
|
390 |
*/ |
|
391 |
final protected Node internalRemoveNamedItemNS(String namespaceURI, |
|
392 |
String name, |
|
393 |
boolean raiseEx) { |
|
394 |
||
395 |
CoreDocumentImpl ownerDocument = ownerNode.ownerDocument(); |
|
396 |
if (ownerDocument.errorChecking && isReadOnly()) { |
|
397 |
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null); |
|
398 |
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg); |
|
399 |
} |
|
400 |
int i = findNamePoint(namespaceURI, name); |
|
401 |
if (i < 0) { |
|
402 |
if (raiseEx) { |
|
403 |
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null); |
|
404 |
throw new DOMException(DOMException.NOT_FOUND_ERR, msg); |
|
405 |
} else { |
|
406 |
return null; |
|
407 |
} |
|
408 |
} |
|
409 |
||
410 |
AttrImpl n = (AttrImpl)nodes.get(i); |
|
411 |
||
412 |
if (n.isIdAttribute()) { |
|
413 |
ownerDocument.removeIdentifier(n.getValue()); |
|
414 |
} |
|
415 |
// If there's a default, add it instead |
|
416 |
String nodeName = n.getNodeName(); |
|
417 |
if (hasDefaults()) { |
|
418 |
NamedNodeMapImpl defaults = ((ElementImpl) ownerNode).getDefaultAttributes(); |
|
419 |
Node d; |
|
420 |
if (defaults != null |
|
421 |
&& (d = defaults.getNamedItem(nodeName)) != null) |
|
422 |
{ |
|
423 |
int j = findNamePoint(nodeName,0); |
|
424 |
if (j>=0 && findNamePoint(nodeName, j+1) < 0) { |
|
425 |
NodeImpl clone = (NodeImpl)d.cloneNode(true); |
|
426 |
clone.ownerNode = ownerNode; |
|
427 |
if (d.getLocalName() != null) { |
|
428 |
// we must rely on the name to find a default attribute |
|
429 |
// ("test:attr"), but while copying it from the DOCTYPE |
|
430 |
// we should not loose namespace URI that was assigned |
|
431 |
// to the attribute in the instance document. |
|
432 |
((AttrNSImpl)clone).namespaceURI = namespaceURI; |
|
433 |
} |
|
434 |
clone.isOwned(true); |
|
435 |
clone.isSpecified(false); |
|
436 |
nodes.set(i, clone); |
|
437 |
if (clone.isIdAttribute()) { |
|
438 |
ownerDocument.putIdentifier(clone.getNodeValue(), |
|
439 |
(ElementImpl)ownerNode); |
|
440 |
} |
|
441 |
} else { |
|
442 |
nodes.remove(i); |
|
443 |
} |
|
444 |
} else { |
|
445 |
nodes.remove(i); |
|
446 |
} |
|
447 |
} else { |
|
448 |
nodes.remove(i); |
|
449 |
} |
|
450 |
||
451 |
// changed(true); |
|
452 |
||
453 |
// remove reference to owner |
|
454 |
n.ownerNode = ownerDocument; |
|
455 |
n.isOwned(false); |
|
456 |
// make sure it won't be mistaken with defaults in case it's |
|
457 |
// reused |
|
458 |
n.isSpecified(true); |
|
459 |
// update id table if needed |
|
460 |
n.isIdAttribute(false); |
|
461 |
||
462 |
// notify document |
|
463 |
ownerDocument.removedAttrNode(n, ownerNode, name); |
|
464 |
||
465 |
return n; |
|
466 |
||
467 |
} // internalRemoveNamedItemNS(String,String,boolean):Node |
|
468 |
||
469 |
// |
|
470 |
// Public methods |
|
471 |
// |
|
472 |
||
473 |
/** |
|
474 |
* Cloning a NamedNodeMap is a DEEP OPERATION; it always clones |
|
475 |
* all the nodes contained in the map. |
|
476 |
*/ |
|
477 |
||
478 |
public NamedNodeMapImpl cloneMap(NodeImpl ownerNode) { |
|
479 |
AttributeMap newmap = |
|
480 |
new AttributeMap((ElementImpl) ownerNode, null); |
|
481 |
newmap.hasDefaults(hasDefaults()); |
|
482 |
newmap.cloneContent(this); |
|
483 |
return newmap; |
|
484 |
} // cloneMap():AttributeMap |
|
485 |
||
486 |
/** |
|
487 |
* Override parent's method to set the ownerNode correctly |
|
488 |
*/ |
|
489 |
protected void cloneContent(NamedNodeMapImpl srcmap) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
490 |
List<Node> srcnodes = srcmap.nodes; |
12005 | 491 |
if (srcnodes != null) { |
492 |
int size = srcnodes.size(); |
|
493 |
if (size != 0) { |
|
494 |
if (nodes == null) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
495 |
nodes = new ArrayList<>(size); |
12005 | 496 |
} |
497 |
else { |
|
498 |
nodes.clear(); |
|
499 |
} |
|
500 |
for (int i = 0; i < size; ++i) { |
|
501 |
NodeImpl n = (NodeImpl) srcnodes.get(i); |
|
502 |
NodeImpl clone = (NodeImpl) n.cloneNode(true); |
|
503 |
clone.isSpecified(n.isSpecified()); |
|
504 |
nodes.add(clone); |
|
505 |
clone.ownerNode = ownerNode; |
|
506 |
clone.isOwned(true); |
|
507 |
} |
|
508 |
} |
|
509 |
} |
|
510 |
} // cloneContent():AttributeMap |
|
511 |
||
512 |
||
513 |
/** |
|
514 |
* Move specified attributes from the given map to this one |
|
515 |
*/ |
|
516 |
void moveSpecifiedAttributes(AttributeMap srcmap) { |
|
517 |
int nsize = (srcmap.nodes != null) ? srcmap.nodes.size() : 0; |
|
518 |
for (int i = nsize - 1; i >= 0; i--) { |
|
519 |
AttrImpl attr = (AttrImpl) srcmap.nodes.get(i); |
|
520 |
if (attr.isSpecified()) { |
|
521 |
srcmap.remove(attr, i, false); |
|
522 |
if (attr.getLocalName() != null) { |
|
523 |
setNamedItem(attr); |
|
524 |
} |
|
525 |
else { |
|
526 |
setNamedItemNS(attr); |
|
527 |
} |
|
528 |
} |
|
529 |
} |
|
530 |
} // moveSpecifiedAttributes(AttributeMap):void |
|
531 |
||
532 |
||
533 |
/** |
|
534 |
* Get this AttributeMap in sync with the given "defaults" map. |
|
535 |
* @param defaults The default attributes map to sync with. |
|
536 |
*/ |
|
537 |
protected void reconcileDefaults(NamedNodeMapImpl defaults) { |
|
538 |
||
539 |
// remove any existing default |
|
540 |
int nsize = (nodes != null) ? nodes.size() : 0; |
|
541 |
for (int i = nsize - 1; i >= 0; --i) { |
|
542 |
AttrImpl attr = (AttrImpl) nodes.get(i); |
|
543 |
if (!attr.isSpecified()) { |
|
544 |
remove(attr, i, false); |
|
545 |
} |
|
546 |
} |
|
547 |
// add the new defaults |
|
548 |
if (defaults == null) { |
|
549 |
return; |
|
550 |
} |
|
551 |
if (nodes == null || nodes.size() == 0) { |
|
552 |
cloneContent(defaults); |
|
553 |
} |
|
554 |
else { |
|
555 |
int dsize = defaults.nodes.size(); |
|
556 |
for (int n = 0; n < dsize; ++n) { |
|
557 |
AttrImpl d = (AttrImpl) defaults.nodes.get(n); |
|
558 |
int i = findNamePoint(d.getNodeName(), 0); |
|
559 |
if (i < 0) { |
|
560 |
i = -1 - i; |
|
561 |
NodeImpl clone = (NodeImpl) d.cloneNode(true); |
|
562 |
clone.ownerNode = ownerNode; |
|
563 |
clone.isOwned(true); |
|
564 |
clone.isSpecified(false); |
|
565 |
nodes.add(i, clone); |
|
566 |
} |
|
567 |
} |
|
568 |
} |
|
569 |
||
570 |
} // reconcileDefaults() |
|
571 |
||
572 |
protected final int addItem (Node arg) { |
|
573 |
||
574 |
final AttrImpl argn = (AttrImpl) arg; |
|
575 |
||
576 |
// set owner |
|
577 |
argn.ownerNode = ownerNode; |
|
578 |
argn.isOwned(true); |
|
579 |
||
580 |
int i = findNamePoint(argn.getNamespaceURI(), argn.getLocalName()); |
|
581 |
if (i >= 0) { |
|
582 |
nodes.set(i, arg); |
|
583 |
} |
|
584 |
else { |
|
585 |
// If we can't find by namespaceURI, localName, then we find by |
|
586 |
// nodeName so we know where to insert. |
|
587 |
i = findNamePoint(argn.getNodeName(),0); |
|
588 |
if (i >= 0) { |
|
589 |
nodes.add(i, arg); |
|
590 |
} |
|
591 |
else { |
|
592 |
i = -1 - i; // Insert point (may be end of list) |
|
593 |
if (null == nodes) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
594 |
nodes = new ArrayList<>(5); |
12005 | 595 |
} |
596 |
nodes.add(i, arg); |
|
597 |
} |
|
598 |
} |
|
599 |
||
600 |
// notify document |
|
601 |
ownerNode.ownerDocument().setAttrNode(argn, null); |
|
602 |
return i; |
|
603 |
} |
|
604 |
||
605 |
} // class AttributeMap |