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.common.document.content.instance.Item;
22  import org.kuali.ole.docstore.common.document.content.instance.OleHoldings;
23  import org.kuali.ole.docstore.common.document.content.instance.SourceHoldings;
24  import org.kuali.ole.docstore.common.document.content.instance.xstream.HoldingOlemlRecordProcessor;
25  import org.kuali.ole.docstore.common.document.content.instance.xstream.ItemOlemlRecordProcessor;
26  import org.kuali.ole.docstore.common.document.content.instance.xstream.SourceHoldingOlemlRecordProcessor;
27  import org.kuali.ole.docstore.model.enums.DocType;
28  import org.kuali.ole.docstore.model.xmlpojo.ingest.RequestDocument;
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          } catch (Exception e) {
90              docStoreLogger
91                      .log("Document was updated in indexer but not in docStore, trying to rollback the changes from indexer",
92                              e);
93  
94              RequestDocument prevRequestDoc = null;
95              session = RepositoryManager.getRepositoryManager().getSession("CheckinManager", "checkIn");
96              Node nodeByUUID = getNodeByUUID(session, requestDocument.getId());
97              try {
98                  DocumentIndexer documentIndexer = new DocumentIndexer();
99                  prevRequestDoc = new RequestDocument();
100                 prevRequestDoc = requestDocument;
101                 String prevContent = nodeByUUID.getNode("jcr:content").getProperty("jcr:data").getValue().getString();
102                 prevRequestDoc.getContent().setContent(prevContent);
103                 documentIndexer.indexDocument(prevRequestDoc);
104             } catch (Exception ex) {
105                 String failMsg = checkInFail + "Unable to Roll back the changes in indexer.  Record UUID "
106                         + requestDocument.getId() + "got updated in indexer, but not in docstore ";
107                 docStoreLogger.log(failMsg, ex);
108                 throw new OleException(failMsg, ex);
109 
110             }
111             docStoreLogger.log(checkInFail, e);
112             throw new OleException(checkInFail, e);
113         } finally {
114             RepositoryManager.getRepositoryManager().logout(session);
115         }
116 
117 
118         return latestVersion;
119     }
120 
121     private void ingestNIndexItemRecForInstance(RequestDocument reqDoc) throws OleException {
122         Session session = null;
123         try {
124             session = RepositoryManager.getRepositoryManager()
125                     .getSession("CheckinManager", "ingestNIndexItemRecForInstance");
126             Node nodeByUUID = getNodeByUUID(session, reqDoc.getId());
127             Node holdingsNode = nodeByUUID.getNode(ProcessParameters.NODE_HOLDINGS);
128             NodeHandler nodeHandler = new NodeHandler();
129 
130             for (RequestDocument linkedItemDocument : reqDoc.getLinkedRequestDocuments()) {
131                 ItemOlemlRecordProcessor recordProcessor = new ItemOlemlRecordProcessor();
132                 Item item = recordProcessor.fromXML(linkedItemDocument.getContent().getContent());
133                 linkedItemDocument.getContent().setContentObject(item);
134                 String uuid = (nodeHandler.initFileNode(linkedItemDocument, FILE_ITEM, holdingsNode, session))
135                         .getIdentifier();
136                 linkedItemDocument.setId(uuid);
137             }
138             session.save();
139         } catch (Exception e) {
140             docStoreLogger.log(e.getMessage());
141             throw new OleException(e.getMessage(), e);
142         } finally {
143             RepositoryManager.getRepositoryManager().logout(session);
144         }
145     }
146 
147 
148     private String updateRecordInDocStore(RequestDocument reqDoc) throws OleException, RepositoryException {
149         Session session = RepositoryManager.getRepositoryManager()
150                 .getSession("CheckinManager", "updateRecordInDocStore");
151         String charset = "UTF-8";
152         byte[] documentBytes = null;
153         String currentVersion = null;
154 
155         try {
156             if (reqDoc.getDocumentName() != null && reqDoc.getDocumentName().trim().length() != 0) {
157                 documentBytes = FileUtils.readFileToByteArray(new File(reqDoc.getDocumentName()));
158             } else if (reqDoc.getContent().getContent() != null) {
159                 setIdentifierValueInContent(reqDoc);
160                 documentBytes = reqDoc.getContent().getContent().getBytes(charset);
161             }
162         } catch (Exception e) {
163             getDocStoreLogger().log("Failed to convert input string to byte[] with charset " + charset, e);
164             throw new OleException(e.getMessage());
165         }
166         RequestDocument linkReqInfo = new RequestDocument();
167         if (reqDoc.getLinkedRequestDocuments() != null && reqDoc.getLinkedRequestDocuments().size() > 0) {
168             for (Iterator<RequestDocument> linkIterator = reqDoc.getLinkedRequestDocuments().iterator(); linkIterator
169                     .hasNext(); ) {
170                 linkReqInfo = linkIterator.next();
171             }
172         }
173         Node nodeByUUID = session.getNodeByIdentifier(reqDoc.getUuid());
174         try {
175             Binary binary = null;
176             if (documentBytes != null) {
177                 binary = session.getValueFactory().createBinary(new ByteArrayInputStream(documentBytes));
178                 nodeByUUID.getNode("jcr:content").setProperty("jcr:data", binary);
179             }
180             if (linkReqInfo != null && linkReqInfo.getId() != null && linkReqInfo.getType().equalsIgnoreCase(
181                     DocType.INSTANCE.getCode())) {
182                 nodeByUUID.setProperty("instanceIdentifier", linkReqInfo.getId());
183             }
184             Calendar lastModified = Calendar.getInstance();
185             lastModified.setTimeInMillis(lastModified.getTimeInMillis());
186             if (!reqDoc.getType().equalsIgnoreCase(DocType.INSTANCE.getCode())) {
187                 nodeByUUID.getNode("jcr:content").setProperty("jcr:lastModified", lastModified);
188             }
189             session.save();
190             if (DocStoreConstants.isVersioningEnabled || DocType.LICENSE.isEqualTo(reqDoc.getType())) {
191                 VersionManager versionManager = getVersionManager(session);
192                 versionManager.checkpoint(nodeByUUID.getPath());
193                 VersionHistory versionHistory = versionManager.getVersionHistory(nodeByUUID.getPath());
194                 VersionIterator allVersions = versionHistory.getAllVersions();
195                 while (allVersions.hasNext()) {
196                     currentVersion = allVersions.nextVersion().getName();
197                 }
198                 getDocStoreLogger()
199                         .log("Version updated for UUID:" + reqDoc.getUuid() + "  ====  version:" + currentVersion);
200             }
201         } catch (Exception e) {
202             docStoreLogger.log(e.getMessage());
203             throw new OleException(e.getMessage(), e);
204         } finally {
205             RepositoryManager.getRepositoryManager().logout(session);
206         }
207         return currentVersion;
208     }
209 
210     private void setIdentifierValueInContent(RequestDocument reqDoc) {
211         if (reqDoc.getType().equalsIgnoreCase(DocType.ITEM.getDescription())) {
212             ItemOlemlRecordProcessor recordProcessor = new ItemOlemlRecordProcessor();
213             Item item = recordProcessor.fromXML(reqDoc.getContent().getContent());
214             item.setItemIdentifier(reqDoc.getId());
215             reqDoc.getContent().setContent(recordProcessor.toXML(item));
216         }
217         if (reqDoc.getType().equalsIgnoreCase(DocType.HOLDINGS.getDescription())) {
218             HoldingOlemlRecordProcessor recordProcessor = new HoldingOlemlRecordProcessor();
219             OleHoldings holdings = recordProcessor.fromXML(reqDoc.getContent().getContent());
220             holdings.setHoldingsIdentifier(reqDoc.getId());
221             reqDoc.getContent().setContent(recordProcessor.toXML(holdings));
222         }
223         if (reqDoc.getType().equalsIgnoreCase(DocType.SOURCEHOLDINGS.getDescription())) {
224             SourceHoldingOlemlRecordProcessor recordProcessor = new SourceHoldingOlemlRecordProcessor();
225             SourceHoldings sourceHoldings = recordProcessor.fromXML(reqDoc.getContent().getContent());
226             sourceHoldings.setHoldingsIdentifier(reqDoc.getId());
227             reqDoc.getContent().setContent(recordProcessor.toXML(sourceHoldings));
228         }
229     }
230 
231     private Node getNodeByUUID(Session newSession, String uuid) throws OleException {
232         return new NodeHandler().getNodeByUUID(newSession, uuid);
233     }
234 
235     public DocStoreLogger getDocStoreLogger() {
236         return docStoreLogger;
237     }
238 
239     public VersionManager getVersionManager(Session session) throws OleException, RepositoryException {
240         return session.getWorkspace().getVersionManager();
241     }
242 }