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