source: trunk/gsdl3/src/java/org/greenstone/gsdl3/gs3build/doctypes/AbstractDocument.java@ 7186

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

Minor adjustments to support date of accession.

  • Property svn:keywords set to Author Date Id Revision
File size: 13.5 KB
Line 
1package org.greenstone.gsdl3.gs3build.doctypes;
2
3import java.util.List;
4import java.util.ArrayList;
5import java.util.Iterator;
6import java.util.HashMap;
7import java.util.Map;
8import java.util.Date;
9
10import java.sql.SQLException;
11import java.sql.ResultSet;
12import java.sql.Timestamp;
13
14import java.net.URL;
15
16import org.greenstone.gsdl3.gs3build.metadata.NamespaceFactory;
17import org.greenstone.gsdl3.gs3build.metadata.StructureIdentifierFactory;
18import org.greenstone.gsdl3.gs3build.metadata.GSDL3Namespace;
19import org.greenstone.gsdl3.gs3build.metadata.METSDescriptiveSet;
20import org.greenstone.gsdl3.gs3build.metadata.METSFile;
21import org.greenstone.gsdl3.gs3build.metadata.METSFileSet;
22import org.greenstone.gsdl3.gs3build.metadata.METSHeader;
23import org.greenstone.gsdl3.gs3build.metadata.METSStructure;
24import org.greenstone.gsdl3.gs3build.metadata.METSStructureSet;
25import org.greenstone.gsdl3.gs3build.metadata.METSDivision;
26import org.greenstone.gsdl3.gs3build.metadata.METSNamespace;
27import org.greenstone.gsdl3.gs3build.metadata.MetadataLabel;
28
29import org.greenstone.gsdl3.gs3build.util.MultiMap;
30import org.greenstone.gsdl3.gs3build.util.GS3SQLConnection;
31
32/**
33 * Provide a base-line functionality for the <code>DocumentInterface</code>
34 * class.
35 */
36
37public abstract class AbstractDocument implements DocumentInterface
38{
39 METSFileSet fileSet;
40 METSDescriptiveSet metadata;
41 METSStructureSet structureSet;
42 METSHeader header;
43 DocumentID id;
44 boolean isModified;
45 StructureIdentifierFactory structureIdFactory;
46 java.sql.Timestamp firstDate;
47 java.sql.Timestamp indexDate;
48
49 /**
50 * <p>Create a very vanilla document with a given document identifier.</p>
51 * <p>Most commonly used in dealing with loading files using DocumentFactory
52 * or similar.</p>
53 *
54 * @param <code>DocumentID</code> the document identifier
55 */
56 public AbstractDocument(DocumentID id)
57 { this.fileSet = new METSFileSet();
58 this.metadata = new METSDescriptiveSet();
59 this.header = new METSHeader();
60 this.structureSet = new METSStructureSet();
61 this.id = id;
62 this.structureIdFactory = new StructureIdentifierFactory();
63
64 java.util.Date thisDate = new java.util.Date();
65 this.firstDate = new java.sql.Timestamp(thisDate.getTime());
66 this.indexDate = new java.sql.Timestamp(thisDate.getTime());
67 }
68
69 /**
70 * Create a basic document from a given <code>URL</code. This is usually the form
71 * called through the recognisers.
72 *
73 * @param <code>URL</code> the URL of the first file in the document package
74 */
75 public AbstractDocument(URL url)
76 { this.fileSet = new METSFileSet();
77 METSFile metsFile = this.fileSet.addFile(url);
78 this.metadata = new METSDescriptiveSet();
79 this.header = new METSHeader();
80 this.structureSet = new METSStructureSet();
81 this.id = null;
82
83 java.util.Date thisDate = new java.util.Date();
84 this.firstDate = new java.sql.Timestamp(thisDate.getTime());
85 this.indexDate = new java.sql.Timestamp(thisDate.getTime());
86
87 METSStructure structure = new METSStructure("All", "All", "Whole Document");
88 METSDivision documentBody = new METSDivision("All", "All", "All", "Whole Document", "Document");
89 structure.addDivision(documentBody);
90 this.structureSet.addStructure(structure);
91 documentBody.addFileReference(metsFile.getID());
92 documentBody.addMetadataReference("DM1");
93 }
94
95 /**
96 * Set the identified for the document. Every document should have
97 * a document number set on its accession, either through metadata
98 * placed upon it internally or externally, or by assignment through
99 * a <code>DocumentIDFactory</code>. Each identifier should be
100 * unique.
101 *
102 * @param <code>DocumentID</code> the document identifier - in XML
103 * terms, the gsdl3:id element.
104 */
105 public void setID(DocumentID id)
106 { this.id = id;
107 this.isModified = true;
108 }
109
110 /**
111 * Get the document identifier - this should be unique to the document,
112 * but care must be taken in the configuration of the collection to
113 * ensure that this is the case.
114 *
115 * @return <code>DocumentID</code> the identifer
116 */
117 public DocumentID getID()
118 { return this.id;
119 }
120
121 /**
122 * Indicate whether this document is indexed.
123 *
124 * @see: DocumentInterface.isIndexed
125 */
126 public boolean isIndexed()
127 { return true;
128 }
129
130 /**
131 * Check if this document is in the database already.
132 *
133 * In this simple implementation, the first file in the document's "default"
134 * filegroup is taken to be the canonical file for this document - any document
135 * of the same type with the same canonical file is taken to be a match.
136 *
137 * @return <code>boolean</code> - if a matching document is found in the
138 * database.
139 */
140 public boolean hasDuplicate(GS3SQLConnection connection)
141 { //String query = "SELECT * FROM document INNER JOIN filegroups ON document.docId=filegroups.docId WHERE DocType=\"" + HTML_DOCUMENT_TYPE + "\"";
142
143 // Query for documents using the same file...
144 String query = "SELECT DocID FROM files INNER JOIN filegroups ON files.FileGroupRef=filegroups.FileGroupRef WHERE (filegroups.FileGroupId=\"default\" AND files.FileLocation=\"" + this.fileSet.getFile(0).getLocation().toString() + "\")";
145 connection.execute(query);
146
147 List docs = new ArrayList();
148 ResultSet results = connection.getResultSet();
149
150 try {
151 if (results != null &&
152 results.first())
153 { do {
154 String value = results.getString("DocID");
155
156 docs.add(value);
157 } while (results.next());
158
159 Iterator docIterator = docs.iterator();
160 while (docIterator.hasNext()) {
161 String docId = docIterator.next().toString();
162 String innerQuery = "SELECT * FROM document WHERE DocID=\"" + docId + "\"";
163 connection.execute(innerQuery);
164 ResultSet innerSet = connection.getResultSet();
165 if (innerSet != null && innerSet.first()) {
166 String docType = innerSet.getString("DocType");
167 if (docType.equals(this.getDocumentType())) {
168 return true;
169 }
170 }
171 }
172 }
173 }
174 catch (java.sql.SQLException sqlEx) {
175 System.err.println(sqlEx);
176 }
177
178 return false;
179 }
180
181 /**
182 * Obtain the METS header of this document
183 *
184 * @return <code>METSHeader</code> the header
185 */
186 public METSHeader getHeader()
187 { return this.header;
188 }
189
190 /**
191 * Set the METS header for this document.
192 *
193 * @param <code>METSHeader</code> the header
194 */
195 public void setHeader(METSHeader header)
196 { this.header = header;
197 }
198
199 /**
200 * A simple implementation of the isDocumentType function that does <b>not</b> consider
201 * inheritance - it <code>must</code> be extended as required.
202 */
203 public boolean isDocumentType(String type)
204 { return type.equals(this.getDocumentType());
205 }
206
207 public abstract String getDocumentType();
208
209 public abstract String getDocumentText();
210
211 public abstract String getSectionText(String sectionId);
212
213 public String getMETSType()
214 { return "document";
215 }
216
217 /**
218 * @see DocumentInterface:addDocumentMetadata
219 */
220 public void addDocumentMetadata(MetadataLabel label, String value)
221 { // no need to set isModified, as the following call will do it anyway!
222 this.addDocumentMetadata(label.getNamespace(), label.getLabel(), value);
223 }
224
225 /**
226 * @see DocumentInterface:addDocumentMetadata
227 */
228 public void setDocumentMetadata(MetadataLabel label, String value)
229 { // no need to set isModified, as the following call will do it anyway!
230 this.setDocumentMetadata(label.getNamespace(), label.getLabel(), value);
231 }
232
233 /**
234 * @see DocumentInterface:addDocumentMetadata
235 */
236 public void addDocumentMetadata(String namespace, String label, String value)
237 { this.metadata.addMetadata("default", namespace, label, value);
238 this.isModified = true;
239 }
240
241 /**
242 * @see DocumentInterface:addDocumentMetadata
243 */
244 public void setDocumentMetadata(String namespace, String label, String value)
245 { this.metadata.setMetadata("default", namespace, label, value);
246 this.isModified = true;
247 }
248
249 /**
250 * @see DocumentInterface:removeDocumentMetadata
251 */
252 public void removeDocumentMetadata(String namespace, String label)
253 { this.metadata.removeMetadata("default", namespace, label);
254 this.isModified = true;
255 }
256
257 /**
258 *
259 */
260 public void removeAllMetadata(String namespace, String label)
261 { this.metadata.removeAllMetadata(namespace, label);
262 this.isModified = true;
263 }
264
265 /**
266 * Post metadata to a file in this document - the appropriate changes
267 * should be made...
268 */
269 public void postFileMetadata(URL fileLocation, String namespace, String label, String value)
270 {
271 // First get the list of file groups, etc. that this file is associated with...
272 List fileGroups = this.fileSet.findGroups(fileLocation);
273
274 // Next, get the METS divisions associated with each file group...
275 List divisions = this.structureSet.findDivisionsForFiles(fileGroups);
276
277 // Finally, post the metadata to the metadata group associated with each structure
278 Iterator divisionIter = divisions.iterator();
279 while (divisionIter.hasNext())
280 { METSDivision division = (METSDivision) divisionIter.next();
281
282 // get the open namespace for this division
283 METSNamespace namespaceMetadata = division.findNamespace(namespace, true, this.metadata);
284
285 // then post the metadata to it...
286 namespaceMetadata.addMetadata(label, value);
287 }
288 }
289
290 /**
291 * Get the metadata structure of the document
292 *
293 * @return <code>METSDescriptive</code> the metadata holder for the document.
294 */
295 public METSDescriptiveSet getDocumentMetadata()
296 { return this.metadata;
297 }
298
299 /**
300 * Set the metadata structure for this document
301 *
302 * @param <code>METSDescriptive</code> the new metadata holder for the document.
303 */
304 public void setDocumentMetadata(METSDescriptiveSet metadata)
305 { this.metadata = metadata;
306 this.isModified = true;
307 }
308
309 /**
310 * Get the metadata structure of the document
311 *
312 * @return <code>METSStructureSet</code> the metadata holder for the document.
313 */
314 public METSStructureSet getDocumentStructure()
315 { return this.structureSet;
316 }
317
318 public void setDocumentStructure(METSStructureSet structureSet)
319 { this.structureSet = structureSet;
320 }
321
322 /**
323 * Get the values associated with a particular metadata value.
324 *
325 * @param <code>String</code> the namespace to find the values in.
326 * @param <code>String</code> the label to match to find the values.
327 *
328 * @return <code>List</code> the values.
329 */
330 public List getDocumentMetadataItem(String namespace, String label)
331 { return this.metadata.getMetadata("default", namespace, label);
332 }
333
334 /**
335 * Get the values associated with a particular metadata value.
336 *
337 * @param <code>String</code> the namespace and label separated by a
338 * colon.
339 *
340 * @return <code>List</code> the values.
341 */
342 public List getDocumentMetadataItem(String namespaceLabel)
343 { String namespace, label;
344
345 int colonAt = namespaceLabel.indexOf(':');
346 if (colonAt < 0)
347 { namespace = GSDL3Namespace.GSDL3_NAMESPACE_ID;
348 label = namespaceLabel;
349 }
350 else
351 { namespace = namespaceLabel.substring(0, colonAt);
352 label = namespaceLabel.substring(colonAt+1);
353 }
354 return this.metadata.getMetadata("default", namespace, label);
355 }
356
357 /**
358 * @see DocumentInterface:getDocumentFiles
359 */
360 public METSFileSet getDocumentFiles()
361 { return this.fileSet;
362 }
363
364 public void setDocumentFiles(METSFileSet fileSet)
365 { this.fileSet = fileSet;
366 }
367
368 /**
369 * This is just a dummy function that does nothing at this level...
370 */
371 public org.w3c.dom.Document getDOMDocument()
372 { return null;
373 }
374
375 /**
376 * @see DocumentInterface:isMETSCompatible
377 */
378 public boolean isMETSCompatible()
379 { return true;
380 }
381
382 /**
383 * Use a default document writer - this may be overridden for subclasses...
384 *
385 * @see DocumentInterface:writeMETSObject
386 */
387 public DocumentWriter getMETSWriter()
388 { return new DocumentWriter();
389 }
390
391 /**
392 * Use a default SQL document writer - this may be overridden for subclasses...
393 *
394 */
395 public DocumentSQLWriter getSQLWriter()
396 { return new DocumentSQLWriter();
397 }
398
399 /**
400 * Obtain a document from the SQL database
401 */
402 public static AbstractDocument readSQL(GS3SQLConnection connection, ResultSet sqlResult)
403 { try {
404 DocumentID id = new DocumentID(sqlResult.getString("DocID"));
405 String type = sqlResult.getString("docType");
406
407 // Use a factory method to create the correct subtype...
408 AbstractDocument document = DocumentFactory.createDocument(type, id);
409
410 // Append the document date information
411 document.indexDate = sqlResult.getTimestamp("IndexedDate");
412 document.firstDate = sqlResult.getTimestamp("AccessionDate");
413
414 // Get the individual components of the document
415 METSFileSet fileSet = METSFileSet.readSQL(document, connection);
416 document.setDocumentFiles(fileSet);
417 METSDescriptiveSet descriptiveSet = METSDescriptiveSet.readSQL(document, connection);
418 document.setDocumentMetadata(descriptiveSet);
419 METSStructureSet structureSet = METSStructureSet.readSQL(document, connection);
420 document.setDocumentStructure(structureSet);
421
422 // indicate that the document is not currently modified
423 document.setModified(false);
424 return document;
425 }
426 catch (SQLException sqlEx) {
427 System.out.println("Failure to load document: " + sqlEx);
428 }
429 return null;
430 }
431
432 /**
433 *
434 */
435 public boolean isModified()
436 { return this.isModified;
437 }
438
439 public void setModified(boolean isModified)
440 { this.isModified = isModified;
441 }
442}
Note: See TracBrowser for help on using the repository browser.