1
19
20 package com.liferay.documentlibrary.util;
21
22 import com.liferay.documentlibrary.DuplicateDirectoryException;
23 import com.liferay.documentlibrary.DuplicateFileException;
24 import com.liferay.documentlibrary.NoSuchDirectoryException;
25 import com.liferay.documentlibrary.NoSuchFileException;
26 import com.liferay.portal.PortalException;
27 import com.liferay.portal.SystemException;
28 import com.liferay.portal.jcr.JCRConstants;
29 import com.liferay.portal.jcr.JCRFactory;
30 import com.liferay.portal.jcr.JCRFactoryUtil;
31 import com.liferay.portal.kernel.log.Log;
32 import com.liferay.portal.kernel.log.LogFactoryUtil;
33 import com.liferay.portal.kernel.search.Document;
34 import com.liferay.portal.kernel.search.Field;
35 import com.liferay.portal.kernel.search.SearchEngineUtil;
36 import com.liferay.portal.kernel.search.SearchException;
37 import com.liferay.portal.kernel.util.GetterUtil;
38 import com.liferay.portal.kernel.util.StringUtil;
39 import com.liferay.portal.kernel.util.Validator;
40
41 import java.io.BufferedInputStream;
42 import java.io.InputStream;
43
44 import java.util.ArrayList;
45 import java.util.Calendar;
46 import java.util.Date;
47 import java.util.List;
48
49 import javax.jcr.Node;
50 import javax.jcr.NodeIterator;
51 import javax.jcr.PathNotFoundException;
52 import javax.jcr.Property;
53 import javax.jcr.RepositoryException;
54 import javax.jcr.Session;
55 import javax.jcr.version.Version;
56 import javax.jcr.version.VersionHistory;
57 import javax.jcr.version.VersionIterator;
58
59 import org.apache.commons.lang.StringUtils;
60
61
68 public class JCRHook extends BaseHook {
69
70 public void addDirectory(long companyId, long repositoryId, String dirName)
71 throws PortalException, SystemException {
72
73 Session session = null;
74
75 try {
76 session = JCRFactoryUtil.createSession();
77
78 Node rootNode = getRootNode(session, companyId);
79 Node repositoryNode = getFolderNode(rootNode, repositoryId);
80
81 if (repositoryNode.hasNode(dirName)) {
82 throw new DuplicateDirectoryException(dirName);
83 }
84 else {
85 String[] dirNameArray = StringUtil.split(dirName, "/");
86
87 Node dirNode = repositoryNode;
88
89 for (int i = 0; i < dirNameArray.length; i++) {
90 if (Validator.isNotNull(dirNameArray[i])) {
91 if (dirNode.hasNode(dirNameArray[i])) {
92 dirNode = dirNode.getNode(dirNameArray[i]);
93 }
94 else {
95 dirNode = dirNode.addNode(
96 dirNameArray[i], JCRConstants.NT_FOLDER);
97 }
98 }
99 }
100
101 session.save();
102 }
103 }
104 catch (RepositoryException re) {
105 throw new SystemException(re);
106 }
107 finally {
108 if (session != null) {
109 session.logout();
110 }
111 }
112 }
113
114 public void addFile(
115 long companyId, String portletId, long groupId, long repositoryId,
116 String fileName, long fileEntryId, String properties,
117 Date modifiedDate, String[] tagsCategories, String[] tagsEntries,
118 InputStream is)
119 throws PortalException, SystemException {
120
121 Session session = null;
122
123 try {
124 session = JCRFactoryUtil.createSession();
125
126 Node rootNode = getRootNode(session, companyId);
127 Node repositoryNode = getFolderNode(rootNode, repositoryId);
128
129 if (repositoryNode.hasNode(fileName)) {
130 throw new DuplicateFileException(fileName);
131 }
132 else {
133 Node fileNode = repositoryNode.addNode(
134 fileName, JCRConstants.NT_FILE);
135
136 Node contentNode = fileNode.addNode(
137 JCRConstants.JCR_CONTENT, JCRConstants.NT_RESOURCE);
138
139 contentNode.addMixin(JCRConstants.MIX_VERSIONABLE);
140 contentNode.setProperty(
141 JCRConstants.JCR_MIME_TYPE, "text/plain");
142 contentNode.setProperty(JCRConstants.JCR_DATA, is);
143 contentNode.setProperty(
144 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
145
146 session.save();
147
148 Version version = contentNode.checkin();
149
150 contentNode.getVersionHistory().addVersionLabel(
151 version.getName(), String.valueOf(DEFAULT_VERSION), false);
152
153 Indexer.addFile(
154 companyId, portletId, groupId, repositoryId, fileName,
155 fileEntryId, properties, modifiedDate, tagsCategories,
156 tagsEntries);
157 }
158 }
159 catch (RepositoryException re) {
160 throw new SystemException(re);
161 }
162 catch (SearchException se) {
163 throw new SystemException(se);
164 }
165 finally {
166 if (session != null) {
167 session.logout();
168 }
169 }
170 }
171
172 public void checkRoot(long companyId) throws SystemException {
173 Session session = null;
174
175 try {
176 session = JCRFactoryUtil.createSession();
177
178 getRootNode(session, companyId);
179
180 session.save();
181 }
182 catch (RepositoryException re) {
183 throw new SystemException(re);
184 }
185 finally {
186 if (session != null) {
187 session.logout();
188 }
189 }
190 }
191
192 public void deleteDirectory(
193 long companyId, String portletId, long repositoryId, String dirName)
194 throws PortalException, SystemException {
195
196 Session session = null;
197
198 try {
199 session = JCRFactoryUtil.createSession();
200
201 Node rootNode = getRootNode(session, companyId);
202 Node repositoryNode = getFolderNode(rootNode, repositoryId);
203 Node dirNode = repositoryNode.getNode(dirName);
204
205 deleteDirectory(companyId, portletId, repositoryId, dirNode);
206
207 dirNode.remove();
208
209 session.save();
210 }
211 catch (PathNotFoundException pnfe) {
212 throw new NoSuchDirectoryException(dirName);
213 }
214 catch (RepositoryException e) {
215 throw new PortalException(e);
216 }
217 catch (SearchException se) {
218 throw new SystemException(se);
219 }
220 finally {
221 if (session != null) {
222 session.logout();
223 }
224 }
225 }
226
227 public void deleteFile(
228 long companyId, String portletId, long repositoryId,
229 String fileName)
230 throws PortalException, SystemException {
231
232 Session session = null;
233
234
237
239 try {
240 session = JCRFactoryUtil.createSession();
241
242 Node rootNode = getRootNode(session, companyId);
243 Node repositoryNode = getFolderNode(rootNode, repositoryId);
244 Node fileNode = repositoryNode.getNode(fileName);
245 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
246
247 contentNode.checkout();
248
249 contentNode.setProperty(JCRConstants.JCR_MIME_TYPE, "text/plain");
250 contentNode.setProperty(JCRConstants.JCR_DATA, "");
251 contentNode.setProperty(
252 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
253
254 session.save();
255
256 Version version = contentNode.checkin();
257
258 contentNode.getVersionHistory().addVersionLabel(
259 version.getName(), "0.0", false);
260 }
261 catch (PathNotFoundException pnfe) {
262 throw new NoSuchFileException(fileName);
263 }
264 catch (RepositoryException re) {
265 throw new SystemException(re);
266 }
267 finally {
268 if (session != null) {
269 session.logout();
270 }
271 }
272
273
275 try {
276 session = JCRFactoryUtil.createSession();
277
278 Node rootNode = getRootNode(session, companyId);
279 Node repositoryNode = getFolderNode(rootNode, repositoryId);
280 Node fileNode = repositoryNode.getNode(fileName);
281 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
282
283 VersionHistory versionHistory = contentNode.getVersionHistory();
284
285 VersionIterator itr = versionHistory.getAllVersions();
286
287 while (itr.hasNext()) {
288 Version version = itr.nextVersion();
289
290 if (itr.getPosition() == itr.getSize()) {
291 break;
292 }
293 else {
294 if (!StringUtils.equals(
295 JCRConstants.JCR_ROOT_VERSION, version.getName())) {
296
297 versionHistory.removeVersion(version.getName());
298 }
299 }
300 }
301
302 session.save();
303 }
304 catch (PathNotFoundException pnfe) {
305 throw new NoSuchFileException(fileName);
306 }
307 catch (RepositoryException re) {
308 throw new SystemException(re);
309 }
310 finally {
311 if (session != null) {
312 session.logout();
313 }
314 }
315
316
318 try {
319 session = JCRFactoryUtil.createSession();
320
321 Node rootNode = getRootNode(session, companyId);
322 Node repositoryNode = getFolderNode(rootNode, repositoryId);
323 Node fileNode = repositoryNode.getNode(fileName);
324
325 Indexer.deleteFile(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 BufferedInputStream(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 = Indexer.getFileDocument(
546 companyId, portletId, groupId, repositoryId,
547 node.getName());
548
549 SearchEngineUtil.updateDocument(
550 companyId, doc.get(Field.UID), doc);
551 }
552 catch (Exception e2) {
553 _log.error("Reindexing " + node.getName(), e2);
554 }
555 }
556 }
557 }
558 catch (Exception e1) {
559 throw new SearchException(e1);
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 String fileName, double versionNumber, String sourceFileName,
576 long fileEntryId, String properties, Date modifiedDate,
577 String[] tagsCategories, String[] tagsEntries, InputStream is)
578 throws PortalException, SystemException {
579
580 String versionLabel = String.valueOf(versionNumber);
581
582 Session session = null;
583
584 try {
585 session = JCRFactoryUtil.createSession();
586
587 Node rootNode = getRootNode(session, companyId);
588 Node repositoryNode = getFolderNode(rootNode, repositoryId);
589 Node fileNode = repositoryNode.getNode(fileName);
590 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
591
592 contentNode.checkout();
593
594 contentNode.setProperty(JCRConstants.JCR_MIME_TYPE, "text/plain");
595 contentNode.setProperty(JCRConstants.JCR_DATA, is);
596 contentNode.setProperty(
597 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
598
599 session.save();
600
601 Version version = contentNode.checkin();
602
603 contentNode.getVersionHistory().addVersionLabel(
604 version.getName(), versionLabel, false);
605
606 Indexer.updateFile(
607 companyId, portletId, groupId, repositoryId, fileName,
608 fileEntryId, properties, modifiedDate, tagsCategories,
609 tagsEntries);
610 }
611 catch (PathNotFoundException pnfe) {
612 throw new NoSuchFileException(fileName);
613 }
614 catch (RepositoryException re) {
615 throw new SystemException(re);
616 }
617 catch (SearchException se) {
618 throw new SystemException(se);
619 }
620 finally {
621 if (session != null) {
622 session.logout();
623 }
624 }
625 }
626
627 public void updateFile(
628 long companyId, String portletId, long groupId, long repositoryId,
629 long newRepositoryId, String fileName, long fileEntryId)
630 throws PortalException, SystemException {
631
632 Session session = null;
633
634 try {
635 session = JCRFactoryUtil.createSession();
636
637 Node rootNode = getRootNode(session, companyId);
638 Node repositoryNode = getFolderNode(rootNode, repositoryId);
639 Node fileNode = repositoryNode.getNode(fileName);
640 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
641
642 Node newRepositoryNode = getFolderNode(rootNode, newRepositoryId);
643
644 if (newRepositoryNode.hasNode(fileName)) {
645 throw new DuplicateFileException(fileName);
646 }
647 else {
648 Node newFileNode = newRepositoryNode.addNode(
649 fileName, JCRConstants.NT_FILE);
650
651 Node newContentNode = newFileNode.addNode(
652 JCRConstants.JCR_CONTENT, JCRConstants.NT_RESOURCE);
653
654 VersionHistory versionHistory = contentNode.getVersionHistory();
655
656 String[] versionLabels = versionHistory.getVersionLabels();
657
658 for (int i = (versionLabels.length - 1); i >= 0; i--) {
659 Version version = versionHistory.getVersionByLabel(
660 versionLabels[i]);
661
662 Node frozenContentNode = version.getNode(
663 JCRConstants.JCR_FROZEN_NODE);
664
665 if (i == (versionLabels.length - 1)) {
666 newContentNode.addMixin(JCRConstants.MIX_VERSIONABLE);
667 }
668 else {
669 newContentNode.checkout();
670 }
671
672 newContentNode.setProperty(
673 JCRConstants.JCR_MIME_TYPE, "text/plain");
674 newContentNode.setProperty(
675 JCRConstants.JCR_DATA,
676 frozenContentNode.getProperty(
677 JCRConstants.JCR_DATA).getStream());
678 newContentNode.setProperty(
679 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
680
681 session.save();
682
683 Version newVersion = newContentNode.checkin();
684
685 newContentNode.getVersionHistory().addVersionLabel(
686 newVersion.getName(), versionLabels[i], false);
687 }
688
689 fileNode.remove();
690
691 session.save();
692
693 try {
694 Indexer.deleteFile(
695 companyId, portletId, repositoryId, fileName);
696 }
697 catch (SearchException se) {
698 }
699
700 Indexer.addFile(
701 companyId, portletId, groupId, newRepositoryId, fileName);
702 }
703 }
704 catch (PathNotFoundException pnfe) {
705 throw new NoSuchFileException(fileName);
706 }
707 catch (RepositoryException re) {
708 throw new SystemException(re);
709 }
710 catch (SearchException se) {
711 throw new SystemException(se);
712 }
713 finally {
714 if (session != null) {
715 session.logout();
716 }
717 }
718 }
719
720 protected void deleteDirectory(
721 long companyId, String portletId, long repositoryId, Node dirNode)
722 throws SearchException {
723
724 try {
725 NodeIterator itr = dirNode.getNodes();
726
727 while (itr.hasNext()) {
728 Node node = (Node)itr.next();
729
730 String primaryNodeTypeName =
731 node.getPrimaryNodeType().getName();
732
733 if (primaryNodeTypeName.equals(JCRConstants.NT_FOLDER)) {
734 deleteDirectory(companyId, portletId, repositoryId, node);
735 }
736 else if (primaryNodeTypeName.equals(JCRConstants.NT_FILE)) {
737 Indexer.deleteFile(
738 companyId, portletId, repositoryId, node.getName());
739 }
740 }
741
742 Indexer.deleteFile(
743 companyId, portletId, repositoryId, dirNode.getName());
744 }
745 catch (RepositoryException e) {
746 _log.error(e);
747 }
748 }
749
750 protected Node getFileContentNode(
751 long companyId, long repositoryId, String fileName,
752 double versionNumber)
753 throws PortalException, SystemException {
754
755 Node contentNode = null;
756
757 Session session = null;
758
759 try {
760 session = JCRFactoryUtil.createSession();
761
762 contentNode = getFileContentNode(
763 session, companyId, repositoryId, fileName, versionNumber);
764 }
765 catch (RepositoryException re) {
766 throw new SystemException(re);
767 }
768 finally {
769 if (session != null) {
770 session.logout();
771 }
772 }
773
774 return contentNode;
775 }
776
777 protected Node getFileContentNode(
778 Session session, long companyId, long repositoryId,
779 String fileName, double versionNumber)
780 throws PortalException, SystemException {
781
782 String versionLabel = String.valueOf(versionNumber);
783
784 Node contentNode = null;
785
786 try {
787 Node rootNode = getRootNode(session, companyId);
788 Node repositoryNode = getFolderNode(rootNode, repositoryId);
789 Node fileNode = repositoryNode.getNode(fileName);
790 contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
791
792 if (versionNumber > 0) {
793 VersionHistory versionHistory =
794 contentNode.getVersionHistory();
795
796 Version version = versionHistory.getVersionByLabel(
797 versionLabel);
798
799 contentNode = version.getNode(JCRConstants.JCR_FROZEN_NODE);
800 }
801 }
802 catch (PathNotFoundException pnfe) {
803 throw new NoSuchFileException(fileName);
804 }
805 catch (RepositoryException re) {
806 throw new SystemException(re);
807 }
808
809 return contentNode;
810 }
811
812 protected Node getFolderNode(Node node, long name)
813 throws RepositoryException {
814
815 return getFolderNode(node, String.valueOf(name));
816 }
817
818 protected Node getFolderNode(Node node, String name)
819 throws RepositoryException {
820
821 Node folderNode = null;
822
823 if (node.hasNode(name)) {
824 folderNode = node.getNode(name);
825 }
826 else {
827 folderNode = node.addNode(name, JCRConstants.NT_FOLDER);
828 }
829
830 return folderNode;
831 }
832
833 protected Node getRootNode(Session session, long companyId)
834 throws RepositoryException {
835
836 Node companyNode = getFolderNode(session.getRootNode(), companyId);
837
838 return getFolderNode(companyNode, JCRFactory.NODE_DOCUMENTLIBRARY);
839 }
840
841 private static Log _log = LogFactoryUtil.getLog(JCRHook.class);
842
843 }