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.OleDocStoreException;
22  import org.kuali.ole.docstore.model.enums.DocFormat;
23  import org.kuali.ole.docstore.model.enums.DocType;
24  import org.kuali.ole.docstore.model.xmlpojo.ingest.AdditionalAttributes;
25  import org.kuali.ole.docstore.model.xmlpojo.ingest.RequestDocument;
26  import org.kuali.ole.documenthandler.WorkBibMarcContentHandler;
27  import org.kuali.ole.documenthandler.WorkInstanceOleMLContentHandler;
28  import org.kuali.ole.pojo.OleException;
29  import org.slf4j.Logger;
30  import org.slf4j.LoggerFactory;
31  
32  import javax.jcr.*;
33  import java.io.ByteArrayInputStream;
34  import java.io.File;
35  import java.io.InputStream;
36  import java.util.Calendar;
37  import java.util.Collection;
38  import java.util.Date;
39  import java.util.Iterator;
40  import java.text.DateFormat;
41  import java.text.SimpleDateFormat;
42  
43  import static org.kuali.ole.docstore.process.ProcessParameters.*;
44  
45  /**
46   * Created by IntelliJ IDEA.
47   * User: pvsubrah
48   * Date: 9/11/11
49   * Time: 10:37 AM
50   * To change this template use File | Settings | File Templates.
51   */
52  public class NodeHandler {
53  
54      private static final Logger logger = LoggerFactory.getLogger(NodeHandler.class);
55  
56      public Node initStaticNode(String nodeName, Node parentNode, Session session) throws RepositoryException {
57          Node node;
58          if (!parentNode.hasNode(nodeName)) {
59              synchronized (session) {
60                  node = parentNode.addNode(nodeName, "nt:unstructured");
61                  node.setProperty("nodeType", "folder");
62                  node.addMixin("mix:referenceable");
63                  session.save();
64              }
65          } else {
66              node = parentNode.getNode(nodeName);
67          }
68          return node;
69      }
70  
71      public Node initNonStaticNode(String nodeName, Node parentNode) throws RepositoryException {
72          Node node;
73          node = parentNode.addNode(nodeName, "nt:unstructured");
74          node.setProperty("nodeType", "folder");
75          node.addMixin("mix:referenceable");
76          return node;
77      }
78  
79      public synchronized Node initFileNode(RequestDocument document, String name, Node parentNode, Session session)
80              throws Exception {
81          DocStoreConstants docStoreConstants = new DocStoreConstants();
82          String uuid = null;
83          Node fileNode = null;
84          try {
85              NodeIterator nodes = parentNode.getNodes(name);
86              if (nodes.getSize() >= BUCKET_SIZE_FILE_NODES) {
87                  if (DocFormat.OLEML.isEqualTo(document.getFormat())) {
88                      throw new RuntimeException("FileNode creation failed as the BUCKET_SIZE[" + BUCKET_SIZE_FILE_NODES
89                              + "] is FULL: for the doc: " + document.getFormat() + "\n@ level: "
90                              + parentNode.getPath() + "/" + name + "[" + (nodes.getSize() + 1) + "]");
91                  } else {
92                      parentNode = initLevelNode(parentNode.getName(), parentNode.getParent(), true, session);
93                  }
94              }
95  
96              fileNode = parentNode.addNode(name, "olefile");
97              fileNode.addMixin("mix:referenceable");
98              if (DocType.LICENSE.isEqualTo(document.getType()) || docStoreConstants.isVersioningEnabled) {
99                  fileNode.addMixin("mix:versionable");
100             }
101 
102             AdditionalAttributes additionalAttributes = document.getAdditionalAttributes();
103             if (DocType.LICENSE.isEqualTo(document.getType()) && !DocFormat.ONIXPL.isEqualTo(document.getFormat())) {
104                 String docName = new File(document.getDocumentName()).getName();
105                 additionalAttributes.setAttribute("dateLoaded", Calendar.getInstance().toString());
106                 additionalAttributes.setAttribute("fileName", docName);
107                 additionalAttributes.setAttribute("owner", document.getUser());
108             }
109 
110             if (additionalAttributes != null) {
111                 Collection<String> attributeNames = additionalAttributes.getAttributeNames();
112                 if (attributeNames != null && attributeNames.size() > 0) {
113                     for (Iterator<String> iterator = attributeNames.iterator(); iterator.hasNext(); ) {
114                         String attributeName = iterator.next();
115                         String attributeValue = additionalAttributes.getAttribute(attributeName);
116                         fileNode.setProperty(attributeName, attributeValue);
117                     }
118                 }
119 
120             } else {
121                 fileNode.setProperty("dateEntered", Calendar.getInstance());
122                 fileNode.setProperty("lastUpdated", Calendar.getInstance());
123             }
124 
125             Node resNode = fileNode.addNode("jcr:content", "nt:resource");
126             resNode.setProperty("jcr:mimeType", "application/xml");
127             resNode.setProperty("jcr:encoding", "");
128 
129             String charset = "UTF-8";
130             byte[] documentBytes = null;
131             try {
132                 uuid = fileNode.getIdentifier();
133                 document.setUuid(uuid);
134                 // Content Manipulations
135                 if (DocFormat.MARC.isEqualTo(document.getFormat())) {
136                     new WorkBibMarcContentHandler().doPreIngestContentManipulations(document, uuid);
137                 } else if (DocFormat.OLEML.isEqualTo(document.getFormat())) {
138                     (new WorkInstanceOleMLContentHandler())
139                             .doInstanceOleMLContentManipulations(document, uuid, parentNode);
140                 }
141 
142                 if (document.getContent() != null && document.getContent().getContent() != null) {
143                     documentBytes = document.getContent().getContent().getBytes();
144                 } else if (document.getDocumentName() != null) {
145                     File file = new File(document.getDocumentName());
146                     if (file.exists()) {
147                         documentBytes = FileUtils.readFileToByteArray(file);
148                     }
149                 }
150             } catch (Exception e) {
151                 logger.error("Failed to convert document string to byte[] with charset " + charset, e);
152             }
153             InputStream docInputStream = new ByteArrayInputStream(documentBytes);
154             Binary binary = session.getValueFactory().createBinary(docInputStream);
155             resNode.setProperty("jcr:data", binary);
156             Calendar lastModified = Calendar.getInstance();
157             lastModified.setTimeInMillis(new Date().getTime());
158             resNode.setProperty("jcr:lastModified", lastModified);
159             logger.debug(fileNode.getPath() + " : " + uuid);
160         } catch (RepositoryException e) {
161             logger.error("File Node Cannot be Created: " + e.getMessage(), e);
162         }
163         return fileNode;
164     }
165 
166     /**
167      * Initializes the given fileNode with info from given requestDocument.
168      *
169      * @param fileNode
170      * @param document
171      * @param name
172      * @param parentNode
173      * @param session
174      * @return
175      * @throws Exception
176      */
177     public synchronized Node initFileNode(Node fileNode, RequestDocument document, String name, Node parentNode,
178                                           Session session) throws Exception {
179         String uuid = null;
180         //Node fileNode = null;
181         DocStoreConstants docStoreConstants = new DocStoreConstants();
182         try {
183             /*NodeIterator nodes = parentNode.getNodes(name);
184             if (nodes.getSize() >= BUCKET_SIZE_FILE_NODES) {
185                 if (DocFormat.OLEML.isEqualTo(document.getFormat()))
186                     throw new RuntimeException("FileNode creation failed as the BUCKET_SIZE[" + BUCKET_SIZE_FILE_NODES + "] is FULL: for the doc: "
187                             + document.getFormat() + "\n@ level: " + parentNode.getPath() + "/" + name + "[" + (nodes.getSize() + 1) + "]");
188                 else
189                     parentNode = initLevelNode(parentNode.getName(), parentNode.getParent(), true, session);
190             }
191 
192             fileNode = parentNode.addNode(name, "olefile"); */
193             DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
194             Date date = new Date();
195             //logger.info("NODE INIT: STARTING TIME \t" + dateFormat.format(date));
196             fileNode.addMixin("mix:referenceable");
197             if (DocType.LICENSE.isEqualTo(document.getType()) || docStoreConstants.isVersioningEnabled) {
198                 fileNode.addMixin("mix:versionable");
199             }
200 
201             AdditionalAttributes additionalAttributes = document.getAdditionalAttributes();
202             if (DocType.LICENSE.isEqualTo(document.getType()) && !DocFormat.ONIXPL.isEqualTo(document.getFormat())) {
203                 String docName = new File(document.getDocumentName()).getName();
204                 additionalAttributes.setAttribute("dateLoaded", Calendar.getInstance().toString());
205                 additionalAttributes.setAttribute("fileName", docName);
206                 additionalAttributes.setAttribute("owner", document.getUser());
207             }
208 
209             if (additionalAttributes != null) {
210                 Collection<String> attributeNames = additionalAttributes.getAttributeNames();
211                 if (attributeNames != null && attributeNames.size() > 0) {
212                     for (Iterator<String> iterator = attributeNames.iterator(); iterator.hasNext(); ) {
213                         String attributeName = iterator.next();
214                         String attributeValue = additionalAttributes.getAttribute(attributeName);
215                         fileNode.setProperty(attributeName, attributeValue);
216                     }
217                 }
218 
219             }
220             //            else {
221             //                fileNode.setProperty("dateEntered", Calendar.getInstance());
222             //                fileNode.setProperty("lastUpdated", Calendar.getInstance());
223             //            }
224 
225             Node resNode = fileNode.addNode("jcr:content", "nt:resource");
226             resNode.setProperty("jcr:mimeType", "application/xml");
227             resNode.setProperty("jcr:encoding", "");
228 
229             String charset = "UTF-8";
230             byte[] documentBytes = null;
231             try {
232                 uuid = fileNode.getIdentifier();
233                 document.setUuid(uuid);
234                 // Content Manipulations
235                 if (DocFormat.MARC.isEqualTo(document.getFormat())) {
236                     new WorkBibMarcContentHandler().doPreIngestContentManipulations(document, uuid);
237                 } else if (DocFormat.OLEML.isEqualTo(document.getFormat())) {
238                     (new WorkInstanceOleMLContentHandler())
239                             .doInstanceOleMLContentManipulations(document, uuid, parentNode);
240                 }
241 
242                 if (document.getContent() != null && document.getContent().getContent() != null) {
243                     documentBytes = document.getContent().getContent().getBytes();
244                 } else if (document.getDocumentName() != null) {
245                     File file = new File(document.getDocumentName());
246                     if (file.exists()) {
247                         documentBytes = FileUtils.readFileToByteArray(file);
248                     }
249                 }
250 
251 
252             } catch (Exception e) {
253                 logger.error("Failed to convert document string to byte[] with charset " + charset, e);
254             }
255             InputStream docInputStream = new ByteArrayInputStream(documentBytes);
256             Binary binary = session.getValueFactory().createBinary(docInputStream);
257             resNode.setProperty("jcr:data", binary);
258             Calendar lastModified = Calendar.getInstance();
259             lastModified.setTimeInMillis(new Date().getTime());
260             resNode.setProperty("jcr:lastModified", lastModified);
261             logger.debug(fileNode.getPath() + " : " + uuid);
262             //logger.info("NODE INIT: ENDING TIME \t" + dateFormat.format(date));
263         } catch (RepositoryException e) {
264             logger.error("File Node Cannot be Created: " + e.getMessage(), e);
265         }
266 
267         return fileNode;
268     }
269 
270     public synchronized Node initLevelNode(String name, Node parent, boolean isRecursiveCall, Session session)
271             throws Exception {
272         long existing = 0;
273         try {
274             long bucketSize = BUCKET_SIZES.get(name);
275             boolean hasRepeatedChild = HAS_REPEATED_CHILD.get(name);
276             if (parent.hasNode(name)) {
277                 NodeIterator existingNodes = parent.getNodes(name);
278                 existing = existingNodes.getSize();
279                 if (existing <= bucketSize && !((isRecursiveCall && existing == bucketSize) || (!hasRepeatedChild
280                         && existing
281                         == bucketSize))) {
282                     if (hasRepeatedChild && !isRecursiveCall) {
283                         existingNodes.skip(existing - 1);
284                         return existingNodes.nextNode();
285                     } else {
286                         Node levelNode = initNonStaticNode(name, parent);
287                         if (existing == 0) {
288                             session.save();
289                         }
290                         return levelNode;
291                     }
292                 } else {
293                     if (!STATIC_NODES.contains(parent.getPath())) {
294                         parent = initLevelNode(parent.getName(), parent.getParent(), true, session);
295                         return initNonStaticNode(name, parent);
296                     } else {
297                         throw new Exception("Node [" + parent.getName() + "/" + name + "[" + (existing + 1)
298                                 + "]] Cannot Be Created. CAUSE: TREE [" + bucketSize + "] FULL ");
299                     }
300                 }
301             } else {
302                 return initNonStaticNode(name, parent);
303             }
304         } catch (Exception e) {
305             try {
306                 logger.error(
307                         "Exception While initializing Node: " + parent.getName() + "/" + name + "[" + (existing + 1)
308                                 + "] \t to Parent: " + parent.getName(), e);
309             } catch (RepositoryException e1) {
310             }
311             throw e;
312         }
313     }
314 
315     public Node getNodeByUUID(Session session, String uuid) throws OleException {
316         logger.debug("Started getting node for UUID:" + uuid);
317         boolean isNewSession = false;
318         if (null == session) {
319             isNewSession = true;
320             logger.debug("Initilalizing new session");
321             session = RepositoryManager.getRepositoryManager().getSession("nodeHandler", "getNodeByUUID");
322         }
323         try {
324             return session.getNodeByIdentifier(uuid);
325         } catch (RepositoryException e) {
326             throw new OleException("getNodeByUUID failed", e);
327         } finally {
328             if (isNewSession) {
329                 RepositoryManager.getRepositoryManager().logout(session);
330             }
331         }
332     }
333 
334 }