1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.apache.harmony.xml.dom;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.w3c.dom.DOMException;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.w3c.dom.Document;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.w3c.dom.NamedNodeMap;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.w3c.dom.Node;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.List;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Provides a straightforward implementation of the corresponding W3C DOM
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * interface. The class is used internally only, thus only notable members that
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are not in the original interface are documented (the W3C docs are quite
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * extensive). Hope that's ok.
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p>
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Some of the fields may have package visibility, so other classes belonging to
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the DOM implementation can easily access them while maintaining the DOM tree
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * structure.
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class NamedNodeMapImpl implements NamedNodeMap {
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private Class<?> type;
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private List<NodeImpl> list;
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NamedNodeMapImpl(Class<?> type) {
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        list = new ArrayList<NodeImpl>();
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.type = type;
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NamedNodeMapImpl(List<NodeImpl> list, Class<?> type) {
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.list = list;
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.type = type;
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getLength() {
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return list.size();
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int indexOfItem(String name) {
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < list.size(); i++) {
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            NodeImpl node = list.get(i);
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (node.matchesName(name, false)) {
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return i;
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int indexOfItemNS(String namespaceURI, String localName) {
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < list.size(); i++) {
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            NodeImpl node = list.get(i);
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (node.matchesNameNS(namespaceURI, localName, false)) {
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return i;
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Node getNamedItem(String name) {
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i = indexOfItem(name);
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (i == -1 ? null : item(i));
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Node getNamedItemNS(String namespaceURI, String localName) {
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i = indexOfItemNS(namespaceURI, localName);
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (i == -1 ? null : item(i));
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Node item(int index) {
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return list.get(index);
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Node removeNamedItem(String name) throws DOMException {
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i = indexOfItem(name);
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (i == -1) {
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new DOMException(DOMException.NOT_FOUND_ERR, null);
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return list.remove(i);
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Node removeNamedItemNS(String namespaceURI, String localName)
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws DOMException {
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i = indexOfItemNS(namespaceURI, localName);
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (i == -1) {
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new DOMException(DOMException.NOT_FOUND_ERR, null);
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return list.remove(i);
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Node setNamedItem(Node arg) throws DOMException {
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Ensure we only accept nodes of the correct type.
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!type.isAssignableFrom(arg.getClass())) {
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // All nodes in the map must belong to the same document.
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (list.size() != 0) {
124e14d736a739d6523fd13d98f13e9d51167197a34Jesse Wilson            Document document = list.get(0).document;
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (document != null && arg.getOwnerDocument() != document) {
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// TODO Theoretically we should ensure that the nodes don't have a parent.
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//        if (newAttrImpl.getOwnerElement() != null) {
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//            throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, null);
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//        }
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i = indexOfItem(arg.getNodeName());
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (i != -1) {
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            list.remove(i);
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        list.add((NodeImpl)arg);
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return arg;
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Node setNamedItemNS(Node arg) throws DOMException {
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Ensure we only accept nodes of the correct type.
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!type.isAssignableFrom(arg.getClass())) {
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // All nodes in the map must belong to the same document.
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (list.size() != 0) {
154e14d736a739d6523fd13d98f13e9d51167197a34Jesse Wilson            Document document = list.get(0).document;
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (document != null && arg.getOwnerDocument() != document) {
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// TODO Theoretically we should ensure that the nodes don't have a parent.
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//        if (newAttrImpl.getOwnerElement() != null) {
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//            throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, null);
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//        }
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i = indexOfItemNS(arg.getNamespaceURI(), arg.getLocalName());
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (i != -1) {
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            list.remove(i);
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        list.add((NodeImpl)arg);
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return arg;
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
177