source: trunk/gli/src/org/greenstone/gatherer/valuetree/GValueModel.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: 9.7 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 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.valuetree;
28
29import java.util.*;
30import javax.swing.tree.*;
31import org.greenstone.gatherer.Gatherer;
32import org.greenstone.gatherer.msm.ElementWrapper;
33import org.greenstone.gatherer.msm.MSMUtils;
34import org.greenstone.gatherer.util.PatternTokenizer;
35import org.greenstone.gatherer.util.StaticStrings;
36import org.greenstone.gatherer.util.Utility;
37import org.w3c.dom.*;
38/*
39 * @author John Thompson, Greenstone Digital Library, University of Waikato
40 * @version 2.1
41 */
42public class GValueModel
43 extends DefaultTreeModel {
44
45 private ElementWrapper element;
46
47 public GValueModel() {
48 super(new DefaultMutableTreeNode("Temp"));
49 }
50
51 public GValueModel(String root) {
52 super(new DefaultMutableTreeNode(root));
53 }
54
55 public GValueModel(ElementWrapper e) {
56 super(new DefaultMutableTreeNode("Temp"));
57 this.element = e;
58 // Load the template value tree document.
59 Document document = MSMUtils.getValueTreeTemplate();
60 Element new_root = document.getDocumentElement();
61 new_root.setAttribute("element", e.getName());
62 root = new GValueNode(new_root);
63 }
64
65 public GValueModel(ElementWrapper e, Document document) {
66 super(new DefaultMutableTreeNode("Temp"));
67 this.element = e;
68 Element new_root = document.getDocumentElement();
69 new_root.setAttribute("element", e.getName());
70 root = new GValueNode(new_root);
71 }
72
73 /** Value may include path ie news\newssw */
74 public GValueNode addValue(String value) {
75 try {
76 // Tokenize the string using the escaped character
77 PatternTokenizer tokenizer = new PatternTokenizer(value, StaticStrings.PIPE_STR);
78 GValueNode subject = (GValueNode) root;
79 while(tokenizer.hasMoreTokens() && subject != null) {
80 String token = tokenizer.nextToken();
81 subject = addValue(token, subject);
82 }
83 return subject;
84 }
85 catch (Exception error) {
86 error.printStackTrace();
87 }
88 return null;
89 }
90
91 public GValueNode addValue(String value, GValueNode subject) {
92 // To add a value we must first ensure it isn't already present in -this- nodes children. The bummer is that the nice getElements functions search the whole tree so...
93 GValueNode value_node = subject.getValue(value);
94 if(value_node == null) {
95 // Now add the new value.
96 Document document = subject.getElement().getOwnerDocument();
97 // Now we create a new subject and add it subject
98 Element new_subject = document.createElementNS("","Subject");
99 Element new_value = document.createElementNS("","Value");
100 new_subject.appendChild(new_value);
101 Text new_text = document.createTextNode(value);
102 new_value.appendChild(new_text);
103 value_node = new GValueNode(new_subject);
104 ///ystem.err.println("(GValueModel) addValue()... " + value_node);
105
106 // Figure out where this node will be inserted in subjects
107 // children.
108 int position = -1;
109 for(int i = 0; position == -1 && i < subject.getChildCount(); i++) {
110 Object sibling = subject.getChildAt(i);
111 int rel_pos = value.compareTo(sibling.toString());
112 ///ystem.err.println("'"+value+"'.compareTo('"+sibling+"') = " + rel_pos);
113 if(rel_pos <= 0) {
114 position = i;
115 }
116 }
117 if(position == -1) {
118 position = subject.getChildCount();
119 }
120 // Insert it. If position is still -1, append it to the end of subjects children.
121 ///ystem.err.println("Inserting '" + value + "' at position " + position);
122 insertNodeInto(value_node, subject, position);
123 ///ystem.err.println("(GValueModel) Done insert node into...");
124 // SynchronizedTreeModelTools.insertNodeInto(this, subject, value_node);
125 // Inform listeners that we've changed.
126 Gatherer.c_man.getCollection().msm.fireValueChanged(element, null, this);
127 }
128 return value_node;
129 }
130
131 public Document getDocument() {
132 return ((GValueNode)root).getElement().getOwnerDocument();
133 }
134
135 public ElementWrapper getElement() {
136 return element;
137 }
138
139 /** Retrieve the hindex for a certain value within the value tree.
140 * @param value The value whose index you wish to determine as a <strong>String</strong>.
141 * @return A <strong>String</strong> containing an index such as "1", "2.1" or "18.2.5".
142 */
143 public String getHIndex(String value) {
144 ///ystem.err.println("getHIndex(" + value + ")");
145 return getHIndex((GValueNode) root, value, null);
146 }
147
148 /** Retrieve a value node given its hierarchical reference or value.
149 * @param index The hierarchy index or value as a <strong>String</strong>.
150 */
151 public GValueNode getValue(String index_str) {
152 ///ystem.err.println("Retrieve the value for: " + index_str);
153 GValueNode result = null;
154 if(isHierarchy() && Utility.isIndex(index_str)) {
155 // StringTokenize the index
156 StringTokenizer tokenizer = new StringTokenizer(index_str, ".");
157 result = (GValueNode) root;
158 // Using the index numbers retrieve the appropriate node.
159 try {
160 while(result != null && tokenizer.hasMoreTokens()) {
161 int index = Integer.parseInt(tokenizer.nextToken()) - 1;
162 // Retrieve the index'th child of the current result node
163 if(0 <= index && index < result.getChildCount()) {
164 result = (GValueNode) result.getChildAt(index);
165 }
166 // Otherwise we're broken.
167 else {
168 ///ystem.err.println("There is no " + index + "th childnode of " + result);
169 result = null;
170 }
171 }
172 }
173 // Most likely caused by parseInt throwing a wobbly.
174 catch (Exception error) {
175 result = null;
176 }
177 }
178 if(result == null) {
179 ///ystem.err.println("No existing value. Adding " + index_str);
180 result = addValue(index_str);
181 }
182 return result;
183 }
184
185 public boolean isHierarchy() {
186 boolean result = false;
187 // We are a hierarchy if our element says so....
188 if(element.isHierarchy()) {
189 return true;
190 }
191 // Or if our children are actually a hierarchy.
192 for(int i = 0; i < root.getChildCount() && !result; i++) {
193 GValueNode node = (GValueNode) root.getChildAt(i);
194 if(node != null && node.getChildCount() > 0) {
195 result = true;
196 }
197 }
198 return result;
199 }
200
201 public void removeValue(GValueNode child) {
202 //SynchronizedTreeModelTools.removeNodeFromParent(this, child);
203 removeNodeFromParent(child);
204 Gatherer.c_man.getCollection().msm.fireValueChanged(new ElementWrapper(child.getElement()), null, this);
205 }
206
207 public void removeValue(String value) {
208 // Retrieve the node to be removed.
209 GValueNode node = getValue(value);
210 if(node != null) {
211 removeValue(node);
212 }
213 }
214
215 public int size() {
216 return size(root);
217 }
218
219 private int size(TreeNode current) {
220 int size = 1;
221 for(int i = 0; i < current.getChildCount(); i++) {
222 size = size + size(current.getChildAt(i));
223 }
224 return size;
225 }
226
227 public String toString() {
228 return element.toString();
229 }
230
231 public Vector traverseTree() {
232 Vector contents = new Vector();
233 contents.addAll(traverseTree((GValueNode) root));
234 contents.remove((GValueNode) root);
235 return contents;
236 }
237
238 private GValueModel copy() {
239 Element document_element = ((GValueNode) root).getElement();
240 Document document_copy = MSMUtils.getValueTreeTemplate();
241 Element document_copy_element = document_copy.getDocumentElement();
242 document_copy_element.setAttribute("element", element.getName());
243 for(Node node = document_element.getFirstChild(); node != null; node = node.getNextSibling()) {
244 if(node.getNodeName().equals("Subject")) {
245 Node node_copy = document_copy.importNode(node, true);
246 document_copy_element.appendChild(node_copy);
247 }
248 }
249 return new GValueModel(element, document_copy);
250 }
251
252 private String getHIndex(GValueNode node, String value, String index) {
253 ///ystem.err.println("Get the HIndex for: " + value);
254 for(int i = node.size(); i != 0; i--) {
255 GValueNode next = (GValueNode)node.get(i - 1);
256 String next_str = next.toString(GValueNode.DOM);
257 ///ystem.err.println("Does " + value + " start with " + next_str + "?");
258 if(value.startsWith(next_str)) {
259 if(index == null) {
260 index = String.valueOf(i);
261 }
262 else {
263 index = index + "." + i;
264 }
265 value = value.substring(next.toString().length());
266 ///ystem.err.println("We matched the start so value is now: " + value);
267 if(value.startsWith(StaticStrings.PIPE_STR) || value.startsWith(StaticStrings.ESCAPE_STR)) {
268 value = value.substring(1);
269 index = getHIndex(next, value, index);
270 }
271 ///ystem.err.println("Returning " + index);
272 return index;
273 }
274 }
275 ///ystem.err.println("Returning " + index);
276 return index;
277 }
278
279 private Vector traverseTree(GValueNode node) {
280 Vector contents = new Vector();
281 contents.add(node);
282 for(int i = 0; i < node.getChildCount(); i++) {
283 contents.addAll(traverseTree((GValueNode)node.getChildAt(i)));
284 }
285 return contents;
286 }
287}
Note: See TracBrowser for help on using the repository browser.