1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
47
48
49
50
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
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
168
169
170
171
172
173
174
175
176
177 public synchronized Node initFileNode(Node fileNode, RequestDocument document, String name, Node parentNode,
178 Session session) throws Exception {
179 String uuid = null;
180
181 DocStoreConstants docStoreConstants = new DocStoreConstants();
182 try {
183
184
185
186
187
188
189
190
191
192
193 DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
194 Date date = new Date();
195
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
221
222
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
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
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 }