1
14
15 package com.liferay.documentlibrary.util;
16
17 import com.liferay.documentlibrary.DuplicateDirectoryException;
18 import com.liferay.documentlibrary.DuplicateFileException;
19 import com.liferay.documentlibrary.NoSuchDirectoryException;
20 import com.liferay.documentlibrary.NoSuchFileException;
21 import com.liferay.portal.PortalException;
22 import com.liferay.portal.SystemException;
23 import com.liferay.portal.jcr.JCRConstants;
24 import com.liferay.portal.jcr.JCRFactory;
25 import com.liferay.portal.jcr.JCRFactoryUtil;
26 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedInputStream;
27 import com.liferay.portal.kernel.log.Log;
28 import com.liferay.portal.kernel.log.LogFactoryUtil;
29 import com.liferay.portal.kernel.search.Document;
30 import com.liferay.portal.kernel.search.Field;
31 import com.liferay.portal.kernel.search.SearchEngineUtil;
32 import com.liferay.portal.kernel.search.SearchException;
33 import com.liferay.portal.kernel.util.GetterUtil;
34 import com.liferay.portal.kernel.util.StringUtil;
35 import com.liferay.portal.kernel.util.Validator;
36
37 import java.io.InputStream;
38
39 import java.util.ArrayList;
40 import java.util.Calendar;
41 import java.util.Date;
42 import java.util.List;
43
44 import javax.jcr.Node;
45 import javax.jcr.NodeIterator;
46 import javax.jcr.PathNotFoundException;
47 import javax.jcr.Property;
48 import javax.jcr.RepositoryException;
49 import javax.jcr.Session;
50 import javax.jcr.version.Version;
51 import javax.jcr.version.VersionHistory;
52 import javax.jcr.version.VersionIterator;
53
54 import org.apache.commons.lang.StringUtils;
55
56
62 public class JCRHook extends BaseHook {
63
64 public void addDirectory(long companyId, long repositoryId, String dirName)
65 throws PortalException, SystemException {
66
67 Session session = null;
68
69 try {
70 session = JCRFactoryUtil.createSession();
71
72 Node rootNode = getRootNode(session, companyId);
73 Node repositoryNode = getFolderNode(rootNode, repositoryId);
74
75 if (repositoryNode.hasNode(dirName)) {
76 throw new DuplicateDirectoryException(dirName);
77 }
78 else {
79 String[] dirNameArray = StringUtil.split(dirName, "/");
80
81 Node dirNode = repositoryNode;
82
83 for (int i = 0; i < dirNameArray.length; i++) {
84 if (Validator.isNotNull(dirNameArray[i])) {
85 if (dirNode.hasNode(dirNameArray[i])) {
86 dirNode = dirNode.getNode(dirNameArray[i]);
87 }
88 else {
89 dirNode = dirNode.addNode(
90 dirNameArray[i], JCRConstants.NT_FOLDER);
91 }
92 }
93 }
94
95 session.save();
96 }
97 }
98 catch (RepositoryException re) {
99 throw new SystemException(re);
100 }
101 finally {
102 if (session != null) {
103 session.logout();
104 }
105 }
106 }
107
108 public void addFile(
109 long companyId, String portletId, long groupId, long repositoryId,
110 String fileName, String properties, Date modifiedDate,
111 String[] tagsEntries, InputStream is)
112 throws PortalException, SystemException {
113
114 Session session = null;
115
116 try {
117 session = JCRFactoryUtil.createSession();
118
119 Node rootNode = getRootNode(session, companyId);
120 Node repositoryNode = getFolderNode(rootNode, repositoryId);
121
122 if (repositoryNode.hasNode(fileName)) {
123 throw new DuplicateFileException(fileName);
124 }
125 else {
126 Node fileNode = repositoryNode.addNode(
127 fileName, JCRConstants.NT_FILE);
128
129 Node contentNode = fileNode.addNode(
130 JCRConstants.JCR_CONTENT, JCRConstants.NT_RESOURCE);
131
132 contentNode.addMixin(JCRConstants.MIX_VERSIONABLE);
133 contentNode.setProperty(
134 JCRConstants.JCR_MIME_TYPE, "text/plain");
135 contentNode.setProperty(JCRConstants.JCR_DATA, is);
136 contentNode.setProperty(
137 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
138
139 session.save();
140
141 Version version = contentNode.checkin();
142
143 contentNode.getVersionHistory().addVersionLabel(
144 version.getName(), String.valueOf(DEFAULT_VERSION), false);
145
146 DLIndexerUtil.addFile(
147 companyId, portletId, groupId, repositoryId, fileName,
148 properties, modifiedDate, tagsEntries);
149 }
150 }
151 catch (RepositoryException re) {
152 throw new SystemException(re);
153 }
154 catch (SearchException se) {
155 throw new SystemException(se);
156 }
157 finally {
158 if (session != null) {
159 session.logout();
160 }
161 }
162 }
163
164 public void checkRoot(long companyId) throws SystemException {
165 Session session = null;
166
167 try {
168 session = JCRFactoryUtil.createSession();
169
170 getRootNode(session, companyId);
171
172 session.save();
173 }
174 catch (RepositoryException re) {
175 throw new SystemException(re);
176 }
177 finally {
178 if (session != null) {
179 session.logout();
180 }
181 }
182 }
183
184 public void deleteDirectory(
185 long companyId, String portletId, long repositoryId, String dirName)
186 throws PortalException, SystemException {
187
188 Session session = null;
189
190 try {
191 session = JCRFactoryUtil.createSession();
192
193 Node rootNode = getRootNode(session, companyId);
194 Node repositoryNode = getFolderNode(rootNode, repositoryId);
195 Node dirNode = repositoryNode.getNode(dirName);
196
197 deleteDirectory(companyId, portletId, repositoryId, dirNode);
198
199 dirNode.remove();
200
201 session.save();
202 }
203 catch (PathNotFoundException pnfe) {
204 throw new NoSuchDirectoryException(dirName);
205 }
206 catch (RepositoryException re) {
207 String message = GetterUtil.getString(re.getMessage());
208
209 if (message.contains("failed to resolve path")) {
210 throw new NoSuchDirectoryException(dirName);
211 }
212 else {
213 throw new PortalException(re);
214 }
215 }
216 catch (SearchException se) {
217 throw new SystemException(se);
218 }
219 finally {
220 if (session != null) {
221 session.logout();
222 }
223 }
224 }
225
226 public void deleteFile(
227 long companyId, String portletId, long repositoryId,
228 String fileName)
229 throws PortalException, SystemException {
230
231 Session session = null;
232
233
236
238 try {
239 session = JCRFactoryUtil.createSession();
240
241 Node rootNode = getRootNode(session, companyId);
242 Node repositoryNode = getFolderNode(rootNode, repositoryId);
243 Node fileNode = repositoryNode.getNode(fileName);
244 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
245
246 contentNode.checkout();
247
248 contentNode.setProperty(JCRConstants.JCR_MIME_TYPE, "text/plain");
249 contentNode.setProperty(JCRConstants.JCR_DATA, "");
250 contentNode.setProperty(
251 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
252
253 session.save();
254
255 Version version = contentNode.checkin();
256
257 contentNode.getVersionHistory().addVersionLabel(
258 version.getName(), "0.0", false);
259 }
260 catch (PathNotFoundException pnfe) {
261 throw new NoSuchFileException(fileName);
262 }
263 catch (RepositoryException re) {
264 throw new SystemException(re);
265 }
266 finally {
267 if (session != null) {
268 session.logout();
269 }
270 }
271
272
274 try {
275 session = JCRFactoryUtil.createSession();
276
277 Node rootNode = getRootNode(session, companyId);
278 Node repositoryNode = getFolderNode(rootNode, repositoryId);
279 Node fileNode = repositoryNode.getNode(fileName);
280 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
281
282 VersionHistory versionHistory = contentNode.getVersionHistory();
283
284 VersionIterator itr = versionHistory.getAllVersions();
285
286 while (itr.hasNext()) {
287 Version version = itr.nextVersion();
288
289 if (itr.getPosition() == itr.getSize()) {
290 break;
291 }
292 else {
293 if (!StringUtils.equals(
294 JCRConstants.JCR_ROOT_VERSION, version.getName())) {
295
296 versionHistory.removeVersion(version.getName());
297 }
298 }
299 }
300
301 session.save();
302 }
303 catch (PathNotFoundException pnfe) {
304 throw new NoSuchFileException(fileName);
305 }
306 catch (RepositoryException re) {
307 throw new SystemException(re);
308 }
309 finally {
310 if (session != null) {
311 session.logout();
312 }
313 }
314
315
317 try {
318 session = JCRFactoryUtil.createSession();
319
320 Node rootNode = getRootNode(session, companyId);
321 Node repositoryNode = getFolderNode(rootNode, repositoryId);
322 Node fileNode = repositoryNode.getNode(fileName);
323
324 DLIndexerUtil.deleteFile(
325 companyId, portletId, repositoryId, fileName);
326
327 fileNode.remove();
328
329 session.save();
330 }
331 catch (PathNotFoundException pnfe) {
332 throw new NoSuchFileException(fileName);
333 }
334 catch (RepositoryException re) {
335 throw new SystemException(re);
336 }
337 catch (SearchException se) {
338 throw new SystemException(se);
339 }
340 finally {
341 if (session != null) {
342 session.logout();
343 }
344 }
345 }
346
347 public void deleteFile(
348 long companyId, String portletId, long repositoryId,
349 String fileName, double versionNumber)
350 throws PortalException, SystemException {
351
352 String versionLabel = String.valueOf(versionNumber);
353
354 Session session = null;
355
356 try {
357 session = JCRFactoryUtil.createSession();
358
359 Node rootNode = getRootNode(session, companyId);
360 Node repositoryNode = getFolderNode(rootNode, repositoryId);
361 Node fileNode = repositoryNode.getNode(fileName);
362 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
363
364 VersionHistory versionHistory = contentNode.getVersionHistory();
365
366 Version version = versionHistory.getVersionByLabel(versionLabel);
367
368 versionHistory.removeVersion(version.getName());
369
370 session.save();
371 }
372 catch (PathNotFoundException pnfe) {
373 throw new NoSuchFileException(fileName);
374 }
375 catch (RepositoryException re) {
376 throw new SystemException(re);
377 }
378 finally {
379 if (session != null) {
380 session.logout();
381 }
382 }
383 }
384
385 public InputStream getFileAsStream(
386 long companyId, long repositoryId, String fileName,
387 double versionNumber)
388 throws PortalException, SystemException {
389
390 InputStream is = null;
391
392 Session session = null;
393
394 try {
395 session = JCRFactoryUtil.createSession();
396
397 Node contentNode = getFileContentNode(
398 session, companyId, repositoryId, fileName, versionNumber);
399
400 Property data = contentNode.getProperty(JCRConstants.JCR_DATA);
401
402 is = new UnsyncBufferedInputStream(data.getStream());
403 }
404 catch (RepositoryException re) {
405 throw new SystemException(re);
406 }
407 finally {
408 if (session != null) {
409 session.logout();
410 }
411 }
412
413 return is;
414 }
415
416 public String[] getFileNames(
417 long companyId, long repositoryId, String dirName)
418 throws PortalException, SystemException {
419
420 List<String> fileNames = new ArrayList<String>();
421
422 Session session = null;
423
424 try {
425 session = JCRFactoryUtil.createSession();
426
427 Node rootNode = getRootNode(session, companyId);
428 Node repositoryNode = getFolderNode(rootNode, repositoryId);
429 Node dirNode = repositoryNode.getNode(dirName);
430
431 NodeIterator itr = dirNode.getNodes();
432
433 while (itr.hasNext()) {
434 Node node = (Node)itr.next();
435
436 if (node.getPrimaryNodeType().getName().equals(
437 JCRConstants.NT_FILE)) {
438
439 fileNames.add(dirName + "/" + node.getName());
440 }
441 }
442 }
443 catch (PathNotFoundException pnfe) {
444 throw new NoSuchDirectoryException(dirName);
445 }
446 catch (RepositoryException re) {
447 throw new SystemException(re);
448 }
449 finally {
450 if (session != null) {
451 session.logout();
452 }
453 }
454
455 return fileNames.toArray(new String[fileNames.size()]);
456 }
457
458 public long getFileSize(
459 long companyId, long repositoryId, String fileName)
460 throws PortalException, SystemException {
461
462 long size;
463
464 Session session = null;
465
466 try {
467 session = JCRFactoryUtil.createSession();
468
469 Node contentNode = getFileContentNode(
470 session, companyId, repositoryId, fileName, 0);
471
472 size = contentNode.getProperty(JCRConstants.JCR_DATA).getLength();
473 }
474 catch (RepositoryException re) {
475 throw new SystemException(re);
476 }
477 finally {
478 if (session != null) {
479 session.logout();
480 }
481 }
482
483 return size;
484 }
485
486 public boolean hasFile(
487 long companyId, long repositoryId, String fileName,
488 double versionNumber)
489 throws PortalException, SystemException {
490
491 try {
492 getFileContentNode(
493 companyId, repositoryId, fileName, versionNumber);
494 }
495 catch (NoSuchFileException nsfe) {
496 return false;
497 }
498
499 return true;
500 }
501
502 public void move(String srcDir, String destDir) throws SystemException {
503 Session session = null;
504
505 try {
506 session = JCRFactoryUtil.createSession();
507
508 session.move(srcDir, destDir);
509
510 session.save();
511 }
512 catch (RepositoryException re) {
513 throw new SystemException(re);
514 }
515 finally {
516 if (session != null) {
517 session.logout();
518 }
519 }
520 }
521
522 public void reIndex(String[] ids) throws SearchException {
523 long companyId = GetterUtil.getLong(ids[0]);
524 String portletId = ids[1];
525 long groupId = GetterUtil.getLong(ids[2]);
526 long repositoryId = GetterUtil.getLong(ids[3]);
527
528 Session session = null;
529
530 try {
531 session = JCRFactoryUtil.createSession();
532
533 Node rootNode = getRootNode(session, companyId);
534 Node repositoryNode = getFolderNode(rootNode, repositoryId);
535
536 NodeIterator itr = repositoryNode.getNodes();
537
538 while (itr.hasNext()) {
539 Node node = (Node)itr.next();
540
541 if (node.getPrimaryNodeType().getName().equals(
542 JCRConstants.NT_FILE)) {
543
544 try {
545 Document doc = DLIndexerUtil.getFileDocument(
546 companyId, portletId, groupId, repositoryId,
547 node.getName());
548
549 SearchEngineUtil.updateDocument(
550 companyId, doc.get(Field.UID), doc);
551 }
552 catch (Exception e1) {
553 _log.error("Reindexing " + node.getName(), e1);
554 }
555 }
556 }
557 }
558 catch (Exception e2) {
559 throw new SearchException(e2);
560 }
561 finally {
562 try {
563 if (session != null) {
564 session.logout();
565 }
566 }
567 catch (Exception e) {
568 _log.error(e);
569 }
570 }
571 }
572
573 public void updateFile(
574 long companyId, String portletId, long groupId, long repositoryId,
575 long newRepositoryId, String fileName)
576 throws PortalException, SystemException {
577
578 Session session = null;
579
580 try {
581 session = JCRFactoryUtil.createSession();
582
583 Node rootNode = getRootNode(session, companyId);
584 Node repositoryNode = getFolderNode(rootNode, repositoryId);
585 Node fileNode = repositoryNode.getNode(fileName);
586 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
587
588 Node newRepositoryNode = getFolderNode(rootNode, newRepositoryId);
589
590 if (newRepositoryNode.hasNode(fileName)) {
591 throw new DuplicateFileException(fileName);
592 }
593 else {
594 Node newFileNode = newRepositoryNode.addNode(
595 fileName, JCRConstants.NT_FILE);
596
597 Node newContentNode = newFileNode.addNode(
598 JCRConstants.JCR_CONTENT, JCRConstants.NT_RESOURCE);
599
600 VersionHistory versionHistory = contentNode.getVersionHistory();
601
602 String[] versionLabels = versionHistory.getVersionLabels();
603
604 for (int i = (versionLabels.length - 1); i >= 0; i--) {
605 Version version = versionHistory.getVersionByLabel(
606 versionLabels[i]);
607
608 Node frozenContentNode = version.getNode(
609 JCRConstants.JCR_FROZEN_NODE);
610
611 if (i == (versionLabels.length - 1)) {
612 newContentNode.addMixin(JCRConstants.MIX_VERSIONABLE);
613 }
614 else {
615 newContentNode.checkout();
616 }
617
618 newContentNode.setProperty(
619 JCRConstants.JCR_MIME_TYPE, "text/plain");
620 newContentNode.setProperty(
621 JCRConstants.JCR_DATA,
622 frozenContentNode.getProperty(
623 JCRConstants.JCR_DATA).getStream());
624 newContentNode.setProperty(
625 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
626
627 session.save();
628
629 Version newVersion = newContentNode.checkin();
630
631 newContentNode.getVersionHistory().addVersionLabel(
632 newVersion.getName(), versionLabels[i], false);
633 }
634
635 fileNode.remove();
636
637 session.save();
638
639 try {
640 DLIndexerUtil.deleteFile(
641 companyId, portletId, repositoryId, fileName);
642 }
643 catch (SearchException se) {
644 }
645
646 DLIndexerUtil.addFile(
647 companyId, portletId, groupId, newRepositoryId, fileName);
648 }
649 }
650 catch (PathNotFoundException pnfe) {
651 throw new NoSuchFileException(fileName);
652 }
653 catch (RepositoryException re) {
654 throw new SystemException(re);
655 }
656 catch (SearchException se) {
657 throw new SystemException(se);
658 }
659 finally {
660 if (session != null) {
661 session.logout();
662 }
663 }
664 }
665
666 public void updateFile(
667 long companyId, String portletId, long groupId, long repositoryId,
668 String fileName, double versionNumber, String sourceFileName,
669 String properties, Date modifiedDate, String[] tagsEntries,
670 InputStream is)
671 throws PortalException, SystemException {
672
673 String versionLabel = String.valueOf(versionNumber);
674
675 Session session = null;
676
677 try {
678 session = JCRFactoryUtil.createSession();
679
680 Node rootNode = getRootNode(session, companyId);
681 Node repositoryNode = getFolderNode(rootNode, repositoryId);
682 Node fileNode = repositoryNode.getNode(fileName);
683 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
684
685 contentNode.checkout();
686
687 contentNode.setProperty(JCRConstants.JCR_MIME_TYPE, "text/plain");
688 contentNode.setProperty(JCRConstants.JCR_DATA, is);
689 contentNode.setProperty(
690 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
691
692 session.save();
693
694 Version version = contentNode.checkin();
695
696 contentNode.getVersionHistory().addVersionLabel(
697 version.getName(), versionLabel, false);
698
699 DLIndexerUtil.updateFile(
700 companyId, portletId, groupId, repositoryId, fileName,
701 properties, modifiedDate, tagsEntries);
702 }
703 catch (PathNotFoundException pnfe) {
704 throw new NoSuchFileException(fileName);
705 }
706 catch (RepositoryException re) {
707 throw new SystemException(re);
708 }
709 catch (SearchException se) {
710 throw new SystemException(se);
711 }
712 finally {
713 if (session != null) {
714 session.logout();
715 }
716 }
717 }
718
719 protected void deleteDirectory(
720 long companyId, String portletId, long repositoryId, Node dirNode)
721 throws SearchException {
722
723 try {
724 NodeIterator itr = dirNode.getNodes();
725
726 while (itr.hasNext()) {
727 Node node = (Node)itr.next();
728
729 String primaryNodeTypeName =
730 node.getPrimaryNodeType().getName();
731
732 if (primaryNodeTypeName.equals(JCRConstants.NT_FOLDER)) {
733 deleteDirectory(companyId, portletId, repositoryId, node);
734 }
735 else if (primaryNodeTypeName.equals(JCRConstants.NT_FILE)) {
736 DLIndexerUtil.deleteFile(
737 companyId, portletId, repositoryId, node.getName());
738 }
739 }
740
741 DLIndexerUtil.deleteFile(
742 companyId, portletId, repositoryId, dirNode.getName());
743 }
744 catch (RepositoryException e) {
745 _log.error(e);
746 }
747 }
748
749 protected Node getFileContentNode(
750 long companyId, long repositoryId, String fileName,
751 double versionNumber)
752 throws PortalException, SystemException {
753
754 Node contentNode = null;
755
756 Session session = null;
757
758 try {
759 session = JCRFactoryUtil.createSession();
760
761 contentNode = getFileContentNode(
762 session, companyId, repositoryId, fileName, versionNumber);
763 }
764 catch (RepositoryException re) {
765 throw new SystemException(re);
766 }
767 finally {
768 if (session != null) {
769 session.logout();
770 }
771 }
772
773 return contentNode;
774 }
775
776 protected Node getFileContentNode(
777 Session session, long companyId, long repositoryId,
778 String fileName, double versionNumber)
779 throws PortalException, SystemException {
780
781 String versionLabel = String.valueOf(versionNumber);
782
783 Node contentNode = null;
784
785 try {
786 Node rootNode = getRootNode(session, companyId);
787 Node repositoryNode = getFolderNode(rootNode, repositoryId);
788 Node fileNode = repositoryNode.getNode(fileName);
789 contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
790
791 if (versionNumber > 0) {
792 VersionHistory versionHistory =
793 contentNode.getVersionHistory();
794
795 Version version = versionHistory.getVersionByLabel(
796 versionLabel);
797
798 contentNode = version.getNode(JCRConstants.JCR_FROZEN_NODE);
799 }
800 }
801 catch (PathNotFoundException pnfe) {
802 throw new NoSuchFileException(fileName);
803 }
804 catch (RepositoryException re) {
805 throw new SystemException(re);
806 }
807
808 return contentNode;
809 }
810
811 protected Node getFolderNode(Node node, long name)
812 throws RepositoryException {
813
814 return getFolderNode(node, String.valueOf(name));
815 }
816
817 protected Node getFolderNode(Node node, String name)
818 throws RepositoryException {
819
820 Node folderNode = null;
821
822 if (node.hasNode(name)) {
823 folderNode = node.getNode(name);
824 }
825 else {
826 folderNode = node.addNode(name, JCRConstants.NT_FOLDER);
827 }
828
829 return folderNode;
830 }
831
832 protected Node getRootNode(Session session, long companyId)
833 throws RepositoryException {
834
835 Node companyNode = getFolderNode(session.getRootNode(), companyId);
836
837 return getFolderNode(companyNode, JCRFactory.NODE_DOCUMENTLIBRARY);
838 }
839
840 private static Log _log = LogFactoryUtil.getLog(JCRHook.class);
841
842 }