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

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

Fix 203B143

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