source: trunk/gsdl3/src/java/org/greenstone/gsdl3/gs3build/metadata/METSDivision.java@ 6103

Last change on this file since 6103 was 6017, checked in by cs025, 21 years ago

Improved field names in database

  • Property svn:keywords set to Author Date Id Revision
File size: 15.6 KB
Line 
1package org.greenstone.gsdl3.gs3build.metadata;
2
3import java.io.PrintWriter;
4
5import java.util.Iterator;
6import java.util.List;
7import java.util.ArrayList;
8import java.util.Map;
9import java.util.HashMap;
10
11import java.sql.SQLException;
12import java.sql.ResultSet;
13
14import org.greenstone.gsdl3.gs3build.doctypes.DocumentID;
15import org.greenstone.gsdl3.gs3build.util.XMLTools;
16import org.greenstone.gsdl3.gs3build.util.GS3SQLConnection;
17import org.greenstone.gsdl3.gs3build.database.*;
18
19
20public class METSDivision
21{
22 String ID; // the unique identifier for this division (unique within the
23 // document, not necessarily unique within the collection).
24 String order; // see the METS documentation for the meaning of the different
25 String orderLabel; // label types.
26 String userLabel;
27 String type; // e.g. section, chapter, physical or logical, etc.
28 List metadataRefs;
29 List adminRefs;
30 List fileRefs;
31 Map children;
32
33 public static final String STRUCTURE_PARENT = "Structure";
34 public static final String DIVISION_PARENT = "Division";
35
36 public METSDivision(String ID, String order, String orderLabel, String userLabel, String type)
37 { this.ID = ID;
38 this.order = order;
39 this.orderLabel = orderLabel;
40 this.userLabel = userLabel;
41 this.type = type;
42 this.fileRefs = new ArrayList();
43 this.metadataRefs = new ArrayList();
44 this.children = new HashMap();
45 }
46
47 public String getID()
48 { return this.ID;
49 }
50
51 /**
52 * Find all the divisions that match a given list of file group
53 * identifiers...
54 *
55 * @param <code>List</code> the list of identifiers to find
56 * @param <code>List</code> the list into which to place any
57 * matching divisions.
58 */
59 public void findDivisionsForFiles(List listOfFileIdentifiers, List resultList)
60 { Iterator iterator = this.fileRefs.iterator();
61
62 // get the references on this division, and mark if necessary
63 while (iterator.hasNext())
64 { String reference = iterator.next().toString();
65
66 Iterator fileIterator = listOfFileIdentifiers.iterator();
67 while (fileIterator.hasNext())
68 { String fileRef = fileIterator.next().toString();
69
70 if (fileRef.equals(reference))
71 { resultList.add(this);
72 }
73 }
74 }
75
76 // get the child groups, and check each in turn...
77 Iterator groups = this.children.values().iterator();
78 while (groups.hasNext())
79 { METSDivision group = (METSDivision) groups.next();
80
81 group.findDivisionsForFiles(listOfFileIdentifiers, resultList);
82 }
83 }
84
85 /**
86 * Get the namespace from the given set of descriptive blocks...
87 */
88 public METSNamespace findNamespace(String namespaceName, boolean isOpenNamespace,
89 METSDescriptiveSet descriptiveSet)
90 { METSNamespace namespace = null;
91
92 // Special case - no existing metadata references
93 if (this.metadataRefs.size() == 0) {
94 // Create new Descriptive and add it to the descriptive set
95 METSDescriptive descriptive = new METSDescriptive("DM"+this.ID, this.orderLabel);
96 descriptiveSet.addDescriptive(descriptive);
97
98 // Create the namespace and add it to the Descriptive
99 namespace = NamespaceFactory.initNamespace(namespaceName);
100 if (namespace != null)
101 { descriptive.addNamespace(namespace);
102 }
103
104 return namespace;
105 }
106
107 Iterator descriptiveIterator = this.metadataRefs.iterator();
108
109 while (descriptiveIterator.hasNext())
110 { String descriptiveRef = descriptiveIterator.next().toString();
111
112 METSDescriptive descriptive = descriptiveSet.getDescriptiveById(descriptiveRef);
113
114 if (isOpenNamespace) {
115 namespace = descriptive.getOpenNamespace(namespaceName);
116 }
117 else {
118 namespace = descriptive.getNamespace(namespaceName);
119 }
120
121 if (namespace != null)
122 break;
123 }
124
125 // Special case - no such namespace in any descriptive list...
126 if (namespace == null)
127 { // take the first descriptive area...
128 METSDescriptive descriptive = descriptiveSet.getDescriptiveById(this.metadataRefs.get(0).toString());
129
130 // create the namespace, and add it to the METSDescriptive
131 namespace = NamespaceFactory.initNamespace(namespaceName);
132 if (namespace != null)
133 { descriptive.addNamespace(namespace);
134 }
135 }
136
137 return namespace;
138 }
139
140 /**
141 * Add a new file reference to the structure
142 *
143 * @param <code>METSFileRef</code> the file to be referenced.
144 */
145 public void addFileReference(METSFileID fileRef)
146 { this.fileRefs.add(fileRef);
147 }
148
149 /**
150 * Add a new metadata reference to the structure
151 */
152 public void addMetadataReference(String metadataRef)
153 { // TODO: correct the type
154 this.metadataRefs.add(metadataRef);
155 }
156
157 /**
158 * Add a child division, or sub-division to the document. For example,
159 * sections within a chapter.
160 *
161 * @param <code>METSDivision</code> the child division.
162 */
163 public void addSubDivision(METSDivision child)
164 { this.children.put(child.getID(), child);
165 }
166
167 /**
168 * Add a child division to a descendent of this division.
169 *
170 * @param <code>String</code> the path to the division into which the
171 * subdivision will be added.
172 * @param <code>METSDivision</code> the division to be added
173 */
174 public void addSubDivision(String divisionID, METSDivision division)
175 { String topDivision = METSDivision.getTopDivisionName(divisionID);
176
177 METSDivision child = (METSDivision) this.children.get(topDivision);
178 if (child == null)
179 { return;
180 }
181
182 String subDivisionID = METSDivision.getSubDivisionName(divisionID);
183 if (subDivisionID == null)
184 { child.addSubDivision(division);
185 }
186 else
187 { child.addSubDivision(subDivisionID, division);
188 }
189 }
190
191 public METSDivision getDivision(String divisionID)
192 { String topDivision = METSDivision.getTopDivisionName(divisionID);
193
194 METSDivision child = (METSDivision) this.children.get(topDivision);
195 if (child == null)
196 { return null;
197 }
198
199 String subDivision = METSDivision.getSubDivisionName(divisionID);
200 if (subDivision != null)
201 { child = child.getDivision(subDivision);
202 }
203
204 return child;
205 }
206
207 public static String getSubDivisionName(String divisionName)
208 { int at = divisionName.indexOf('.');
209
210 if (at >= 0)
211 { return divisionName.substring(at+1);
212 }
213 else
214 { return null;
215 }
216 }
217
218 public static String getTopDivisionName(String divisionName)
219 { int at = divisionName.indexOf('.');
220
221 if (at >= 0)
222 { return divisionName.substring(0, at);
223 }
224 else
225 { return divisionName;
226 }
227 }
228
229 /**
230 * Write the METS file in an XML to a text-output sink
231 *
232 * @param <code>PrintWriter</code> the destination of the output
233 */
234 public void write(PrintWriter writer)
235 { String tag = XMLTools.getOpenTag("mets", "div");
236 tag = XMLTools.addAttribute(tag, "ID", this.ID.toString());
237 tag = XMLTools.addAttribute(tag, "TYPE", this.type);
238 tag = XMLTools.addAttribute(tag, "ORDER", this.order);
239 if (this.orderLabel != null)
240 { tag = XMLTools.addAttribute(tag, "ORDERLABEL", this.orderLabel);
241 }
242 if (this.userLabel != null)
243 { tag = XMLTools.addAttribute(tag, "LABEL", this.userLabel);
244 }
245 writer.println(tag);
246
247 // write the list of file pointers for this structural element
248 if (this.fileRefs.size() > 0)
249 { tag = XMLTools.getOpenTag("mets", "fptr");
250
251 String fileList = this.writeList(this.fileRefs);
252
253 tag = XMLTools.addAttribute(tag, "FILEID", fileList);
254
255 tag = XMLTools.makeSingleton(tag);
256 writer.println(tag);
257 }
258
259 // ..and then the metadata - this is the same code at present,
260 // but is replicated here in case of future amendment.
261 if (this.metadataRefs.size() > 0)
262 { tag = XMLTools.getOpenTag("mets", "mptr");
263
264 String metaList = this.writeList(this.metadataRefs);
265 tag = XMLTools.addAttribute(tag, "METAID", metaList);
266 tag = XMLTools.makeSingleton(tag);
267 writer.println(tag);
268 }
269
270 // close the div element
271 writer.println(XMLTools.getCloseTag("mets", "div"));
272 }
273
274 private String writeList(List list)
275 { StringBuffer listString = new StringBuffer();
276
277 Iterator iterator = list.iterator();
278 while (iterator.hasNext())
279 { String item = iterator.next().toString();
280 if (listString.length() > 0)
281 { listString.append(" ");
282 }
283 listString.append(item);
284 }
285 return listString.toString();
286 }
287
288 public boolean writeSQL(DocumentID docId, int parentRef, boolean parentIsStructure,
289 GS3SQLConnection connection)
290 { int sqlRef = -1;
291
292 // set the "where" to find the reference for this division
293 GS3SQLSelect select = new GS3SQLSelect("divisions");
294 select.addField("DivisionRef");
295 GS3SQLWhereItem whereItem = new GS3SQLWhereItem("ParentRef", "=", Integer.toString(parentRef), GS3SQLField.INTEGER_TYPE);
296 GS3SQLWhereItem parentItem = new GS3SQLWhereItem("ParentType", "=", parentIsStructure ? "Structure" : "Division");
297 GS3SQLWhereItem item = new GS3SQLWhereItem("SectionID", "=", this.ID.toString());
298 GS3SQLWhere where = new GS3SQLWhere(whereItem);
299 where.add(parentItem);
300 where.add(item);
301 select.setWhere(where);
302
303 connection.execute(select.toString());
304
305 // Do the actual writing
306 GS3SQLAction action;
307
308 ResultSet resultSet = connection.getResultSet();
309 try {
310 if (resultSet == null ||
311 !resultSet.first())
312 { resultSet = null;
313
314 GS3SQLInsert insert = new GS3SQLInsert("divisions");
315 insert.addValue("DocID", docId.toString());
316 insert.addValue("SectionID", this.ID.toString());
317 insert.addValue("ParentRef", Integer.toString(parentRef));
318 insert.addValue("ParentType", parentIsStructure == true ? STRUCTURE_PARENT : DIVISION_PARENT);
319
320 action = insert;
321 }
322 else {
323 sqlRef = resultSet.getInt("DivisionRef");
324
325 GS3SQLUpdate update = new GS3SQLUpdate("divisions");
326 GS3SQLWhere updateWhere =
327 new GS3SQLWhere(new GS3SQLWhereItem("DivisionRef", "=", Integer.toString(sqlRef),
328 GS3SQLField.INTEGER_TYPE));
329 update.setWhere(updateWhere);
330 action = update;
331 }
332 }
333 catch (SQLException sql) {
334 System.err.println(sql);
335 return false;
336 }
337
338 action.addValue("DivisionType", this.type.toString());
339 action.addValue("LabelOrder", this.order);
340 action.addValue("ShortLabel", this.orderLabel);
341 action.addValue("UserLabel", this.userLabel);
342
343 if (!connection.execute(action.toString()))
344 { return false;
345 }
346
347 // if doing a fresh item, get the new structure reference...
348 if (resultSet == null)
349 { // get the new structure reference
350 connection.execute(select.toString());
351
352 // get the sql reference for the division
353 try {
354 // read in the structure reference
355 resultSet = connection.getResultSet();
356 if (resultSet == null) {
357 return false;
358 }
359 resultSet.first();
360 sqlRef = resultSet.getInt("DivisionRef");
361 resultSet.close();
362 resultSet = null;
363 }
364 catch (SQLException sqlex) {
365 System.err.println("Unable to retrieve reference for Division " + sqlex);
366 return false;
367 }
368 }
369 // close the open resultSet, as we don't need it any longer...
370 else {
371 try {
372 resultSet.close();
373 }
374 catch (SQLException sql) {
375 System.err.println(sql);
376 }
377 }
378
379 // delete the old file/metadata references
380 GS3SQLWhere referenceWhere =
381 new GS3SQLWhere(new GS3SQLWhereItem("DivisionRef", "=", Integer.toString(sqlRef),
382 GS3SQLField.INTEGER_TYPE));
383
384 GS3SQLDelete delete = new GS3SQLDelete("divisionfilerefs");
385 delete.setWhere(referenceWhere);
386 connection.execute(delete.toString());
387
388 delete = new GS3SQLDelete("divisionmetarefs");
389 delete.setWhere(referenceWhere);
390 connection.execute(delete.toString());
391
392 // write the new file references
393 if (this.fileRefs.size() > 0)
394 { Iterator iterator = this.fileRefs.iterator();
395
396 while (iterator.hasNext())
397 { GS3SQLInsert fileinsert = new GS3SQLInsert("divisionfilerefs");
398 fileinsert.addValue("DocID", docId.toString());
399 fileinsert.addValue("DivisionRef", Integer.toString(sqlRef), GS3SQLField.INTEGER_TYPE);
400 fileinsert.addValue("DivisionType", "Group");
401 fileinsert.addValue("FileID", iterator.next().toString());
402 connection.execute(fileinsert.toString());
403 }
404 }
405
406 // write the metadata references
407 if (this.metadataRefs.size() > 0)
408 { Iterator iterator = this.metadataRefs.iterator();
409
410 while (iterator.hasNext())
411 { GS3SQLInsert metainsert = new GS3SQLInsert("divisionmetarefs");
412 metainsert.addValue("DocID", docId.toString());
413 metainsert.addValue("DivisionRef", Integer.toString(sqlRef), GS3SQLField.INTEGER_TYPE);
414 metainsert.addValue("DivisionType", "Group");
415 metainsert.addValue("MetaID", iterator.next().toString());
416 connection.execute(metainsert.toString());
417 }
418 }
419
420 // write out any children in turn
421 Iterator groups = this.children.values().iterator();
422
423 while (groups.hasNext())
424 { METSDivision group = (METSDivision) groups.next();
425
426 if (!group.writeSQL(docId, sqlRef, false, connection)) {
427 return false;
428 }
429 }
430 return true;
431 }
432
433 public static METSDivision readSQL(GS3SQLConnection connection, ResultSet resultSet)
434 {
435 METSLocation metsLocation = null;
436
437 try {
438 // read the basic information
439 String ID = resultSet.getString("SectionID");
440 String type = resultSet.getString("DivisionType");
441 String order = resultSet.getString("LabelOrder");
442 String orderLabel = resultSet.getString("ShortLabel");
443 String userLabel = resultSet.getString("UserLabel");
444
445 // construct the division object
446 METSDivision division = new METSDivision(ID, order, orderLabel, userLabel, type);
447
448 // obtain a list of child divisions
449 int divisionRef = resultSet.getInt("DivisionRef");
450
451 GS3SQLSelect select = new GS3SQLSelect("divisions");
452 select.addField("*");
453 GS3SQLWhereItem whereItem = new GS3SQLWhereItem("ParentRef", "=", Integer.toString(divisionRef),
454 GS3SQLField.INTEGER_TYPE);
455 GS3SQLWhere where = new GS3SQLWhere(whereItem);
456 whereItem = new GS3SQLWhereItem("ParentType", "=", DIVISION_PARENT);
457 where.add(whereItem);
458 select.setWhere(where);
459
460 connection.execute(select.toString());
461
462 // circulate through to obtain further children
463 ResultSet childSet = connection.getResultSet();
464 if (childSet.first())
465 {
466 do {
467 METSDivision childDivision = METSDivision.readSQL(connection, childSet);
468 division.addSubDivision(childDivision);
469 }
470 while (childSet.next());
471 }
472
473 select = new GS3SQLSelect("divisionfilerefs");
474 select.addField("*");
475 where = new GS3SQLWhere(new GS3SQLWhereItem("DivisionRef", "=", Integer.toString(divisionRef),
476 GS3SQLField.INTEGER_TYPE));
477 select.setWhere(where);
478
479 connection.execute(select.toString());
480
481 ResultSet fileSet = connection.getResultSet();
482 if (fileSet != null && fileSet.first())
483 { do
484 { String reference = fileSet.getString("FileID");
485 division.fileRefs.add(reference);
486 }
487 while (fileSet.next());
488 }
489
490 select = new GS3SQLSelect("divisionmetarefs");
491 select.addField("*");
492 where = new GS3SQLWhere(new GS3SQLWhereItem("DivisionRef", "=", Integer.toString(divisionRef),
493 GS3SQLField.INTEGER_TYPE));
494 select.setWhere(where);
495
496 connection.execute(select.toString());
497
498 ResultSet metaSet = connection.getResultSet();
499 if (metaSet != null && metaSet.first())
500 { do
501 { String reference = metaSet.getString("MetaID");
502 division.metadataRefs.add(reference);
503 }
504 while (metaSet.next());
505 }
506
507 return division;
508 }
509 catch (SQLException sqlEx)
510 { System.out.println(sqlEx);
511 }
512 return null;
513 }
514}
Note: See TracBrowser for help on using the repository browser.