source: trunk/gli/src/org/greenstone/gatherer/gems/GValueNode.java@ 8270

Last change on this file since 8270 was 8270, checked in by mdewsnip, 20 years ago

Source files for the Greenstone Editor for Metadata Sets (GEMS). This is currently just the old MetadataEditorManager, modified to run stand-alone. It will be substantially improved by Attila Aros.

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