View Javadoc
1   package org.kuali.ole.docstore.document.jcr;
2   
3   import org.apache.commons.lang.StringUtils;
4   import org.apache.commons.lang.time.StopWatch;
5   import org.kuali.ole.RepositoryManager;
6   import org.kuali.ole.docstore.OleDocStoreException;
7   import org.kuali.ole.docstore.common.document.content.instance.InstanceCollection;
8   import org.kuali.ole.docstore.common.document.content.instance.Item;
9   import org.kuali.ole.docstore.common.document.content.instance.Items;
10  import org.kuali.ole.docstore.common.document.content.instance.xstream.InstanceOlemlRecordProcessor;
11  import org.kuali.ole.docstore.document.AbstractDocumentManager;
12  import org.kuali.ole.docstore.document.DocumentManager;
13  import org.kuali.ole.docstore.model.enums.DocCategory;
14  import org.kuali.ole.docstore.model.enums.DocFormat;
15  import org.kuali.ole.docstore.model.enums.DocType;
16  import org.kuali.ole.docstore.model.xmlpojo.ingest.*;
17  import org.kuali.ole.docstore.common.document.content.instance.Instance;
18  import org.kuali.ole.docstore.process.ProcessParameters;
19  import org.kuali.ole.docstore.process.batch.BulkProcessRequest;
20  import org.kuali.ole.docstore.repository.CustomNodeManager;
21  import org.kuali.ole.docstore.repository.NodeManager;
22  import org.kuali.ole.docstore.repository.WorkInstanceNodeManager;
23  import org.kuali.ole.docstore.service.BeanLocator;
24  import org.kuali.ole.docstore.service.OleUuidCheckWebService;
25  import org.kuali.ole.docstore.service.OleWebServiceProvider;
26  import org.kuali.ole.docstore.service.ServiceLocator;
27  import org.kuali.ole.docstore.service.impl.OleWebServiceProviderImpl;
28  import org.kuali.ole.docstore.utility.BatchIngestStatistics;
29  import org.kuali.ole.docstore.utility.BulkIngestStatistics;
30  import org.kuali.ole.pojo.OleException;
31  import org.kuali.ole.repository.NodeHandler;
32  import org.kuali.rice.core.api.config.property.ConfigContext;
33  import org.slf4j.Logger;
34  import org.slf4j.LoggerFactory;
35  
36  import javax.jcr.Binary;
37  import javax.jcr.Node;
38  import javax.jcr.RepositoryException;
39  import javax.jcr.Session;
40  import javax.jcr.version.VersionHistory;
41  import javax.jcr.version.VersionIterator;
42  import javax.jcr.version.VersionManager;
43  import java.io.ByteArrayInputStream;
44  import java.io.FileNotFoundException;
45  import java.util.*;
46  
47  import static org.kuali.ole.docstore.process.ProcessParameters.FILE;
48  
49  /**
50   * Provides the common and basic implementation for the DocumentManager interface.
51   *
52   * @author tirumalesh.b
53   * @version %I%, %G%
54   *          Date: 28/8/12 Time: 12:22 PM
55   */
56  public abstract class JcrAbstractDocumentManager
57          extends AbstractDocumentManager {
58      private Logger logger = LoggerFactory.getLogger(this.getClass());
59  
60      public static DocCategory docCategory;
61      public static DocType docType;
62      public static DocFormat docFormat;
63      //    private static final String DELETE_WITH_LINKED_DOCS = "deleteWithLinkedDocs";
64      private static final String BIBLIOGRAPHIC = "bibliographic";
65      private static final String INSTANCE_IDENTIFIER = "instanceIdentifier";
66      private static final String SUCCESS = "Success";
67      private static final String FAILURE = "Failure";
68  
69      protected RepositoryManager repositoryManager;
70      protected NodeManager nodeManager;
71  
72      public JcrAbstractDocumentManager() {
73          try {
74              this.repositoryManager = RepositoryManager.getRepositoryManager();
75          } catch (OleException oe) {
76              //throw new OleDocStoreException(oe);
77              // TODO: log the exception
78          }
79          this.nodeManager = CustomNodeManager.getInstance();
80      }
81  
82      /**
83       * @inheritDoc
84       */
85      @Override
86      public List<ResponseDocument> ingest(List<RequestDocument> requestDocuments, Object object)
87              throws OleDocStoreException {
88          Session session = (Session) object;
89          if (null == session) {
90              throw new OleDocStoreException("Invalid session.");
91          }
92          ResponseDocument respDoc = new ResponseDocument();
93          // Store data in docstore, but do not commit.
94          for (RequestDocument requestDocument : requestDocuments) {
95              ingest(requestDocument, session, respDoc);
96          }
97  
98          List<ResponseDocument> responseDocuments = buildResponseDocuments(
99                  requestDocuments); //buildResponseDocuments(requestDocuments);
100         return responseDocuments;
101     }
102 
103     @Override
104     public ResponseDocument ingest(RequestDocument requestDocument, Object object, ResponseDocument respDoc) throws OleDocStoreException {
105         Session session = (Session) object;
106         if (null == session) {
107             throw new OleDocStoreException("Invalid session.");
108         }
109         // Store the document of the requestDocument.
110         Node fileNode = storeDocument(requestDocument, session, respDoc);
111 
112         // Store the linked documents of the requestDocument.
113         storeLinkedDocuments(requestDocument, fileNode, session, respDoc);
114         return respDoc;
115     }
116 
117 
118     @Override
119     public List<ResponseDocument> checkout(List<RequestDocument> requestDocuments, Object object) throws OleDocStoreException {
120         // TODO: implement this.
121         return null;
122     }
123 
124     @Override
125     public ResponseDocument checkout(RequestDocument requestDocument, Object object) throws OleDocStoreException {
126         Session session = (Session) object;
127         String content = "";
128         String uuid = requestDocument.getUuid();
129         if (session == null) {
130             throw new OleDocStoreException("Invalid session.");
131         }
132         try {
133             Node nodeByUUID = nodeManager.getNodeByUUID(session, uuid);
134             if (nodeByUUID != null) {
135                 content = checkOutContent(nodeByUUID, requestDocument.getFormat(), requestDocument.getUser());
136             }
137         } catch (Exception e) {
138             logger.error("Error in checking out the file. Please refer to the logs for more details!" + e.getMessage(),
139                     e);
140             throw new OleDocStoreException(e);
141         }
142 
143         ResponseDocument respDoc = new ResponseDocument();
144         Content contentObj = new Content();
145         contentObj.setContent(content);
146         respDoc.setContent(contentObj);
147         String category = requestDocument.getCategory();
148         String type = requestDocument.getType();
149         AdditionalAttributes additionalAttributes = new AdditionalAttributes();
150         Map<String, String> map = additionalAttributes.getAttributeMap();
151         Node node = null;
152         try {
153             node = session.getNodeByIdentifier(requestDocument.getUuid());
154         } catch (RepositoryException e) {
155             logger.info("Failed to get Node:" + e.getMessage(), e);
156         }
157 
158         if (node != null) {
159             try {
160 
161                 Collection<String> attributeKeyCollection = additionalAttributes.getAdditionalAttributeKeyCollection();
162                 for (String key : attributeKeyCollection) {
163                     if (node.hasProperty(key)) {
164                         additionalAttributes.setAttribute(key, node.getProperty(key).getString());
165                     }
166                 }
167 
168                 if (additionalAttributes != null && category.equals(DocCategory.WORK.getDescription()) && type
169                         .equals(DocType.BIB.getDescription())) {
170                     respDoc.setAdditionalAttributes(additionalAttributes);
171                 }
172             } catch (RepositoryException e) {
173                 logger.info("Failed to get node property:" + e.getMessage(), e);
174             }
175         }
176 
177         return respDoc;
178     }
179 
180     protected String checkOutContent(Node nodeByUUID, String format, String user)
181             throws RepositoryException, OleDocStoreException, FileNotFoundException {
182         String content = nodeManager.getData(nodeByUUID);
183         return content;
184     }
185 
186     @Override
187     public List<ResponseDocument> checkin(List<RequestDocument> requestDocuments, Object object) throws OleDocStoreException {
188         // TODO: implement this.
189         return null;
190     }
191 
192     @Override
193     public ResponseDocument checkin(RequestDocument requestDocument, Object object, ResponseDocument respDoc) throws OleDocStoreException {
194         Session session = (Session) object;
195         String checkInFail = "Check in failed. ";
196         if (requestDocument.getId() != null || requestDocument.getId().trim().length() > 0) {
197             requestDocument.setUuid(requestDocument.getId());
198         }
199 
200         //adding new record to docstore but do not commit
201         addNewRecordsToDocStore(requestDocument, session); // item for instance
202 
203         try {
204             // Store data in docstore and update version if enables .
205             String version = updateDocstore(requestDocument, session);
206         } catch (Exception e) {
207             logger.info(
208                     "Document was updated in indexer but not in docStore, trying to rollback the changes from indexer",
209                     e);
210             /* try {
211                 session.refresh(false);
212                 if (session == null) {
213                     session = repositoryManager.getSession();
214                 }
215                 Node nodeByUUID = nodeManager.getNodeByUUID(session, requestDocument.getId());
216                 RequestDocument prevRequestDoc = new RequestDocument();
217                 prevRequestDoc = requestDocument;
218                 String prevContent = nodeByUUID.getNode("jcr:content").getProperty("jcr:data").getValue().getString();
219                 prevRequestDoc.getContent().setContent(prevContent);
220                 ServiceLocator.getIndexerService().indexDocument(prevRequestDoc);
221             }
222             catch (Exception ex) {
223                 String failMsg = checkInFail + "Unable to Roll back the changes in indexer.  Record UUID "
224                                  + requestDocument.getId() + "got updated in indexer, but not in docstore ";
225                 logger.info(failMsg, ex);
226                 throw new OleDocStoreException(failMsg, ex);
227             }*/
228             logger.info(checkInFail, e);
229             throw new OleDocStoreException(checkInFail, e);
230         }
231         //return buildResponseDocument(requestDocument);
232         buildResponseDocument(requestDocument, session, respDoc);
233         //return buildResponseDocument(requestDocument, session);
234         return respDoc;
235     }
236 
237     protected void addNewRecordsToDocStore(RequestDocument requestDocument, Session session)
238             throws OleDocStoreException {
239     }
240 
241 
242     public String updateDocstore(RequestDocument reqDoc, Session session)
243             throws OleDocStoreException, RepositoryException, FileNotFoundException {
244 
245         Node nodeByUUID = session.getNodeByIdentifier(reqDoc.getUuid());
246         modifyContent(reqDoc, session, nodeByUUID);
247         byte[] documentBytes = convertContentToBytes(reqDoc);
248         modifyAdditionalAttributes(reqDoc, nodeByUUID);
249         updateContentToNode(reqDoc, session, documentBytes, nodeByUUID);
250         //Get the updated version from docstore.
251         String currentVersion = updateVersion(session, nodeByUUID);
252         return currentVersion;
253     }
254 
255     protected void modifyContent(RequestDocument reqDoc, Session session, Node node) throws RepositoryException, FileNotFoundException, OleDocStoreException {
256     }
257 
258     protected String updateVersion(Session session, Node nodeByUUID) throws RepositoryException, OleDocStoreException {
259         session.save();
260         String currentVersion = null;
261         if (isVersioningEnabled()) {
262             VersionManager versionManager = getVersionManager(session);
263             versionManager.checkpoint(nodeByUUID.getPath());
264             VersionHistory versionHistory = versionManager.getVersionHistory(nodeByUUID.getPath());
265             VersionIterator allVersions = versionHistory.getAllVersions();
266             while (allVersions.hasNext()) {
267                 currentVersion = allVersions.nextVersion().getName();
268             }
269             logger.info("Version updated for UUID:" + nodeByUUID.getIdentifier() + "  ====  version:" + currentVersion);
270         }
271         return currentVersion;
272     }
273 
274     protected void updateContentToNode(RequestDocument reqDoc, Session session, byte[] documentBytes, Node nodeByUUID)
275             throws RepositoryException, OleDocStoreException {
276         try {
277             Binary binary = null;
278             if (documentBytes != null) {
279                 binary = session.getValueFactory().createBinary(new ByteArrayInputStream(documentBytes));
280                 nodeByUUID.getNode("jcr:content").setProperty("jcr:data", binary);
281             }
282 
283             AdditionalAttributes additionalAttributes = reqDoc.getAdditionalAttributes();
284             if (additionalAttributes != null) {
285                 Collection<String> attributeNames = additionalAttributes.getAttributeNames();
286                 if (attributeNames != null && attributeNames.size() > 0) {
287                     for (Iterator<String> iterator = attributeNames.iterator(); iterator.hasNext(); ) {
288                         String attributeName = iterator.next();
289                         String attributeValue = additionalAttributes.getAttribute(attributeName);
290                         nodeByUUID.setProperty(attributeName, attributeValue);
291                     }
292                 }
293 
294             }
295             Calendar lastModified = Calendar.getInstance();
296             lastModified.setTimeInMillis(lastModified.getTimeInMillis());
297         } catch (Exception e) {
298             logger.info(e.getMessage());
299             throw new OleDocStoreException(e.getMessage(), e);
300         }
301     }
302 
303     protected byte[] convertContentToBytes(RequestDocument reqDoc) throws OleDocStoreException {
304         String charset = "UTF-8";
305         byte[] documentBytes = null;
306         try {
307             if (reqDoc.getContent().getContent() != null) {
308                 documentBytes = reqDoc.getContent().getContent().getBytes(charset);
309             }
310         } catch (Exception e) {
311             logger.info("Failed to convert input string to byte[] with charset " + charset, e);
312             throw new OleDocStoreException(e.getMessage());
313         }
314         return documentBytes;
315     }
316 
317     protected String updateIndex(RequestDocument requestDocument) throws OleDocStoreException {
318         String result = "failure";
319         result = updateRecord(requestDocument);
320         if (!result.startsWith("success")) {
321             throw new OleDocStoreException("Check in failed. " + result);
322         }
323         return result;
324     }
325 
326     protected String updateRecord(RequestDocument requestDocument) {
327         String result = ServiceLocator.getIndexerService().indexDocument(requestDocument);
328         return result;
329     }
330 
331 
332     @Override
333     public List<ResponseDocument> delete(List<RequestDocument> requestDocuments, Object object) throws OleDocStoreException {
334         // TODO: implement this.
335         return null;
336     }
337 
338     @Override
339     public ResponseDocument delete(RequestDocument requestDocument, Object object) throws Exception {
340         Session session = (Session) object;
341         ResponseDocument rs = new ResponseDocument();
342         try {
343             rs = deleteDoc(requestDocument, session);
344         } catch (Exception e) {
345             throw new OleDocStoreException(e.getMessage(), e);
346         }
347         return rs;
348     }
349 
350     /**
351      * @inheritDoc
352      */
353     @Override
354     public void bulkIngest(BulkProcessRequest bulkProcessRequest, List<RequestDocument> requestDocuments)
355             throws OleDocStoreException {
356         Session session = bulkProcessRequest.getSession();
357         if (session == null) {
358             try {
359                 session = RepositoryManager.getRepositoryManager().getSession(bulkProcessRequest.getUser(),
360                         bulkProcessRequest.getOperation()
361                                 .toString());
362             } catch (Exception e) {
363                 throw new OleDocStoreException(e);
364             }
365             bulkProcessRequest.setSession(session);
366         }
367         if (bulkProcessRequest.getPreviousBatchDocuments() == null) {
368             List<RequestDocument> newList = new ArrayList<RequestDocument>();
369             bulkProcessRequest.setPreviousBatchDocuments(newList);
370         }
371         bulkProcessRequest.getPreviousBatchDocuments().addAll(requestDocuments);
372 
373         batchIngest(bulkProcessRequest, requestDocuments, session);
374 
375         if (session != null) {
376             try {
377                 if (bulkProcessRequest.getBulkIngestStatistics().isLastBatch()) {
378                     RepositoryManager.getRepositoryManager().logout(session);
379                     session = null;
380                 }
381             } catch (OleException e) {
382             }
383         }
384     }
385 
386     private ResponseDocument deleteDoc(RequestDocument document, Session session1) throws Exception {
387         //List<String> uuidsList = new ArrayList<String>();
388         String status = null;
389         String category = null;
390         Response response = new Response();
391         List<String> respositoryUuidList = new ArrayList<String>();
392         category = document.getCategory();
393         String uuid = document.getUuid();
394         String operation = document.getOperation();
395         respositoryUuidList = getLinkedDocsFromRepository(uuid, session1, respositoryUuidList, operation);
396         logger.info("respository UuidList size-->" + respositoryUuidList);
397         deleteFromRepository(respositoryUuidList, session1);
398         String statusValue = ServiceLocator.getIndexerService().deleteDocuments(category, respositoryUuidList);
399         return prepareResponseDocument(document);
400 
401     }
402 
403     private ResponseDocument prepareResponseDocument(RequestDocument requestDocument) {
404         ResponseDocument responseDocument = new ResponseDocument();
405         responseDocument.setStatus("success");
406         responseDocument.setStatusMessage("Success");
407         responseDocument.setUuid(requestDocument.getUuid());
408         return responseDocument;
409     }
410 
411     private List<String> getLinkedDocsFromRepository(String uuid, Session session, List<String> respositoryUuidList,
412                                                      String operation) throws Exception {
413         if (operation.equalsIgnoreCase(Request.Operation.deleteWithLinkedDocs.toString())) {
414             Node node = session.getNodeByIdentifier(uuid);
415             if (node.getPath().contains(BIBLIOGRAPHIC)) {
416                 String instanceId = node.getProperty(INSTANCE_IDENTIFIER).getString();
417                 respositoryUuidList.add(instanceId);
418             }
419         }
420         respositoryUuidList.add(uuid);
421         return respositoryUuidList;
422     }
423 
424     protected void deleteFromRepository(List<String> uuidsList, Session session) throws Exception {
425         if (uuidsList != null && uuidsList.size() > 0) {
426             for (int i = 0; i < uuidsList.size(); i++) {
427                 Node deleteNode = new NodeHandler().getNodeByUUID(session, uuidsList.get(i));
428                 if (deleteNode != null) {
429                     deleteNode.remove();
430                 }
431             }
432         }
433     }
434 
435     public List<String> batchIngest(BulkProcessRequest bulkProcessRequest, List<RequestDocument> requestDocuments,
436                                     Session session) {
437         //RequestDocument requestDocument = request.getRequestDocuments().get(0);
438         //DocumentManager documentManager = BeanLocator.getDocumentManagerFactory().getDocumentManager(requestDocument);
439         BulkIngestStatistics bulkIngestStatistics = bulkProcessRequest.getBulkIngestStatistics();
440         BatchIngestStatistics batchStatistics = bulkIngestStatistics.getCurrentBatch();
441         long commitSize = ProcessParameters.BULK_INGEST_COMMIT_SIZE;
442         logger.debug("commitSize = " + commitSize);
443         logger.debug("bulkIngestNIndex(" + requestDocuments.size() + ") START");
444         logger.debug("BULK_INGEST_IS_LINKING_ENABLED=" + ProcessParameters.BULK_INGEST_IS_LINKING_ENABLED);
445         //Session session = null;
446         List<String> docUUIDs = new ArrayList<String>();
447         StopWatch ingestTimer = new StopWatch();
448         StopWatch indexTimer = new StopWatch();
449         StopWatch totalTimer = new StopWatch();
450         StopWatch createNodesTimer = new StopWatch();
451         StopWatch sessionSaveTimer = new StopWatch();
452         StopWatch solrOptimizeTimer = new StopWatch();
453         long recCount = requestDocuments.size();
454         boolean isCommit = false;
455         totalTimer.start();
456         try {
457             ingestTimer.start();
458             createNodesTimer.start();
459             //session = RepositoryManager.getRepositoryManager().getSession(request.getUser(), request.getOperation());
460             //List<RequestDocument> reqDocs = requestDocuments;
461             //docUUIDs.addAll(documentIngester.ingestRequestDocumentsForBulk(requestDocuments, session));
462             //docUUIDs.addAll(documentIngester.ingestRequestDocumentsForBulkUsingBTreeMgr(reqDocs, session));
463             store(requestDocuments, session);
464             createNodesTimer.stop();
465             try {
466                 ingestTimer.suspend();
467                 indexTimer.start();
468             } catch (Exception e2) {
469                 logger.info("Exception :" + e2);
470             }
471             bulkIngestStatistics.setCommitRecCount(bulkIngestStatistics.getCommitRecCount() + recCount);
472             if (bulkIngestStatistics.getCommitRecCount() == commitSize || bulkIngestStatistics.isLastBatch()) {
473                 isCommit = true;
474             }
475             //documentIndexer.indexDocumentsForBulk(requestDocuments, isCommit);
476             index(requestDocuments, isCommit);
477             try {
478                 indexTimer.suspend();
479                 ingestTimer.resume();
480             } catch (Exception e2) {
481                 logger.info("Exception :" + e2);
482             }
483             if (isCommit) {
484                 sessionSaveTimer.start();
485                 logger.info("Bulk ingest: Repository commit started. Number of records being committed : "
486                         + bulkIngestStatistics.getCommitRecCount());
487                 session.save();
488                 bulkIngestStatistics.setCommitRecCount(0);
489                 bulkProcessRequest.setPreviousBatchDocuments(null);
490                 sessionSaveTimer.stop();
491             }
492 
493             try {
494                 ingestTimer.stop();
495             } catch (Exception e2) {
496                 logger.info("Exception :" + e2);
497             }
498             // Documents processed can be different from records processed as in the case of Instance data.
499             logger.debug("Documents processed:" + recCount);
500             bulkIngestStatistics.setFileRecCount(bulkIngestStatistics.getFileRecCount() + recCount);
501             logger.info(
502                     "Bulk ingest: Records processed in the current file :" + bulkIngestStatistics.getFileRecCount());
503         } catch (Exception e) {
504             logger.info("Exception :" + e);
505             bulkIngestStatistics.setCommitRecCount(0);
506             try {
507                 ingestTimer.resume();
508             } catch (Exception e2) {
509                 logger.info("Exception :" + e2);
510             }
511             //documentIngester.rollbackDocStoreIngestedData(session, request.getRequestDocuments());
512             //documentIngester.rollbackDocStoreIngestedData(session, prevRequestDocs);
513             delete(bulkProcessRequest.getPreviousBatchDocuments(), session);
514             ingestTimer.stop();
515             try {
516                 indexTimer.resume();
517             } catch (Exception e2) {
518                 logger.info("Exception :" + e2);
519             }
520             //documentIndexer.rollbackIndexedData(request.getRequestDocuments());
521             //prevRequestDocs = prevRequestDocs.subList(0, prevRequestDocs.size() - request.getRequestDocuments().size());
522             //logger.info("prevRequestDocs before remove INDEXES = " + prevRequestDocs.size());
523             //documentIndexer.rollbackIndexedData(prevRequestDocs);
524             try {
525                 deleteIndex(bulkProcessRequest.getPreviousBatchDocuments());
526                 indexTimer.stop();
527             } catch (Exception e2) {
528                 logger.info("Exception :" + e2);
529             }
530             bulkProcessRequest.setPreviousBatchDocuments(null);
531             logger.error("Document Ingest & Index Failed, Cause: " + e.getMessage(), e);
532             try {
533                 totalTimer.stop();
534             } catch (Exception e2) {
535                 logger.info("Exception :" + e2);
536             }
537             logger.debug("Time Consumptions...:\tcreatingNodes(" + docUUIDs.size() + "):" + createNodesTimer
538                     + "\tSessionSave(" + docUUIDs.size() + "):" + sessionSaveTimer + "\tIngest(" + docUUIDs.size()
539                     + "):" + ingestTimer + "\tIndexing(" + docUUIDs.size() + "):" + indexTimer + "\tTotal Time: "
540                     + totalTimer);
541             docUUIDs.clear();
542         } finally {
543             /*if (session != null) {
544                 try {
545                     RepositoryManager.getRepositoryManager().logout(session);
546                 } catch (OleException e) {
547                 }
548             } */
549         }
550         try {
551             totalTimer.stop();
552         } catch (Exception exe) {
553             logger.info("Exception :" + exe);
554         }
555         logger.debug(
556                 "Time Consumptions...:\tcreatingNodes(" + docUUIDs.size() + "):" + createNodesTimer + "\tSessionSave("
557                         + docUUIDs.size() + "):" + sessionSaveTimer + "\tIngest(" + docUUIDs.size() + "):" + ingestTimer
558                         + "\tIndexing(" + docUUIDs.size() + "):" + indexTimer + "\tTotal Time: " + totalTimer);
559         logger.debug("bulkIngestNIndex(" + requestDocuments.size() + ") END");
560         batchStatistics.setTimeToCreateNodesInJcr(createNodesTimer.getTime());
561         batchStatistics.setTimeToSaveJcrSession(sessionSaveTimer.getTime());
562         batchStatistics.setIngestingTime(ingestTimer.getTime());
563         batchStatistics.setIndexingTime(indexTimer.getTime());
564         batchStatistics.setIngestNIndexTotalTime(totalTimer.getTime());
565         //updateProcessTimer(docUUIDs.size(), ingestTimer, indexTimer, totalTimer);
566         solrOptimizeTimer.start();
567         //optimizeSolr(docUUIDs.size());
568         solrOptimizeTimer.stop();
569         batchStatistics.setTimeToSolrOptimize(solrOptimizeTimer.getTime());
570         return docUUIDs;
571     }
572 
573 
574     /**
575      * @inheritDoc
576      */
577     //@Override
578     public void store(List<RequestDocument> requestDocuments, Session session) throws OleDocStoreException {
579         for (RequestDocument requestDocument : requestDocuments) {
580             store(requestDocument, session);
581         }
582     }
583 
584     /**
585      * @inheritDoc
586      */
587     @Override
588     public void index(List<RequestDocument> requestDocuments, boolean commit) throws OleDocStoreException {
589         if (commit == true) {
590             String result = ServiceLocator.getIndexerService().indexDocuments(requestDocuments);
591             if (!result.startsWith("success")) {
592                 throw new OleDocStoreException(result);
593             }
594         } else {
595             String result = ServiceLocator.getIndexerService().bulkIndexDocuments(requestDocuments, commit);
596             if (!result.startsWith("success")) {
597                 throw new OleDocStoreException(result);
598             }
599         }
600     }
601 
602     protected void delete(List<RequestDocument> requestDocuments, Session session) {
603         // TODO: implement this.
604     }
605 
606     /**
607      * @inheritDoc
608      */
609     //@Override
610     public void deleteIndex(List<RequestDocument> requestDocuments) throws OleDocStoreException {
611         try {
612             Map<String, List<String>> uuids = new HashMap<String, List<String>>();
613             for (RequestDocument document : requestDocuments) {
614                 for (RequestDocument linkedDoc : document.getLinkedRequestDocuments()) {
615                     if (uuids.get(linkedDoc.getCategory()) == null) {
616                         uuids.put(linkedDoc.getCategory(), new ArrayList<String>());
617                     }
618                     uuids.get(linkedDoc.getCategory()).add(linkedDoc.getUuid());
619                 }
620                 if (uuids.get(document.getCategory()) == null) {
621                     uuids.put(document.getCategory(), new ArrayList<String>());
622                 }
623                 uuids.get(document.getCategory()).add(document.getUuid());
624             }
625             for (String category : uuids.keySet()) {
626                 ServiceLocator.getIndexerService().deleteDocuments(category, uuids.get(category));
627             }
628         } catch (Exception e) {
629             throw new OleDocStoreException(e);
630         }
631 
632     }
633 
634     public void store(RequestDocument requestDocument, Session session) throws OleDocStoreException {
635         // Store the document of the requestDocument.
636         ResponseDocument responseDocument = new ResponseDocument();
637         Node fileNode = storeDocument(requestDocument, session, responseDocument);
638 
639         // Store the linked documents of the requestDocument.
640         storeLinkedDocuments(requestDocument, fileNode, session, responseDocument);
641     }
642 
643     public Node storeDocument(RequestDocument requestDocument, Object object, ResponseDocument responseDocument) throws OleDocStoreException {
644         Session session = (Session) object;
645         Node fileNode = null;
646         String validationMsg = null;
647         try {
648             AdditionalAttributes additionalAttributes = requestDocument.getAdditionalAttributes();
649             modifyAdditionalAttributes(requestDocument, null);
650 
651             // get the parent node
652             Node parentNode = nodeManager.getParentNode(requestDocument, session);
653             String fileName = requestDocument.getFormat() + FILE;
654 
655             // create the file node
656             fileNode = nodeManager.createFileNode(requestDocument, fileName, parentNode, session);
657 
658             if (isVersioningEnabled()) {
659                 nodeManager.enableVersioning(fileNode);
660             }
661 
662             // modify document content with node identifier information
663             String parentNodeIdentifier = parentNode.getIdentifier();
664             String nodeIdentifier = fileNode.getIdentifier();
665             modifyDocumentContent(requestDocument, nodeIdentifier, parentNodeIdentifier);
666 
667             // create content node for the document
668             Node contentNode = nodeManager.createContentNode(fileNode, requestDocument, parentNode, session);
669             buildResponseDocument(requestDocument, session, responseDocument);
670             if (validationMsg != null) {
671                 responseDocument.setStatusMessage(validationMsg);
672                 responseDocument.setStatus(ResponseStatus.INVALID_DATA.toString());
673             }
674         } catch (Exception e) {
675             throw new OleDocStoreException(e);
676         }
677         return fileNode;
678     }
679 
680     protected void storeLinkedDocuments(RequestDocument requestDocument, Node node, Session session, ResponseDocument responseDocument)
681             throws OleDocStoreException {
682         // store the linked documents if any.
683         List<ResponseDocument> linkedResponseDocumentList = new ArrayList<ResponseDocument>();
684         if (responseDocument.getLinkedDocuments() != null && responseDocument.getLinkedDocuments().size() > 0) {
685             linkedResponseDocumentList.addAll(responseDocument.getLinkedDocuments());
686         }
687         responseDocument.setLinkedDocuments(linkedResponseDocumentList);
688         for (RequestDocument linkedRequestDocument : requestDocument.getLinkedRequestDocuments()) {
689             ResponseDocument linkedResponseDocument = new ResponseDocument();
690             linkedResponseDocumentList.add(linkedResponseDocument);
691             DocumentManager documentManager = BeanLocator.getDocstoreFactory()
692                     .getDocumentManager(linkedRequestDocument.getCategory(), linkedRequestDocument.getType(), linkedRequestDocument.getFormat());
693             if (linkedRequestDocument.getContent().getContentObject() instanceof InstanceCollection) {
694                 InstanceCollection instCol = (InstanceCollection) linkedRequestDocument.getContent().getContentObject();
695                 if (instCol != null) {
696                     for (Instance inst : instCol.getInstance()) {
697                         List<String> resIdList = new ArrayList<String>();
698                         resIdList.addAll(inst.getResourceIdentifier());
699                         for (String resId : inst.getResourceIdentifier()) {
700                             try {
701                                 nodeManager.getNodeByUUID(session, resId);
702                             } catch (Exception e) {
703                                 resIdList.remove(resId);
704                             }
705                         }
706                         inst.setResourceIdentifier(resIdList);
707                     }
708                 }
709             }
710             Node linkedDocumentNode = documentManager.storeDocument(linkedRequestDocument, session, linkedResponseDocument);
711             nodeManager.linkNodes(node, linkedDocumentNode, session);
712             //buildResponseDocument(linkedRequestDocument,session,linkedResponseDocument);
713         }
714 
715     }
716 
717 /*    protected void validateInput(List<RequestDocument> requestDocuments) throws OleDocStoreException, RepositoryException, FileNotFoundException {
718         if ((null == requestDocuments) || (requestDocuments.size() == 0)) {
719             throw new OleDocStoreException("RequestDocuments are not specified.");
720         }
721         for (RequestDocument requestDocument : requestDocuments) {
722             validateInput(requestDocument );
723         }
724     }*/
725 
726 
727     public List<ResponseDocument> buildResponseDocuments(List<RequestDocument> requestDocuments) {
728         List<ResponseDocument> responseDocumentList = new ArrayList<ResponseDocument>();
729         for (int i = 0; i < requestDocuments.size(); i++) {
730             responseDocumentList.add(buildResponseDocument(requestDocuments.get(i)));
731         }
732         return responseDocumentList;
733     }
734 
735     public ResponseDocument buildResponseDocument(RequestDocument requestDocument) {
736         ResponseDocument responseDocument = new ResponseDocument();
737         responseDocument.setId(requestDocument.getId());
738         responseDocument.setCategory(requestDocument.getCategory());
739         responseDocument.setType(requestDocument.getType());
740         responseDocument.setFormat(requestDocument.getFormat());
741         responseDocument.setUuid(requestDocument.getUuid());
742         buildLinkedResponseDocuments(requestDocument, responseDocument);
743         return responseDocument;
744     }
745 
746     public void buildResponseDocument(RequestDocument requestDocument, Session session, ResponseDocument responseDocument) {
747         responseDocument.setId(requestDocument.getId());
748         responseDocument.setCategory(requestDocument.getCategory());
749         responseDocument.setType(requestDocument.getType());
750         responseDocument.setFormat(requestDocument.getFormat());
751         responseDocument.setUuid(requestDocument.getUuid());
752         String category = requestDocument.getCategory();
753         String type = requestDocument.getType();
754         Node node = null;
755         try {
756             node = session.getNodeByIdentifier(requestDocument.getUuid());
757         } catch (RepositoryException e) {
758             logger.info("Failed to get node:" + e.getMessage(), e);
759         }
760 
761         if (node != null) {
762             try {
763                 AdditionalAttributes additionalAttributes = requestDocument.getAdditionalAttributes();
764                 if (additionalAttributes != null && category.equals(DocCategory.WORK.getDescription()) && type
765                         .equals(DocType.BIB.getDescription())) {
766                     Collection<String> attributeNames = additionalAttributes.getAttributeNames();
767                     if (attributeNames != null && attributeNames.size() > 0) {
768                         for (Iterator<String> iterator = attributeNames.iterator(); iterator.hasNext(); ) {
769                             String attributeName = iterator.next();
770                             if (node.hasProperty(attributeName)) {
771                                 additionalAttributes
772                                         .setAttribute(attributeName, node.getProperty(attributeName).getString());
773                             }
774                         }
775                     }
776                     responseDocument.setAdditionalAttributes(additionalAttributes);
777                 }
778             } catch (RepositoryException e) {
779                 logger.info("Failed to get node property:" + e.getMessage(), e);
780             }
781         }
782 
783         if (requestDocument.getType().equalsIgnoreCase(DocType.INSTANCE.getCode())) {
784             buildLinkedResponseDocuments(requestDocument, responseDocument);
785         }
786         // buildLinkedResponseDocuments(requestDocument, responseDocument);
787         //  return responseDocument;
788     }
789 
790     protected void buildLinkedResponseDocuments(RequestDocument requestDocument, ResponseDocument responseDocument) {
791 
792     }
793 
794     protected void setResponseParameters(ResponseDocument responseDocument, RequestDocument docStoreDocument) {
795         responseDocument.setId(docStoreDocument.getId());
796         responseDocument.setCategory(docStoreDocument.getCategory());
797         responseDocument.setType(docStoreDocument.getType());
798         responseDocument.setFormat(docStoreDocument.getFormat());
799         responseDocument.setContent(docStoreDocument.getContent());
800         responseDocument.setUuid(docStoreDocument.getUuid());
801     }
802 
803 
804     protected void modifyAdditionalAttributes(RequestDocument requestDocument, Node node) {
805     }
806 
807     @Override
808     public ResponseDocument bind(RequestDocument requestDocument, Object object, String operation) throws OleDocStoreException, RepositoryException, OleException, FileNotFoundException {
809         Session session = (Session) object;
810         return new JcrWorkInstanceDocumentManager().bind(requestDocument, session, operation);
811     }
812 
813     @Override
814     public ResponseDocument unbind(RequestDocument requestDocument, Object object, String operation) throws OleDocStoreException, RepositoryException, OleException, FileNotFoundException {
815         Session session = (Session) object;
816         return new JcrWorkInstanceDocumentManager().unbind(requestDocument, session, operation);
817     }
818 
819     protected void modifyDocumentContent(RequestDocument requestDocument, String nodeIdentifier,
820                                          String parentNodeIdentifier) {
821     }
822 
823     public boolean isVersioningEnabled() {
824         return false;
825     }
826 
827     public VersionManager getVersionManager(Session session) throws OleDocStoreException, RepositoryException {
828         return session.getWorkspace().getVersionManager();
829     }
830 
831 //    public boolean checkItemsExists( List<Item> itemIdentifierList,Session session) throws Exception{
832 //        for (Item item : itemIdentifierList) {
833 //           //TODO
834 //       }
835 //        return false;
836 //    }
837 
838     public boolean checkItemsExists() throws Exception {
839 
840         //TODO
841 
842         return false;
843     }
844 
845 
846     public boolean checkInstancesOrItemsExistsInOLE(List<String> uuidsList) {
847         String uuidsNotInOle = null;
848         String serviceURL = ConfigContext.getCurrentContextConfig().getProperty("uuidCheckServiceURL");
849         OleWebServiceProvider oleWebServiceProvider = new OleWebServiceProviderImpl();
850         OleUuidCheckWebService oleUuidCheckWebService = (OleUuidCheckWebService) oleWebServiceProvider
851                 .getService("org.kuali.ole.docstore.service.OleUuidCheckWebService", "oleUuidCheckWebService", serviceURL);
852         StringBuilder uuidsSB = new StringBuilder();
853         for (String uuid : uuidsList) {
854             //uuidsSB.append(requestDocument.getId()).append(",");
855             uuidsSB.append(uuid).append(",");
856         }
857         logger.debug("JcrAbstractDocumentManager checkInstancesOrItemsExistsInOLE :uuidsSB " + uuidsSB.toString());
858         uuidsNotInOle = oleUuidCheckWebService.checkUuidExsistence(uuidsSB.substring(0, uuidsSB.length() - 1));
859         logger.debug("JcrAbstractDocumentManager checkInstancesOrItemsExistsInOLE :uuidsNotInOle " + uuidsNotInOle);
860         String[] uuids = StringUtils.split(uuidsNotInOle, ",");
861         if (uuids.length == uuidsList.size()) {
862             return false;
863         } else {
864             return true;
865         }
866         //false means not exists
867     }
868 
869     //checks whether instance and its corresponding item identifiers are exists in ole
870     public boolean checkInstancesOrItemsExistsInOLE(String instanceIdentifier, Session session) throws Exception {
871         String uuidsNotInOle = null;
872         List<String> instanceOrItemIdentifiersList = new ArrayList<String>();
873         Node instanceNode = session.getNodeByIdentifier(instanceIdentifier);
874         String instanceXML = WorkInstanceNodeManager.getInstance().getInstanceData(instanceNode);
875         InstanceCollection instanceCollection = new InstanceOlemlRecordProcessor().fromXML(instanceXML);
876         Items items = instanceCollection.getInstance().get(0).getItems();
877         List<Item> itemIdentifierList = items.getItem();
878         for (Item item : itemIdentifierList) {
879             instanceOrItemIdentifiersList.add(item.getItemIdentifier());
880         }
881         instanceOrItemIdentifiersList.add(instanceIdentifier);
882         return checkInstancesOrItemsExistsInOLE(instanceOrItemIdentifiersList);
883     }
884 
885     public boolean checkInstanceForBoundsWith(String instanceIdentifier, RequestDocument requestDocument,
886                                               Session session, ResponseDocument responseDocument) throws Exception {
887 
888         Node instanceNode = session.getNodeByIdentifier(instanceIdentifier);
889         String bibIdentifier = instanceNode.getProperty("bibIdentifier").getString();
890         String[] bibIds = bibIdentifier.split(",");
891         logger.debug("JcrAbstractDocumentManager : checkInstanceForBoundsWith bibIds length " + bibIds.length);
892         if (bibIds.length > 1) {
893             responseDocument.setCategory(requestDocument.getCategory());
894             responseDocument.setType(requestDocument.getType());
895             responseDocument.setFormat(requestDocument.getFormat());
896             responseDocument.setUuid(requestDocument.getUuid());
897             responseDocument.setStatus("failure'");
898             responseDocument.setStatusMessage("Instance is bound with more than one bid. So deletion cannot be done");
899             return true;
900         } else {
901             return false;
902         }
903     }
904 
905     public RequestDocument prepareRequestDocument(ResponseDocument responseDocument) {
906         RequestDocument requestDocument = new RequestDocument();
907         requestDocument.setCategory(responseDocument.getCategory());
908         requestDocument.setFormat(responseDocument.getFormat());
909         requestDocument.setType(responseDocument.getType());
910         requestDocument.setUuid(responseDocument.getUuid());
911         return requestDocument;
912 
913     }
914 }