View Javadoc

1   /*
2    * Copyright 2011 The Kuali Foundation.
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.repository;
17  
18  import org.apache.commons.io.FileUtils;
19  import org.kuali.ole.RepositoryManager;
20  import org.kuali.ole.docstore.DocStoreConstants;
21  import org.kuali.ole.docstore.model.enums.DocType;
22  import org.kuali.ole.docstore.model.xmlpojo.ingest.RequestDocument;
23  import org.kuali.ole.docstore.model.xmlpojo.work.instance.oleml.Item;
24  import org.kuali.ole.docstore.model.xmlpojo.work.instance.oleml.OleHoldings;
25  import org.kuali.ole.docstore.model.xmlpojo.work.instance.oleml.SourceHoldings;
26  import org.kuali.ole.docstore.model.xstream.work.instance.oleml.WorkHoldingOlemlRecordProcessor;
27  import org.kuali.ole.docstore.model.xstream.work.instance.oleml.WorkItemOlemlRecordProcessor;
28  import org.kuali.ole.docstore.model.xstream.work.instance.oleml.WorkSourceHoldingOlemlRecordProcessor;
29  import org.kuali.ole.docstore.process.ProcessParameters;
30  import org.kuali.ole.docstore.service.DocumentIndexer;
31  import org.kuali.ole.docstore.service.ServiceLocator;
32  import org.kuali.ole.logger.DocStoreLogger;
33  import org.kuali.ole.pojo.OleException;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  import javax.jcr.Binary;
38  import javax.jcr.Node;
39  import javax.jcr.RepositoryException;
40  import javax.jcr.Session;
41  import javax.jcr.version.VersionHistory;
42  import javax.jcr.version.VersionIterator;
43  import javax.jcr.version.VersionManager;
44  import java.io.ByteArrayInputStream;
45  import java.io.File;
46  import java.util.Calendar;
47  import java.util.Iterator;
48  
49  import static org.kuali.ole.docstore.process.ProcessParameters.FILE_ITEM;
50  
51  public class CheckinManager {
52  
53      DocStoreLogger docStoreLogger = new DocStoreLogger(this.getClass().getName());
54      private static final Logger LOG = LoggerFactory.getLogger(CheckinManager.class);
55  
56      public String updateContent(RequestDocument requestDocument) throws OleException {
57          //        List<String> ingestDocs = new ArrayList<String>();
58          //        List<String> uuids = new ArrayList<String>();
59          //        StringBuilder sb = new StringBuilder();
60          //        String uuid = null;
61          String content = null;
62          String latestVersion = null;
63          String checkInFail = "Check in failed. ";
64          content = requestDocument.getContent().getContent();
65          if (requestDocument.getUuid() == null || requestDocument.getUuid().trim().length() == 0) {
66              requestDocument.setUuid(requestDocument.getId());
67          }
68          //        uuid = requestDocument.getUuid();
69          //        ingestDocs.add(sb.toString());
70          //        uuids.add(uuid);
71          if (DocType.INSTANCE.getCode().equalsIgnoreCase(requestDocument.getType()) && content == null
72              && requestDocument.getId() != null) {
73              for (RequestDocument linkedItemDocument : requestDocument.getLinkedRequestDocuments()) {
74                  if (DocType.ITEM.getDescription().equalsIgnoreCase(linkedItemDocument.getType())
75                      && linkedItemDocument.getContent().getContent() != null) {
76                      ingestNIndexItemRecForInstance(requestDocument);
77                  }
78              }
79          }
80          if (!DocType.SOURCEHOLDINGS.getDescription().equalsIgnoreCase(requestDocument.getType())) {
81              String result = ServiceLocator.getIndexerService().indexDocument(requestDocument);
82              if (!result.startsWith("success")) {
83                  throw new OleException(checkInFail + result);
84              }
85          }
86          Session session = null;
87          try {
88              latestVersion = updateRecordInDocStore(requestDocument);
89          }
90          catch (Exception e) {
91              docStoreLogger
92                      .log("Document was updated in indexer but not in docStore, trying to rollback the changes from indexer",
93                           e);
94  
95              RequestDocument prevRequestDoc = null;
96              session = RepositoryManager.getRepositoryManager().getSession("CheckinManager", "checkIn");
97              Node nodeByUUID = getNodeByUUID(session, requestDocument.getId());
98              try {
99                  DocumentIndexer documentIndexer = new DocumentIndexer();
100                 prevRequestDoc = new RequestDocument();
101                 prevRequestDoc = requestDocument;
102                 String prevContent = nodeByUUID.getNode("jcr:content").getProperty("jcr:data").getValue().getString();
103                 prevRequestDoc.getContent().setContent(prevContent);
104                 documentIndexer.indexDocument(prevRequestDoc);
105             }
106             catch (Exception ex) {
107                 String failMsg = checkInFail + "Unable to Roll back the changes in indexer.  Record UUID "
108                                  + requestDocument.getId() + "got updated in indexer, but not in docstore ";
109                 docStoreLogger.log(failMsg, ex);
110                 throw new OleException(failMsg, ex);
111 
112             }
113             docStoreLogger.log(checkInFail, e);
114             throw new OleException(checkInFail, e);
115         }
116         finally {
117             RepositoryManager.getRepositoryManager().logout(session);
118         }
119 
120 
121         return latestVersion;
122     }
123 
124     private void ingestNIndexItemRecForInstance(RequestDocument reqDoc) throws OleException {
125         Session session = null;
126         try {
127             session = RepositoryManager.getRepositoryManager()
128                                        .getSession("CheckinManager", "ingestNIndexItemRecForInstance");
129             Node nodeByUUID = getNodeByUUID(session, reqDoc.getId());
130             Node holdingsNode = nodeByUUID.getNode(ProcessParameters.NODE_HOLDINGS);
131             NodeHandler nodeHandler = new NodeHandler();
132 
133             for (RequestDocument linkedItemDocument : reqDoc.getLinkedRequestDocuments()) {
134                 WorkItemOlemlRecordProcessor recordProcessor = new WorkItemOlemlRecordProcessor();
135                 Item item = recordProcessor.fromXML(linkedItemDocument.getContent().getContent());
136                 linkedItemDocument.getContent().setContentObject(item);
137                 String uuid = (nodeHandler.initFileNode(linkedItemDocument, FILE_ITEM, holdingsNode, session))
138                         .getIdentifier();
139                 linkedItemDocument.setId(uuid);
140             }
141             session.save();
142         }
143         catch (Exception e) {
144             docStoreLogger.log(e.getMessage());
145             throw new OleException(e.getMessage(), e);
146         }
147         finally {
148             RepositoryManager.getRepositoryManager().logout(session);
149         }
150     }
151 
152 
153     private String updateRecordInDocStore(RequestDocument reqDoc) throws OleException, RepositoryException {
154         Session session = RepositoryManager.getRepositoryManager()
155                                            .getSession("CheckinManager", "updateRecordInDocStore");
156         String charset = "UTF-8";
157         byte[] documentBytes = null;
158         String currentVersion = null;
159 
160         try {
161             if (reqDoc.getDocumentName() != null && reqDoc.getDocumentName().trim().length() != 0) {
162                 documentBytes = FileUtils.readFileToByteArray(new File(reqDoc.getDocumentName()));
163             }
164             else if (reqDoc.getContent().getContent() != null) {
165                 setIdentifierValueInContent(reqDoc);
166                 documentBytes = reqDoc.getContent().getContent().getBytes(charset);
167             }
168         }
169         catch (Exception e) {
170             getDocStoreLogger().log("Failed to convert input string to byte[] with charset " + charset, e);
171             throw new OleException(e.getMessage());
172         }
173         RequestDocument linkReqInfo = new RequestDocument();
174         if (reqDoc.getLinkedRequestDocuments() != null && reqDoc.getLinkedRequestDocuments().size() > 0) {
175             for (Iterator<RequestDocument> linkIterator = reqDoc.getLinkedRequestDocuments().iterator(); linkIterator
176                     .hasNext(); ) {
177                 linkReqInfo = linkIterator.next();
178             }
179         }
180         Node nodeByUUID = session.getNodeByIdentifier(reqDoc.getUuid());
181         try {
182             Binary binary = null;
183             if (documentBytes != null) {
184                 binary = session.getValueFactory().createBinary(new ByteArrayInputStream(documentBytes));
185                 nodeByUUID.getNode("jcr:content").setProperty("jcr:data", binary);
186             }
187             if (linkReqInfo != null && linkReqInfo.getId() != null && linkReqInfo.getType().equalsIgnoreCase(
188                     DocType.INSTANCE.getCode())) {
189                 nodeByUUID.setProperty("instanceIdentifier", linkReqInfo.getId());
190             }
191             Calendar lastModified = Calendar.getInstance();
192             lastModified.setTimeInMillis(lastModified.getTimeInMillis());
193             if (!reqDoc.getType().equalsIgnoreCase(DocType.INSTANCE.getCode())) {
194                 nodeByUUID.getNode("jcr:content").setProperty("jcr:lastModified", lastModified);
195             }
196             session.save();
197             if (DocStoreConstants.isVersioningEnabled || DocType.LICENSE.isEqualTo(reqDoc.getType())) {
198                 VersionManager versionManager = getVersionManager(session);
199                 versionManager.checkpoint(nodeByUUID.getPath());
200                 VersionHistory versionHistory = versionManager.getVersionHistory(nodeByUUID.getPath());
201                 VersionIterator allVersions = versionHistory.getAllVersions();
202                 while (allVersions.hasNext()) {
203                     currentVersion = allVersions.nextVersion().getName();
204                 }
205                 getDocStoreLogger()
206                         .log("Version updated for UUID:" + reqDoc.getUuid() + "  ====  version:" + currentVersion);
207             }
208         }
209         catch (Exception e) {
210             docStoreLogger.log(e.getMessage());
211             throw new OleException(e.getMessage(), e);
212         }
213         finally {
214             RepositoryManager.getRepositoryManager().logout(session);
215         }
216         return currentVersion;
217     }
218 
219     private void setIdentifierValueInContent(RequestDocument reqDoc) {
220         if (reqDoc.getType().equalsIgnoreCase(DocType.ITEM.getDescription())) {
221             WorkItemOlemlRecordProcessor recordProcessor = new WorkItemOlemlRecordProcessor();
222             Item item = recordProcessor.fromXML(reqDoc.getContent().getContent());
223             item.setItemIdentifier(reqDoc.getId());
224             reqDoc.getContent().setContent(recordProcessor.toXML(item));
225         }
226         if (reqDoc.getType().equalsIgnoreCase(DocType.HOLDINGS.getDescription())) {
227             WorkHoldingOlemlRecordProcessor recordProcessor = new WorkHoldingOlemlRecordProcessor();
228             OleHoldings holdings = recordProcessor.fromXML(reqDoc.getContent().getContent());
229             holdings.setHoldingsIdentifier(reqDoc.getId());
230             reqDoc.getContent().setContent(recordProcessor.toXML(holdings));
231         }
232         if (reqDoc.getType().equalsIgnoreCase(DocType.SOURCEHOLDINGS.getDescription())) {
233             WorkSourceHoldingOlemlRecordProcessor recordProcessor = new WorkSourceHoldingOlemlRecordProcessor();
234             SourceHoldings sourceHoldings = recordProcessor.fromXML(reqDoc.getContent().getContent());
235             sourceHoldings.setHoldingsIdentifier(reqDoc.getId());
236             reqDoc.getContent().setContent(recordProcessor.toXML(sourceHoldings));
237         }
238     }
239 
240     private Node getNodeByUUID(Session newSession, String uuid) throws OleException {
241         return new NodeHandler().getNodeByUUID(newSession, uuid);
242     }
243 
244     public DocStoreLogger getDocStoreLogger() {
245         return docStoreLogger;
246     }
247 
248     public VersionManager getVersionManager(Session session) throws OleException, RepositoryException {
249         return session.getWorkspace().getVersionManager();
250     }
251 }