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

Last change on this file since 6044 was 6044, checked in by jmt12, 20 years ago

Removed obsolete alias stuff

  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 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/**
40 * Title: The Gatherer<br>
41 * Description: The Gatherer: a tool for gathering and enriching digital collections.<br>
42 * Copyright: Copyright (c) 2001<br>
43 * Company: The University of Waikato<br>
44 * First Coded: 20/06/02
45 * Revised:<br>
46 * @author John Thompson, Greenstone Digital Libraries
47 * @version 2.1
48 */
49
50import java.util.*;
51import javax.swing.tree.*;
52import org.greenstone.gatherer.Gatherer;
53import org.greenstone.gatherer.msm.MSMUtils;
54import org.greenstone.gatherer.util.Codec;
55import org.greenstone.gatherer.util.StaticStrings;
56import org.greenstone.gatherer.util.Utility;
57import org.w3c.dom.*;
58
59/** 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.
60 */
61public class GValueNode
62 extends DefaultMutableTreeNode {
63
64 static final public int DOM = 0;
65 static final public int GREENSTONE = 1;
66 static final public int TEXT = 2;
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
82 /** Compares two GValueNodes for ordering by using the String.compareTo method.
83 * @param sibling The <strong>Object</strong> representing the GValueNode we are comparing ourselves to.
84 * @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.
85 */
86 public int compareTo(Object sibling) {
87 return toString().compareTo(sibling.toString());
88 }
89
90 /** Determine if this tree node contains a child with a matching value.
91 * @param value The value we are attempting to match, as a <strong>String</strong>.
92 * @return <i>true</i> if there is a matching child node, <i>false</i> otherwise.
93 */
94 /* private boolean containsValue(String value) {
95 if(default_value != null) {
96 return false;
97 }
98 return getValue(value) != null;
99 } */
100
101 /** Returns an enumeration of the child nodes.
102 * @return An <strong>Enumeration</strong> containing the child nodes.
103 */
104 public Enumeration children() {
105 if(default_value != null) {
106 return null;
107 }
108 if(children == null) {
109 map();
110 }
111 return children.elements();
112 }
113 public boolean equals(Object other) {
114 return compareTo(other) == 0;
115 }
116
117 public GValueNode get(int index) {
118 GValueNode result = null;
119 if(children != null) {
120 result = (GValueNode) children.get(index);
121 }
122 return result;
123 }
124
125 /** Returns <I>true</I> if the reciever allows children. */
126 public boolean getAllowsChildren() {
127 return true;
128 }
129
130 /** Returns the child <I>TreeNode</I> at index <I>childIndex</I>.*/
131 public TreeNode getChildAt(int index) {
132 if(default_value != null) {
133 return this;
134 }
135 if(children == null) {
136 map();
137 }
138 return (GValueNode) children.get(index);
139 }
140
141 /** Returns the number of children <I>TreeNode</I>s the reciever contains. */
142 public int getChildCount() {
143 int size = 0;
144 if(default_value != null) {
145 size = 0;
146 }
147 if(children == null) {
148 map();
149 }
150 return children.size();
151 }
152
153 public Element getElement() {
154 return (Element) userObject;
155 }
156
157 /** Return the path to this node within the value tree model.
158 * @return A <strong>String</strong> representing the path, ie "Titles\Modern\The Green Mile"
159 */
160 public String getFullPath(boolean as_text) {
161 if(default_value != null) {
162 return default_value;
163 }
164 StringBuffer path = new StringBuffer(toString());
165 GValueNode node = (GValueNode) getParent();
166 while(node != null && !node.getElement().getNodeName().equalsIgnoreCase("AssignedValues")) {
167 path.insert(0, StaticStrings.PIPE_STR);
168 path.insert(0, node.toString());
169 node = (GValueNode) node.getParent();
170 }
171 if(as_text) {
172 String temp = Codec.transform(path.toString(), Codec.GREENSTONE_TO_TEXT);
173 return Codec.transform(temp, Codec.DECODE_PATH);
174 }
175 else {
176 return path.toString();
177 }
178 }
179
180 /** Returns the index of <I>node</I> in the recievers children. If the
181 * reciever does not contain <I>node</I>, <I>-1</I> will be returned. */
182 public int getIndex(TreeNode node) {
183 if(default_value != null) {
184 return 0;
185 }
186 if(children == null) {
187 map();
188 }
189 return children.indexOf(node);
190 }
191
192 public String getMetadataElementName() {
193 if(default_value != null) {
194 return element_name;
195 }
196 GValueNode node = this;
197 while(node != null && !node.getElement().getNodeName().equalsIgnoreCase("AssignedValues")) {
198 node = (GValueNode)node.getParent();
199 }
200 if(node != null) {
201 return node.getElement().getAttribute("element");
202 }
203 return null;
204 }
205
206 public GValueNode getValue(String value) {
207 ///ystem.err.println("GValueNode.getValue(" + value + ")");
208 if(default_value != null) {
209 return this;
210 }
211 if(children == null) {
212 map();
213 }
214 for(int i = 0; i < children.size(); i++) {
215 GValueNode child = (GValueNode) children.get(i);
216 ///ystem.err.println("Comparing value and '" + child.toString(GValueNode.DOM));
217 if(child.toString(GValueNode.DOM).equalsIgnoreCase(value)) {
218 return child;
219 }
220 }
221 return null;
222 }
223
224 /** Adds <I>child</I> to the receiever at <I>index</I>. <I>child</I> will
225 * be messaged with setParent().
226 */
227 public void insert(MutableTreeNode child, int index) {
228 if(default_value != null) {
229 return;
230 }
231 if(index >= children.size()) {
232 // Append to children.
233 children.add(child);
234 // And to document
235 getElement().appendChild(((GValueNode)child).getElement());
236 }
237 else {
238 GValueNode sibling = (GValueNode) children.get(index);
239 // Insert in children
240 children.add(index, child);
241 // And in document
242 getElement().insertBefore(((GValueNode)child).getElement(), sibling.getElement());
243 }
244 child.setParent(this);
245 }
246
247 /** Returns <I>true</I> if the reciever is a leaf. */
248 public boolean isLeaf() {
249 if(default_value != null || getChildCount() > 0) {
250 return false;
251 }
252 return true;
253 }
254
255 /** Ensure that the children nodes of this tree are instantiated, and record the initial mappings for legacy sake.
256 * @param mapping A <strong>HashMap</strong> into which to write the initial mappings.
257 * @param prefix The prefix to use for indexes, as a <strong>String</strong>.
258 */
259 public void map(HashMap mapping, String prefix) {
260 if(default_value != null) {
261 return;
262 }
263 children = new Vector();
264 if(prefix.length() > 0) {
265 prefix = prefix + ".";
266 }
267 int i = 1;
268 for(Node node = getElement().getFirstChild(); node != null; node = node.getNextSibling()) {
269 if(node.getNodeName().equals("Subject")) {
270 GValueNode child = new GValueNode((Element)node);
271 child.setParent(this);
272 children.add(child);
273 String index = prefix + i;
274 mapping.put(index, child);
275 child.map(mapping, index);
276 i++;
277 }
278 }
279 }
280
281 /** Resets the user object of the reciever to <I>object</I>. */
282 public void setUserObject(Object object) {
283 // Can't ever change Elements from here. Have to use editor. */
284 }
285
286 public void setValue(String value) {
287 setNodeValue("Value", value);
288 }
289
290 public int size() {
291 int size = 0;
292 if(children != null) {
293 size = children.size();
294 }
295 return size;
296 }
297
298 /** Returns a <I>String</I> representation of the reciever. If this
299 * happens to be the AssignedValues 'root' then we do something slightly
300 * different, otherwise we return the value of the <I>#Text</I> child of
301 * the <I>Value</I> of this <I>Subject</I> node!
302 */
303 public String toString() {
304 return toString(GValueNode.TEXT);
305 }
306
307 public String toString(int decode_type) {
308 if(default_value != null) {
309 return default_value;
310 }
311 Element element = getElement();
312 String name = element.getNodeName();
313 String result = null;
314 if(name.equals("Subject")) {
315 result = MSMUtils.getValue(element);
316 result = Codec.transform(result, Codec.DECODE_PATH);
317 switch(decode_type) {
318 case GValueNode.GREENSTONE:
319 // We want this as greenstone format
320 ///ystem.err.print(result);
321 result = Codec.transform(result, Codec.DOM_TO_GREENSTONE);
322 ///ystem.err.println(" -> D2G decode -> " + result);
323 break;
324 case GValueNode.TEXT:
325 ///ystem.err.print(result);
326 result = Codec.transform(result, Codec.DOM_TO_TEXT);
327 ///ystem.err.println(" -> D2T decode -> " + result);
328 break;
329 default:
330 ///ystem.err.println(result + " -> nothing to do.");
331 }
332 }
333 else if(name.equals("AssignedValues")) {
334 result = getMetadataElementName();
335 }
336 return 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 node.setParent(null);
359 // Remove from DOM
360 Element child_element = ((GValueNode)node).getElement();
361 Node parent_node = child_element.getParentNode();
362 parent_node.removeChild(child_element);
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.