source: trunk/gli/src/org/greenstone/gatherer/valuetree/GValueNode.java@ 4407

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

2030090: Adding previous values is no longer case sensitive.

  • Property svn:keywords set to Author Date Id Revision
File size: 12.1 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 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37
38
39
40
41
42
43package org.greenstone.gatherer.valuetree;
44/**
45 * Title: The Gatherer<br>
46 * Description: The Gatherer: a tool for gathering and enriching digital collections.<br>
47 * Copyright: Copyright (c) 2001<br>
48 * Company: The University of Waikato<br>
49 * First Coded: 20/06/02
50 * Revised:<br>
51 * @author John Thompson, Greenstone Digital Libraries
52 * @version 2.1
53 */
54import java.util.Collections;
55import java.util.Enumeration;
56import java.util.HashMap;
57import java.util.Hashtable;
58import java.util.Vector;
59import javax.swing.tree.*;
60import org.greenstone.gatherer.Gatherer;
61import org.greenstone.gatherer.msm.ElementWrapper;
62import org.greenstone.gatherer.msm.MSMUtils;
63import org.greenstone.gatherer.util.Utility;
64import org.w3c.dom.Document;
65import org.w3c.dom.Element;
66import org.w3c.dom.Node;
67import org.w3c.dom.NodeList;
68/** This class is instantiated using a metadata element. From this parent element, which refers to a specific Element in the mds DOM model, the AssignedValues child is used as the root of a tree data-structure encompassing all of the nodes within the AssignedValues tree. This class also provide methods for adding, updating and removing nodes within this tree, as well as implementing all of the methods necessary for this node to be used as the basis of a tree model.
69 */
70public class GValueNode
71 extends DefaultMutableTreeNode {
72
73 private String element_name = null;
74 private String default_value = null;
75
76 public GValueNode(Element element) {
77 this.children = null;
78 this.userObject = element;
79 this.default_value = null;
80 }
81
82 public GValueNode(String element_name, String default_value) {
83 this.element_name = element_name;
84 this.default_value = default_value;
85 }
86 /** Compares two GValueNodes for ordering by using the String.compareTo method.
87 * @param sibling The <strong>Object</strong> representing the GValueNode we are comparing ourselves to.
88 * @return An <i>int</i> indicating the ordering. The value is less than zero if we are before the parameter object, zero if we are equal and greater than zero if we preceed sibling.
89 */
90 public int compareTo(Object sibling) {
91 return toString().compareTo(sibling.toString());
92 }
93 /** Determine if this tree node contains a child with a matching value.
94 * @param value The value we are attempting to match, as a <strong>String</strong>.
95 * @return <i>true</i> if there is a matching child node, <i>false</i> otherwise.
96 */
97 public boolean containsValue(String value) {
98 if(default_value != null) {
99 return false;
100 }
101 return getValue(value) != null;
102 }
103 /** Returns an enumeration of the child nodes.
104 * @return An <strong>Enumeration</strong> containing the child nodes.
105 */
106 public Enumeration children() {
107 if(default_value != null) {
108 return null;
109 }
110 if(children == null) {
111 map();
112 }
113 return children.elements();
114 }
115 public boolean equals(Object other) {
116 return compareTo(other) == 0;
117 }
118
119 public GValueNode get(int index) {
120 GValueNode result = null;
121 if(children != null) {
122 result = (GValueNode) children.get(index);
123 }
124 return result;
125 }
126
127 public String getAlias() {
128 // Attempt to retrieve a child node named Alias
129 Element element = (Element) userObject;
130 for(Node pos_node = element.getFirstChild(); pos_node != null; pos_node = pos_node.getNextSibling()) {
131 // And if we find such a node
132 if(pos_node.getNodeName().equals("Alias")) {
133 // Retrieve its text node
134 for(Node pos_text = pos_node.getFirstChild(); pos_text != null; pos_text = pos_text.getNextSibling()) {
135 // When we find the node return its value
136 if(pos_text.getNodeName().equals("#text")) {
137 return pos_text.getNodeValue();
138 }
139 }
140 }
141 }
142 return "";
143 }
144
145 public String getAlias(String index) {
146 return index;
147 }
148
149 /** Returns <I>true</I> if the reciever allows children. */
150 public boolean getAllowsChildren() {
151 return true;
152 }
153
154 /** Returns the child <I>TreeNode</I> at index <I>childIndex</I>.*/
155 public TreeNode getChildAt(int index) {
156 if(default_value != null) {
157 return this;
158 }
159 if(children == null) {
160 map();
161 }
162 return (GValueNode) children.get(index);
163 }
164 /** Returns the number of children <I>TreeNode</I>s the reciever contains. */
165 public int getChildCount() {
166 int size = 0;
167 if(default_value != null) {
168 size = 0;
169 }
170 if(children == null) {
171 map();
172 }
173 return children.size();
174 }
175
176 public Element getElement() {
177 return (Element) userObject;
178 }
179
180 /** Return the path to this node within the value tree model.
181 * @return A <strong>String</strong> representing the path, ie "Titles\Modern\The Green Mile"
182 */
183 public String getFullPath() {
184 if(default_value != null) {
185 return default_value;
186 }
187 StringBuffer path = new StringBuffer(toString());
188 GValueNode node = (GValueNode) getParent();
189 while(node != null && !node.getElement().getNodeName().equalsIgnoreCase("AssignedValues")) {
190 path.insert(0, "\\");
191 path.insert(0, node.toString());
192 node = (GValueNode) node.getParent();
193 }
194 return path.toString();
195 }
196
197 /** Returns the index of <I>node</I> in the recievers children. If the
198 * reciever does not contain <I>node</I>, <I>-1</I> will be returned. */
199 public int getIndex(TreeNode node) {
200 if(default_value != null) {
201 return 0;
202 }
203 if(children == null) {
204 map();
205 }
206 return children.indexOf(node);
207 }
208
209 public String getMetadataElementName() {
210 if(default_value != null) {
211 return element_name;
212 }
213 GValueNode node = this;
214 while(node != null && !node.getElement().getNodeName().equalsIgnoreCase("AssignedValues")) {
215 node = (GValueNode)node.getParent();
216 }
217 if(node != null) {
218 return node.getElement().getAttribute("element");
219 }
220 return null;
221 }
222
223 public GValueNode getValue(String value) {
224 if(default_value != null) {
225 return this;
226 }
227 if(children == null) {
228 map();
229 }
230 GValueNode result = null;
231 for(int i = 0; result == null && i < children.size(); i++) {
232 Object child = children.get(i);
233 if(child.toString().equalsIgnoreCase(value)) {
234 result = (GValueNode) child;
235 }
236 }
237 return result;
238 }
239
240 /** Adds <I>child</I> to the receiever at <I>index</I>. <I>child</I> will
241 * be messaged with setParent().
242 */
243 public void insert(MutableTreeNode child, int index) {
244 if(default_value != null) {
245 return;
246 }
247 if(index >= children.size()) {
248 // Append to children.
249 children.add(child);
250 // And to document
251 getElement().appendChild(((GValueNode)child).getElement());
252 }
253 else {
254 GValueNode sibling = (GValueNode) children.get(index);
255 // Insert in children
256 children.add(index, child);
257 // And in document
258 getElement().insertBefore(((GValueNode)child).getElement(), sibling.getElement());
259 }
260 child.setParent(this);
261 }
262
263 /** Returns <I>true</I> if the reciever is a leaf. */
264 public boolean isLeaf() {
265 if(default_value != null || getChildCount() > 0) {
266 return false;
267 }
268 return true;
269 }
270
271 /** Ensure that the children nodes of this tree are instantiated, and record the initial mappings for legacy sake.
272 * @param mapping A <strong>HashMap</strong> into which to write the initial mappings.
273 * @param prefix The prefix to use for indexes, as a <strong>String</strong>.
274 */
275 public void map(HashMap mapping, String prefix) {
276 if(default_value != null) {
277 return;
278 }
279 children = new Vector();
280 if(prefix.length() > 0) {
281 prefix = prefix + ".";
282 }
283 int i = 1;
284 for(Node node = getElement().getFirstChild(); node != null; node = node.getNextSibling()) {
285 if(node.getNodeName().equals("Subject")) {
286 GValueNode child = new GValueNode((Element)node);
287 child.setParent(this);
288 children.add(child);
289 String index = prefix + i;
290 mapping.put(index, child);
291 child.map(mapping, index);
292 i++;
293 }
294 }
295 }
296
297 public void setAlias(String alias) {
298 setNodeValue("Alias", alias);
299 }
300
301 /** Resets the user object of the reciever to <I>object</I>. */
302 public void setUserObject(Object object) {
303 // Can't ever change Elements from here. Have to use editor. */
304 }
305
306 public void setValue(String value) {
307 setNodeValue("Value", value);
308 }
309
310 public int size() {
311 int size = 0;
312 if(children != null) {
313 size = children.size();
314 }
315 return size;
316 }
317
318 /** Returns a <I>String</I> representation of the reciever. If this
319 * happens to be the AssignedValues 'root' then we do something slightly
320 * different, otherwise we return the value of the <I>#Text</I> child of
321 * the <I>Value</I> of this <I>Subject</I> node!
322 */
323 public String toString() {
324 if(default_value != null) {
325 return default_value;
326 }
327 Element element = getElement();
328 String name = element.getNodeName();
329 String result = null;
330 if(name.equals("Subject")) {
331 result = MSMUtils.getValue(element);
332 }
333 else if(name.equals("AssignedValues")) {
334 result = getMetadataElementName();
335 }
336 return Utility.stripNL(result);
337 }
338
339 private void map() {
340 children = new Vector();
341 for(Node node = getElement().getFirstChild(); node != null; node = node.getNextSibling()) {
342 if(node.getNodeName().equals("Subject")) {
343 GValueNode child = new GValueNode((Element)node);
344 child.setParent(this);
345 children.add(child);
346 }
347 }
348 }
349
350 /** Removes the child at index from the receiver. */
351 public void remove(int index) {
352 remove((MutableTreeNode)getChildAt(index));
353 }
354
355 /** Removes node from the receiver. */
356 public void remove(MutableTreeNode node) {
357 children.remove(node);
358 parent = null;
359 // Remove from DOM
360 Node child_node = (Node) userObject;
361 Node parent_node = child_node.getParentNode();
362 parent_node.removeChild(child_node);
363 }
364
365 /** Removes the receiver from its parent. */
366 public void removeFromParent() {
367 if(parent != null) {
368 parent.remove(this);
369 }
370 }
371
372 private void setNodeValue(String name, String value) {
373 boolean found = false;
374 // Attempt to retrieve a child node named name
375 Element element = (Element) userObject;
376 for(Node pos_node = element.getFirstChild(); pos_node != null; pos_node = pos_node.getNextSibling()) {
377 // And if we find such a node
378 if(pos_node.getNodeName().equals(name)) {
379 // And the new value is non-null, retrieve its text node and change it.
380 if(value != null) {
381 for(Node pos_text = pos_node.getFirstChild(); pos_text != null; pos_text = pos_text.getNextSibling()) {
382 // When we find the node...
383 if(pos_text.getNodeName().equals("#text")) {
384 pos_text.setNodeValue(value);
385 }
386 }
387 }
388 // Otherwise remove the node altogether
389 else {
390 element.removeChild(pos_node);
391 }
392 found = true;
393 }
394 }
395 // Otherwise if no such node exists add it.
396 if(!found && value != null) {
397 Document document = element.getOwnerDocument();
398 Node new_node = document.createElementNS("", name);
399 element.appendChild(new_node);
400 Node new_text = document.createTextNode(value);
401 new_node.appendChild(new_text);
402 new_text = null;
403 new_node = null;
404 }
405 // Done.
406 element = null;
407 return;
408 }
409}
Note: See TracBrowser for help on using the repository browser.