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

Last change on this file since 36136 was 36136, checked in by kjdon, 2 years ago

method to set a class type, now that we have INdex and MGIndex, and we might need to swap between the two

  • Property svn:keywords set to Author Date Id Revision
File size: 11.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.greenstone.gatherer.util.StaticStrings;
33import org.greenstone.gatherer.util.XMLTools;
34import org.w3c.dom.*;
35
36/** This class provides ListModel like access to a list of nodes within a DOM model.
37 * @author John Thompson, Greenstone Digital Library, University of Waikato
38 * @version 2.3d
39 */
40public class DOMProxyListModel
41extends AbstractListModel {
42 protected Element root;
43 private DOMProxyListEntry class_type;
44 private HashMap cache = new HashMap ();
45 private NodeList children = null;
46 private String tag_name;
47
48 /** Constructor.
49 * @param root the Element at the root of the subtree to be searched for appropriate child elements
50 * @param tag_name the name of appropriate elements as a String
51 * @param class_type the type of object to wrap the elements returned in, as a DOMProxyListEntry
52 */
53 public DOMProxyListModel (Element root, String tag_name, DOMProxyListEntry class_type) {
54 this.class_type = class_type;
55 this.root = root;
56 this.tag_name = tag_name;
57 this.children = this.root.getElementsByTagName (this.tag_name);
58 }
59
60 /** 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. */
61 public synchronized void add (DOMProxyListEntry entry) {
62 Element element = entry.getElement ();
63 if(root.hasChildNodes ()) {
64 Node sibling = root.getFirstChild ();
65 root.insertBefore (element, sibling);
66 sibling = null;
67 }
68 else {
69 root.appendChild (element);
70 }
71 element = null;
72 // Regardless fire update event
73 cache.clear ();
74 fireIntervalAdded (this, 0, 0);
75 }
76
77 /** Used to add an element into the underlying dom, and fire the appropriate repaint events.
78 * @param index the index where the element should be inserted (relative of the other elements in this proxy list)
79 * @param entry the <strong>DOMProxyListEntry</strong> to be inserted
80 */
81 public synchronized void add (int index, DOMProxyListEntry entry) {
82 ///atherer.println("Add entry at " + index + " where size = " + getSize());
83 Element element = entry.getElement ();
84 // retrieve the node where we want to insert
85 if(index < children.getLength ()) {
86 Node sibling = children.item (index);
87 // Find the parent node
88 Node parent_node = sibling.getParentNode ();
89 parent_node.insertBefore (element, sibling);
90 sibling = null;
91 }
92 // 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!)
93 else {
94 // Retrieve the currently last entry
95 index = children.getLength () - 1;
96 Node sibling = null;
97 Node parent_node = null;
98 if(index >= 0) {
99 sibling = children.item (index);
100 parent_node = sibling.getParentNode ();
101 sibling = sibling.getNextSibling ();
102 }
103 if(sibling != null && parent_node != null) {
104 parent_node.insertBefore (element, sibling);
105 }
106 // Add to the root node
107 else {
108 index = 0;
109 root.appendChild (element);
110 }
111 }
112 // Regardless fire update event
113 cache.clear ();
114 fireIntervalAdded (this, index, index);
115 }
116
117 /** 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.
118 * @param entry the DOMProxyListEntry to be inserted
119 * @param preceeding_entry the DOMProxyListEntry immediately before where we want the new entry
120 */
121 public synchronized void addAfter (DOMProxyListEntry entry, DOMProxyListEntry preceeding_entry) {
122 Element element = entry.getElement ();
123 Element preceeding_sibling = preceeding_entry.getElement ();
124 Node parent_node = preceeding_sibling.getParentNode ();
125 Node following_sibling = preceeding_sibling.getNextSibling ();
126 if(following_sibling != null) {
127 parent_node.insertBefore (element, following_sibling);
128 }
129 else {
130 parent_node.appendChild (element);
131 }
132 // Regardless fire update event
133 cache.clear ();
134 int index = indexOf (entry);
135 fireIntervalAdded (this, index, index);
136 }
137
138 /** 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.
139 * @param entry the DOMProxyListEntry to be inserted
140 * @param following_entry the DOMProxyListEntry immediately after where we want the new entry
141 */
142 public synchronized void addBefore (DOMProxyListEntry entry, DOMProxyListEntry following_entry) {
143 Element element = entry.getElement ();
144 Element following_sibling = following_entry.getElement ();
145 Node parent_node = following_sibling.getParentNode ();
146 parent_node.insertBefore (element, following_sibling);
147 // Regardless fire update event
148 cache.clear ();
149 int index = indexOf (entry);
150 fireIntervalAdded (this, index, index);
151 }
152
153 public synchronized void add (Node parent, DOMProxyListEntry entry, Node sibling) {
154 Element child = entry.getElement ();
155 if(sibling != null) {
156 parent.insertBefore (child, sibling);
157 }
158 else {
159 parent.appendChild (child);
160 }
161 cache.clear ();
162 int index = indexOf (entry);
163
164
165 fireIntervalAdded (this, index, index);
166 }
167
168 /** 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. */
169 public synchronized void append (DOMProxyListEntry entry) {
170 Element element = entry.getElement ();
171 root.appendChild (element);
172 element = null;
173 // Regardless fire update event
174 cache.clear ();
175 fireIntervalAdded (this, 0, 0);
176 }
177
178 public synchronized ArrayList children () {
179 ArrayList child_list = new ArrayList ();
180 int child_count = children.getLength ();
181 for(int i = 0; i < child_count; i++) {
182 child_list.add (getElementAt (i));
183 }
184 return child_list;
185 }
186
187 public synchronized boolean contains (Object entry) {
188 boolean found = false;
189 int size = getSize ();
190
191 for(int i = 0; !found && i < size; i++) {
192 DOMProxyListEntry sibling = (DOMProxyListEntry) getElementAt (i);
193 if(sibling.equals (entry)) {
194
195 found = true;
196 }
197 }
198 return found;
199 }
200
201 public synchronized Object getElementAt (int index) {
202 /** There are times when the length of the 'cache' is not as same as the length of the 'children', etc. not up to date.
203 eg, when a classifier has been deleted. So we rather not have this efficiency for Format4gs3.java.*/
204 if (class_type instanceof Format4gs3) {
205 Element element = (Element) children.item (index);
206 // Now wrap it in the object of the users choice
207 Object object = class_type.create (element);
208 return object;
209 }
210
211 Object object = cache.get (Integer.valueOf(index));
212 if (object != null) {
213 return object;
214 }
215
216 // Retrieve the required element
217 Element element = (Element) children.item (index);
218 if (element == null) {
219 return null;
220 }
221 DebugStream.println ("Element at index " + index + " not in cache: " + element);
222
223 // Now wrap it in the object of the users choice
224 object = class_type.create (element);
225 cache.put (Integer.valueOf(index), object);
226 return object;
227 }
228
229 public synchronized int indexOf (DOMProxyListEntry entry) {
230 Element element = entry.getElement ();
231 int children_length = children.getLength ();
232 for(int i = 0; i < children_length; i++) {
233 Node node = children.item (i);
234 if(element == node) {
235 return i;
236 }
237 }
238 return -1;
239 }
240
241 public synchronized int getSize () {
242
243 if(children == null) {
244 children = root.getElementsByTagName (tag_name);
245 }
246 return children.getLength ();
247 }
248
249 public synchronized void refresh () {
250 fireContentsChanged (this, 0, getSize ());
251 }
252
253 public synchronized void refresh (DOMProxyListEntry entry) {
254 int index = indexOf (entry);
255 fireContentsChanged (this, index, index);
256 }
257
258 public synchronized void remove (DOMProxyListEntry entry) {
259 remove (indexOf (entry));
260 }
261
262 public synchronized void remove (int index) {
263 // Retrieve the required element
264 Node node = children.item (index);
265 // Find its parent
266 Node parent_node = node.getParentNode ();
267 // Now remove it
268 parent_node.removeChild (node);
269 // Refresh model
270 cache.clear ();
271
272 fireIntervalRemoved (this, index, index);
273 }
274
275
276 /** Changes the 'root' element that this list sources its information from.
277 * @param root the new root Element
278 */
279 public synchronized void setRoot (Element root) {
280 this.children = null;
281 cache.clear ();
282 this.root = root;
283 this.children = this.root.getElementsByTagName (this.tag_name);
284 fireContentsChanged (this, 0, getSize ());
285 }
286
287 public synchronized void setAssigned (boolean assigned) {
288 if (assigned) {
289 root.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
290 }
291 else {
292 root.setAttribute (StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
293 }
294 }
295
296 public boolean isAssigned () {
297 return (root.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals ("") || root.getAttribute (StaticStrings.ASSIGNED_ATTRIBUTE).equals (StaticStrings.TRUE_STR));
298 }
299
300 public void setClassType(DOMProxyListEntry class_type) {
301 this.class_type = class_type;
302 }
303
304}
Note: See TracBrowser for help on using the repository browser.