source: trunk/gli/src/org/greenstone/gatherer/cdm/DOMProxyListModel.java@ 5756

Last change on this file since 5756 was 5756, checked in by jmt12, 21 years ago

Added a new method for appending children nodes to the proxy root

  • Property svn:keywords set to Author Date Id Revision
File size: 8.9 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28
29import java.util.*;
30import javax.swing.*;
31import org.greenstone.gatherer.Gatherer;
32import org.greenstone.gatherer.cdm.DOMProxyListEntry;
33import org.w3c.dom.*;
34
35/** This class provides ListModel like access to a list of nodes within a DOM model.
36 * @author John Thompson, Greenstone Digital Library, University of Waikato
37 * @version 2.3d
38 */
39public class DOMProxyListModel
40 extends AbstractListModel {
41 protected Element root;
42 private DOMProxyListEntry class_type;
43 private HashMap cache = new HashMap();
44 private NodeList children = null;
45 private String tag_name;
46
47 /** Constructor.
48 * @param root the Element at the root of the subtree to be searched for appropriate child elements
49 * @param tag_name the name of appropriate elements as a String
50 * @param class_type the type of object to wrap the elements returned in, as a DOMProxyListEntry
51 */
52 public DOMProxyListModel(Element root, String tag_name, DOMProxyListEntry class_type) {
53 this.class_type = class_type;
54 this.root = root;
55 this.tag_name = tag_name;
56 }
57
58 /** Used to add an element into the underlying dom, and fire the appropriate repaint events. This version always adds the new element at the very head of the DOM. */
59 public synchronized void add(DOMProxyListEntry entry) {
60 Element element = entry.getElement();
61 if(root.hasChildNodes()) {
62 Node sibling = root.getFirstChild();
63 root.insertBefore(element, sibling);
64 sibling = null;
65 }
66 else {
67 root.appendChild(element);
68 }
69 element = null;
70 // Regardless fire update event
71 cache.clear();
72 fireIntervalAdded(this, 0, 0);
73 }
74
75 /** Used to add an element into the underlying dom, and fire the appropriate repaint events.
76 * @param index the index where the element should be inserted (relative of the other elements in this proxy list)
77 * @param element the Element to be inserted
78 */
79 public synchronized void add(int index, DOMProxyListEntry entry) {
80 ///atherer.println("Add entry at " + index + " where size = " + getSize());
81 Element element = entry.getElement();
82 // retrieve the node where we want to insert
83 if(index < children.getLength()) {
84 Node sibling = children.item(index);
85 // Find the parent node
86 Node parent_node = sibling.getParentNode();
87 parent_node.insertBefore(element, sibling);
88 sibling = null;
89 }
90 // If the index is too large, we are adding to the end of our list of entries. However you have to remember that this list is only a viewport on the entire DOM so there might be entries following this group that we actually want to insert before (not append at the very end!)
91 else {
92 // Retrieve the currently last entry
93 index = children.getLength() - 1;
94 Node sibling = null;
95 Node parent_node = null;
96 if(index >= 0) {
97 sibling = children.item(index);
98 parent_node = sibling.getParentNode();
99 sibling = sibling.getNextSibling();
100 }
101 if(sibling != null && parent_node != null) {
102 parent_node.insertBefore(element, sibling);
103 }
104 // Add to the root node
105 else {
106 index = 0;
107 root.appendChild(element);
108 }
109 }
110 // Regardless fire update event
111 cache.clear();
112 fireIntervalAdded(this, index, index);
113 }
114
115 /** Used to add an element into the underlying dom, and fire the appropriate repaint events. This version inserts the new entry immediately -after- the given entry in the DOM.
116 * @param entry the DOMProxyListEntry to be inserted
117 * @param proceeding_entry the DOMProxyListEntry immediately before where we want the new entry
118 */
119 public synchronized void addAfter(DOMProxyListEntry entry, DOMProxyListEntry proceeding_entry) {
120 Element element = entry.getElement();
121 Element proceeding_sibling = proceeding_entry.getElement();
122 Node parent_node = proceeding_sibling.getParentNode();
123 Node following_sibling = proceeding_sibling.getNextSibling();
124 if(following_sibling != null) {
125 parent_node.insertBefore(element, following_sibling);
126 }
127 else {
128 parent_node.appendChild(element);
129 }
130 // Regardless fire update event
131 cache.clear();
132 int index = indexOf(proceeding_entry) + 1;
133 fireIntervalAdded(this, index, index);
134 }
135
136 /** Used to add an element into the underlying dom, and fire the appropriate repaint events. This version inserts the new entry immediately -before- the given entry in the DOM.
137 * @param entry the DOMProxyListEntry to be inserted
138 * @param following_entry the DOMProxyListEntry immediately after where we want the new entry
139 */
140 public synchronized void addBefore(DOMProxyListEntry entry, DOMProxyListEntry following_entry) {
141 Element element = entry.getElement();
142 Element following_sibling = following_entry.getElement();
143 Node parent_node = following_sibling.getParentNode();
144 parent_node.insertBefore(element, following_sibling);
145 // Regardless fire update event
146 cache.clear();
147 int index = indexOf(entry);
148 fireIntervalAdded(this, index, index);
149 }
150
151 public synchronized void add(Node parent, DOMProxyListEntry entry, Node sibling) {
152 Element child = entry.getElement();
153 if(sibling != null) {
154 parent.insertBefore(child, sibling);
155 }
156 else {
157 parent.appendChild(child);
158 }
159 cache.clear();
160 int index = indexOf(entry);
161 fireIntervalAdded(this, index, index);
162 }
163
164 /** Used to add an element into the underlying dom, and fire the appropriate repaint events. This version always adds the new element at the end of the children. */
165 public synchronized void append(DOMProxyListEntry entry) {
166 Element element = entry.getElement();
167 root.appendChild(element);
168 element = null;
169 // Regardless fire update event
170 cache.clear();
171 fireIntervalAdded(this, 0, 0);
172 }
173
174 public synchronized ArrayList children() {
175 ArrayList child_list = new ArrayList();
176 int child_count = children.getLength();
177 for(int i = 0; i < child_count; i++) {
178 child_list.add(getElementAt(i));
179 }
180 return child_list;
181 }
182
183 public synchronized boolean contains(Object entry) {
184 boolean found = false;
185 int size = getSize();
186 for(int i = 0; !found && i < size; i++) {
187 DOMProxyListEntry sibling = (DOMProxyListEntry) getElementAt(i);
188 if(sibling.equals(entry)) {
189 found = true;
190 }
191 }
192 return found;
193 }
194
195 public synchronized Object getElementAt(int index) {
196 Object object = cache.get(new Integer(index));
197 if(object == null) {
198 // Retrieve the required element
199 Element element = (Element) children.item(index);
200 // Now wrap it in the object of the users choice
201 object = class_type.create(element);
202 cache.put(new Integer(index), object);
203 }
204 return object;
205 }
206
207 public synchronized int indexOf(DOMProxyListEntry entry) {
208 Element element = entry.getElement();
209 int children_length = children.getLength();
210 for(int i = 0; i < children_length; i++) {
211 Node node = children.item(i);
212 if(element == node) {
213 return i;
214 }
215 }
216 return -1;
217 }
218
219 public synchronized int getSize() {
220 if(children == null) {
221 children = root.getElementsByTagName(tag_name);
222 }
223 return children.getLength();
224 }
225
226 public synchronized void refresh() {
227 fireContentsChanged(this, 0, getSize());
228 }
229
230 public synchronized void refresh(DOMProxyListEntry entry) {
231 int index = indexOf(entry);
232 fireContentsChanged(this, index, index);
233 }
234
235 public synchronized void remove(DOMProxyListEntry entry) {
236 remove(indexOf(entry));
237 }
238
239 public synchronized void remove(int index) {
240 // Retrieve the required element
241 Node node = children.item(index);
242 // Find its parent
243 Node parent_node = node.getParentNode();
244 // Now remove it
245 parent_node.removeChild(node);
246 // Refresh model
247 cache.clear();
248 fireIntervalRemoved(this, index, index);
249 }
250
251 /** Changes the 'root' element that this list sources its information from.
252 * @param root the new root Element
253 */
254 public synchronized void setRoot(Element root) {
255 this.children = null;
256 cache.clear();
257 this.root = root;
258 }
259}
Note: See TracBrowser for help on using the repository browser.