source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSDocumentModel.java@ 24393

Last change on this file since 24393 was 24393, checked in by sjm84, 13 years ago

Adding in the server-side code for the Document Maker as well as several other enhancements

  • Property svn:executable set to *
File size: 49.5 KB
Line 
1package org.greenstone.gsdl3.util;
2
3import java.io.BufferedWriter;
4import java.io.File;
5import java.io.FileInputStream;
6import java.io.FileOutputStream;
7import java.io.FileWriter;
8import java.nio.channels.FileChannel;
9import java.util.ArrayList;
10import java.util.HashMap;
11import java.util.Vector;
12
13import javax.xml.parsers.DocumentBuilder;
14import javax.xml.parsers.DocumentBuilderFactory;
15import javax.xml.transform.Result;
16import javax.xml.transform.Transformer;
17import javax.xml.transform.TransformerFactory;
18import javax.xml.transform.dom.DOMSource;
19import javax.xml.transform.stream.StreamResult;
20
21import org.greenstone.gsdl3.core.MessageRouter;
22import org.w3c.dom.Document;
23import org.w3c.dom.Element;
24import org.w3c.dom.Node;
25import org.w3c.dom.NodeList;
26
27import com.oopsconsultancy.xmltask.InsertAction.Position;
28
29public class GSDocumentModel
30{
31 //The two archive databases
32 protected static final String ARCHIVEINFSRC = "archiveinf-src";
33 protected static final String ARCHIVEINFDOC = "archiveinf-doc";
34
35 //Set section operations
36 public static final int OPERATION_REPLACE = 1;
37 public static final int OPERATION_INSERT_BEFORE = 2;
38 public static final int OPERATION_INSERT_AFTER = 3;
39 public static final int OPERATION_APPEND = 4;
40
41 //Duplicate and move operations
42 public static final int OPERATION_TYPE_DOC_TO_DOC = 1;
43 public static final int OPERATION_TYPE_DOC_TO_SEC = 2;
44 public static final int OPERATION_TYPE_SEC_TO_DOC = 3;
45 public static final int OPERATION_TYPE_SEC_TO_SEC = 4;
46
47 //Error codes
48 protected static final int NO_ERROR = 0;
49 protected static final int ERROR_OID_NOT_SPECIFIED = -1;
50 protected static final int ERROR_COLLECTION_NOT_SPECIFIED = -2;
51 protected static final int ERROR_SOURCE_DOCUMENT_OR_SECTION_DOES_NOT_EXIST = -3;
52 protected static final int ERROR_DESTINATION_DOCUMENT_OR_SECTION_DOES_NOT_EXIST = -4;
53 protected static final int ERROR_DESTINATION_DOCUMENT_OR_SECTION_ALREADY_EXISTS = -5;
54 protected static final int ERROR_COULD_NOT_DUPLICATE = -6;
55 protected static final int ERROR_COULD_NOT_MOVE = -7;
56 protected static final int ERROR_DOC_XML_COULD_NOT_BE_CREATED = -8;
57 protected static final int ERROR_EXCEPTION_CREATING_DOC_XML_FILE = -9;
58 protected static final int ERROR_METADATA_NAME_NOT_SPECIFIED = -10;
59 protected static final int ERROR_METADATA_VALUE_NOT_SPECIFIED = -11;
60 protected static final int ERROR_COULD_NOT_RETRIEVE_DOC_XML = -12;
61 protected static final int ERROR_COULD_NOT_WRITE_TO_DOC_XML = -13;
62 protected static final int ERROR_COULD_NOT_RETRIEVE_SECTION = -14;
63 protected static final int ERROR_COULD_NOT_OPEN_DATABASE = -15;
64 protected static final int ERROR_DATA_NOT_FOUND_IN_DATABASE = -16;
65 protected static final int ERROR_COULD_NOT_DELETE = -16;
66 protected static final int ERROR_OID_INCORRECT_FORMAT = -17;
67 protected static final int ERROR_INVALID_MERGE = -18;
68 protected static final int ERROR_INVALID_METADATA_POSITION = -19;
69 protected static final int ERROR_INVALID_SPLIT = -20;
70 protected static final int ERROR_DESTINATION_OID_NOT_SPECIFIED = -21;
71 protected static final HashMap<Integer, String> _errorMessageMap;
72
73 static
74 {
75 //Corresponding error messages
76 HashMap<Integer, String> errorMessageMap = new HashMap<Integer, String>();
77 errorMessageMap.put(ERROR_OID_NOT_SPECIFIED, "OID not specified");
78 errorMessageMap.put(ERROR_COLLECTION_NOT_SPECIFIED, "Collection not specified");
79 errorMessageMap.put(ERROR_SOURCE_DOCUMENT_OR_SECTION_DOES_NOT_EXIST, "The specified source document or section does not exist");
80 errorMessageMap.put(ERROR_DESTINATION_DOCUMENT_OR_SECTION_DOES_NOT_EXIST, "The specified destination document or section does not exist");
81 errorMessageMap.put(ERROR_DESTINATION_DOCUMENT_OR_SECTION_ALREADY_EXISTS, "The specified destination document or section already exists");
82 errorMessageMap.put(ERROR_COULD_NOT_DUPLICATE, "There was an error duplicating document or section");
83 errorMessageMap.put(ERROR_COULD_NOT_MOVE, "There was an error moving document or section");
84 errorMessageMap.put(ERROR_DOC_XML_COULD_NOT_BE_CREATED, "The doc.xml file already exists or could not be created");
85 errorMessageMap.put(ERROR_EXCEPTION_CREATING_DOC_XML_FILE, "There was an exception while creating the doc.xml file");
86 errorMessageMap.put(ERROR_METADATA_NAME_NOT_SPECIFIED, "The name of the requested metadata was not specified");
87 errorMessageMap.put(ERROR_METADATA_VALUE_NOT_SPECIFIED, "The new value for this metadata was not specified");
88 errorMessageMap.put(ERROR_COULD_NOT_RETRIEVE_DOC_XML, "Could not retrieve the necessary doc.xml file");
89 errorMessageMap.put(ERROR_COULD_NOT_WRITE_TO_DOC_XML, "There was an error writing to the doc.xml file");
90 errorMessageMap.put(ERROR_COULD_NOT_RETRIEVE_SECTION, "There was an error retrieving the specified section from the doc.xml file");
91 errorMessageMap.put(ERROR_COULD_NOT_OPEN_DATABASE, "There was an error opening the archive database");
92 errorMessageMap.put(ERROR_DATA_NOT_FOUND_IN_DATABASE, "The specified information could not be found in the database");
93 errorMessageMap.put(ERROR_COULD_NOT_DELETE, "There was an error deleting this document");
94 errorMessageMap.put(ERROR_OID_INCORRECT_FORMAT, "The given OID was not in the correct format");
95 errorMessageMap.put(ERROR_INVALID_MERGE, "Merge can only be performed on two sections of the same level or a section and it's parent. Also the destination section cannot have any child sections");
96 errorMessageMap.put(ERROR_INVALID_METADATA_POSITION, "There is no metadata at the given position");
97 errorMessageMap.put(ERROR_INVALID_SPLIT, "A split at the given location is not possible, either the section does not have text or the split point does not exist");
98 errorMessageMap.put(ERROR_DESTINATION_OID_NOT_SPECIFIED, "The destination OID was not specified");
99 _errorMessageMap = errorMessageMap;
100 }
101
102 protected int _errorStatus = NO_ERROR;
103
104 protected String _siteHome;
105 protected Document _mainDoc;
106 protected MessageRouter _router;
107 protected HashMap<String, Document> _docCache = new HashMap<String, Document>();
108
109 public GSDocumentModel(String siteHome, Document mainDocument, MessageRouter router)
110 {
111 _siteHome = siteHome;
112 _mainDoc = mainDocument;
113 _router = router;
114 }
115
116 public void documentCreate(String oid, String collection, String lang, String uid)
117 {
118 _errorStatus = NO_ERROR;
119 //If the collection is not specified then we cannot continue
120 if (collection == null || collection.equals(""))
121 {
122 _errorStatus = ERROR_COLLECTION_NOT_SPECIFIED;
123 return;
124 }
125
126 //If the document does not have an OID specified then generate one
127 if (oid == null || oid.equals(""))
128 {
129 oid = generateOID();
130 }
131 else if (archiveCheckDocumentOrSectionExists(oid, collection, lang, uid))
132 {
133 _errorStatus = ERROR_DESTINATION_DOCUMENT_OR_SECTION_ALREADY_EXISTS;
134 return;
135 }
136
137 //Check if the OID is the OID for a section
138 boolean section = false;
139 if (oid.contains("."))
140 {
141 section = true;
142 }
143
144 if (!section)
145 {
146 File newDir = new File(_siteHome + File.separatorChar + "collect" + File.separatorChar + collection + File.separatorChar + "archives" + File.separatorChar + oid);
147
148 if (!newDir.exists())
149 {
150 newDir.mkdir();
151 }
152
153 HashMap<String, ArrayList<String>> entries = new HashMap<String, ArrayList<String>>();
154 ArrayList<String> values = new ArrayList<String>();
155 values.add(oid + "/doc.xml");
156 entries.put("doc-file", values);
157
158 //Write the new entry to the archive database
159 archiveWriteEntryToDatabase(oid, collection, entries, lang, uid);
160 if (_errorStatus != NO_ERROR)
161 {
162 return;
163 }
164
165 //Create a basic doc.xml file to go in the new folder
166 documentXMLCreateDocXML(oid, collection, lang, uid);
167 }
168 else
169 {
170 documentXMLCreateSection(oid, collection, lang, uid);
171 }
172 }
173
174 public void documentDelete(String oid, String collection, String lang, String uid)
175 {
176 _errorStatus = NO_ERROR;
177 if (oid == null || oid.equals(""))
178 {
179 _errorStatus = ERROR_OID_NOT_SPECIFIED;
180 return;
181 }
182 else if (collection == null || collection.equals(""))
183 {
184 _errorStatus = ERROR_COLLECTION_NOT_SPECIFIED;
185 return;
186 }
187
188 if (!archiveCheckDocumentOrSectionExists(oid, collection, lang, uid))
189 {
190 _errorStatus = ERROR_SOURCE_DOCUMENT_OR_SECTION_DOES_NOT_EXIST;
191 return;
192 }
193
194 //Check if the OID is the OID for a section
195 boolean section = false;
196 if (oid.contains("."))
197 {
198 section = true;
199 }
200
201 if (!section)
202 {
203 File dirToDelete = new File(_siteHome + File.separatorChar + "collect" + File.separatorChar + collection + File.separatorChar + "archives" + File.separatorChar + oid);
204
205 if (!dirToDelete.exists() || !dirToDelete.isDirectory() || !deleteDirectory(dirToDelete))
206 {
207 _errorStatus = ERROR_COULD_NOT_DELETE;
208 return;
209 }
210
211 //Remove the entry from the archive database
212 archiveRemoveEntryFromDatabase(oid, collection, lang, uid);
213 }
214 else
215 {
216 documentXMLDeleteSection(oid, collection, lang, uid);
217 }
218 }
219
220 public void documentDuplicate(String oid, String collection, String newOID, String newCollection, String lang, String uid)
221 {
222 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
223 {
224 return;
225 }
226
227 //If a new collection is not specified then assume the collection of the original document
228 if (newCollection == null || newCollection.equals(""))
229 {
230 newCollection = collection;
231 }
232
233 //Generate an OID for the duplicate if we are not given one
234 if (newOID == null || newOID.equals(""))
235 {
236 _errorStatus = ERROR_DESTINATION_OID_NOT_SPECIFIED;
237 return;
238 }
239 else if (archiveCheckDocumentOrSectionExists(newOID, newCollection, lang, uid))
240 {
241 _errorStatus = ERROR_DESTINATION_DOCUMENT_OR_SECTION_ALREADY_EXISTS;
242 return;
243 }
244
245 //Check what operation we are performing
246 int op = getOperation(oid, newOID);
247
248 boolean requiresDatabaseEntry = false;
249 switch (op)
250 {
251 case OPERATION_TYPE_DOC_TO_DOC:
252 {
253 String archiveDir = archiveGetDocumentFilePath(oid, collection, lang, uid);
254 if (_errorStatus != NO_ERROR)
255 {
256 return;
257 }
258
259 //Remove doc.xml from the file name
260 archiveDir = archiveDir.substring(0, archiveDir.lastIndexOf(File.separator));
261 File dirToDuplicate = new File(archiveDir);
262
263 //This is possibly not the best way to name the new directory
264 File newDir = new File(archiveDir.substring(0, archiveDir.lastIndexOf(File.separator) + File.separator.length()) + newOID);
265
266 if (dirToDuplicate.exists() && dirToDuplicate.isDirectory() && !newDir.exists())
267 {
268 if (!copyDirectory(dirToDuplicate, newDir))
269 {
270 _errorStatus = ERROR_COULD_NOT_DUPLICATE;
271 return;
272 }
273 }
274 requiresDatabaseEntry = true;
275 break;
276 }
277 case OPERATION_TYPE_DOC_TO_SEC:
278 {
279 Document originalDocument = getDocXML(oid, collection, lang, uid);
280 Element originalSection = getTopLevelSectionElement(originalDocument);
281
282 documentXMLCreateSection(newOID, newCollection, lang, uid);
283 if (_errorStatus != NO_ERROR)
284 {
285 return;
286 }
287
288 documentXMLSetSection(newOID, newCollection, originalSection, OPERATION_REPLACE, lang, uid);
289 break;
290 }
291 case OPERATION_TYPE_SEC_TO_DOC:
292 {
293 Document originalDocument = getDocXML(oid, collection, lang, uid);
294 Element originalSection = getSectionBySectionNumber(originalDocument, getSectionFromOID(oid));
295
296 documentCreate(newOID, newCollection, lang, uid);
297 if (_errorStatus != NO_ERROR)
298 {
299 return;
300 }
301
302 documentXMLCreateSection(newOID, newCollection, lang, uid);
303 if (_errorStatus != NO_ERROR)
304 {
305 return;
306 }
307
308 documentXMLSetSection(newOID, newCollection, originalSection, OPERATION_REPLACE, lang, uid);
309
310 requiresDatabaseEntry = true;
311 break;
312 }
313 case OPERATION_TYPE_SEC_TO_SEC:
314 {
315 Document originalDocument = getDocXML(oid, collection, lang, uid);
316 Element originalSection = getSectionBySectionNumber(originalDocument, getSectionFromOID(oid));
317
318 documentXMLCreateSection(newOID, newCollection, lang, uid);
319 if (_errorStatus != NO_ERROR)
320 {
321 return;
322 }
323
324 documentXMLSetSection(newOID, newCollection, originalSection, OPERATION_REPLACE, lang, uid);
325 break;
326 }
327 }
328
329 if (requiresDatabaseEntry)
330 {
331 HashMap<String, ArrayList<String>> entries = new HashMap<String, ArrayList<String>>();
332 ArrayList<String> values = new ArrayList<String>();
333 values.add(newOID + "/doc.xml");
334 entries.put("doc-file", values);
335
336 //Write the new entry to the archive database
337 archiveWriteEntryToDatabase(newOID, newCollection, entries, lang, uid);
338 }
339 }
340
341 //TODO: Change return type to something else
342 public void documentGetInformation(String oid, String collection, String[] requestedInfo, String lang, String uid)
343 {
344 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
345 {
346 return;
347 }
348
349 for (int j = 0; j < requestedInfo.length; j++)
350 {
351 String currentRequest = requestedInfo[j];
352 //TODO: Decide what info requests are valid (e.g. number of sections etc.)
353 //-How many child/sibling sections
354 //-Metadata keys
355 }
356 }
357
358 public void documentMove(String oid, String collection, String newOID, String newCollection, String lang, String uid)
359 {
360 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
361 {
362 return;
363 }
364
365 documentDuplicate(oid, collection, newOID, newCollection, lang, uid);
366 if (_errorStatus != NO_ERROR)
367 {
368 return;
369 }
370
371 documentDelete(oid, collection, lang, uid);
372 }
373
374 public void documentMerge(String oid, String collection, String mergeOID, String lang, String uid)
375 {
376 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
377 {
378 return;
379 }
380
381 if ((_errorStatus = checkOIDandCollection(mergeOID, collection, lang, uid)) != NO_ERROR)
382 {
383 return;
384 }
385
386 int op = getOperation(oid, mergeOID);
387 if (op != OPERATION_TYPE_SEC_TO_SEC && op != OPERATION_TYPE_SEC_TO_DOC) //We allow SEC_TO_DOC in the case that someone wants to merge D11.1 with D11 (for example)
388 {
389 _errorStatus = ERROR_INVALID_MERGE;
390 return;
391 }
392
393 String[] sourceLevels = oid.split("\\.");
394 String[] destinationLevels = mergeOID.split("\\.");
395
396 if (destinationLevels.length > sourceLevels.length)
397 {
398 _errorStatus = ERROR_INVALID_MERGE;
399 return;
400 }
401
402 for (int i = 0; i < sourceLevels.length - 1; i++)
403 {
404 if (i >= destinationLevels.length || !sourceLevels[i].equals(destinationLevels[i]))
405 {
406 _errorStatus = ERROR_INVALID_MERGE;
407 return;
408 }
409 }
410
411 Document docXML = getDocXML(oid, collection, lang, uid);
412 if (docXML == null)
413 {
414 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
415 return;
416 }
417
418 Element sourceSection = getSectionBySectionNumber(docXML, getSectionFromOID(oid));
419 Element destinationSection = getSectionBySectionNumber(docXML, getSectionFromOID(mergeOID));
420
421 //Make sure the destination Section does not have any child Sections.
422 NodeList childSections = GSXML.getChildrenByTagName(destinationSection, GSXML.DOCXML_SECTION_ELEM);
423 if (childSections.getLength() != 0 && sourceLevels.length == destinationLevels.length)
424 {
425 _errorStatus = ERROR_INVALID_MERGE;
426 return;
427 }
428
429 //Get the children of the destination section so we can copy them to the source section before we overwrite the destination
430 NodeList childrenToKeep = destinationSection.getChildNodes();
431 ArrayList<Node> childList = new ArrayList<Node>();
432 for (int i = 0; i < childrenToKeep.getLength(); i++)
433 {
434 //Need to put these in a list to make them easier to loop through as using a NodeList is messy
435 childList.add(childrenToKeep.item(i));
436 }
437
438 //for(int i = 0; i < childrenToKeep.getLength(); i++)
439 for (int i = 0; i < childList.size(); i++)
440 {
441 Node currentChild = childList.get(i);
442 //If the child is not a <Content> node then add it to source section
443 if (!currentChild.getNodeName().equals(GSXML.DOCXML_CONTENT_ELEM))
444 {
445 sourceSection.appendChild(currentChild);
446 continue;
447 }
448
449 //Get the destination Section's Content node's text node, if it's empty then we don't need to worry about appending it
450 Node destinationTextNode = currentChild.getFirstChild();
451 if (destinationTextNode == null || destinationTextNode.getNodeValue() == null || destinationTextNode.getNodeValue().equals(""))
452 {
453 continue;
454 }
455
456 //If the source Section does not have a content then directly append the destination content
457 Element sourceContent = (Element) GSXML.getChildByTagName(sourceSection, GSXML.DOCXML_CONTENT_ELEM);
458 if (sourceContent == null)
459 {
460 sourceSection.appendChild(currentChild);
461 continue;
462 }
463
464 //If the source Section's Content is empty then again we can directly append the destination content
465 Node sourceTextNode = sourceContent.getFirstChild();
466 if (sourceTextNode == null || sourceTextNode.getNodeValue() == null || sourceTextNode.getNodeValue().equals(""))
467 {
468 sourceSection.appendChild(currentChild);
469 continue;
470 }
471
472 //Otherwise, set the new content to be destination + source text in that order.
473 sourceTextNode.setNodeValue(destinationTextNode.getNodeValue() + " " + sourceTextNode.getNodeValue());
474 }
475
476 documentXMLSetSection(mergeOID, collection, sourceSection, OPERATION_REPLACE, lang, uid);
477 if (_errorStatus != NO_ERROR)
478 {
479 return;
480 }
481
482 documentXMLDeleteSection(oid, collection, lang, uid);
483 }
484
485 public void documentSplit(String oid, String collection, int splitPoint, String lang, String uid)
486 {
487 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
488 {
489 return;
490 }
491
492 Document docXML = getDocXML(oid, collection, lang, uid);
493 if (docXML == null)
494 {
495 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
496 return;
497 }
498
499 Element sectionToSplit = null;
500 if (!oid.contains("."))
501 {
502 sectionToSplit = getTopLevelSectionElement(docXML);
503 }
504 else
505 {
506 sectionToSplit = getSectionBySectionNumber(docXML, getSectionFromOID(oid));
507 }
508
509 Element content = (Element) GSXML.getChildByTagName(sectionToSplit, GSXML.DOCXML_CONTENT_ELEM);
510 if (content == null)
511 {
512 _errorStatus = ERROR_INVALID_SPLIT;
513 return;
514 }
515
516 Node textNode = content.getFirstChild();
517 if (textNode == null)
518 {
519 _errorStatus = ERROR_INVALID_SPLIT;
520 return;
521 }
522
523 String text = textNode.getNodeValue();
524 if (splitPoint > text.length() - 2 || splitPoint < 1) //-1 would be the index of the last character, so the last valid split point is -2
525 {
526 _errorStatus = ERROR_INVALID_SPLIT;
527 return;
528 }
529
530 String firstPart = text.substring(0, splitPoint);
531 String secondPart = text.substring(splitPoint);
532
533 Element newSection = docXML.createElement(GSXML.DOCXML_SECTION_ELEM);
534 Element newContent = docXML.createElement(GSXML.DOCXML_CONTENT_ELEM);
535 Node newTextNode = docXML.createTextNode(firstPart);
536 newContent.appendChild(newTextNode);
537 newSection.appendChild(newContent);
538
539 documentXMLSetSection(oid, collection, newSection, OPERATION_INSERT_BEFORE, lang, uid);
540 if (_errorStatus != NO_ERROR)
541 {
542 return;
543 }
544 textNode.setNodeValue(secondPart);
545
546 //Write the new change back into the file
547 if (!writeXMLFile(docXML, oid, collection, lang, uid))
548 {
549 _errorStatus = ERROR_COULD_NOT_WRITE_TO_DOC_XML;
550 }
551 }
552
553 public void documentXMLCreateDocXML(String oid, String collection, String lang, String uid)
554 {
555 _errorStatus = NO_ERROR;
556 try
557 {
558 Document docXML = null;
559
560 String filePath = archiveGetDocumentFilePath(oid, collection, lang, uid);
561 File docFile = new File(filePath);
562 if (!docFile.exists() && !docFile.createNewFile())
563 {
564 _errorStatus = ERROR_DOC_XML_COULD_NOT_BE_CREATED;
565 return;
566 }
567
568 BufferedWriter bw = new BufferedWriter(new FileWriter(docFile));
569 bw.write("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n");
570 bw.write("<!DOCTYPE Archive SYSTEM \"http://greenstone.org/dtd/Archive/1.0/Archive.dtd\">\n");
571 bw.write("<Archive>\n");
572 bw.write("</Archive>\n");
573 bw.close();
574
575 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
576 DocumentBuilder db = dbf.newDocumentBuilder();
577 docXML = db.parse(docFile);
578
579 _docCache.put(oid + "__" + collection, docXML);
580 }
581 catch (Exception ex)
582 {
583 ex.printStackTrace();
584 _errorStatus = ERROR_EXCEPTION_CREATING_DOC_XML_FILE;
585 return;
586 }
587 }
588
589 public ArrayList<Element> documentXMLGetMetadata(String oid, String collection, String metadataName, String lang, String uid)
590 {
591 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
592 {
593 return null;
594 }
595 else if (metadataName == null || metadataName.equals(""))
596 {
597 _errorStatus = ERROR_METADATA_NAME_NOT_SPECIFIED;
598 return null;
599 }
600
601 Document docXML = getDocXML(oid, collection, lang, uid);
602 if (docXML == null)
603 {
604 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
605 return null;
606 }
607
608 return getMetadataElementsFromSection(docXML, oid, metadataName);
609 }
610
611 public void documentXMLSetMetadata(String oid, String collection, String metadataName, String newMetadataValue, int position, int operation, String lang, String uid)
612 {
613 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
614 {
615 return;
616 }
617 else if (metadataName == null || metadataName.equals(""))
618 {
619 _errorStatus = ERROR_METADATA_NAME_NOT_SPECIFIED;
620 return;
621 }
622 else if (newMetadataValue == null || newMetadataValue.equals(""))
623 {
624 _errorStatus = ERROR_METADATA_VALUE_NOT_SPECIFIED;
625 return;
626 }
627
628 Document docXML = getDocXML(oid, collection, lang, uid);
629 if (docXML == null)
630 {
631 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
632 return;
633 }
634
635 ArrayList<Element> metadataElems = getMetadataElementsFromSection(docXML, oid, metadataName);
636
637 if (operation != OPERATION_APPEND && metadataElems.get(position) == null)
638 {
639 _errorStatus = ERROR_INVALID_METADATA_POSITION;
640 return;
641 }
642
643 if (operation == OPERATION_REPLACE)
644 {
645 metadataElems.get(position).setNodeValue(newMetadataValue);
646 }
647 else if (operation == OPERATION_INSERT_BEFORE)
648 {
649 Element newMetadata = createElementWithValue(docXML, GSXML.DOCXML_METADATA_ELEM, metadataName, newMetadataValue);
650 Element existingMetadata = metadataElems.get(position);
651
652 existingMetadata.getParentNode().insertBefore(newMetadata, existingMetadata);
653 }
654 else if (operation == OPERATION_INSERT_AFTER)
655 {
656 Element newMetadata = createElementWithValue(docXML, GSXML.DOCXML_METADATA_ELEM, metadataName, newMetadataValue);
657 Element existingMetadata = metadataElems.get(position + 1);
658
659 if (existingMetadata != null)
660 {
661 existingMetadata.getParentNode().insertBefore(newMetadata, existingMetadata);
662 }
663 else
664 {
665 existingMetadata = metadataElems.get(position);
666 existingMetadata.getParentNode().appendChild(newMetadata);
667 }
668 }
669 else
670 {
671 Element section = getSectionBySectionNumber(docXML, getSectionFromOID(oid));
672 Element description = (Element) GSXML.getChildByTagName(section, GSXML.DOCXML_DESCRIPTION_ELEM);
673 if (description == null)
674 {
675 description = docXML.createElement(GSXML.DOCXML_DESCRIPTION_ELEM);
676 section.appendChild(description);
677 }
678 Element newMetadata = createElementWithValue(docXML, GSXML.DOCXML_METADATA_ELEM, metadataName, newMetadataValue);
679 description.appendChild(newMetadata);
680 }
681
682 //Write the new change back into the file
683 if (!writeXMLFile(docXML, oid, collection, lang, uid))
684 {
685 _errorStatus = ERROR_COULD_NOT_WRITE_TO_DOC_XML;
686 }
687 }
688
689 public void documentXMLDeleteMetadata(String oid, String collection, String metadataName, int position, String lang, String uid)
690 {
691 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
692 {
693 return;
694 }
695 else if (metadataName == null || metadataName.equals(""))
696 {
697 _errorStatus = ERROR_METADATA_NAME_NOT_SPECIFIED;
698 return;
699 }
700
701 Document docXML = getDocXML(oid, collection, lang, uid);
702 if (docXML == null)
703 {
704 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
705 return;
706 }
707
708 ArrayList<Element> metadataElems = getMetadataElementsFromSection(docXML, oid, metadataName);
709
710 if (metadataElems.get(position) != null)
711 {
712 metadataElems.get(position).getParentNode().removeChild(metadataElems.get(position));
713 }
714 }
715
716 public void documentXMLDeleteMetadata(String oid, String collection, String metadataName, String lang, String uid)
717 {
718 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
719 {
720 return;
721 }
722 else if (metadataName == null || metadataName.equals(""))
723 {
724 _errorStatus = ERROR_METADATA_NAME_NOT_SPECIFIED;
725 return;
726 }
727
728 Document docXML = getDocXML(oid, collection, lang, uid);
729 if (docXML == null)
730 {
731 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
732 return;
733 }
734
735 ArrayList<Element> metadataElems = getMetadataElementsFromSection(docXML, oid, metadataName);
736
737 for (Element elem : metadataElems)
738 {
739 elem.getParentNode().removeChild(elem);
740 }
741 }
742
743 public void documentXMLReplaceMetadata(String oid, String collection, String metadataName, String oldMetadataValue, String newMetadataValue, String lang, String uid)
744 {
745 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
746 {
747 return;
748 }
749 else if (metadataName == null || metadataName.equals(""))
750 {
751 _errorStatus = ERROR_METADATA_NAME_NOT_SPECIFIED;
752 return;
753 }
754 else if (newMetadataValue == null || newMetadataValue.equals(""))
755 {
756 _errorStatus = ERROR_METADATA_VALUE_NOT_SPECIFIED;
757 return;
758 }
759 else if (oldMetadataValue == null || oldMetadataValue.equals(""))
760 {
761 _errorStatus = ERROR_METADATA_VALUE_NOT_SPECIFIED;
762 return;
763 }
764
765 Document docXML = getDocXML(oid, collection, lang, uid);
766 if (docXML == null)
767 {
768 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
769 return;
770 }
771
772 ArrayList<Element> metadataElems = getMetadataElementsFromSection(docXML, oid, metadataName);
773
774 for (Element elem : metadataElems)
775 {
776 Node textNode = elem.getFirstChild();
777
778 if (textNode != null && textNode.getNodeValue().equals(oldMetadataValue))
779 {
780 textNode.setNodeValue(newMetadataValue);
781 }
782 }
783
784 //Write the new change back into the file
785 if (!writeXMLFile(docXML, oid, collection, lang, uid))
786 {
787 _errorStatus = ERROR_COULD_NOT_WRITE_TO_DOC_XML;
788 }
789 }
790
791 public void documentXMLCreateSection(String oid, String collection, String lang, String uid)
792 {
793 _errorStatus = NO_ERROR;
794 if (oid == null || oid.equals(""))
795 {
796 _errorStatus = ERROR_OID_NOT_SPECIFIED;
797 return;
798 }
799 else if (collection == null || collection.equals(""))
800 {
801 _errorStatus = ERROR_COLLECTION_NOT_SPECIFIED;
802 return;
803 }
804
805 if (oid.contains(".") && !archiveCheckDocumentOrSectionExists(oid.substring(0, oid.indexOf(".")), collection, lang, uid))
806 {
807 documentCreate(oid.substring(0, oid.indexOf(".")), collection, lang, uid);
808 if (_errorStatus != NO_ERROR)
809 {
810 return;
811 }
812 }
813
814 Document docXML = getDocXML(oid, collection, lang, uid);
815 if (docXML == null)
816 {
817 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
818 return;
819 }
820
821 Element topLevel = docXML.getDocumentElement();
822 if (!oid.contains("."))
823 {
824 if (GSXML.getChildByTagName(topLevel, GSXML.DOCXML_SECTION_ELEM) == null)
825 {
826 Element newSection = docXML.createElement(GSXML.DOCXML_SECTION_ELEM);
827 topLevel.appendChild(newSection);
828 }
829 }
830 else
831 {
832 int[] intLevels = null;
833 try
834 {
835 intLevels = oidToSectionNumberArray(oid);
836 }
837 catch (Exception ex)
838 {
839 _errorStatus = ERROR_OID_INCORRECT_FORMAT;
840 return;
841 }
842
843 Element current = (Element) GSXML.getChildByTagName(topLevel, GSXML.DOCXML_SECTION_ELEM);
844 if (current == null)
845 {
846 Element topLevelSection = docXML.createElement(GSXML.DOCXML_SECTION_ELEM);
847 topLevel.appendChild(topLevelSection);
848 current = topLevelSection;
849 }
850
851 for (int currentLevelValue : intLevels)
852 {
853 NodeList sections = GSXML.getChildrenByTagName(current, GSXML.DOCXML_SECTION_ELEM);
854
855 if (sections.item(currentLevelValue - 1) == null)
856 {
857 Element latest = null;
858 for (int j = 0; j < currentLevelValue - sections.getLength(); j++)
859 {
860 Element blankSection = docXML.createElement(GSXML.DOCXML_SECTION_ELEM);
861 current.appendChild(blankSection);
862 latest = blankSection;
863 }
864 current = latest;
865 }
866 else
867 {
868 current = (Element) sections.item(currentLevelValue - 1);
869 }
870 }
871 }
872
873 //Write the new change back into the file
874 if (!writeXMLFile(docXML, oid, collection, lang, uid))
875 {
876 _errorStatus = ERROR_COULD_NOT_WRITE_TO_DOC_XML;
877 }
878 }
879
880 public void documentXMLDeleteSection(String oid, String collection, String lang, String uid)
881 {
882 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
883 {
884 return;
885 }
886
887 Document docXML = getDocXML(oid, collection, lang, uid);
888 if (docXML == null)
889 {
890 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
891 return;
892 }
893
894 Element section = getSectionBySectionNumber(docXML, getSectionFromOID(oid));
895 if (section == null)
896 {
897 _errorStatus = ERROR_COULD_NOT_DELETE;
898 return;
899 }
900
901 section.getParentNode().removeChild(section);
902
903 //Write the new change back into the file
904 if (!writeXMLFile(docXML, oid, collection, lang, uid))
905 {
906 _errorStatus = ERROR_COULD_NOT_WRITE_TO_DOC_XML;
907 }
908 }
909
910 public Element documentXMLGetSection(String oid, String collection, String lang, String uid)
911 {
912 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
913 {
914 return null;
915 }
916
917 Document docXML = getDocXML(oid, collection, lang, uid);
918 if (docXML == null)
919 {
920 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
921 return null;
922 }
923
924 Element section = null;
925 if (!oid.contains("."))
926 {
927 section = getTopLevelSectionElement(docXML);
928 }
929 else
930 {
931 section = getSectionBySectionNumber(docXML, getSectionFromOID(oid));
932 }
933
934 if (section == null)
935 {
936 _errorStatus = ERROR_COULD_NOT_RETRIEVE_SECTION;
937 return null;
938 }
939
940 return section;
941 }
942
943 public void documentXMLSetSection(String oid, String collection, Element newSection, int op, String lang, String uid)
944 {
945 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
946 {
947 return;
948 }
949
950 Document docXML = getDocXML(oid, collection, lang, uid);
951 if (docXML == null)
952 {
953 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
954 return;
955 }
956
957 Element existingSection = null;
958 if (!oid.contains("."))
959 {
960 existingSection = getTopLevelSectionElement(docXML);
961 }
962 else
963 {
964 existingSection = getSectionBySectionNumber(docXML, getSectionFromOID(oid));
965 }
966
967 if (existingSection == null)
968 {
969 _errorStatus = ERROR_COULD_NOT_RETRIEVE_SECTION;
970 return;
971 }
972
973 Element importedSection = (Element) docXML.importNode(newSection, true);
974
975 if (op == OPERATION_APPEND)
976 {
977 existingSection.appendChild(importedSection);
978 }
979 else
980 {
981 Node sectionParent = existingSection.getParentNode();
982
983 //Remove the attributes that are only there to help us find the section
984 importedSection.removeAttribute(GSXML.NODE_ID_ATT);
985 importedSection.removeAttribute(GSXML.COLLECTION_ATT);
986
987 if (op == OPERATION_INSERT_BEFORE || op == OPERATION_REPLACE)
988 {
989 sectionParent.insertBefore(importedSection, existingSection);
990 }
991 else if (op == OPERATION_INSERT_AFTER)
992 {
993 Element sibling = (Element) existingSection.getNextSibling();
994 if (sibling == null)
995 {
996 sectionParent.insertBefore(importedSection, sibling);
997 }
998 else
999 {
1000 sectionParent.appendChild(importedSection);
1001 }
1002 }
1003
1004 if (op == OPERATION_REPLACE)
1005 {
1006 sectionParent.removeChild(existingSection);
1007 }
1008 }
1009
1010 //Write the new change back into the file
1011 if (!writeXMLFile(docXML, oid, collection, lang, uid))
1012 {
1013 _errorStatus = ERROR_COULD_NOT_WRITE_TO_DOC_XML;
1014 return;
1015 }
1016 }
1017
1018 public String documentXMLGetText(String oid, String collection, String lang, String uid)
1019 {
1020 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
1021 {
1022 return null;
1023 }
1024
1025 Document docXML = getDocXML(oid, collection, lang, uid);
1026 if (docXML == null)
1027 {
1028 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
1029 return null;
1030 }
1031
1032 Element section = null;
1033 if (!oid.contains("."))
1034 {
1035 section = getTopLevelSectionElement(docXML);
1036 }
1037 else
1038 {
1039 section = getSectionBySectionNumber(docXML, getSectionFromOID(oid));
1040 }
1041
1042 if (section == null)
1043 {
1044 _errorStatus = ERROR_COULD_NOT_RETRIEVE_SECTION;
1045 return null;
1046 }
1047
1048 Element contentNode = (Element) GSXML.getChildByTagName(section, GSXML.DOCXML_CONTENT_ELEM);
1049 if (contentNode == null)
1050 {
1051 return null;
1052 }
1053
1054 Node textNode = contentNode.getFirstChild();
1055 if (textNode == null)
1056 {
1057 return null;
1058 }
1059
1060 return textNode.getNodeValue();
1061 }
1062
1063 public void documentXMLSetText(String oid, String collection, Element newContent, String lang, String uid)
1064 {
1065 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
1066 {
1067 return;
1068 }
1069
1070 Document docXML = getDocXML(oid, collection, lang, uid);
1071 if (docXML == null)
1072 {
1073 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
1074 return;
1075 }
1076
1077 Element section = null;
1078 if (!oid.contains("."))
1079 {
1080 section = getTopLevelSectionElement(docXML);
1081 }
1082 else
1083 {
1084 section = getSectionBySectionNumber(docXML, getSectionFromOID(oid));
1085 }
1086
1087 if (section == null)
1088 {
1089 _errorStatus = ERROR_COULD_NOT_RETRIEVE_SECTION;
1090 return;
1091 }
1092
1093 Element existingContent = (Element) GSXML.getChildByTagName(section, GSXML.DOCXML_CONTENT_ELEM);
1094
1095 //Remove the attributes that are only there to help us find the content
1096 newContent.removeAttribute(GSXML.NODE_ID_ATT);
1097 newContent.removeAttribute(GSXML.COLLECTION_ATT);
1098
1099 Element importedContent = (Element) docXML.importNode(newContent, true);
1100 //If the current section does not have content then just add it, otherwise replace the existing one
1101 if (existingContent == null)
1102 {
1103 section.appendChild(importedContent);
1104 }
1105 else
1106 {
1107 Node contentParent = existingContent.getParentNode();
1108
1109 //Replace the old node in the document tree
1110 contentParent.insertBefore(importedContent, existingContent);
1111 contentParent.removeChild(existingContent);
1112 }
1113
1114 //Write the new change back into the file
1115 if (!writeXMLFile(docXML, oid, collection, lang, uid))
1116 {
1117 _errorStatus = ERROR_COULD_NOT_WRITE_TO_DOC_XML;
1118 return;
1119 }
1120 }
1121
1122 public void documentXMLSetText(String oid, String collection, String newContent, String lang, String uid)
1123 {
1124 if ((_errorStatus = checkOIDandCollection(oid, collection, lang, uid)) != NO_ERROR)
1125 {
1126 return;
1127 }
1128
1129 Document docXML = getDocXML(oid, collection, lang, uid);
1130 if (docXML == null)
1131 {
1132 _errorStatus = ERROR_COULD_NOT_RETRIEVE_DOC_XML;
1133 return;
1134 }
1135
1136 Element section = null;
1137 if (!oid.contains("."))
1138 {
1139 section = getTopLevelSectionElement(docXML);
1140 }
1141 else
1142 {
1143 section = getSectionBySectionNumber(docXML, getSectionFromOID(oid));
1144 }
1145
1146 if (section == null)
1147 {
1148 _errorStatus = ERROR_COULD_NOT_RETRIEVE_SECTION;
1149 return;
1150 }
1151
1152 Element existingContent = (Element) GSXML.getChildByTagName(section, GSXML.DOCXML_CONTENT_ELEM);
1153
1154 //If the current section does not have content then just add it, otherwise replace the existing one
1155 if (existingContent == null)
1156 {
1157 Element newContentElem = docXML.createElement(GSXML.DOCXML_CONTENT_ELEM);
1158 Node textNode = docXML.createTextNode(newContent);
1159 newContentElem.appendChild(textNode);
1160 }
1161 else
1162 {
1163 Node textNode = existingContent.getFirstChild();
1164 if (textNode != null)
1165 {
1166 textNode.setNodeValue(newContent);
1167 }
1168 else
1169 {
1170 existingContent.appendChild(docXML.createTextNode(newContent));
1171 }
1172 }
1173
1174 //Write the new change back into the file
1175 if (!writeXMLFile(docXML, oid, collection, lang, uid))
1176 {
1177 _errorStatus = ERROR_COULD_NOT_WRITE_TO_DOC_XML;
1178 return;
1179 }
1180 }
1181
1182 public String archiveGetDocumentFilePath(String oid, String collection, String lang, String uid)
1183 {
1184 _errorStatus = NO_ERROR;
1185
1186 if (oid.contains("."))
1187 {
1188 oid = oid.substring(0, oid.indexOf("."));
1189 }
1190
1191 String assocFilePath = getDocFilePathFromDatabase(oid, collection, lang, uid);
1192 if (assocFilePath == null)
1193 {
1194 _errorStatus = ERROR_DATA_NOT_FOUND_IN_DATABASE;
1195 return null;
1196 }
1197
1198 if (File.separator.equals("\\"))
1199 {
1200 assocFilePath = assocFilePath.replace("/", "\\");
1201 }
1202
1203 String docFilePath = _siteHome + File.separatorChar + "collect" + File.separatorChar + collection + File.separatorChar + "archives" + File.separatorChar + assocFilePath;
1204 return docFilePath;
1205 }
1206
1207 public String archiveGetSourceFileOID(String srcFile, String collection, String lang, String uid)
1208 {
1209 _errorStatus = NO_ERROR;
1210 SimpleCollectionDatabase coll_db = openDatabase(collection, ARCHIVEINFSRC, SimpleCollectionDatabase.READ, lang, uid);
1211 if (coll_db == null)
1212 {
1213 _errorStatus = ERROR_COULD_NOT_OPEN_DATABASE;
1214 return null;
1215 }
1216
1217 DBInfo info = coll_db.getInfo(srcFile);
1218 if (info == null)
1219 {
1220 _errorStatus = ERROR_DATA_NOT_FOUND_IN_DATABASE;
1221 coll_db.closeDatabase();
1222 return null;
1223 }
1224
1225 String oid = info.getInfo("oid");
1226
1227 coll_db.closeDatabase();
1228 return oid;
1229 }
1230
1231 public boolean archiveCheckDocumentOrSectionExists(String oid, String collection, String lang, String uid)
1232 {
1233 _errorStatus = NO_ERROR;
1234 SimpleCollectionDatabase coll_db = openDatabase(collection, ARCHIVEINFDOC, SimpleCollectionDatabase.READ, lang, uid);
1235 if (coll_db == null)
1236 {
1237 _errorStatus = ERROR_COULD_NOT_OPEN_DATABASE;
1238 return false;
1239 }
1240
1241 boolean section = false;
1242 if (oid.contains("."))
1243 {
1244 section = true;
1245 }
1246
1247 DBInfo info = null;
1248 if (section)
1249 {
1250 info = coll_db.getInfo(oid.substring(0, oid.indexOf(".")));
1251 }
1252 else
1253 {
1254 info = coll_db.getInfo(oid);
1255 }
1256 boolean exists = (info != null);
1257
1258 coll_db.closeDatabase();
1259 if (section && exists)
1260 {
1261 Document docXML = getDocXML(oid, collection, lang, uid);
1262 if (getSectionBySectionNumber(docXML, getSectionFromOID(oid)) == null)
1263 {
1264 return false;
1265 }
1266 return true;
1267 }
1268
1269 return exists;
1270 }
1271
1272 public void archiveWriteEntryToDatabase(String oid, String collection, HashMap<String, ArrayList<String>> infoList, String lang, String uid)
1273 {
1274 _errorStatus = NO_ERROR;
1275 if (oid == null || oid.equals(""))
1276 {
1277 _errorStatus = ERROR_OID_NOT_SPECIFIED;
1278 return;
1279 }
1280 else if (collection == null || collection.equals(""))
1281 {
1282 _errorStatus = ERROR_COLLECTION_NOT_SPECIFIED;
1283 return;
1284 }
1285
1286 DBInfo info = new DBInfo();
1287
1288 for (String s : infoList.keySet())
1289 {
1290 for (String v : infoList.get(s))
1291 {
1292 info.addInfo(s, v);
1293 }
1294 }
1295
1296 SimpleCollectionDatabase coll_db = openDatabase(collection, ARCHIVEINFDOC, SimpleCollectionDatabase.WRITE, lang, uid);
1297 if (coll_db == null)
1298 {
1299 _errorStatus = ERROR_COULD_NOT_OPEN_DATABASE;
1300 return;
1301 }
1302 coll_db.setInfo(oid, info);
1303 coll_db.closeDatabase();
1304 }
1305
1306 public void archiveRemoveEntryFromDatabase(String oid, String collection, String lang, String uid)
1307 {
1308 _errorStatus = NO_ERROR;
1309 if (oid == null || oid.equals(""))
1310 {
1311 _errorStatus = ERROR_OID_NOT_SPECIFIED;
1312 return;
1313 }
1314 else if (collection == null || collection.equals(""))
1315 {
1316 _errorStatus = ERROR_COLLECTION_NOT_SPECIFIED;
1317 return;
1318 }
1319
1320 SimpleCollectionDatabase coll_db = openDatabase(collection, ARCHIVEINFDOC, SimpleCollectionDatabase.WRITE, lang, uid);
1321 if (coll_db == null)
1322 {
1323 _errorStatus = ERROR_COULD_NOT_OPEN_DATABASE;
1324 return;
1325 }
1326 coll_db.deleteKey(oid);
1327 coll_db.closeDatabase();
1328 }
1329
1330 public ArrayList<String> archiveGetAssociatedImportFiles(String oid, String collection, String lang, String uid)
1331 {
1332 _errorStatus = NO_ERROR;
1333 if (oid == null || oid.equals(""))
1334 {
1335 _errorStatus = ERROR_OID_NOT_SPECIFIED;
1336 return null;
1337 }
1338 else if (collection == null || collection.equals(""))
1339 {
1340 _errorStatus = ERROR_COLLECTION_NOT_SPECIFIED;
1341 return null;
1342 }
1343
1344 SimpleCollectionDatabase coll_db = openDatabase(collection, ARCHIVEINFDOC, SimpleCollectionDatabase.READ, lang, uid);
1345 if (coll_db == null)
1346 {
1347 _errorStatus = ERROR_COULD_NOT_OPEN_DATABASE;
1348 return null;
1349 }
1350
1351 DBInfo info = coll_db.getInfo(oid);
1352 if (info == null)
1353 {
1354 _errorStatus = ERROR_DATA_NOT_FOUND_IN_DATABASE;
1355 coll_db.closeDatabase();
1356 return null;
1357 }
1358
1359 String srcFile = info.getInfo("src-file");
1360 Vector data = info.getMultiInfo("assoc-file");
1361
1362 ArrayList<String> assocFiles = new ArrayList<String>();
1363 assocFiles.add(srcFile);
1364 for (String d : (Vector<String>) data)
1365 {
1366 assocFiles.add(d);
1367 }
1368
1369 coll_db.closeDatabase();
1370 return assocFiles;
1371 }
1372
1373 /********************
1374 * Helper functions *
1375 *******************/
1376
1377 public boolean checkError(Element elem, String methodName)
1378 {
1379 if (_errorMessageMap.get(_errorStatus) != null)
1380 {
1381 GSXML.addError(elem.getOwnerDocument(), elem, methodName + ": " + _errorMessageMap.get(_errorStatus), GSXML.ERROR_TYPE_SYNTAX);
1382 return true;
1383 }
1384
1385 return false;
1386 }
1387
1388 public String getSectionFromOID(String oid)
1389 {
1390 if (!oid.contains("."))
1391 {
1392 return null;
1393 }
1394 return oid.substring(oid.indexOf(".") + 1);
1395 }
1396
1397 public Element createElementWithValue(Document doc, String nodeName, String name, String value)
1398 {
1399 Element metadataElem = doc.createElement(nodeName);
1400 metadataElem.setAttribute(GSXML.NAME_ATT, name);
1401 Node textNode = doc.createTextNode(value);
1402 metadataElem.appendChild(textNode);
1403 return metadataElem;
1404 }
1405
1406 public int getOperation(String to, String from)
1407 {
1408 int op;
1409 if (!to.contains(".") && !from.contains("."))
1410 {
1411 op = OPERATION_TYPE_DOC_TO_DOC;
1412 }
1413 else if (!to.contains(".") && from.contains("."))
1414 {
1415 op = OPERATION_TYPE_DOC_TO_SEC;
1416 }
1417 else if (to.contains(".") && !from.contains("."))
1418 {
1419 op = OPERATION_TYPE_SEC_TO_DOC;
1420 }
1421 else
1422 {
1423 op = OPERATION_TYPE_SEC_TO_SEC;
1424 }
1425 return op;
1426 }
1427
1428 public int[] oidToSectionNumberArray(String oid) throws Exception
1429 {
1430 String[] strLevels = oid.split("\\.");
1431 int[] intLevels = new int[strLevels.length - 1];
1432
1433 for (int i = 1; i < strLevels.length; i++) //Start at 1 to avoid the document identifier part of the OID
1434 {
1435 intLevels[i - 1] = Integer.parseInt(strLevels[i]);
1436 }
1437
1438 return intLevels;
1439 }
1440
1441 public String getDocFilePathFromDatabase(String oid, String collection, String lang, String uid)
1442 {
1443 SimpleCollectionDatabase coll_db = openDatabase(collection, ARCHIVEINFDOC, SimpleCollectionDatabase.WRITE, lang, uid);
1444 if (coll_db == null)
1445 {
1446 return null;
1447 }
1448 DBInfo info = coll_db.getInfo(oid);
1449 if (info == null)
1450 {
1451 return null;
1452 }
1453
1454 String docFile = info.getInfo("doc-file");
1455 coll_db.closeDatabase();
1456 return docFile;
1457 }
1458
1459 public boolean deleteDirectory(File current)
1460 {
1461 try
1462 {
1463 if (current == null || !current.exists())
1464 {
1465 return false;
1466 }
1467
1468 if (!current.isDirectory())
1469 {
1470 current.delete();
1471 return true;
1472 }
1473
1474 for (File f : current.listFiles())
1475 {
1476 if (f.isDirectory())
1477 {
1478 deleteDirectory(f);
1479 }
1480 else
1481 {
1482 f.delete();
1483 }
1484 }
1485 current.delete();
1486 }
1487 catch (Exception ex)
1488 {
1489 return false;
1490 }
1491
1492 return true;
1493 }
1494
1495 public int checkOIDandCollection(String oid, String collection, String lang, String uid)
1496 {
1497 if (oid == null || oid.equals(""))
1498 {
1499 return ERROR_OID_NOT_SPECIFIED;
1500 }
1501
1502 if (collection == null || collection.equals(""))
1503 {
1504 return ERROR_COLLECTION_NOT_SPECIFIED;
1505 }
1506
1507 if (!archiveCheckDocumentOrSectionExists(oid, collection, lang, uid))
1508 {
1509 return ERROR_SOURCE_DOCUMENT_OR_SECTION_DOES_NOT_EXIST;
1510 }
1511 return NO_ERROR;
1512 }
1513
1514 protected static String generateOID()
1515 {
1516 return "temp";
1517 }
1518
1519 public boolean copyDirectory(File src, File dest)
1520 {
1521 if (src.isDirectory())
1522 {
1523 //If the destination directory does not exist then create it
1524 if (!dest.exists())
1525 {
1526 dest.mkdir();
1527 }
1528
1529 //Get all the files in the directory
1530 String files[] = src.list();
1531 for (String file : files)
1532 {
1533 File srcFile = new File(src, file);
1534 File destFile = new File(dest, file);
1535
1536 if (!copyDirectory(srcFile, destFile))
1537 {
1538 return false;
1539 }
1540 }
1541 }
1542 else
1543 {
1544 try
1545 {
1546 FileChannel in = new FileInputStream(src).getChannel();
1547 FileChannel out = new FileOutputStream(dest).getChannel();
1548
1549 in.transferTo(0, in.size(), out);
1550
1551 in.close();
1552 out.close();
1553 }
1554 catch (Exception ex)
1555 {
1556 ex.printStackTrace();
1557 return false;
1558 }
1559 }
1560 return true;
1561 }
1562
1563 public Element getTopLevelSectionElement(Document docXML)
1564 {
1565 return (Element) GSXML.getChildByTagName(docXML.getDocumentElement(), GSXML.DOCXML_SECTION_ELEM);
1566 }
1567
1568 public boolean writeXMLFile(Document doc, String oid, String collection, String lang, String uid)
1569 {
1570 try
1571 {
1572 DOMSource source = new DOMSource(doc);
1573
1574 String test = archiveGetDocumentFilePath(oid, collection, lang, uid);
1575 File xmlFile = new File(test);
1576 Result result = new StreamResult(xmlFile);
1577
1578 Transformer transformer = TransformerFactory.newInstance().newTransformer();
1579 transformer.transform(source, result);
1580 }
1581 catch (Exception ex)
1582 {
1583 return false;
1584 }
1585 return true;
1586 }
1587
1588 public Document getDocXML(String oid, String collection, String lang, String uid)
1589 {
1590 if (oid.contains("."))
1591 {
1592 oid = oid.substring(0, oid.indexOf("."));
1593 }
1594
1595 Document docXML = null;
1596 if ((docXML = _docCache.get(oid + "__" + collection)) == null)
1597 {
1598 String filePath = archiveGetDocumentFilePath(oid, collection, lang, uid);
1599 File docFile = new File(filePath);
1600
1601 if (!docFile.exists())
1602 {
1603 return null;
1604 }
1605
1606 try
1607 {
1608 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1609 DocumentBuilder db = dbf.newDocumentBuilder();
1610 docXML = db.parse(docFile);
1611
1612 _docCache.put(oid + "__" + collection, docXML);
1613 }
1614 catch (Exception ex)
1615 {
1616 return null;
1617 }
1618 }
1619 return docXML;
1620 }
1621
1622 public ArrayList<Element> getMetadataElementsFromSection(Document docXML, String oid, String metadataName)
1623 {
1624 if (oid.contains("."))
1625 {
1626 Element section = getSectionBySectionNumber(docXML, getSectionFromOID(oid));
1627 return getMetadataElementsFromSection(section, metadataName);
1628 }
1629 else
1630 {
1631 return getMetadataElementsFromSection(getTopLevelSectionElement(docXML), metadataName);
1632 }
1633 }
1634
1635 public ArrayList<Element> getMetadataElementsFromSection(Element section, String metadataName)
1636 {
1637 Element description = (Element) GSXML.getChildByTagName(section, GSXML.DOCXML_DESCRIPTION_ELEM);
1638 if (description == null)
1639 {
1640 return null;
1641 }
1642
1643 ArrayList<Element> elemList = new ArrayList<Element>();
1644 NodeList metadataNodes = GSXML.getChildrenByTagName(description, GSXML.DOCXML_METADATA_ELEM);
1645 for (int j = 0; j < metadataNodes.getLength(); j++)
1646 {
1647 //If this is a metadata element with the requested name then we have found what we are looking for
1648 if (((Element) metadataNodes.item(j)).getAttribute(GSXML.NAME_ATT).equals(metadataName))
1649 {
1650 elemList.add((Element) metadataNodes.item(j));
1651 }
1652 }
1653
1654 return elemList;
1655 }
1656
1657 public Element getSectionBySectionNumber(Document docXML, String sectionNum)
1658 {
1659 return getSectionBySectionNumber(getTopLevelSectionElement(docXML), sectionNum);
1660 }
1661
1662 public Element getSectionBySectionNumber(Element current, String sectionNum)
1663 {
1664 if (sectionNum == null || sectionNum.equals(""))
1665 {
1666 return current;
1667 }
1668
1669 try
1670 {
1671 String[] levels = sectionNum.split("\\.");
1672 int currentSectionNum = Integer.parseInt(levels[0]);
1673
1674 NodeList sections = GSXML.getChildrenByTagName(current, GSXML.DOCXML_SECTION_ELEM);
1675
1676 if (levels.length > 1)
1677 {
1678 return getSectionBySectionNumber((Element) sections.item(currentSectionNum - 1), sectionNum.substring(sectionNum.indexOf(".") + 1));
1679 }
1680 else
1681 {
1682 return (Element) sections.item(currentSectionNum - 1);
1683 }
1684 }
1685 catch (Exception ex)
1686 {
1687 return null;
1688 }
1689 }
1690
1691 public String getDatabaseTypeFromCollection(String collection, String lang, String uid)
1692 {
1693 //Find out what kind of database we have
1694 Element dbTypeMessage = _mainDoc.createElement(GSXML.MESSAGE_ELEM);
1695 Element dbTypeRequest = GSXML.createBasicRequest(_mainDoc, GSXML.REQUEST_TYPE_DESCRIBE, collection, lang, uid);
1696 dbTypeMessage.appendChild(dbTypeRequest);
1697 Element dbTypeResponse = (Element) _router.process(dbTypeMessage);
1698
1699 String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.COLLECTION_ELEM);
1700 Element collectionElem = (Element) GSXML.getNodeByPath(dbTypeResponse, path);
1701
1702 if (collectionElem != null)
1703 {
1704 return collectionElem.getAttribute(GSXML.DB_TYPE_ATT);
1705 }
1706 return "gdbm"; //The default collection database type
1707 }
1708
1709 public SimpleCollectionDatabase openDatabase(String collection, String dbName, int readWrite, String lang, String uid)
1710 {
1711 //Find out what kind of database we have
1712 String databaseType = getDatabaseTypeFromCollection(collection, lang, uid);
1713 String dbExt = DBHelper.getDBExtFromDBType(databaseType);
1714
1715 SimpleCollectionDatabase coll_db = new SimpleCollectionDatabase(databaseType);
1716 if (!coll_db.databaseOK())
1717 {
1718 System.err.println("Couldn't create the collection database of type " + databaseType);
1719 return null;
1720 }
1721
1722 coll_db.openDatabase(_siteHome + File.separatorChar + "collect" + File.separatorChar + collection + File.separatorChar + "archives" + File.separatorChar + dbName + dbExt, readWrite);
1723
1724 return coll_db;
1725 }
1726}
Note: See TracBrowser for help on using the repository browser.