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

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

Have rearranged where and how strings are feed through the Codec. After several hours work and a dozen paper trials I discovered the TEXT_TO_DOM conversion was completely pointless (DOM does it itself). Also the quotes only need to be dealt to if they are being sent to the collect.cfg file. Hopefully I've got it all going now - including using that pesky pipe character that I would rather not have to deal with. And everything seems to be ok - I tested all the dangerous characters including square brackets and amperstamp. I also tried hierarchies, and then as the piece'd'resistance I tried a hierarchies with dangerous characters. All good. I'm all about the working metadata.

  • Property svn:keywords set to Author Date Id Revision
File size: 12.6 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(DOM));
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(DOM));
169 node = (GValueNode) node.getParent();
170 }
171 if(as_text) {
172 String temp = path.toString(); ///odec.transform(path.toString(), codec.GREENSTONE_TO_TEXT);
173 System.err.println("Raw: " + temp);
174 temp = Codec.transform(temp, Codec.DECODE_PATH);
175 temp = Codec.transform(temp, Codec.DECODE_SQUARE_BRACKETS);
176 System.err.println("Decoded: " + temp);
177 return temp;
178 }
179 else {
180 return path.toString();
181 }
182 }
183
184 /** Returns the index of <I>node</I> in the recievers children. If the
185 * reciever does not contain <I>node</I>, <I>-1</I> will be returned. */
186 public int getIndex(TreeNode node) {
187 if(default_value != null) {
188 return 0;
189 }
190 if(children == null) {
191 map();
192 }
193 return children.indexOf(node);
194 }
195
196 public String getMetadataElementName() {
197 if(default_value != null) {
198 return element_name;
199 }
200 GValueNode node = this;
201 while(node != null && !node.getElement().getNodeName().equalsIgnoreCase("AssignedValues")) {
202 node = (GValueNode)node.getParent();
203 }
204 if(node != null) {
205 return node.getElement().getAttribute("element");
206 }
207 return null;
208 }
209
210 public GValueNode getValue(String value) {
211 ///ystem.err.println("GValueNode.getValue(" + value + ")");
212 if(default_value != null) {
213 return this;
214 }
215 if(children == null) {
216 map();
217 }
218 for(int i = 0; i < children.size(); i++) {
219 GValueNode child = (GValueNode) children.get(i);
220 ///ystem.err.println("Comparing value and '" + child.toString(GValueNode.DOM));
221 if(child.toString(GValueNode.DOM).equalsIgnoreCase(value)) {
222 return child;
223 }
224 }
225 return null;
226 }
227
228 /** Adds <I>child</I> to the receiever at <I>index</I>. <I>child</I> will
229 * be messaged with setParent().
230 */
231 public void insert(MutableTreeNode child, int index) {
232 if(default_value != null) {
233 return;
234 }
235 if(index >= children.size()) {
236 // Append to children.
237 children.add(child);
238 // And to document
239 getElement().appendChild(((GValueNode)child).getElement());
240 }
241 else {
242 GValueNode sibling = (GValueNode) children.get(index);
243 // Insert in children
244 children.add(index, child);
245 // And in document
246 getElement().insertBefore(((GValueNode)child).getElement(), sibling.getElement());
247 }
248 child.setParent(this);
249 }
250
251 /** Returns <I>true</I> if the reciever is a leaf. */
252 public boolean isLeaf() {
253 if(default_value != null || getChildCount() > 0) {
254 return false;
255 }
256 return true;
257 }
258
259 /** Ensure that the children nodes of this tree are instantiated, and record the initial mappings for legacy sake.
260 * @param mapping A <strong>HashMap</strong> into which to write the initial mappings.
261 * @param prefix The prefix to use for indexes, as a <strong>String</strong>.
262 */
263 public void map(HashMap mapping, String prefix) {
264 if(default_value != null) {
265 return;
266 }
267 children = new Vector();
268 if(prefix.length() > 0) {
269 prefix = prefix + ".";
270 }
271 int i = 1;
272 for(Node node = getElement().getFirstChild(); node != null; node = node.getNextSibling()) {
273 if(node.getNodeName().equals("Subject")) {
274 GValueNode child = new GValueNode((Element)node);
275 child.setParent(this);
276 children.add(child);
277 String index = prefix + i;
278 mapping.put(index, child);
279 child.map(mapping, index);
280 i++;
281 }
282 }
283 }
284
285 /** Resets the user object of the reciever to <I>object</I>. */
286 public void setUserObject(Object object) {
287 // Can't ever change Elements from here. Have to use editor. */
288 }
289
290 public void setValue(String value) {
291 setNodeValue("Value", value);
292 }
293
294 public int size() {
295 int size = 0;
296 if(children != null) {
297 size = children.size();
298 }
299 return size;
300 }
301
302 /** Returns a <I>String</I> representation of the reciever. If this
303 * happens to be the AssignedValues 'root' then we do something slightly
304 * different, otherwise we return the value of the <I>#Text</I> child of
305 * the <I>Value</I> of this <I>Subject</I> node!
306 */
307 public String toString() {
308 return toString(GValueNode.TEXT);
309 }
310
311 public String toString(int decode_type) {
312 if(default_value != null) {
313 return default_value;
314 }
315 Element element = getElement();
316 String name = element.getNodeName();
317 String result = null;
318 if(name.equals("Subject")) {
319 result = MSMUtils.getValue(element);
320 ///ystem.err.print(result);
321 switch(decode_type) {
322 case GValueNode.GREENSTONE:
323 // We want this as greenstone format
324 ///ystem.err.print(result);
325 //result = /odec.transform(result, /odec.DOM_TO_GREENSTONE);
326 ///ystem.err.println(" -> D2G decode -> " + result);
327 break;
328 case GValueNode.TEXT:
329 //result = /odec.transform(result, /odec.DOM_TO_TEXT);
330 result = Codec.transform(result, Codec.DECODE_PATH);
331 result = Codec.transform(result, Codec.DECODE_SQUARE_BRACKETS);
332 ///ystem.err.println(" -> D2T decode -> " + result);
333 break;
334 default:
335 ///ystem.err.println(result + " -> nothing to do.");
336 }
337 }
338 else if(name.equals("AssignedValues")) {
339 result = getMetadataElementName();
340 }
341 return result;
342 }
343
344 private void map() {
345 children = new Vector();
346 for(Node node = getElement().getFirstChild(); node != null; node = node.getNextSibling()) {
347 if(node.getNodeName().equals("Subject")) {
348 GValueNode child = new GValueNode((Element)node);
349 child.setParent(this);
350 children.add(child);
351 }
352 }
353 }
354
355 /** Removes the child at index from the receiver. */
356 public void remove(int index) {
357 remove((MutableTreeNode)getChildAt(index));
358 }
359
360 /** Removes node from the receiver. */
361 public void remove(MutableTreeNode node) {
362 children.remove(node);
363 node.setParent(null);
364 // Remove from DOM
365 Element child_element = ((GValueNode)node).getElement();
366 Node parent_node = child_element.getParentNode();
367 parent_node.removeChild(child_element);
368 }
369
370 /** Removes the receiver from its parent. */
371 public void removeFromParent() {
372 if(parent != null) {
373 parent.remove(this);
374 }
375 }
376
377 private void setNodeValue(String name, String value) {
378 boolean found = false;
379 // Attempt to retrieve a child node named name
380 Element element = (Element) userObject;
381 for(Node pos_node = element.getFirstChild(); pos_node != null; pos_node = pos_node.getNextSibling()) {
382 // And if we find such a node
383 if(pos_node.getNodeName().equals(name)) {
384 // And the new value is non-null, retrieve its text node and change it.
385 if(value != null) {
386 for(Node pos_text = pos_node.getFirstChild(); pos_text != null; pos_text = pos_text.getNextSibling()) {
387 // When we find the node...
388 if(pos_text.getNodeName().equals("#text")) {
389 pos_text.setNodeValue(value);
390 }
391 }
392 }
393 // Otherwise remove the node altogether
394 else {
395 element.removeChild(pos_node);
396 }
397 found = true;
398 }
399 }
400 // Otherwise if no such node exists add it.
401 if(!found && value != null) {
402 Document document = element.getOwnerDocument();
403 Node new_node = document.createElementNS("", name);
404 element.appendChild(new_node);
405 Node new_text = document.createTextNode(value);
406 new_node.appendChild(new_text);
407 new_text = null;
408 new_node = null;
409 }
410 // Done.
411 element = null;
412 return;
413 }
414}
Note: See TracBrowser for help on using the repository browser.