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

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

Major CDM rewrite so it uses DOM.

  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 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 Node sibling = children.item(children.getLength() - 1);
94 Node parent_node = sibling.getParentNode();
95 sibling = sibling.getNextSibling();
96 if(sibling != null) {
97 parent_node.insertBefore(element, sibling);
98 }
99 // Add to the root node
100 else {
101 root.appendChild(element);
102 }
103 }
104 // Regardless fire update event
105 cache.clear();
106 fireIntervalAdded(this, index, index);
107 }
108
109 /** 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.
110 * @param entry the DOMProxyListEntry to be inserted
111 * @param proceeding_entry the DOMProxyListEntry immediately before where we want the new entry
112 */
113 public synchronized void addAfter(DOMProxyListEntry entry, DOMProxyListEntry proceeding_entry) {
114 Element element = entry.getElement();
115 Element proceeding_sibling = proceeding_entry.getElement();
116 Node parent_node = proceeding_sibling.getParentNode();
117 Node following_sibling = proceeding_sibling.getNextSibling();
118 if(following_sibling != null) {
119 parent_node.insertBefore(element, following_sibling);
120 }
121 else {
122 parent_node.appendChild(element);
123 }
124 // Regardless fire update event
125 cache.clear();
126 int index = indexOf(proceeding_entry) + 1;
127 fireIntervalAdded(this, index, index);
128 }
129
130 /** 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.
131 * @param entry the DOMProxyListEntry to be inserted
132 * @param following_entry the DOMProxyListEntry immediately after where we want the new entry
133 */
134 public synchronized void addBefore(DOMProxyListEntry entry, DOMProxyListEntry following_entry) {
135 Element element = entry.getElement();
136 Element following_sibling = following_entry.getElement();
137 Node parent_node = following_sibling.getParentNode();
138 parent_node.insertBefore(element, following_sibling);
139 // Regardless fire update event
140 cache.clear();
141 int index = indexOf(entry);
142 fireIntervalAdded(this, index, index);
143 }
144
145 public synchronized void add(Node parent, DOMProxyListEntry entry, Node sibling) {
146 Element child = entry.getElement();
147 if(sibling != null) {
148 parent.insertBefore(child, sibling);
149 }
150 else {
151 parent.appendChild(child);
152 }
153 cache.clear();
154 int index = indexOf(entry);
155 fireIntervalAdded(this, index, index);
156 }
157
158 public synchronized ArrayList children() {
159 ArrayList child_list = new ArrayList();
160 int child_count = children.getLength();
161 for(int i = 0; i < child_count; i++) {
162 child_list.add(class_type.create((Element)children.item(i)));
163 }
164 return child_list;
165 }
166
167 public synchronized boolean contains(DOMProxyListEntry entry) {
168 boolean found = false;
169 int size = getSize();
170 for(int i = 0; !found && i < size; i++) {
171 DOMProxyListEntry sibling = (DOMProxyListEntry) getElementAt(i);
172 if(sibling.equals(entry)) {
173 found = true;
174 }
175 }
176 return found;
177 }
178
179 public synchronized Object getElementAt(int index) {
180 Object object = cache.get(new Integer(index));
181 if(object == null) {
182 // Retrieve the required element
183 Element element = (Element) children.item(index);
184 // Now wrap it in the object of the users choice
185 object = class_type.create(element);
186 cache.put(new Integer(index), object);
187 }
188 return object;
189 }
190
191 public synchronized int indexOf(DOMProxyListEntry entry) {
192 Element element = entry.getElement();
193 int children_length = children.getLength();
194 for(int i = 0; i < children_length; i++) {
195 Node node = children.item(i);
196 if(element == node) {
197 return i;
198 }
199 }
200 return -1;
201 }
202
203 public synchronized int getSize() {
204 if(children == null) {
205 children = root.getElementsByTagName(tag_name);
206 }
207 return children.getLength();
208 }
209
210 public synchronized void refresh() {
211 fireContentsChanged(this, 0, getSize());
212 }
213
214 public synchronized void refresh(DOMProxyListEntry entry) {
215 int index = indexOf(entry);
216 fireContentsChanged(this, index, index);
217 }
218
219 public synchronized void remove(DOMProxyListEntry entry) {
220 remove(indexOf(entry));
221 }
222
223 public synchronized void remove(int index) {
224 // Retrieve the required element
225 Node node = children.item(index);
226 // Find its parent
227 Node parent_node = node.getParentNode();
228 // Now remove it
229 parent_node.removeChild(node);
230 // Refresh model
231 cache.clear();
232 fireIntervalRemoved(this, index, index);
233 }
234}
235
236
237
Note: See TracBrowser for help on using the repository browser.