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