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.log.Log;
35 import com.liferay.portal.kernel.log.LogFactoryUtil;
36 import com.liferay.portal.kernel.search.Document;
37 import com.liferay.portal.kernel.search.Field;
38 import com.liferay.portal.kernel.search.SearchEngineUtil;
39 import com.liferay.portal.kernel.search.SearchException;
40 import com.liferay.portal.kernel.util.GetterUtil;
41 import com.liferay.portal.kernel.util.StringUtil;
42 import com.liferay.portal.kernel.util.Validator;
43
44 import java.io.BufferedInputStream;
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
71 public class JCRHook extends BaseHook {
72
73 public void addDirectory(long companyId, long repositoryId, String dirName)
74 throws PortalException, SystemException {
75
76 Session session = null;
77
78 try {
79 session = JCRFactoryUtil.createSession();
80
81 Node rootNode = getRootNode(session, companyId);
82 Node repositoryNode = getFolderNode(rootNode, repositoryId);
83
84 if (repositoryNode.hasNode(dirName)) {
85 throw new DuplicateDirectoryException(dirName);
86 }
87 else {
88 String[] dirNameArray = StringUtil.split(dirName, "/");
89
90 Node dirNode = repositoryNode;
91
92 for (int i = 0; i < dirNameArray.length; i++) {
93 if (Validator.isNotNull(dirNameArray[i])) {
94 if (dirNode.hasNode(dirNameArray[i])) {
95 dirNode = dirNode.getNode(dirNameArray[i]);
96 }
97 else {
98 dirNode = dirNode.addNode(
99 dirNameArray[i], JCRConstants.NT_FOLDER);
100 }
101 }
102 }
103
104 session.save();
105 }
106 }
107 catch (RepositoryException re) {
108 throw new SystemException(re);
109 }
110 finally {
111 if (session != null) {
112 session.logout();
113 }
114 }
115 }
116
117 public void addFile(
118 long companyId, String portletId, long groupId, long repositoryId,
119 String fileName, long fileEntryId, String properties,
120 Date modifiedDate, String[] tagsCategories, String[] tagsEntries,
121 InputStream is)
122 throws PortalException, SystemException {
123
124 Session session = null;
125
126 try {
127 session = JCRFactoryUtil.createSession();
128
129 Node rootNode = getRootNode(session, companyId);
130 Node repositoryNode = getFolderNode(rootNode, repositoryId);
131
132 if (repositoryNode.hasNode(fileName)) {
133 throw new DuplicateFileException(fileName);
134 }
135 else {
136 Node fileNode = repositoryNode.addNode(
137 fileName, JCRConstants.NT_FILE);
138
139 Node contentNode = fileNode.addNode(
140 JCRConstants.JCR_CONTENT, JCRConstants.NT_RESOURCE);
141
142 contentNode.addMixin(JCRConstants.MIX_VERSIONABLE);
143 contentNode.setProperty(
144 JCRConstants.JCR_MIME_TYPE, "text/plain");
145 contentNode.setProperty(JCRConstants.JCR_DATA, is);
146 contentNode.setProperty(
147 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
148
149 session.save();
150
151 Version version = contentNode.checkin();
152
153 contentNode.getVersionHistory().addVersionLabel(
154 version.getName(), String.valueOf(DEFAULT_VERSION), false);
155
156 Indexer.addFile(
157 companyId, portletId, groupId, repositoryId, fileName,
158 fileEntryId, properties, modifiedDate, tagsCategories,
159 tagsEntries);
160 }
161 }
162 catch (RepositoryException re) {
163 throw new SystemException(re);
164 }
165 catch (SearchException se) {
166 throw new SystemException(se);
167 }
168 finally {
169 if (session != null) {
170 session.logout();
171 }
172 }
173 }
174
175 public void checkRoot(long companyId) throws SystemException {
176 Session session = null;
177
178 try {
179 session = JCRFactoryUtil.createSession();
180
181 getRootNode(session, companyId);
182
183 session.save();
184 }
185 catch (RepositoryException re) {
186 throw new SystemException(re);
187 }
188 finally {
189 if (session != null) {
190 session.logout();
191 }
192 }
193 }
194
195 public void deleteDirectory(
196 long companyId, String portletId, long repositoryId, String dirName)
197 throws PortalException, SystemException {
198
199 Session session = null;
200
201 try {
202 session = JCRFactoryUtil.createSession();
203
204 Node rootNode = getRootNode(session, companyId);
205 Node repositoryNode = getFolderNode(rootNode, repositoryId);
206 Node dirNode = repositoryNode.getNode(dirName);
207
208 deleteDirectory(companyId, portletId, repositoryId, dirNode);
209
210 dirNode.remove();
211
212 session.save();
213 }
214 catch (PathNotFoundException pnfe) {
215 throw new NoSuchDirectoryException(dirName);
216 }
217 catch (RepositoryException e) {
218 throw new PortalException(e);
219 }
220 catch (SearchException se) {
221 throw new SystemException(se);
222 }
223 finally {
224 if (session != null) {
225 session.logout();
226 }
227 }
228 }
229
230 public void deleteFile(
231 long companyId, String portletId, long repositoryId,
232 String fileName)
233 throws PortalException, SystemException {
234
235 Session session = null;
236
237
240
242 try {
243 session = JCRFactoryUtil.createSession();
244
245 Node rootNode = getRootNode(session, companyId);
246 Node repositoryNode = getFolderNode(rootNode, repositoryId);
247 Node fileNode = repositoryNode.getNode(fileName);
248 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
249
250 contentNode.checkout();
251
252 contentNode.setProperty(JCRConstants.JCR_MIME_TYPE, "text/plain");
253 contentNode.setProperty(JCRConstants.JCR_DATA, "");
254 contentNode.setProperty(
255 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
256
257 session.save();
258
259 Version version = contentNode.checkin();
260
261 contentNode.getVersionHistory().addVersionLabel(
262 version.getName(), "0.0", false);
263 }
264 catch (PathNotFoundException pnfe) {
265 throw new NoSuchFileException(fileName);
266 }
267 catch (RepositoryException re) {
268 throw new SystemException(re);
269 }
270 finally {
271 if (session != null) {
272 session.logout();
273 }
274 }
275
276
278 try {
279 session = JCRFactoryUtil.createSession();
280
281 Node rootNode = getRootNode(session, companyId);
282 Node repositoryNode = getFolderNode(rootNode, repositoryId);
283 Node fileNode = repositoryNode.getNode(fileName);
284 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
285
286 VersionHistory versionHistory = contentNode.getVersionHistory();
287
288 VersionIterator itr = versionHistory.getAllVersions();
289
290 while (itr.hasNext()) {
291 Version version = itr.nextVersion();
292
293 if (itr.getPosition() == itr.getSize()) {
294 break;
295 }
296 else {
297 if (!StringUtils.equals(
298 JCRConstants.JCR_ROOT_VERSION, version.getName())) {
299
300 versionHistory.removeVersion(version.getName());
301 }
302 }
303 }
304
305 session.save();
306 }
307 catch (PathNotFoundException pnfe) {
308 throw new NoSuchFileException(fileName);
309 }
310 catch (RepositoryException re) {
311 throw new SystemException(re);
312 }
313 finally {
314 if (session != null) {
315 session.logout();
316 }
317 }
318
319
321 try {
322 session = JCRFactoryUtil.createSession();
323
324 Node rootNode = getRootNode(session, companyId);
325 Node repositoryNode = getFolderNode(rootNode, repositoryId);
326 Node fileNode = repositoryNode.getNode(fileName);
327
328 Indexer.deleteFile(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 BufferedInputStream(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 = Indexer.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 String fileName, double versionNumber, String sourceFileName,
579 long fileEntryId, String properties, Date modifiedDate,
580 String[] tagsCategories, String[] tagsEntries, InputStream is)
581 throws PortalException, SystemException {
582
583 String versionLabel = String.valueOf(versionNumber);
584
585 Session session = null;
586
587 try {
588 session = JCRFactoryUtil.createSession();
589
590 Node rootNode = getRootNode(session, companyId);
591 Node repositoryNode = getFolderNode(rootNode, repositoryId);
592 Node fileNode = repositoryNode.getNode(fileName);
593 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
594
595 contentNode.checkout();
596
597 contentNode.setProperty(JCRConstants.JCR_MIME_TYPE, "text/plain");
598 contentNode.setProperty(JCRConstants.JCR_DATA, is);
599 contentNode.setProperty(
600 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
601
602 session.save();
603
604 Version version = contentNode.checkin();
605
606 contentNode.getVersionHistory().addVersionLabel(
607 version.getName(), versionLabel, false);
608
609 Indexer.updateFile(
610 companyId, portletId, groupId, repositoryId, fileName,
611 fileEntryId, properties, modifiedDate, tagsCategories,
612 tagsEntries);
613 }
614 catch (PathNotFoundException pnfe) {
615 throw new NoSuchFileException(fileName);
616 }
617 catch (RepositoryException re) {
618 throw new SystemException(re);
619 }
620 catch (SearchException se) {
621 throw new SystemException(se);
622 }
623 finally {
624 if (session != null) {
625 session.logout();
626 }
627 }
628 }
629
630 public void updateFile(
631 long companyId, String portletId, long groupId, long repositoryId,
632 long newRepositoryId, String fileName, long fileEntryId)
633 throws PortalException, SystemException {
634
635 Session session = null;
636
637 try {
638 session = JCRFactoryUtil.createSession();
639
640 Node rootNode = getRootNode(session, companyId);
641 Node repositoryNode = getFolderNode(rootNode, repositoryId);
642 Node fileNode = repositoryNode.getNode(fileName);
643 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
644
645 Node newRepositoryNode = getFolderNode(rootNode, newRepositoryId);
646
647 if (newRepositoryNode.hasNode(fileName)) {
648 throw new DuplicateFileException(fileName);
649 }
650 else {
651 Node newFileNode = newRepositoryNode.addNode(
652 fileName, JCRConstants.NT_FILE);
653
654 Node newContentNode = newFileNode.addNode(
655 JCRConstants.JCR_CONTENT, JCRConstants.NT_RESOURCE);
656
657 VersionHistory versionHistory = contentNode.getVersionHistory();
658
659 String[] versionLabels = versionHistory.getVersionLabels();
660
661 for (int i = (versionLabels.length - 1); i >= 0; i--) {
662 Version version = versionHistory.getVersionByLabel(
663 versionLabels[i]);
664
665 Node frozenContentNode = version.getNode(
666 JCRConstants.JCR_FROZEN_NODE);
667
668 if (i == (versionLabels.length - 1)) {
669 newContentNode.addMixin(JCRConstants.MIX_VERSIONABLE);
670 }
671 else {
672 newContentNode.checkout();
673 }
674
675 newContentNode.setProperty(
676 JCRConstants.JCR_MIME_TYPE, "text/plain");
677 newContentNode.setProperty(
678 JCRConstants.JCR_DATA,
679 frozenContentNode.getProperty(
680 JCRConstants.JCR_DATA).getStream());
681 newContentNode.setProperty(
682 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
683
684 session.save();
685
686 Version newVersion = newContentNode.checkin();
687
688 newContentNode.getVersionHistory().addVersionLabel(
689 newVersion.getName(), versionLabels[i], false);
690 }
691
692 fileNode.remove();
693
694 session.save();
695
696 try {
697 Indexer.deleteFile(
698 companyId, portletId, repositoryId, fileName);
699 }
700 catch (SearchException se) {
701 }
702
703 Indexer.addFile(
704 companyId, portletId, groupId, newRepositoryId, fileName);
705 }
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 Indexer.deleteFile(
741 companyId, portletId, repositoryId, node.getName());
742 }
743 }
744
745 Indexer.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 }