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