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.search.Document;
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.List;
47
48 import javax.jcr.Node;
49 import javax.jcr.NodeIterator;
50 import javax.jcr.PathNotFoundException;
51 import javax.jcr.Property;
52 import javax.jcr.RepositoryException;
53 import javax.jcr.Session;
54 import javax.jcr.version.Version;
55 import javax.jcr.version.VersionHistory;
56 import javax.jcr.version.VersionIterator;
57
58 import org.apache.commons.lang.StringUtils;
59 import org.apache.commons.logging.Log;
60 import org.apache.commons.logging.LogFactory;
61
62
69 public class JCRHook extends BaseHook {
70
71 public void addDirectory(long companyId, long repositoryId, String dirName)
72 throws PortalException, SystemException {
73
74 Session session = null;
75
76 try {
77 session = JCRFactoryUtil.createSession();
78
79 Node rootNode = getRootNode(session, companyId);
80 Node repositoryNode = getFolderNode(rootNode, repositoryId);
81
82 if (repositoryNode.hasNode(dirName)) {
83 throw new DuplicateDirectoryException(dirName);
84 }
85 else {
86 String[] dirNameArray = StringUtil.split(dirName, "/");
87
88 Node dirNode = repositoryNode;
89
90 for (int i = 0; i < dirNameArray.length; i++) {
91 if (Validator.isNotNull(dirNameArray[i])) {
92 if (dirNode.hasNode(dirNameArray[i])) {
93 dirNode = dirNode.getNode(dirNameArray[i]);
94 }
95 else {
96 dirNode = dirNode.addNode(
97 dirNameArray[i], JCRConstants.NT_FOLDER);
98 }
99 }
100 }
101
102 session.save();
103 }
104 }
105 catch (RepositoryException re) {
106 throw new SystemException(re);
107 }
108 finally {
109 if (session != null) {
110 session.logout();
111 }
112 }
113 }
114
115 public void addFile(
116 long companyId, String portletId, long groupId, long repositoryId,
117 String fileName, String properties, 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 properties, tagsEntries);
156 }
157 }
158 catch (RepositoryException re) {
159 throw new SystemException(re);
160 }
161 catch (SearchException se) {
162 throw new SystemException(se);
163 }
164 finally {
165 if (session != null) {
166 session.logout();
167 }
168 }
169 }
170
171 public void checkRoot(long companyId) throws SystemException {
172 Session session = null;
173
174 try {
175 session = JCRFactoryUtil.createSession();
176
177 getRootNode(session, companyId);
178
179 session.save();
180 }
181 catch (RepositoryException re) {
182 throw new SystemException(re);
183 }
184 finally {
185 if (session != null) {
186 session.logout();
187 }
188 }
189 }
190
191 public void deleteDirectory(
192 long companyId, String portletId, long repositoryId, String dirName)
193 throws PortalException, SystemException {
194
195 Session session = null;
196
197 try {
198 session = JCRFactoryUtil.createSession();
199
200 Node rootNode = getRootNode(session, companyId);
201 Node repositoryNode = getFolderNode(rootNode, repositoryId);
202 Node dirNode = repositoryNode.getNode(dirName);
203
204 deleteDirectory(companyId, portletId, repositoryId, dirNode);
205
206 dirNode.remove();
207
208 session.save();
209 }
210 catch (PathNotFoundException pnfe) {
211 throw new NoSuchDirectoryException(dirName);
212 }
213 catch (RepositoryException e) {
214 throw new PortalException(e);
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 Indexer.deleteFile(companyId, portletId, repositoryId, fileName);
325
326 fileNode.remove();
327
328 session.save();
329 }
330 catch (PathNotFoundException pnfe) {
331 throw new NoSuchFileException(fileName);
332 }
333 catch (RepositoryException re) {
334 throw new SystemException(re);
335 }
336 catch (SearchException se) {
337 throw new SystemException(se);
338 }
339 finally {
340 if (session != null) {
341 session.logout();
342 }
343 }
344 }
345
346 public void deleteFile(
347 long companyId, String portletId, long repositoryId,
348 String fileName, double versionNumber)
349 throws PortalException, SystemException {
350
351 String versionLabel = String.valueOf(versionNumber);
352
353 Session session = null;
354
355 try {
356 session = JCRFactoryUtil.createSession();
357
358 Node rootNode = getRootNode(session, companyId);
359 Node repositoryNode = getFolderNode(rootNode, repositoryId);
360 Node fileNode = repositoryNode.getNode(fileName);
361 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
362
363 VersionHistory versionHistory = contentNode.getVersionHistory();
364
365 Version version = versionHistory.getVersionByLabel(versionLabel);
366
367 versionHistory.removeVersion(version.getName());
368
369 session.save();
370 }
371 catch (PathNotFoundException pnfe) {
372 throw new NoSuchFileException(fileName);
373 }
374 catch (RepositoryException re) {
375 throw new SystemException(re);
376 }
377 finally {
378 if (session != null) {
379 session.logout();
380 }
381 }
382 }
383
384 public InputStream getFileAsStream(
385 long companyId, long repositoryId, String fileName,
386 double versionNumber)
387 throws PortalException, SystemException {
388
389 InputStream is = null;
390
391 Session session = null;
392
393 try {
394 session = JCRFactoryUtil.createSession();
395
396 Node contentNode = getFileContentNode(
397 session, companyId, repositoryId, fileName, versionNumber);
398
399 Property data = contentNode.getProperty(JCRConstants.JCR_DATA);
400
401 is = new BufferedInputStream(data.getStream());
402 }
403 catch (RepositoryException re) {
404 throw new SystemException(re);
405 }
406 finally {
407 if (session != null) {
408 session.logout();
409 }
410 }
411
412 return is;
413 }
414
415 public String[] getFileNames(
416 long companyId, long repositoryId, String dirName)
417 throws PortalException, SystemException {
418
419 List<String> fileNames = new ArrayList<String>();
420
421 Session session = null;
422
423 try {
424 session = JCRFactoryUtil.createSession();
425
426 Node rootNode = getRootNode(session, companyId);
427 Node repositoryNode = getFolderNode(rootNode, repositoryId);
428 Node dirNode = repositoryNode.getNode(dirName);
429
430 NodeIterator itr = dirNode.getNodes();
431
432 while (itr.hasNext()) {
433 Node node = (Node)itr.next();
434
435 if (node.getPrimaryNodeType().getName().equals(
436 JCRConstants.NT_FILE)) {
437
438 fileNames.add(dirName + "/" + node.getName());
439 }
440 }
441 }
442 catch (PathNotFoundException pnfe) {
443 throw new NoSuchDirectoryException(dirName);
444 }
445 catch (RepositoryException re) {
446 throw new SystemException(re);
447 }
448 finally {
449 if (session != null) {
450 session.logout();
451 }
452 }
453
454 return fileNames.toArray(new String[fileNames.size()]);
455 }
456
457 public long getFileSize(
458 long companyId, long repositoryId, String fileName)
459 throws PortalException, SystemException {
460
461 long size;
462
463 Session session = null;
464
465 try {
466 session = JCRFactoryUtil.createSession();
467
468 Node contentNode = getFileContentNode(
469 session, companyId, repositoryId, fileName, 0);
470
471 size = contentNode.getProperty(JCRConstants.JCR_DATA).getLength();
472 }
473 catch (RepositoryException re) {
474 throw new SystemException(re);
475 }
476 finally {
477 if (session != null) {
478 session.logout();
479 }
480 }
481
482 return size;
483 }
484
485 public boolean hasFile(
486 long companyId, long repositoryId, String fileName,
487 double versionNumber)
488 throws PortalException, SystemException {
489
490 try {
491 getFileContentNode(
492 companyId, repositoryId, fileName, versionNumber);
493 }
494 catch (NoSuchFileException nsfe) {
495 return false;
496 }
497
498 return true;
499 }
500
501 public void move(String srcDir, String destDir) throws SystemException {
502 Session session = null;
503
504 try {
505 session = JCRFactoryUtil.createSession();
506
507 session.move(srcDir, destDir);
508
509 session.save();
510 }
511 catch (RepositoryException re) {
512 throw new SystemException(re);
513 }
514 finally {
515 if (session != null) {
516 session.logout();
517 }
518 }
519 }
520
521 public void reIndex(String[] ids) throws SearchException {
522 long companyId = GetterUtil.getLong(ids[0]);
523 String portletId = ids[1];
524 long groupId = GetterUtil.getLong(ids[2]);
525 long repositoryId = GetterUtil.getLong(ids[3]);
526
527 Session session = null;
528
529 try {
530 session = JCRFactoryUtil.createSession();
531
532 Node rootNode = getRootNode(session, companyId);
533 Node repositoryNode = getFolderNode(rootNode, repositoryId);
534
535 NodeIterator itr = repositoryNode.getNodes();
536
537 while (itr.hasNext()) {
538 Node node = (Node)itr.next();
539
540 if (node.getPrimaryNodeType().getName().equals(
541 JCRConstants.NT_FILE)) {
542
543 try {
544 Document doc = Indexer.getFileDocument(
545 companyId, portletId, groupId, repositoryId,
546 node.getName());
547
548 SearchEngineUtil.addDocument(companyId, 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, String[] tagsEntries, InputStream is)
575 throws PortalException, SystemException {
576
577 String versionLabel = String.valueOf(versionNumber);
578
579 Session session = null;
580
581 try {
582 session = JCRFactoryUtil.createSession();
583
584 Node rootNode = getRootNode(session, companyId);
585 Node repositoryNode = getFolderNode(rootNode, repositoryId);
586 Node fileNode = repositoryNode.getNode(fileName);
587 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
588
589 contentNode.checkout();
590
591 contentNode.setProperty(JCRConstants.JCR_MIME_TYPE, "text/plain");
592 contentNode.setProperty(JCRConstants.JCR_DATA, is);
593 contentNode.setProperty(
594 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
595
596 session.save();
597
598 Version version = contentNode.checkin();
599
600 contentNode.getVersionHistory().addVersionLabel(
601 version.getName(), versionLabel, false);
602
603 Indexer.updateFile(
604 companyId, portletId, groupId, repositoryId, fileName,
605 properties, tagsEntries);
606 }
607 catch (PathNotFoundException pnfe) {
608 throw new NoSuchFileException(fileName);
609 }
610 catch (RepositoryException re) {
611 throw new SystemException(re);
612 }
613 catch (SearchException se) {
614 throw new SystemException(se);
615 }
616 finally {
617 if (session != null) {
618 session.logout();
619 }
620 }
621 }
622
623 public void updateFile(
624 long companyId, String portletId, long groupId, long repositoryId,
625 long newRepositoryId, String fileName)
626 throws PortalException, SystemException {
627
628 Session session = null;
629
630 try {
631 session = JCRFactoryUtil.createSession();
632
633 Node rootNode = getRootNode(session, companyId);
634 Node repositoryNode = getFolderNode(rootNode, repositoryId);
635 Node fileNode = repositoryNode.getNode(fileName);
636 Node contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
637
638 Node newRepositoryNode = getFolderNode(rootNode, newRepositoryId);
639
640 if (newRepositoryNode.hasNode(fileName)) {
641 throw new DuplicateFileException(fileName);
642 }
643 else {
644 Node newFileNode = newRepositoryNode.addNode(
645 fileName, JCRConstants.NT_FILE);
646
647 Node newContentNode = newFileNode.addNode(
648 JCRConstants.JCR_CONTENT, JCRConstants.NT_RESOURCE);
649
650 VersionHistory versionHistory = contentNode.getVersionHistory();
651
652 String[] versionLabels = versionHistory.getVersionLabels();
653
654 for (int i = (versionLabels.length - 1); i >= 0; i--) {
655 Version version = versionHistory.getVersionByLabel(
656 versionLabels[i]);
657
658 Node frozenContentNode = version.getNode(
659 JCRConstants.JCR_FROZEN_NODE);
660
661 if (i == (versionLabels.length - 1)) {
662 newContentNode.addMixin(JCRConstants.MIX_VERSIONABLE);
663 }
664 else {
665 newContentNode.checkout();
666 }
667
668 newContentNode.setProperty(
669 JCRConstants.JCR_MIME_TYPE, "text/plain");
670 newContentNode.setProperty(
671 JCRConstants.JCR_DATA,
672 frozenContentNode.getProperty(
673 JCRConstants.JCR_DATA).getStream());
674 newContentNode.setProperty(
675 JCRConstants.JCR_LAST_MODIFIED, Calendar.getInstance());
676
677 session.save();
678
679 Version newVersion = newContentNode.checkin();
680
681 newContentNode.getVersionHistory().addVersionLabel(
682 newVersion.getName(), versionLabels[i], false);
683 }
684
685 fileNode.remove();
686
687 session.save();
688
689 try {
690 Indexer.deleteFile(
691 companyId, portletId, repositoryId, fileName);
692 }
693 catch (SearchException se) {
694 }
695
696 Indexer.addFile(
697 companyId, portletId, groupId, newRepositoryId, fileName);
698 }
699 }
700 catch (PathNotFoundException pnfe) {
701 throw new NoSuchFileException(fileName);
702 }
703 catch (RepositoryException re) {
704 throw new SystemException(re);
705 }
706 catch (SearchException se) {
707 throw new SystemException(se);
708 }
709 finally {
710 if (session != null) {
711 session.logout();
712 }
713 }
714 }
715
716 protected void deleteDirectory(
717 long companyId, String portletId, long repositoryId, Node dirNode)
718 throws SearchException {
719
720 try {
721 NodeIterator itr = dirNode.getNodes();
722
723 while (itr.hasNext()) {
724 Node node = (Node)itr.next();
725
726 String primaryNodeTypeName =
727 node.getPrimaryNodeType().getName();
728
729 if (primaryNodeTypeName.equals(JCRConstants.NT_FOLDER)) {
730 deleteDirectory(companyId, portletId, repositoryId, node);
731 }
732 else if (primaryNodeTypeName.equals(JCRConstants.NT_FILE)) {
733 Indexer.deleteFile(
734 companyId, portletId, repositoryId, node.getName());
735 }
736 }
737
738 Indexer.deleteFile(
739 companyId, portletId, repositoryId, dirNode.getName());
740 }
741 catch (RepositoryException e) {
742 _log.error(e);
743 }
744 }
745
746 protected Node getFileContentNode(
747 long companyId, long repositoryId, String fileName,
748 double versionNumber)
749 throws PortalException, SystemException {
750
751 Node contentNode = null;
752
753 Session session = null;
754
755 try {
756 session = JCRFactoryUtil.createSession();
757
758 contentNode = getFileContentNode(
759 session, companyId, repositoryId, fileName, versionNumber);
760 }
761 catch (RepositoryException re) {
762 throw new SystemException(re);
763 }
764 finally {
765 if (session != null) {
766 session.logout();
767 }
768 }
769
770 return contentNode;
771 }
772
773 protected Node getFileContentNode(
774 Session session, long companyId, long repositoryId,
775 String fileName, double versionNumber)
776 throws PortalException, SystemException {
777
778 String versionLabel = String.valueOf(versionNumber);
779
780 Node contentNode = null;
781
782 try {
783 Node rootNode = getRootNode(session, companyId);
784 Node repositoryNode = getFolderNode(rootNode, repositoryId);
785 Node fileNode = repositoryNode.getNode(fileName);
786 contentNode = fileNode.getNode(JCRConstants.JCR_CONTENT);
787
788 if (versionNumber > 0) {
789 VersionHistory versionHistory =
790 contentNode.getVersionHistory();
791
792 Version version = versionHistory.getVersionByLabel(
793 versionLabel);
794
795 contentNode = version.getNode(JCRConstants.JCR_FROZEN_NODE);
796 }
797 }
798 catch (PathNotFoundException pnfe) {
799 throw new NoSuchFileException(fileName);
800 }
801 catch (RepositoryException re) {
802 throw new SystemException(re);
803 }
804
805 return contentNode;
806 }
807
808 protected Node getFolderNode(Node node, long name)
809 throws RepositoryException {
810
811 return getFolderNode(node, String.valueOf(name));
812 }
813
814 protected Node getFolderNode(Node node, String name)
815 throws RepositoryException {
816
817 Node folderNode = null;
818
819 if (node.hasNode(name)) {
820 folderNode = node.getNode(name);
821 }
822 else {
823 folderNode = node.addNode(name, JCRConstants.NT_FOLDER);
824 }
825
826 return folderNode;
827 }
828
829 protected Node getRootNode(Session session, long companyId)
830 throws RepositoryException {
831
832 Node companyNode = getFolderNode(session.getRootNode(), companyId);
833
834 return getFolderNode(companyNode, JCRFactory.NODE_DOCUMENTLIBRARY);
835 }
836
837 private static Log _log = LogFactory.getLog(JCRHook.class);
838
839 }