| /* |
| * Copyright (C) 2007 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.harmony.xml.dom; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import org.w3c.dom.DOMException; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.NamedNodeMap; |
| import org.w3c.dom.Node; |
| |
| /** |
| * Provides a straightforward implementation of the corresponding W3C DOM |
| * interface. The class is used internally only, thus only notable members that |
| * are not in the original interface are documented (the W3C docs are quite |
| * extensive). Hope that's ok. |
| * <p> |
| * Some of the fields may have package visibility, so other classes belonging to |
| * the DOM implementation can easily access them while maintaining the DOM tree |
| * structure. |
| */ |
| public class NamedNodeMapImpl implements NamedNodeMap { |
| |
| private Class<?> type; |
| |
| private List<NodeImpl> list; |
| |
| NamedNodeMapImpl(Class<?> type) { |
| list = new ArrayList<NodeImpl>(); |
| this.type = type; |
| } |
| |
| NamedNodeMapImpl(List<NodeImpl> list, Class<?> type) { |
| this.list = list; |
| this.type = type; |
| } |
| |
| public int getLength() { |
| return list.size(); |
| } |
| |
| private int indexOfItem(String name) { |
| for (int i = 0; i < list.size(); i++) { |
| NodeImpl node = list.get(i); |
| if (node.matchesName(name, false)) { |
| return i; |
| } |
| } |
| |
| return -1; |
| } |
| |
| private int indexOfItemNS(String namespaceURI, String localName) { |
| for (int i = 0; i < list.size(); i++) { |
| NodeImpl node = list.get(i); |
| if (node.matchesNameNS(namespaceURI, localName, false)) { |
| return i; |
| } |
| } |
| |
| return -1; |
| } |
| |
| public Node getNamedItem(String name) { |
| int i = indexOfItem(name); |
| |
| return (i == -1 ? null : item(i)); |
| } |
| |
| public Node getNamedItemNS(String namespaceURI, String localName) { |
| int i = indexOfItemNS(namespaceURI, localName); |
| |
| return (i == -1 ? null : item(i)); |
| } |
| |
| public Node item(int index) { |
| return list.get(index); |
| } |
| |
| public Node removeNamedItem(String name) throws DOMException { |
| int i = indexOfItem(name); |
| |
| if (i == -1) { |
| throw new DOMException(DOMException.NOT_FOUND_ERR, null); |
| } |
| |
| return list.remove(i); |
| } |
| |
| public Node removeNamedItemNS(String namespaceURI, String localName) |
| throws DOMException { |
| int i = indexOfItemNS(namespaceURI, localName); |
| |
| if (i == -1) { |
| throw new DOMException(DOMException.NOT_FOUND_ERR, null); |
| } |
| |
| return list.remove(i); |
| } |
| |
| public Node setNamedItem(Node arg) throws DOMException { |
| // Ensure we only accept nodes of the correct type. |
| if (!type.isAssignableFrom(arg.getClass())) { |
| throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null); |
| } |
| |
| // All nodes in the map must belong to the same document. |
| if (list.size() != 0) { |
| Document document = list.get(0).document; |
| |
| if (document != null && arg.getOwnerDocument() != document) { |
| throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null); |
| } |
| } |
| |
| // TODO Theoretically we should ensure that the nodes don't have a parent. |
| // if (newAttrImpl.getOwnerElement() != null) { |
| // throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, null); |
| // } |
| |
| int i = indexOfItem(arg.getNodeName()); |
| |
| if (i != -1) { |
| list.remove(i); |
| } |
| |
| list.add((NodeImpl)arg); |
| return arg; |
| } |
| |
| public Node setNamedItemNS(Node arg) throws DOMException { |
| // Ensure we only accept nodes of the correct type. |
| if (!type.isAssignableFrom(arg.getClass())) { |
| throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null); |
| } |
| |
| // All nodes in the map must belong to the same document. |
| if (list.size() != 0) { |
| Document document = list.get(0).document; |
| |
| if (document != null && arg.getOwnerDocument() != document) { |
| throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null); |
| } |
| } |
| |
| // TODO Theoretically we should ensure that the nodes don't have a parent. |
| // if (newAttrImpl.getOwnerElement() != null) { |
| // throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, null); |
| // } |
| |
| int i = indexOfItemNS(arg.getNamespaceURI(), arg.getLocalName()); |
| |
| if (i != -1) { |
| list.remove(i); |
| } |
| |
| list.add((NodeImpl)arg); |
| return arg; |
| } |
| |
| } |