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

Last change on this file since 12468 was 12414, checked in by shaoqun, 18 years ago

force the model to refresh when set root, e.g. call setRoot method

  • Property svn:keywords set to Author Date Id Revision
File size: 9.7 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.DebugStream;
32import org.w3c.dom.*;
33
34/** This class provides ListModel like access to a list of nodes within a DOM model.
35 * @author John Thompson, Greenstone Digital Library, University of Waikato
36 * @version 2.3d
37 */
38public class DOMProxyListModel
39 extends AbstractListModel {
40 protected Element root;
41 private DOMProxyListEntry class_type;
42 private HashMap cache = new HashMap();
43 private NodeList children = null;
44 private String tag_name;
45
46 /** Constructor.
47 * @param root the Element at the root of the subtree to be searched for appropriate child elements
48 * @param tag_name the name of appropriate elements as a String
49 * @param class_type the type of object to wrap the elements returned in, as a DOMProxyListEntry
50 */
51 public DOMProxyListModel(Element root, String tag_name, DOMProxyListEntry class_type) {
52 this.class_type = class_type;
53 this.root = root;
54 this.tag_name = tag_name;
55 this.children = this.root.getElementsByTagName(this.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 entry the <strong>DOMProxyListEntry</strong> 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 preceeding_entry the DOMProxyListEntry immediately before where we want the new entry
118 */
119 public synchronized void addAfter(DOMProxyListEntry entry, DOMProxyListEntry preceeding_entry) {
120 Element element = entry.getElement();
121 Element preceeding_sibling = preceeding_entry.getElement();
122 Node parent_node = preceeding_sibling.getParentNode();
123 Node following_sibling = preceeding_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(entry);
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
162
163 fireIntervalAdded(this, index, index);
164 }
165
166 /** 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. */
167 public synchronized void append(DOMProxyListEntry entry) {
168 Element element = entry.getElement();
169 root.appendChild(element);
170 element = null;
171 // Regardless fire update event
172 cache.clear();
173 fireIntervalAdded(this, 0, 0);
174 }
175
176 public synchronized ArrayList children() {
177 ArrayList child_list = new ArrayList();
178 int child_count = children.getLength();
179 for(int i = 0; i < child_count; i++) {
180 child_list.add(getElementAt(i));
181 }
182 return child_list;
183 }
184
185 public synchronized boolean contains(Object entry) {
186 boolean found = false;
187 int size = getSize();
188
189 for(int i = 0; !found && i < size; i++) {
190 DOMProxyListEntry sibling = (DOMProxyListEntry) getElementAt(i);
191 if(sibling.equals(entry)) {
192
193 found = true;
194 }
195 }
196 return found;
197 }
198
199
200 public synchronized Object getElementAt(int index)
201 {
202 Object object = cache.get(new Integer(index));
203 if (object != null) {
204 return object;
205 }
206
207 // Retrieve the required element
208 Element element = (Element) children.item(index);
209 DebugStream.println("Element at index " + index + " not in cache: " + element);
210
211 // Now wrap it in the object of the users choice
212 object = class_type.create(element);
213 cache.put(new Integer(index), object);
214 return object;
215 }
216
217 public synchronized int indexOf(DOMProxyListEntry entry) {
218 Element element = entry.getElement();
219 int children_length = children.getLength();
220 for(int i = 0; i < children_length; i++) {
221 Node node = children.item(i);
222 if(element == node) {
223 return i;
224 }
225 }
226 return -1;
227 }
228
229 public synchronized int getSize() {
230 if(children == null) {
231 children = root.getElementsByTagName(tag_name);
232 }
233 return children.getLength();
234 }
235
236 public synchronized void refresh() {
237 fireContentsChanged(this, 0, getSize());
238 }
239
240 public synchronized void refresh(DOMProxyListEntry entry) {
241 int index = indexOf(entry);
242 fireContentsChanged(this, index, index);
243 }
244
245 public synchronized void remove(DOMProxyListEntry entry) {
246 remove(indexOf(entry));
247 }
248
249 public synchronized void remove(int index) {
250 // Retrieve the required element
251 Node node = children.item(index);
252 // Find its parent
253 Node parent_node = node.getParentNode();
254 // Now remove it
255 parent_node.removeChild(node);
256 // Refresh model
257 cache.clear();
258 fireIntervalRemoved(this, index, index);
259 }
260
261
262 /** Changes the 'root' element that this list sources its information from.
263 * @param root the new root Element
264 */
265 public synchronized void setRoot(Element root) {
266 this.children = null;
267 cache.clear();
268 this.root = root;
269 this.children = this.root.getElementsByTagName(this.tag_name);
270 fireContentsChanged(this, 0, getSize());
271 }
272
273 public synchronized void setAssigned(boolean assigned) {
274 if (assigned) {
275 root.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.TRUE_STR);
276 }
277 else {
278 root.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.FALSE_STR);
279 }
280 }
281
282 public boolean isAssigned() {
283 return (root.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals("") || root.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.TRUE_STR));
284 }
285}
Note: See TracBrowser for help on using the repository browser.