source: trunk/gsdl3/src/java/org/greenstone/gsdl3/gs3build/classifier/AbstractHierarchyNode.java@ 7268

Last change on this file since 7268 was 7268, checked in by cs025, 20 years ago

Updated Hierarchy classifiers; small other changes

  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1package org.greenstone.gsdl3.gs3build.classifier;
2
3import java.util.List;
4import java.util.ArrayList;
5import java.util.Iterator;
6
7import java.sql.ResultSet;
8import java.sql.SQLException;
9
10import org.greenstone.gsdl3.gs3build.doctypes.DocumentID;
11
12import org.greenstone.gsdl3.gs3build.util.GS3SQLConnection;
13import org.greenstone.gsdl3.gs3build.database.*;
14
15public abstract class AbstractHierarchyNode
16{
17 String prefix; // a basic prefix used in this hierarchy
18 String descriptor; // the textual descriptor used on screen or long-hand
19 String name; // the index number, letter assignment or other item
20 // used to identify the position of the item in the
21 // hierarchy
22 String id; // an identifier used by the GLI for maintenance
23 // purposes; this plays no active role in the
24 // rebuilding process (at the moment)
25 List childNodes; // the child classification nodes of this node
26 List childDocs; // the child documents of this node
27 List matches; // the other metadata values that may be matched
28 // against the classifier
29 AbstractHierarchyNode parent; // the parent of the node
30
31 class AbstractHierarchyDocument
32 { DocumentID documentId;
33 String sortKey;
34
35 public AbstractHierarchyDocument(DocumentID documentId, String sortKey)
36 { this.documentId = documentId;
37 this.sortKey = sortKey;
38 }
39
40 public DocumentID getID()
41 { return this.documentId;
42 }
43
44 public String toString()
45 { return this.sortKey;
46 }
47 }
48
49 /**
50 * Simple node
51 */
52 public AbstractHierarchyNode()
53 { this.descriptor = "";
54 this.name = "";
55 this.id = "";
56 this.prefix = "";
57 this.childNodes = new ArrayList();
58 this.childDocs = new ArrayList();
59 this.parent = null;
60 this.matches = new ArrayList();
61 }
62
63 public AbstractHierarchyNode(String prefix, String name, String id, String descriptor)
64 { this.descriptor = descriptor;
65 this.name = name;
66 this.id = id;
67 this.prefix = prefix;
68 this.childNodes = new ArrayList();
69 this.childDocs = new ArrayList();
70 this.parent = null;
71 this.matches = new ArrayList();
72 this.matches.add(this.id);
73 this.matches.add(this.name);
74 }
75
76 public void addChild(AbstractHierarchyNode child)
77 { this.childNodes.add(child);
78 child.setParent(this);
79
80 /**
81 if (this.id == null) {
82 System.out.println(child.id.toString() + " added to root");
83 }
84 else {
85 System.out.println(child.id.toString() + " added to " + this.id);
86 }
87 */
88 }
89
90 public boolean add(AbstractHierarchyNode child)
91 { if (this.id != null && this.id.length() > 0 &&
92 !child.id.startsWith(this.id + "."))
93 { return false;
94 }
95
96 Iterator subNodes = this.childNodes.iterator();
97 while (subNodes.hasNext()) {
98 AbstractHierarchyNode subNode = (AbstractHierarchyNode) subNodes.next();
99
100 if (subNode.add(child)) {
101 return true;
102 }
103 }
104
105 this.addChild(child);
106 return true;
107 }
108
109 public void addDocument(DocumentID document, String sortKey)
110 { this.childDocs.add(new AbstractHierarchyDocument(document, sortKey));
111
112 if (sortKey != null) {
113 int first = 0;
114 int last = this.childDocs.size() - 1;
115
116 while (first != last) {
117 int at = (first + last) / 2;
118
119 if (this.childDocs.get(at) == null) {
120 last = at;
121 continue;
122 }
123
124 if (this.childDocs.get(at).toString().compareTo(sortKey) > 0) {
125 last = at;
126 }
127 else {
128 first = at + 1;
129 }
130 }
131
132 Object newItem = this.childDocs.get(this.childDocs.size() - 1);
133 last = this.childDocs.size() - 1;
134 while (last > first) {
135 this.childDocs.set(last, this.childDocs.get(last-1));
136 last --;
137 }
138 this.childDocs.set(first, newItem);
139 }
140 }
141
142 public void setParent(AbstractHierarchyNode parent)
143 { this.parent = parent;
144 }
145
146 public AbstractHierarchyNode getParent()
147 { return this.parent;
148 }
149
150 public String getParentId()
151 {
152 if (this.id == null) {
153 return "";
154 }
155
156 int dotAt = this.id.lastIndexOf('.');
157 if (dotAt < 0) {
158 return "";
159 }
160 return this.id.substring(0, dotAt);
161 }
162
163 public void setDescriptor(String descriptor)
164 { this.descriptor = descriptor;
165 }
166
167 public void setID(String id)
168 { this.id = id;
169 this.matches.add(id);
170 }
171
172 public String getID()
173 { return this.id;
174 }
175
176 public int noOfChildDocs()
177 { return this.childDocs.size();
178 }
179
180 public int noOfLeafDocs()
181 { int total = this.childDocs.size();
182
183 Iterator iterator = this.childNodes.iterator();
184 while (iterator.hasNext()) {
185 AbstractHierarchyNode childNode = (AbstractHierarchyNode) iterator.next();
186
187 total += childNode.noOfLeafDocs();
188 }
189
190 return total;
191 }
192
193 /**
194 * Set the name for this hierarchy node - i.e. its brief description
195 *
196 * @param <code>String</code> the new node name.
197 */
198 public void setName(String name)
199 { this.name = name;
200 }
201
202 /**
203 * Get the name for this hierarchy node - i.e. its brief description
204 *
205 * @return <code>String</code> the node's name.
206 */
207 public String getName()
208 { return this.name;
209 }
210
211 /**
212 * Add another string which can be used to describe this hierarchy node - i.e. one which if
213 * found in a document would indicate that that document belongs to this hierarchy node.
214 *
215 * @param <code>String</code> the string to match.
216 */
217 public void addMatch(String match)
218 { this.matches.add(match);
219 }
220
221 /**
222 * Check if a given string matches any of the values given for this hierarchy node...
223 *
224 * @param <code>String</code> the descriptive string to be compared against the hierarchy
225 * @return <code>boolean</code> <code>true</code> whether the string matches this hierarchy
226 */
227 public boolean isMatch (String toMatch)
228 { Iterator thisMatch = this.matches.iterator();
229
230 while (thisMatch.hasNext())
231 { String thisMatchText = thisMatch.next().toString();
232
233 if (thisMatchText.equals(toMatch))
234 { return true;
235 }
236 }
237 return false;
238 }
239
240 /**
241 * Take a document, and find the classifications that it matches against in
242 * the current hierarchy.
243 *
244 * @param <code>DocumentID</code> the id of the document being classified
245 * @param <code>List</code> the values against which the classifier should
246 * test for the document being a match - i.e. the pertinent document
247 * property values.
248 * @param <code>ClassifierObserverInterface</code>
249 * object modifies the document with information about the
250 * classifications that it fell within.
251 */
252 abstract public void getClassifications(DocumentID documentID, List values, String sortKey,
253 ClassifierObserverInterface observer);
254
255 public boolean writeSQL(GS3SQLConnection connection)
256 {
257 int classifyRef;
258 GS3SQLAction action = null;
259 GS3SQLSelect select;
260 GS3SQLInsert insert;
261
262 // Get own full id
263 String fullId = this.id.length() > 0 ? this.prefix+"."+this.id : this.prefix;
264
265 // check for an existing instance of this classifier
266 select = new GS3SQLSelect("classifiers");
267 select.addField("ClassifyRef");
268 GS3SQLWhereItem whereItem = new GS3SQLWhereItem("ClassifyID", "=", fullId);
269 GS3SQLWhere where = new GS3SQLWhere(whereItem);
270 select.setWhere(where);
271
272 connection.execute(select.toString());
273
274 // update or insert the classifier as required
275 try {
276 ResultSet results = connection.getResultSet();
277 if (results != null && results.first()) {
278 GS3SQLUpdate update = new GS3SQLUpdate("classifiers");
279 update.setWhere(where);
280 action = update;
281
282 classifyRef = results.getInt("ClassifyRef");
283 }
284 else {
285 insert = new GS3SQLInsert("classifiers");
286
287 if (this.id == null || this.id.length() == 0) {
288 insert.addValue("ParentID", "");
289 }
290 else {
291 String parentId = this.getParentId();
292
293 if (parentId.length() > 0) {
294 insert.addValue("ParentID", this.prefix+"."+this.getParentId());
295 }
296 else {
297 insert.addValue("ParentID", this.prefix);
298 }
299 }
300
301 action = insert;
302 }
303 action.addValue("ClassifyID", fullId);
304 action.addValue("Name", this.name);
305 action.addValue("Description", this.descriptor);
306
307 String tailId = "0";
308 if (this.id.length() > 0) {
309 int lastDot = this.id.lastIndexOf('.');
310 if (lastDot >= 0) {
311 tailId = this.id.substring(lastDot+1);
312 }
313 else {
314 tailId = this.id;
315 }
316 }
317 action.addValue("ClassifyOrder", tailId, GS3SQLField.INTEGER_TYPE);
318 action.addValue("NumLeafDocs", Integer.toString(this.noOfLeafDocs()), GS3SQLField.INTEGER_TYPE);
319
320 connection.execute(action.toString());
321 classifyRef = -1;
322 }
323 catch (SQLException sqlEx) {
324 if (action == null) {
325 System.err.println(sqlEx);
326 }
327 else {
328 System.err.println(sqlEx + " " + action.toString());
329 }
330 return false;
331 }
332
333 // get the ClassifyRef if we don't already have it (have done a
334 // insert action above)...
335 if (classifyRef == -1) {
336 connection.execute(select.toString());
337
338 try {
339 ResultSet results = connection.getResultSet();
340 if (results == null || !results.first()) {
341 return false;
342 }
343
344 classifyRef = results.getInt("ClassifyRef");
345 }
346 catch (SQLException sqlEx) {
347 System.err.println(sqlEx);
348 return false;
349 }
350 }
351 else {
352 // TODO: clear 'dead' child classifications
353
354 // delete child documents
355 GS3SQLDelete delete = new GS3SQLDelete("classdocuments");
356 delete.setWhere(where);
357
358 connection.execute(delete.toString());
359 }
360
361 // post the child nodes...
362 Iterator iterator = this.childNodes.iterator();
363 while (iterator.hasNext()) {
364 AbstractHierarchyNode childNode = (AbstractHierarchyNode) iterator.next();
365
366 if (!childNode.writeSQL(connection)) {
367 System.out.println("Failed to write " );
368 return false;
369 }
370 }
371
372 // note the child documents...
373 iterator = this.childDocs.iterator();
374 int order = 1;
375 while (iterator.hasNext()) {
376 AbstractHierarchyDocument hierarchyDoc = (AbstractHierarchyDocument) iterator.next();
377 DocumentID docId = hierarchyDoc.getID();
378
379 insert = new GS3SQLInsert("classdocuments");
380 insert.addValue("ClassifyRef", Integer.toString(classifyRef), GS3SQLField.INTEGER_TYPE);
381 insert.addValue("DocID", docId.toString());
382 insert.addValue("DocOrder", Integer.toString(order), GS3SQLField.INTEGER_TYPE);
383
384 connection.execute(insert.toString());
385
386 order ++;
387 }
388 return true;
389 }
390}
391
392
Note: See TracBrowser for help on using the repository browser.