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

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

Initial revision

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