001
014
015 package com.liferay.portal.repository.cmis;
016
017 import com.liferay.portal.NoSuchRepositoryEntryException;
018 import com.liferay.portal.kernel.dao.orm.QueryUtil;
019 import com.liferay.portal.kernel.exception.PortalException;
020 import com.liferay.portal.kernel.exception.SystemException;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.repository.RepositoryException;
024 import com.liferay.portal.kernel.repository.cmis.BaseCmisRepository;
025 import com.liferay.portal.kernel.repository.cmis.CMISRepositoryHandler;
026 import com.liferay.portal.kernel.repository.cmis.search.CMISSearchQueryBuilderUtil;
027 import com.liferay.portal.kernel.repository.model.FileEntry;
028 import com.liferay.portal.kernel.repository.model.FileVersion;
029 import com.liferay.portal.kernel.repository.model.Folder;
030 import com.liferay.portal.kernel.search.DocumentImpl;
031 import com.liferay.portal.kernel.search.Field;
032 import com.liferay.portal.kernel.search.Hits;
033 import com.liferay.portal.kernel.search.HitsImpl;
034 import com.liferay.portal.kernel.search.Query;
035 import com.liferay.portal.kernel.search.QueryConfig;
036 import com.liferay.portal.kernel.search.SearchContext;
037 import com.liferay.portal.kernel.search.SearchException;
038 import com.liferay.portal.kernel.servlet.PortalSessionThreadLocal;
039 import com.liferay.portal.kernel.util.AutoResetThreadLocal;
040 import com.liferay.portal.kernel.util.ListUtil;
041 import com.liferay.portal.kernel.util.OrderByComparator;
042 import com.liferay.portal.kernel.util.StringBundler;
043 import com.liferay.portal.kernel.util.StringPool;
044 import com.liferay.portal.kernel.util.StringUtil;
045 import com.liferay.portal.kernel.util.Time;
046 import com.liferay.portal.kernel.util.TransientValue;
047 import com.liferay.portal.kernel.util.Validator;
048 import com.liferay.portal.model.Lock;
049 import com.liferay.portal.model.RepositoryEntry;
050 import com.liferay.portal.repository.cmis.model.CMISFileEntry;
051 import com.liferay.portal.repository.cmis.model.CMISFileVersion;
052 import com.liferay.portal.repository.cmis.model.CMISFolder;
053 import com.liferay.portal.security.auth.PrincipalException;
054 import com.liferay.portal.security.auth.PrincipalThreadLocal;
055 import com.liferay.portal.service.ServiceContext;
056 import com.liferay.portal.service.persistence.RepositoryEntryUtil;
057 import com.liferay.portal.util.PropsValues;
058 import com.liferay.portlet.documentlibrary.DuplicateFileException;
059 import com.liferay.portlet.documentlibrary.DuplicateFolderNameException;
060 import com.liferay.portlet.documentlibrary.FileNameException;
061 import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
062 import com.liferay.portlet.documentlibrary.NoSuchFileVersionException;
063 import com.liferay.portlet.documentlibrary.NoSuchFolderException;
064 import com.liferay.portlet.documentlibrary.model.DLFileEntryConstants;
065 import com.liferay.portlet.documentlibrary.model.DLFolder;
066 import com.liferay.portlet.documentlibrary.service.persistence.DLFolderUtil;
067 import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelCreateDateComparator;
068 import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelModifiedDateComparator;
069 import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelNameComparator;
070 import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelSizeComparator;
071
072 import java.io.InputStream;
073
074 import java.math.BigInteger;
075
076 import java.util.ArrayList;
077 import java.util.HashMap;
078 import java.util.Iterator;
079 import java.util.List;
080 import java.util.Map;
081 import java.util.Set;
082
083 import javax.servlet.http.HttpSession;
084
085 import org.apache.chemistry.opencmis.client.api.CmisObject;
086 import org.apache.chemistry.opencmis.client.api.Document;
087 import org.apache.chemistry.opencmis.client.api.FileableCmisObject;
088 import org.apache.chemistry.opencmis.client.api.ItemIterable;
089 import org.apache.chemistry.opencmis.client.api.ObjectId;
090 import org.apache.chemistry.opencmis.client.api.QueryResult;
091 import org.apache.chemistry.opencmis.client.api.Session;
092 import org.apache.chemistry.opencmis.client.runtime.ObjectIdImpl;
093 import org.apache.chemistry.opencmis.commons.PropertyIds;
094 import org.apache.chemistry.opencmis.commons.data.AllowableActions;
095 import org.apache.chemistry.opencmis.commons.data.ContentStream;
096 import org.apache.chemistry.opencmis.commons.data.PropertyData;
097 import org.apache.chemistry.opencmis.commons.data.RepositoryCapabilities;
098 import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
099 import org.apache.chemistry.opencmis.commons.enums.Action;
100 import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
101 import org.apache.chemistry.opencmis.commons.enums.CapabilityQuery;
102 import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
103 import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
104 import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
105 import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
106 import org.apache.chemistry.opencmis.commons.impl.Base64;
107 import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
108
109
122 public class CMISRepository extends BaseCmisRepository {
123
124 public CMISRepository(CMISRepositoryHandler cmisRepositoryHandler) {
125 _cmisRepositoryHandler = cmisRepositoryHandler;
126 }
127
128 public FileEntry addFileEntry(
129 long folderId, String sourceFileName, String mimeType, String title,
130 String description, String changeLog, InputStream is, long size,
131 ServiceContext serviceContext)
132 throws PortalException, SystemException {
133
134 if (Validator.isNull(title)) {
135 if (size == 0) {
136 throw new FileNameException();
137 }
138 else {
139 title = sourceFileName;
140 }
141 }
142
143 try {
144 Session session = getSession();
145
146 validateTitle(session, folderId, title);
147
148 org.apache.chemistry.opencmis.client.api.Folder cmisFolder =
149 getCmisFolder(session, folderId);
150
151 Map<String, Object> properties = new HashMap<String, Object>();
152
153 properties.put(PropertyIds.NAME, title);
154 properties.put(
155 PropertyIds.OBJECT_TYPE_ID, BaseTypeId.CMIS_DOCUMENT.value());
156
157 ContentStream contentStream = new ContentStreamImpl(
158 title, BigInteger.valueOf(size), mimeType, is);
159
160 return toFileEntry(
161 cmisFolder.createDocument(properties, contentStream, null));
162 }
163 catch (PortalException pe) {
164 throw pe;
165 }
166 catch (SystemException se) {
167 throw se;
168 }
169 catch (Exception e) {
170 processException(e);
171
172 throw new RepositoryException(e);
173 }
174 }
175
176 public Folder addFolder(
177 long parentFolderId, String title, String description,
178 ServiceContext serviceContext)
179 throws PortalException, SystemException {
180
181 try {
182 Session session = getSession();
183
184 validateTitle(session, parentFolderId, title);
185
186 org.apache.chemistry.opencmis.client.api.Folder cmisFolder =
187 getCmisFolder(session, parentFolderId);
188
189 Map<String, Object> properties = new HashMap<String, Object>();
190
191 properties.put(PropertyIds.NAME, title);
192 properties.put(
193 PropertyIds.OBJECT_TYPE_ID, BaseTypeId.CMIS_FOLDER.value());
194
195 return toFolder(cmisFolder.createFolder(properties));
196 }
197 catch (PortalException pe) {
198 throw pe;
199 }
200 catch (SystemException se) {
201 throw se;
202 }
203 catch (Exception e) {
204 processException(e);
205
206 throw new RepositoryException(e);
207 }
208 }
209
210 public FileVersion cancelCheckOut(long fileEntryId) throws SystemException {
211 Document draftDocument = null;
212
213 try {
214 Session session = getSession();
215
216 String versionSeriesId = toFileEntryId(fileEntryId);
217
218 Document document = (Document)session.getObject(versionSeriesId);
219
220 document.refresh();
221
222 String versionSeriesCheckedOutId =
223 document.getVersionSeriesCheckedOutId();
224
225 if (Validator.isNotNull(versionSeriesCheckedOutId)) {
226 draftDocument = (Document)session.getObject(
227 versionSeriesCheckedOutId);
228
229 draftDocument.cancelCheckOut();
230
231 document = (Document)session.getObject(versionSeriesId);
232
233 document.refresh();
234 }
235 }
236 catch (Exception e) {
237 _log.error(
238 "Unable to cancel checkout for file entry with {fileEntryId=" +
239 fileEntryId + "}",
240 e);
241 }
242
243 if (draftDocument != null) {
244 return toFileVersion(draftDocument);
245 }
246
247 return null;
248 }
249
250 public void checkInFileEntry(
251 long fileEntryId, boolean major, String changeLog,
252 ServiceContext serviceContext) {
253
254 try {
255 clearManualCheckInRequired(fileEntryId, serviceContext);
256
257 Session session = getSession();
258
259 String versionSeriesId = toFileEntryId(fileEntryId);
260
261 Document document = (Document)session.getObject(versionSeriesId);
262
263 document.refresh();
264
265 String versionSeriesCheckedOutId =
266 document.getVersionSeriesCheckedOutId();
267
268 if (Validator.isNotNull(versionSeriesCheckedOutId)) {
269 if (!isSupportsMinorVersions()) {
270 major = true;
271 }
272
273 document = (Document)session.getObject(
274 versionSeriesCheckedOutId);
275
276 document.checkIn(major, null, null, changeLog);
277
278 document = (Document)session.getObject(versionSeriesId);
279
280 document.refresh();
281 }
282 }
283 catch (Exception e) {
284 _log.error(
285 "Unable to check in file entry with {fileEntryId=" +
286 fileEntryId + "}", e);
287 }
288 }
289
290 public void checkInFileEntry(
291 long fileEntryId, String lockUuid, ServiceContext serviceContext) {
292
293 checkInFileEntry(fileEntryId, false, StringPool.BLANK, serviceContext);
294 }
295
296 public FileEntry checkOutFileEntry(
297 long fileEntryId, ServiceContext serviceContext)
298 throws PortalException, SystemException {
299
300 try {
301 setManualCheckInRequired(fileEntryId, serviceContext);
302
303 Session session = getSession();
304
305 String versionSeriesId = toFileEntryId(fileEntryId);
306
307 Document document = (Document)session.getObject(versionSeriesId);
308
309 document.refresh();
310
311 document.checkOut();
312
313 document = (Document)session.getObject(versionSeriesId);
314
315 document.refresh();
316 }
317 catch (Exception e) {
318 _log.error(
319 "Unable checkout file entry with {fileEntryId=" + fileEntryId +
320 "}",
321 e);
322 }
323
324 return getFileEntry(fileEntryId);
325 }
326
327 public FileEntry checkOutFileEntry(
328 long fileEntryId, String owner, long expirationTime,
329 ServiceContext serviceContext) {
330
331 throw new UnsupportedOperationException();
332 }
333
334 public FileEntry copyFileEntry(
335 long groupId, long fileEntryId, long destFolderId,
336 ServiceContext serviceContext)
337 throws PortalException, SystemException {
338
339 try {
340 Session session = getSession();
341
342 Document document = getDocument(session, fileEntryId);
343
344 validateTitle(session, destFolderId, document.getName());
345
346 String destFolderObjectId = toFolderId(session, destFolderId);
347
348 Document newDocument = document.copy(
349 new ObjectIdImpl(destFolderObjectId));
350
351 return toFileEntry(newDocument);
352 }
353 catch (CmisObjectNotFoundException confe) {
354 throw new NoSuchFolderException(
355 "No CMIS folder with {folderId=" + destFolderId + "}", confe);
356 }
357 catch (PortalException pe) {
358 throw pe;
359 }
360 catch (SystemException se) {
361 throw se;
362 }
363 catch (Exception e) {
364 processException(e);
365
366 throw new RepositoryException(e);
367 }
368 }
369
370 public void deleteFileEntry(long fileEntryId)
371 throws PortalException, SystemException {
372
373 try {
374 Session session = getSession();
375
376 Document document = getDocument(session, fileEntryId);
377
378 deleteMappedFileEntry(document);
379
380 document.deleteAllVersions();
381 }
382 catch (PortalException pe) {
383 throw pe;
384 }
385 catch (SystemException se) {
386 throw se;
387 }
388 catch (Exception e) {
389 processException(e);
390
391 throw new RepositoryException(e);
392 }
393 }
394
395 public void deleteFolder(long folderId)
396 throws PortalException, SystemException {
397
398 try {
399 Session session = getSession();
400
401 org.apache.chemistry.opencmis.client.api.Folder cmisFolder =
402 getCmisFolder(session, folderId);
403
404 deleteMappedFolder(cmisFolder);
405
406 cmisFolder.deleteTree(true, UnfileObject.DELETE, false);
407 }
408 catch (PortalException pe) {
409 throw pe;
410 }
411 catch (SystemException se) {
412 throw se;
413 }
414 catch (Exception e) {
415 processException(e);
416
417 throw new RepositoryException(e);
418 }
419 }
420
421 public List<FileEntry> getFileEntries(
422 long folderId, int start, int end, OrderByComparator obc)
423 throws SystemException {
424
425 List<FileEntry> fileEntries = getFileEntries(folderId);
426
427 return subList(fileEntries, start, end, obc);
428 }
429
430 public List<FileEntry> getFileEntries(
431 long folderId, long fileEntryTypeId, int start, int end,
432 OrderByComparator obc) {
433
434 return new ArrayList<FileEntry>();
435 }
436
437 public List<FileEntry> getFileEntries(
438 long folderId, String[] mimeTypes, int start, int end,
439 OrderByComparator obc)
440 throws PortalException, SystemException {
441
442 Map<Long, List<FileEntry>> fileEntriesCache = _fileEntriesCache.get();
443
444 List<FileEntry> fileEntries = fileEntriesCache.get(folderId);
445
446 if ((fileEntries == null) || (mimeTypes != null)) {
447 fileEntries = new ArrayList<FileEntry>();
448
449 List<String> documentIds = getDocumentIds(
450 getSession(), folderId, mimeTypes);
451
452 for (String documentId : documentIds) {
453 FileEntry fileEntry = toFileEntry(documentId);
454
455 fileEntries.add(fileEntry);
456 }
457
458 if (mimeTypes == null) {
459 fileEntriesCache.put(folderId, fileEntries);
460 }
461 }
462
463 return subList(fileEntries, start, end, obc);
464 }
465
466 public int getFileEntriesCount(long folderId) throws SystemException {
467 List<FileEntry> fileEntries = getFileEntries(folderId);
468
469 return fileEntries.size();
470 }
471
472 public int getFileEntriesCount(long folderId, long fileEntryTypeId) {
473 List<FileEntry> fileEntries = getFileEntries(folderId, fileEntryTypeId);
474
475 return fileEntries.size();
476 }
477
478 public int getFileEntriesCount(long folderId, String[] mimeTypes)
479 throws PortalException, SystemException {
480
481 Session session = getSession();
482
483 List<String> documentIds = getDocumentIds(session, folderId, mimeTypes);
484
485 return documentIds.size();
486 }
487
488 public FileEntry getFileEntry(long fileEntryId)
489 throws PortalException, SystemException {
490
491 try {
492 Session session = getSession();
493
494 Document document = getDocument(session, fileEntryId);
495
496 return toFileEntry(document);
497 }
498 catch (PortalException pe) {
499 throw pe;
500 }
501 catch (SystemException se) {
502 throw se;
503 }
504 catch (Exception e) {
505 processException(e);
506
507 throw new RepositoryException(e);
508 }
509 }
510
511 public FileEntry getFileEntry(long folderId, String title)
512 throws PortalException, SystemException {
513
514 try {
515 Session session = getSession();
516
517 String objectId = getObjectId(session, folderId, true, title);
518
519 if (objectId != null) {
520 CmisObject cmisObject = session.getObject(objectId);
521
522 Document document = (Document)cmisObject;
523
524 return toFileEntry(document);
525 }
526 }
527 catch (CmisObjectNotFoundException confe) {
528 throw new NoSuchFileEntryException(
529 "No CMIS file entry with {folderId=" + folderId + ", title=" +
530 title + "}",
531 confe);
532 }
533 catch (PortalException pe) {
534 throw pe;
535 }
536 catch (SystemException se) {
537 throw se;
538 }
539 catch (Exception e) {
540 processException(e);
541
542 throw new RepositoryException(e);
543 }
544
545 throw new NoSuchFileEntryException(
546 "No CMIS file entry with {folderId=" + folderId + ", title=" +
547 title + "}");
548 }
549
550 public FileEntry getFileEntryByUuid(String uuid)
551 throws PortalException, SystemException {
552
553 try {
554 Session session = getSession();
555
556 RepositoryEntry repositoryEntry = RepositoryEntryUtil.findByUUID_G(
557 uuid, getGroupId());
558
559 String objectId = repositoryEntry.getMappedId();
560
561 return toFileEntry((Document)session.getObject(objectId));
562 }
563 catch (CmisObjectNotFoundException confe) {
564 throw new NoSuchFileEntryException(
565 "No CMIS file entry with {uuid=" + uuid + "}", confe);
566 }
567 catch (NoSuchRepositoryEntryException nsree) {
568 throw new NoSuchFileEntryException(nsree);
569 }
570 catch (SystemException se) {
571 throw se;
572 }
573 catch (Exception e) {
574 processException(e);
575
576 throw new RepositoryException(e);
577 }
578 }
579
580 public FileVersion getFileVersion(long fileVersionId)
581 throws PortalException, SystemException {
582
583 try {
584 Session session = getSession();
585
586 return getFileVersion(session, fileVersionId);
587 }
588 catch (PortalException pe) {
589 throw pe;
590 }
591 catch (SystemException se) {
592 throw se;
593 }
594 catch (Exception e) {
595 processException(e);
596
597 throw new RepositoryException(e);
598 }
599 }
600
601 public Folder getFolder(long folderId)
602 throws PortalException, SystemException {
603
604 try {
605 Session session = getSession();
606
607 return getFolder(session, folderId);
608 }
609 catch (PortalException pe) {
610 throw pe;
611 }
612 catch (SystemException se) {
613 throw se;
614 }
615 catch (Exception e) {
616 processException(e);
617
618 throw new RepositoryException(e);
619 }
620 }
621
622 public Folder getFolder(long parentFolderId, String title)
623 throws PortalException, SystemException {
624
625 try {
626 Session session = getSession();
627
628 String objectId = getObjectId(
629 session, parentFolderId, false, title);
630
631 if (objectId != null) {
632 CmisObject cmisObject = session.getObject(objectId);
633
634 return toFolder(
635 (org.apache.chemistry.opencmis.client.api.Folder)
636 cmisObject);
637 }
638 }
639 catch (CmisObjectNotFoundException confe) {
640 throw new NoSuchFolderException(
641 "No CMIS folder with {parentFolderId=" + parentFolderId +
642 ", title=" + title + "}",
643 confe);
644 }
645 catch (PortalException pe) {
646 throw pe;
647 }
648 catch (SystemException se) {
649 throw se;
650 }
651 catch (Exception e) {
652 processException(e);
653
654 throw new RepositoryException(e);
655 }
656
657 throw new NoSuchFolderException(
658 "No CMIS folder with {parentFolderId=" + parentFolderId +
659 ", title=" + title + "}");
660 }
661
662 public List<Folder> getFolders(
663 long parentFolderId, boolean includeMountfolders, int start,
664 int end, OrderByComparator obc)
665 throws PortalException, SystemException {
666
667 List<Folder> folders = getFolders(parentFolderId);
668
669 return subList(folders, start, end, obc);
670 }
671
672 @Override
673 public List<Object> getFoldersAndFileEntries(
674 long folderId, int start, int end, OrderByComparator obc)
675 throws SystemException {
676
677 List<Object> foldersAndFileEntries = getFoldersAndFileEntries(folderId);
678
679 return subList(foldersAndFileEntries, start, end, obc);
680 }
681
682 @Override
683 public List<Object> getFoldersAndFileEntries(
684 long folderId, String[] mimeTypes, int start, int end,
685 OrderByComparator obc)
686 throws PortalException, SystemException {
687
688 Map<Long, List<Object>> foldersAndFileEntriesCache =
689 _foldersAndFileEntriesCache.get();
690
691 List<Object> foldersAndFileEntries = foldersAndFileEntriesCache.get(
692 folderId);
693
694 if ((foldersAndFileEntries == null) || (mimeTypes != null)) {
695 foldersAndFileEntries = new ArrayList<Object>(getFolders(folderId));
696
697 List<FileEntry> fileEntries = getFileEntries(
698 folderId, mimeTypes, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
699 null);
700
701 foldersAndFileEntries.addAll(fileEntries);
702
703 if (mimeTypes == null) {
704 foldersAndFileEntriesCache.put(folderId, foldersAndFileEntries);
705 }
706 }
707
708 return subList(foldersAndFileEntries, start, end, obc);
709 }
710
711 @Override
712 public int getFoldersAndFileEntriesCount(long folderId)
713 throws SystemException {
714
715 List<Object> foldersAndFileEntries = getFoldersAndFileEntries(folderId);
716
717 return foldersAndFileEntries.size();
718 }
719
720 @Override
721 public int getFoldersAndFileEntriesCount(long folderId, String[] mimeTypes)
722 throws PortalException, SystemException {
723
724 if ((mimeTypes != null) && (mimeTypes.length > 0)) {
725 List<Folder> folders = getFolders(folderId);
726
727 Session session = getSession();
728
729 List<String> documentIds = getDocumentIds(
730 session, folderId, mimeTypes);
731
732 return folders.size() + documentIds.size();
733 }
734 else {
735 List<Object> foldersAndFileEntries = getFoldersAndFileEntries(
736 folderId);
737
738 return foldersAndFileEntries.size();
739 }
740 }
741
742 public int getFoldersCount(long parentFolderId, boolean includeMountfolders)
743 throws PortalException, SystemException {
744
745 List<Folder> folders = getFolders(parentFolderId);
746
747 return folders.size();
748 }
749
750 public int getFoldersFileEntriesCount(List<Long> folderIds, int status)
751 throws SystemException {
752
753 int count = 0;
754
755 for (long folderId : folderIds) {
756 List<FileEntry> fileEntries = getFileEntries(folderId);
757
758 count += fileEntries.size();
759 }
760
761 return count;
762 }
763
764 @Override
765 public String getLatestVersionId(String objectId) throws SystemException {
766 try {
767 Session session = getSession();
768
769 Document document = (Document)session.getObject(objectId);
770
771 List<Document> documentVersions = document.getAllVersions();
772
773 document = documentVersions.get(0);
774
775 return document.getId();
776 }
777 catch (Exception e) {
778 throw new RepositoryException(e);
779 }
780 }
781
782 public List<Folder> getMountFolders(
783 long parentFolderId, int start, int end, OrderByComparator obc) {
784
785 return new ArrayList<Folder>();
786 }
787
788 public int getMountFoldersCount(long parentFolderId) {
789 return 0;
790 }
791
792 @Override
793 public String getObjectName(String objectId)
794 throws PortalException, SystemException {
795
796 Session session = getSession();
797
798 CmisObject cmisObject = session.getObject(objectId);
799
800 return cmisObject.getName();
801 }
802
803 @Override
804 public List<String> getObjectPaths(String objectId)
805 throws PortalException, SystemException {
806
807 Session session = getSession();
808
809 CmisObject cmisObject = session.getObject(objectId);
810
811 if (cmisObject instanceof FileableCmisObject) {
812 FileableCmisObject fileableCmisObject =
813 (FileableCmisObject)cmisObject;
814
815 return fileableCmisObject.getPaths();
816 }
817
818 throw new RepositoryException(
819 "CMIS object is unfileable for id " + objectId);
820 }
821
822 public Session getSession() throws PortalException, SystemException {
823 Session session = getCachedSession();
824
825 if (session != null) {
826 return session;
827 }
828
829 SessionImpl sessionImpl =
830 (SessionImpl)_cmisRepositoryHandler.getSession();
831
832 session = sessionImpl.getSession();
833
834 setCachedSession(session);
835
836 return session;
837 }
838
839 public void getSubfolderIds(List<Long> folderIds, long folderId)
840 throws SystemException {
841
842 try {
843 List<Folder> subfolders = getFolders(
844 folderId, false, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
845
846 getSubfolderIds(folderIds, subfolders, true);
847 }
848 catch (SystemException se) {
849 throw se;
850 }
851 catch (Exception e) {
852 throw new RepositoryException(e);
853 }
854 }
855
856 public List<Long> getSubfolderIds(long folderId, boolean recurse)
857 throws SystemException {
858
859 try {
860 List<Long> subfolderIds = new ArrayList<Long>();
861
862 List<Folder> subfolders = getFolders(
863 folderId, false, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
864
865 getSubfolderIds(subfolderIds, subfolders, recurse);
866
867 return subfolderIds;
868 }
869 catch (SystemException se) {
870 throw se;
871 }
872 catch (Exception e) {
873 throw new RepositoryException(e);
874 }
875 }
876
877 public String[] getSupportedConfigurations() {
878 return _cmisRepositoryHandler.getSupportedConfigurations();
879 }
880
881 public String[][] getSupportedParameters() {
882 return _cmisRepositoryHandler.getSupportedParameters();
883 }
884
885 @Override
886 public void initRepository() throws PortalException, SystemException {
887 try {
888 _sessionKey =
889 Session.class.getName().concat(StringPool.POUND).concat(
890 String.valueOf(getRepositoryId()));
891
892 Session session = getSession();
893
894 session.getRepositoryInfo();
895 }
896 catch (PortalException pe) {
897 throw pe;
898 }
899 catch (SystemException se) {
900 throw se;
901 }
902 catch (Exception e) {
903 processException(e);
904
905 throw new RepositoryException(
906 "Unable to initialize CMIS session for repository with " +
907 "{repositoryId=" + getRepositoryId() + "}",
908 e);
909 }
910 }
911
912 @Override
913 public boolean isCancelCheckOutAllowable(String objectId)
914 throws PortalException, SystemException {
915
916 return isActionAllowable(objectId, Action.CAN_CANCEL_CHECK_OUT);
917 }
918
919 @Override
920 public boolean isCheckInAllowable(String objectId)
921 throws PortalException, SystemException {
922
923 return isActionAllowable(objectId, Action.CAN_CHECK_IN);
924 }
925
926 @Override
927 public boolean isCheckOutAllowable(String objectId)
928 throws PortalException, SystemException {
929
930 return isActionAllowable(objectId, Action.CAN_CHECK_OUT);
931 }
932
933 public boolean isDocumentRetrievableByVersionSeriesId() {
934 return _cmisRepositoryHandler.isDocumentRetrievableByVersionSeriesId();
935 }
936
937 public boolean isRefreshBeforePermissionCheck() {
938 return _cmisRepositoryHandler.isRefreshBeforePermissionCheck();
939 }
940
941 @Override
942 public boolean isSupportsMinorVersions()
943 throws PortalException, SystemException {
944
945 try {
946 Session session = getSession();
947
948 RepositoryInfo repositoryInfo = session.getRepositoryInfo();
949
950 String productName = repositoryInfo.getProductName();
951
952 return _cmisRepositoryHandler.isSupportsMinorVersions(productName);
953 }
954 catch (PortalException pe) {
955 throw pe;
956 }
957 catch (SystemException se) {
958 throw se;
959 }
960 catch (Exception e) {
961 processException(e);
962
963 throw new RepositoryException(e);
964 }
965 }
966
967 public Lock lockFolder(long folderId) {
968 throw new UnsupportedOperationException();
969 }
970
971 public Lock lockFolder(
972 long folderId, String owner, boolean inheritable, long expirationTime) {
973
974 throw new UnsupportedOperationException();
975 }
976
977 public FileEntry moveFileEntry(
978 long fileEntryId, long newFolderId, ServiceContext serviceContext)
979 throws PortalException, SystemException {
980
981 try {
982 Session session = getSession();
983
984 String newFolderObjectId = toFolderId(session, newFolderId);
985
986 Document document = getDocument(session, fileEntryId);
987
988 validateTitle(session, newFolderId, document.getName());
989
990 String oldFolderObjectId = document.getParents().get(0).getId();
991
992 if (oldFolderObjectId.equals(newFolderObjectId)) {
993 return toFileEntry(document);
994 }
995
996 document = (Document)document.move(
997 new ObjectIdImpl(oldFolderObjectId),
998 new ObjectIdImpl(newFolderObjectId));
999
1000 String versionSeriesId = toFileEntryId(fileEntryId);
1001
1002 String newObjectId = document.getVersionSeriesId();
1003
1004 if (!versionSeriesId.equals(newObjectId)) {
1005 document = (Document)session.getObject(newObjectId);
1006
1007 updateMappedId(fileEntryId, document.getVersionSeriesId());
1008 }
1009
1010 FileEntry fileEntry = toFileEntry(document);
1011
1012 document = null;
1013
1014 return fileEntry;
1015 }
1016 catch (CmisObjectNotFoundException confe) {
1017 throw new NoSuchFolderException(
1018 "No CMIS folder with {folderId=" + newFolderId + "}", confe);
1019 }
1020 catch (PortalException pe) {
1021 throw pe;
1022 }
1023 catch (SystemException se) {
1024 throw se;
1025 }
1026 catch (Exception e) {
1027 processException(e);
1028
1029 throw new RepositoryException(e);
1030 }
1031 }
1032
1033 public Folder moveFolder(
1034 long folderId, long parentFolderId, ServiceContext serviceContext)
1035 throws PortalException, SystemException {
1036
1037 try {
1038 Session session = getSession();
1039
1040 org.apache.chemistry.opencmis.client.api.Folder cmisFolder =
1041 getCmisFolder(session, folderId);
1042
1043 validateTitle(session, parentFolderId, cmisFolder.getName());
1044
1045 org.apache.chemistry.opencmis.client.api.Folder parentCmisFolder =
1046 cmisFolder.getFolderParent();
1047
1048 if (parentCmisFolder == null) {
1049 throw new RepositoryException(
1050 "Unable to move CMIS root folder with {folderId=" +
1051 folderId + "}");
1052 }
1053
1054 String objectId = toFolderId(session, folderId);
1055
1056 String sourceFolderId = parentCmisFolder.getId();
1057
1058 String targetFolderId = toFolderId(session, parentFolderId);
1059
1060 if (!sourceFolderId.equals(targetFolderId) &&
1061 !targetFolderId.equals(objectId)) {
1062
1063 cmisFolder =
1064 (org.apache.chemistry.opencmis.client.api.Folder)
1065 cmisFolder.move(
1066 new ObjectIdImpl(sourceFolderId),
1067 new ObjectIdImpl(targetFolderId));
1068 }
1069
1070 return toFolder(cmisFolder);
1071 }
1072 catch (CmisObjectNotFoundException confe) {
1073 throw new NoSuchFolderException(
1074 "No CMIS folder with {folderId=" + parentFolderId + "}", confe);
1075 }
1076 catch (PortalException pe) {
1077 throw pe;
1078 }
1079 catch (SystemException se) {
1080 throw se;
1081 }
1082 catch (Exception e) {
1083 processException(e);
1084
1085 throw new RepositoryException(e);
1086 }
1087 }
1088
1089 public Lock refreshFileEntryLock(
1090 String lockUuid, long companyId, long expirationTime) {
1091
1092 throw new UnsupportedOperationException();
1093 }
1094
1095 public Lock refreshFolderLock(
1096 String lockUuid, long companyId, long expirationTime) {
1097
1098 throw new UnsupportedOperationException();
1099 }
1100
1101 public void revertFileEntry(
1102 long fileEntryId, String version, ServiceContext serviceContext)
1103 throws PortalException, SystemException {
1104
1105 try {
1106 Session session = getSession();
1107
1108 Document document = getDocument(session, fileEntryId);
1109
1110 Document oldVersion = null;
1111
1112 List<Document> documentVersions = document.getAllVersions();
1113
1114 for (Document currentVersion : documentVersions) {
1115 String currentVersionLabel = currentVersion.getVersionLabel();
1116
1117 if (Validator.isNull(currentVersionLabel)) {
1118 currentVersionLabel = DLFileEntryConstants.VERSION_DEFAULT;
1119 }
1120
1121 if (currentVersionLabel.equals(version)) {
1122 oldVersion = currentVersion;
1123
1124 break;
1125 }
1126 }
1127
1128 String mimeType = oldVersion.getContentStreamMimeType();
1129 String changeLog = "Reverted to " + version;
1130 String title = oldVersion.getName();
1131 ContentStream contentStream = oldVersion.getContentStream();
1132
1133 updateFileEntry(
1134 fileEntryId, contentStream.getFileName(), mimeType, title,
1135 StringPool.BLANK, changeLog, true, contentStream.getStream(),
1136 contentStream.getLength(), serviceContext);
1137 }
1138 catch (PortalException pe) {
1139 throw pe;
1140 }
1141 catch (SystemException se) {
1142 throw se;
1143 }
1144 catch (Exception e) {
1145 processException(e);
1146
1147 throw new RepositoryException(e);
1148 }
1149 }
1150
1151 public Hits search(SearchContext searchContext, Query query)
1152 throws SearchException {
1153
1154 try {
1155 QueryConfig queryConfig = searchContext.getQueryConfig();
1156
1157 queryConfig.setScoreEnabled(false);
1158
1159 return doSearch(searchContext, query);
1160 }
1161 catch (Exception e) {
1162 throw new SearchException(e);
1163 }
1164 }
1165
1166 public FileEntry toFileEntry(Document document)
1167 throws PortalException, SystemException {
1168
1169 return toFileEntry(document, false);
1170 }
1171
1172 @Override
1173 public FileEntry toFileEntry(String objectId)
1174 throws PortalException, SystemException {
1175
1176 return toFileEntry(objectId, false);
1177 }
1178
1179 public FileVersion toFileVersion(Document version) throws SystemException {
1180 Object[] ids = getRepositoryEntryIds(version.getId());
1181
1182 long fileVersionId = (Long)ids[0];
1183 String uuid = (String)ids[1];
1184
1185 return new CMISFileVersion(this, uuid, fileVersionId, version);
1186 }
1187
1188 public Folder toFolder(
1189 org.apache.chemistry.opencmis.client.api.Folder cmisFolder)
1190 throws SystemException {
1191
1192 Object[] ids = getRepositoryEntryIds(cmisFolder.getId());
1193
1194 long folderId = (Long)ids[0];
1195 String uuid = (String)ids[1];
1196
1197 return new CMISFolder(this, uuid, folderId, cmisFolder);
1198 }
1199
1200 @Override
1201 public Folder toFolder(String objectId)
1202 throws PortalException, SystemException {
1203
1204 try {
1205 Session session = getSession();
1206
1207 org.apache.chemistry.opencmis.client.api.Folder cmisFolder =
1208 (org.apache.chemistry.opencmis.client.api.Folder)
1209 session.getObject(objectId);
1210
1211 return toFolder(cmisFolder);
1212 }
1213 catch (CmisObjectNotFoundException confe) {
1214 throw new NoSuchFolderException(
1215 "No CMIS folder with {objectId=" + objectId + "}", confe);
1216 }
1217 catch (SystemException se) {
1218 throw se;
1219 }
1220 catch (Exception e) {
1221 processException(e);
1222
1223 throw new RepositoryException(e);
1224 }
1225 }
1226
1227 public void unlockFolder(long folderId, String lockUuid) {
1228 throw new UnsupportedOperationException();
1229 }
1230
1231 public FileEntry updateFileEntry(
1232 long fileEntryId, String sourceFileName, String mimeType,
1233 String title, String description, String changeLog,
1234 boolean majorVersion, InputStream is, long size,
1235 ServiceContext serviceContext)
1236 throws PortalException, SystemException {
1237
1238 Document document = null;
1239
1240 ObjectId checkOutDocumentObjectId = null;
1241
1242 try {
1243 Session session = getSession();
1244
1245 document = getDocument(session, fileEntryId);
1246
1247 String versionSeriesCheckedOutId =
1248 document.getVersionSeriesCheckedOutId();
1249
1250 if (Validator.isNotNull(versionSeriesCheckedOutId)) {
1251 document = (Document)session.getObject(
1252 versionSeriesCheckedOutId);
1253
1254 document.refresh();
1255 }
1256
1257 String currentTitle = document.getName();
1258
1259 AllowableActions allowableActions = document.getAllowableActions();
1260
1261 Set<Action> allowableActionsSet =
1262 allowableActions.getAllowableActions();
1263
1264 if (allowableActionsSet.contains(Action.CAN_CHECK_OUT)) {
1265 checkOutDocumentObjectId = document.checkOut();
1266
1267 document = (Document)session.getObject(
1268 checkOutDocumentObjectId);
1269 }
1270
1271 Map<String, Object> properties = null;
1272
1273 ContentStream contentStream = null;
1274
1275 if (Validator.isNotNull(title) && !title.equals(currentTitle)) {
1276 properties = new HashMap<String, Object>();
1277
1278 properties.put(PropertyIds.NAME, title);
1279 }
1280
1281 if (is != null) {
1282 contentStream = new ContentStreamImpl(
1283 sourceFileName, BigInteger.valueOf(size), mimeType, is);
1284 }
1285
1286 checkUpdatable(allowableActionsSet, properties, contentStream);
1287
1288 if (checkOutDocumentObjectId != null) {
1289 if (!isSupportsMinorVersions()) {
1290 majorVersion = true;
1291 }
1292
1293 document.checkIn(
1294 majorVersion, properties, contentStream, changeLog);
1295
1296 checkOutDocumentObjectId = null;
1297 }
1298 else {
1299 if (properties != null) {
1300 document = (Document)document.updateProperties(properties);
1301 }
1302
1303 if (contentStream != null) {
1304 document.setContentStream(contentStream, true, false);
1305 }
1306 }
1307
1308 String versionSeriesId = toFileEntryId(fileEntryId);
1309
1310 document = (Document)session.getObject(versionSeriesId);
1311
1312 return toFileEntry(document);
1313 }
1314 catch (PortalException pe) {
1315 throw pe;
1316 }
1317 catch (SystemException se) {
1318 throw se;
1319 }
1320 catch (Exception e) {
1321 processException(e);
1322
1323 throw new RepositoryException(e);
1324 }
1325 finally {
1326 if (checkOutDocumentObjectId != null) {
1327 document.cancelCheckOut();
1328 }
1329 }
1330 }
1331
1332 @Override
1333 public FileEntry updateFileEntry(
1334 String objectId, String mimeType, Map<String, Object> properties,
1335 InputStream is, String sourceFileName, long size,
1336 ServiceContext serviceContext)
1337 throws PortalException, SystemException {
1338
1339 try {
1340 Session session = getSession();
1341
1342 Document document = (Document)session.getObject(objectId);
1343
1344 AllowableActions allowableActions = document.getAllowableActions();
1345
1346 Set<Action> allowableActionsSet =
1347 allowableActions.getAllowableActions();
1348
1349 ContentStream contentStream = null;
1350
1351 if (is != null) {
1352 is = new Base64.InputStream(is, Base64.ENCODE);
1353
1354 contentStream = new ContentStreamImpl(
1355 sourceFileName, BigInteger.valueOf(size), mimeType, is);
1356 }
1357
1358 checkUpdatable(allowableActionsSet, properties, contentStream);
1359
1360 if (properties != null) {
1361 document = (Document)document.updateProperties(properties);
1362 }
1363
1364 if (contentStream != null) {
1365 document.setContentStream(contentStream, true, false);
1366 }
1367
1368 return toFileEntry(document);
1369 }
1370 catch (PortalException pe) {
1371 throw pe;
1372 }
1373 catch (SystemException se) {
1374 throw se;
1375 }
1376 catch (Exception e) {
1377 processException(e);
1378
1379 throw new RepositoryException(e);
1380 }
1381 }
1382
1383 public Folder updateFolder(
1384 long folderId, String title, String description,
1385 ServiceContext serviceContext)
1386 throws PortalException, SystemException {
1387
1388 try {
1389 Session session = getSession();
1390
1391 String objectId = toFolderId(session, folderId);
1392
1393 org.apache.chemistry.opencmis.client.api.Folder cmisFolder =
1394 (org.apache.chemistry.opencmis.client.api.Folder)
1395 session.getObject(objectId);
1396
1397 String currentTitle = cmisFolder.getName();
1398
1399 Map<String, Object> properties = new HashMap<String, Object>();
1400
1401 if (Validator.isNotNull(title) && !title.equals(currentTitle)) {
1402 properties.put(PropertyIds.NAME, title);
1403 }
1404
1405 String newObjectId = cmisFolder.updateProperties(
1406 properties, true).getId();
1407
1408 if (!objectId.equals(newObjectId)) {
1409 cmisFolder =
1410 (org.apache.chemistry.opencmis.client.api.Folder)
1411 session.getObject(newObjectId);
1412
1413 updateMappedId(folderId, newObjectId);
1414 }
1415
1416 return toFolder(cmisFolder);
1417 }
1418 catch (CmisObjectNotFoundException confe) {
1419 throw new NoSuchFolderException(
1420 "No CMIS folder with {folderId=" + folderId + "}", confe);
1421 }
1422 catch (PortalException pe) {
1423 throw pe;
1424 }
1425 catch (SystemException se) {
1426 throw se;
1427 }
1428 catch (Exception e) {
1429 processException(e);
1430
1431 throw new RepositoryException(e);
1432 }
1433 }
1434
1435 public boolean verifyFileEntryCheckOut(long fileEntryId, String lockUuid) {
1436 throw new UnsupportedOperationException();
1437 }
1438
1439 public boolean verifyInheritableLock(long folderId, String lockUuid) {
1440 throw new UnsupportedOperationException();
1441 }
1442
1443 protected void cacheFoldersAndFileEntries(long folderId)
1444 throws SystemException {
1445
1446 try {
1447 Map<Long, List<Object>> foldersAndFileEntriesCache =
1448 _foldersAndFileEntriesCache.get();
1449
1450 if (foldersAndFileEntriesCache.containsKey(folderId)) {
1451 return;
1452 }
1453
1454 List<Object> foldersAndFileEntries = new ArrayList<Object>();
1455 List<Folder> folders = new ArrayList<Folder>();
1456 List<FileEntry> fileEntries = new ArrayList<FileEntry>();
1457
1458 Session session = getSession();
1459
1460 org.apache.chemistry.opencmis.client.api.Folder cmisParentFolder =
1461 getCmisFolder(session, folderId);
1462
1463 Folder parentFolder = toFolder(cmisParentFolder);
1464
1465 ItemIterable<CmisObject> cmisObjects =
1466 cmisParentFolder.getChildren();
1467
1468 for (CmisObject cmisObject : cmisObjects) {
1469 if (cmisObject instanceof
1470 org.apache.chemistry.opencmis.client.api.Folder) {
1471
1472 CMISFolder cmisFolder = (CMISFolder)toFolder(
1473 (org.apache.chemistry.opencmis.client.api.Folder)
1474 cmisObject);
1475
1476 cmisFolder.setParentFolder(parentFolder);
1477
1478 foldersAndFileEntries.add(cmisFolder);
1479 folders.add(cmisFolder);
1480 }
1481 else if (cmisObject instanceof Document) {
1482 CMISFileEntry cmisFileEntry = (CMISFileEntry)toFileEntry(
1483 (Document)cmisObject);
1484
1485 cmisFileEntry.setParentFolder(parentFolder);
1486
1487 foldersAndFileEntries.add(cmisFileEntry);
1488 fileEntries.add(cmisFileEntry);
1489 }
1490 }
1491
1492 foldersAndFileEntriesCache.put(folderId, foldersAndFileEntries);
1493
1494 Map<Long, List<Folder>> foldersCache = _foldersCache.get();
1495
1496 foldersCache.put(folderId, folders);
1497
1498 Map<Long, List<FileEntry>> fileEntriesCache =
1499 _fileEntriesCache.get();
1500
1501 fileEntriesCache.put(folderId, fileEntries);
1502 }
1503 catch (SystemException se) {
1504 throw se;
1505 }
1506 catch (Exception e) {
1507 throw new RepositoryException(e);
1508 }
1509 }
1510
1511 protected void checkUpdatable(
1512 Set<Action> allowableActionsSet, Map<String, Object> properties,
1513 ContentStream contentStream)
1514 throws PrincipalException {
1515
1516 if (properties != null) {
1517 if (!allowableActionsSet.contains(Action.CAN_UPDATE_PROPERTIES)) {
1518 throw new PrincipalException();
1519 }
1520 }
1521
1522 if (contentStream != null) {
1523 if (!allowableActionsSet.contains(Action.CAN_SET_CONTENT_STREAM)) {
1524 throw new PrincipalException();
1525 }
1526 }
1527 }
1528
1529 protected void deleteMappedFileEntry(Document document)
1530 throws SystemException {
1531
1532 if (PropsValues.DL_REPOSITORY_CMIS_DELETE_DEPTH == _DELETE_NONE) {
1533 return;
1534 }
1535
1536 List<Document> documentVersions = document.getAllVersions();
1537
1538 for (Document version : documentVersions) {
1539 try {
1540 RepositoryEntryUtil.removeByR_M(
1541 getRepositoryId(), version.getId());
1542 }
1543 catch (NoSuchRepositoryEntryException nsree) {
1544 }
1545 }
1546
1547 try {
1548 RepositoryEntryUtil.removeByR_M(
1549 getRepositoryId(), document.getId());
1550 }
1551 catch (NoSuchRepositoryEntryException nsree) {
1552 }
1553 }
1554
1555 protected void deleteMappedFolder(
1556 org.apache.chemistry.opencmis.client.api.Folder cmisFolder)
1557 throws SystemException {
1558
1559 if (PropsValues.DL_REPOSITORY_CMIS_DELETE_DEPTH == _DELETE_NONE) {
1560 return;
1561 }
1562
1563 ItemIterable<CmisObject> cmisObjects = cmisFolder.getChildren();
1564
1565 for (CmisObject cmisObject : cmisObjects) {
1566 if (cmisObject instanceof Document) {
1567 Document document = (Document)cmisObject;
1568
1569 deleteMappedFileEntry(document);
1570 }
1571 else if (cmisObject instanceof
1572 org.apache.chemistry.opencmis.client.api.Folder) {
1573
1574 org.apache.chemistry.opencmis.client.api.Folder cmisSubfolder =
1575 (org.apache.chemistry.opencmis.client.api.Folder)cmisObject;
1576
1577 try {
1578 RepositoryEntryUtil.removeByR_M(
1579 getRepositoryId(), cmisObject.getId());
1580
1581 if (PropsValues.DL_REPOSITORY_CMIS_DELETE_DEPTH ==
1582 _DELETE_DEEP) {
1583
1584 deleteMappedFolder(cmisSubfolder);
1585 }
1586 }
1587 catch (NoSuchRepositoryEntryException nsree) {
1588 }
1589 }
1590 }
1591 }
1592
1593 protected Hits doSearch(SearchContext searchContext, Query query)
1594 throws Exception {
1595
1596 long startTime = System.currentTimeMillis();
1597
1598 Session session = getSession();
1599
1600 RepositoryInfo repositoryInfo = session.getRepositoryInfo();
1601
1602 RepositoryCapabilities repositoryCapabilities =
1603 repositoryInfo.getCapabilities();
1604
1605 QueryConfig queryConfig = searchContext.getQueryConfig();
1606
1607 CapabilityQuery capabilityQuery =
1608 repositoryCapabilities.getQueryCapability();
1609
1610 queryConfig.setAttribute("capabilityQuery", capabilityQuery.value());
1611
1612 String queryString = CMISSearchQueryBuilderUtil.buildQuery(
1613 searchContext, query);
1614
1615 String productName = repositoryInfo.getProductName();
1616 String productVersion = repositoryInfo.getProductVersion();
1617
1618 if (productName.contains("Nuxeo") && productVersion.contains("5.4")) {
1619 queryString +=
1620 " AND (" + PropertyIds.IS_LATEST_VERSION + " = true)";
1621 }
1622
1623 if (_log.isDebugEnabled()) {
1624 _log.debug("CMIS search query: " + queryString);
1625 }
1626
1627 ItemIterable<QueryResult> queryResults = session.query(
1628 queryString, false);
1629
1630 int start = searchContext.getStart();
1631 int end = searchContext.getEnd();
1632
1633 if ((start == QueryUtil.ALL_POS) && (end == QueryUtil.ALL_POS)) {
1634 start = 0;
1635 }
1636
1637 int total = 0;
1638
1639 List<com.liferay.portal.kernel.search.Document> documents =
1640 new ArrayList<com.liferay.portal.kernel.search.Document>();
1641 List<String> snippets = new ArrayList<String>();
1642 List<Float> scores = new ArrayList<Float>();
1643
1644 for (QueryResult queryResult : queryResults) {
1645 total++;
1646
1647 if (total <= start) {
1648 continue;
1649 }
1650
1651 if ((total > end) && (end != QueryUtil.ALL_POS)) {
1652 continue;
1653 }
1654
1655 com.liferay.portal.kernel.search.Document document =
1656 new DocumentImpl();
1657
1658 String objectId = queryResult.getPropertyValueByQueryName(
1659 PropertyIds.OBJECT_ID);
1660
1661 if (_log.isDebugEnabled()) {
1662 _log.debug("Search result object ID " + objectId);
1663 }
1664
1665 FileEntry fileEntry = null;
1666
1667 try {
1668 fileEntry = toFileEntry(objectId, true);
1669 }
1670 catch (Exception e) {
1671 if (_log.isDebugEnabled()) {
1672 Throwable cause = e.getCause();
1673
1674 if (cause != null) {
1675 cause = cause.getCause();
1676 }
1677
1678 if (cause instanceof CmisObjectNotFoundException) {
1679 _log.debug(
1680 "Search result ignored for CMIS document which " +
1681 "has a version with an invalid object ID " +
1682 cause.getMessage());
1683 }
1684 else {
1685 _log.debug(
1686 "Search result ignored for invalid object ID", e);
1687 }
1688 }
1689
1690 total--;
1691
1692 continue;
1693 }
1694
1695 document.addKeyword(
1696 Field.ENTRY_CLASS_NAME, fileEntry.getModelClassName());
1697 document.addKeyword(
1698 Field.ENTRY_CLASS_PK, fileEntry.getFileEntryId());
1699 document.addKeyword(Field.TITLE, fileEntry.getTitle());
1700
1701 documents.add(document);
1702
1703 if (queryConfig.isScoreEnabled()) {
1704 Object scoreObj = queryResult.getPropertyValueByQueryName(
1705 "HITS");
1706
1707 if (scoreObj != null) {
1708 scores.add(Float.valueOf(scoreObj.toString()));
1709 }
1710 else {
1711 scores.add(1.0f);
1712 }
1713 }
1714 else {
1715 scores.add(1.0f);
1716 }
1717
1718 snippets.add(StringPool.BLANK);
1719 }
1720
1721 float searchTime =
1722 (float)(System.currentTimeMillis() - startTime) / Time.SECOND;
1723
1724 Hits hits = new HitsImpl();
1725
1726 hits.setDocs(
1727 documents.toArray(
1728 new com.liferay.portal.kernel.search.Document[
1729 documents.size()]));
1730 hits.setLength(total);
1731 hits.setQuery(query);
1732 hits.setQueryTerms(new String[0]);
1733 hits.setScores(scores.toArray(new Float[scores.size()]));
1734 hits.setSearchTime(searchTime);
1735 hits.setSnippets(snippets.toArray(new String[snippets.size()]));
1736 hits.setStart(startTime);
1737
1738 return hits;
1739 }
1740
1741 protected Session getCachedSession() {
1742 HttpSession httpSession = PortalSessionThreadLocal.getHttpSession();
1743
1744 if (httpSession == null) {
1745 return null;
1746 }
1747
1748 TransientValue<Session> transientValue =
1749 (TransientValue<Session>)httpSession.getAttribute(_sessionKey);
1750
1751 if (transientValue == null) {
1752 return null;
1753 }
1754
1755 return transientValue.getValue();
1756 }
1757
1758 protected org.apache.chemistry.opencmis.client.api.Folder getCmisFolder(
1759 Session session, long folderId)
1760 throws PortalException, SystemException {
1761
1762 Folder folder = getFolder(session, folderId);
1763
1764 org.apache.chemistry.opencmis.client.api.Folder cmisFolder =
1765 (org.apache.chemistry.opencmis.client.api.Folder)folder.getModel();
1766
1767 return cmisFolder;
1768 }
1769
1770 protected List<String> getCmisFolderIds(Session session, long folderId)
1771 throws PortalException, SystemException {
1772
1773 StringBundler sb = new StringBundler(4);
1774
1775 sb.append("SELECT cmis:objectId FROM cmis:folder");
1776
1777 if (folderId > 0) {
1778 sb.append(" WHERE IN_FOLDER(");
1779
1780 String objectId = toFolderId(session, folderId);
1781
1782 sb.append(StringUtil.quote(objectId));
1783 sb.append(StringPool.CLOSE_PARENTHESIS);
1784 }
1785
1786 String query = sb.toString();
1787
1788 if (_log.isDebugEnabled()) {
1789 _log.debug("Calling query " + query);
1790 }
1791
1792 ItemIterable<QueryResult> queryResults = session.query(
1793 query, isAllVersionsSearchableSupported(session));
1794
1795 List<String> cmsFolderIds = new ArrayList<String>();
1796
1797 for (QueryResult queryResult : queryResults) {
1798 PropertyData<String> propertyData = queryResult.getPropertyById(
1799 PropertyIds.OBJECT_ID);
1800
1801 List<String> values = propertyData.getValues();
1802
1803 String value = values.get(0);
1804
1805 cmsFolderIds.add(value);
1806 }
1807
1808 return cmsFolderIds;
1809 }
1810
1811 protected Document getDocument(Session session, long fileEntryId)
1812 throws PortalException, SystemException {
1813
1814 try {
1815 String versionSeriesId = toFileEntryId(fileEntryId);
1816
1817 Document document = (Document)session.getObject(versionSeriesId);
1818
1819 return document;
1820 }
1821 catch (CmisObjectNotFoundException confe) {
1822 throw new NoSuchFileEntryException(
1823 "No CMIS file entry with {fileEntryId=" + fileEntryId+ "}",
1824 confe);
1825 }
1826 }
1827
1828 protected List<String> getDocumentIds(
1829 Session session, long folderId, String[] mimeTypes)
1830 throws PortalException, SystemException {
1831
1832 StringBundler sb = new StringBundler();
1833
1834 sb.append("SELECT cmis:objectId FROM cmis:document");
1835
1836 if ((mimeTypes != null) && (mimeTypes.length > 0)) {
1837 sb.append(" WHERE cmis:contentStreamMimeType IN (");
1838
1839 for (int i = 0; i < mimeTypes.length; i++) {
1840 sb.append(StringUtil.quote(mimeTypes[i]));
1841
1842 if ((i + 1) < mimeTypes.length) {
1843 sb.append(", ");
1844 }
1845 }
1846
1847 sb.append(StringPool.CLOSE_PARENTHESIS);
1848 }
1849
1850 if (folderId > 0) {
1851 if ((mimeTypes != null) && (mimeTypes.length > 0)) {
1852 sb.append(" AND ");
1853 }
1854 else {
1855 sb.append(" WHERE ");
1856 }
1857
1858 sb.append("IN_FOLDER(");
1859
1860 String objectId = toFolderId(session, folderId);
1861
1862 sb.append(StringUtil.quote(objectId));
1863 sb.append(StringPool.CLOSE_PARENTHESIS);
1864 }
1865
1866 String query = sb.toString();
1867
1868 if (_log.isDebugEnabled()) {
1869 _log.debug("Calling query " + query);
1870 }
1871
1872 ItemIterable<QueryResult> queryResults = session.query(query, false);
1873
1874 List<String> cmisDocumentIds = new ArrayList<String>();
1875
1876 for (QueryResult queryResult : queryResults) {
1877 String objectId = queryResult.getPropertyValueByQueryName(
1878 PropertyIds.OBJECT_ID);
1879
1880 cmisDocumentIds.add(objectId);
1881 }
1882
1883 return cmisDocumentIds;
1884 }
1885
1886 protected List<FileEntry> getFileEntries(long folderId)
1887 throws SystemException {
1888
1889 cacheFoldersAndFileEntries(folderId);
1890
1891 Map<Long, List<FileEntry>> fileEntriesCache = _fileEntriesCache.get();
1892
1893 return fileEntriesCache.get(folderId);
1894 }
1895
1896 protected List<FileEntry> getFileEntries(long folderId, long repositoryId) {
1897 return new ArrayList<FileEntry>();
1898 }
1899
1900 protected FileVersion getFileVersion(Session session, long fileVersionId)
1901 throws PortalException, SystemException {
1902
1903 try {
1904 String objectId = toFileVersionId(fileVersionId);
1905
1906 return toFileVersion((Document)session.getObject(objectId));
1907 }
1908 catch (CmisObjectNotFoundException confe) {
1909 throw new NoSuchFileVersionException(
1910 "No CMIS file version with {fileVersionId=" + fileVersionId +
1911 "}",
1912 confe);
1913 }
1914 }
1915
1916 protected Folder getFolder(Session session, long folderId)
1917 throws PortalException, SystemException {
1918
1919 try {
1920 String objectId = toFolderId(session, folderId);
1921
1922 CmisObject cmisObject = session.getObject(objectId);
1923
1924 return (Folder)toFolderOrFileEntry(cmisObject);
1925 }
1926 catch (CmisObjectNotFoundException confe) {
1927 throw new NoSuchFolderException(
1928 "No CMIS folder with {folderId=" + folderId + "}", confe);
1929 }
1930 }
1931
1932 protected List<Folder> getFolders(long parentFolderId)
1933 throws PortalException, SystemException {
1934
1935 Map<Long, List<Folder>> foldersCache = _foldersCache.get();
1936
1937 List<Folder> folders = foldersCache.get(parentFolderId);
1938
1939 if (folders == null) {
1940 List<String> folderIds = getCmisFolderIds(
1941 getSession(), parentFolderId);
1942
1943 folders = new ArrayList<Folder>(folderIds.size());
1944
1945 for (String folderId : folderIds) {
1946 folders.add(toFolder(folderId));
1947 }
1948
1949 foldersCache.put(parentFolderId, folders);
1950 }
1951
1952 return folders;
1953 }
1954
1955 protected List<Object> getFoldersAndFileEntries(long folderId)
1956 throws SystemException {
1957
1958 cacheFoldersAndFileEntries(folderId);
1959
1960 Map<Long, List<Object>> foldersAndFileEntriesCache =
1961 _foldersAndFileEntriesCache.get();
1962
1963 return foldersAndFileEntriesCache.get(folderId);
1964 }
1965
1966 protected String getObjectId(
1967 Session session, long folderId, boolean fileEntry, String name)
1968 throws PortalException, SystemException {
1969
1970 String objectId = toFolderId(session, folderId);
1971
1972 StringBundler sb = new StringBundler(7);
1973
1974 sb.append("SELECT cmis:objectId FROM ");
1975
1976 if (fileEntry) {
1977 sb.append("cmis:document ");
1978 }
1979 else {
1980 sb.append("cmis:folder ");
1981 }
1982
1983 sb.append("WHERE cmis:name = '");
1984 sb.append(name);
1985 sb.append("' AND IN_FOLDER('");
1986 sb.append(objectId);
1987 sb.append("')");
1988
1989 String query = sb.toString();
1990
1991 if (_log.isDebugEnabled()) {
1992 _log.debug("Calling query " + query);
1993 }
1994
1995 ItemIterable<QueryResult> queryResults = session.query(query, false);
1996
1997 Iterator<QueryResult> itr = queryResults.iterator();
1998
1999 if (itr.hasNext()) {
2000 QueryResult queryResult = itr.next();
2001
2002 PropertyData<String> propertyData = queryResult.getPropertyById(
2003 PropertyIds.OBJECT_ID);
2004
2005 List<String> values = propertyData.getValues();
2006
2007 return values.get(0);
2008 }
2009
2010 return null;
2011 }
2012
2013 protected void getSubfolderIds(
2014 List<Long> subfolderIds, List<Folder> subfolders, boolean recurse)
2015 throws PortalException, SystemException {
2016
2017 for (Folder subfolder : subfolders) {
2018 long subfolderId = subfolder.getFolderId();
2019
2020 subfolderIds.add(subfolderId);
2021
2022 if (recurse) {
2023 List<Folder> subSubFolders = getFolders(
2024 subfolderId, false, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
2025 null);
2026
2027 getSubfolderIds(subfolderIds, subSubFolders, recurse);
2028 }
2029 }
2030 }
2031
2032 protected boolean isActionAllowable(String objectId, Action action)
2033 throws PortalException, SystemException {
2034
2035 Session session = getSession();
2036
2037 Document document = (Document)session.getObject(objectId);
2038
2039 AllowableActions allowableActions = document.getAllowableActions();
2040
2041 Set<Action> allowableActionsSet =
2042 allowableActions.getAllowableActions();
2043
2044 if (allowableActionsSet.contains(action)) {
2045 return true;
2046 }
2047 else {
2048 return false;
2049 }
2050 }
2051
2052 protected boolean isAllVersionsSearchableSupported(Session session) {
2053 RepositoryInfo repositoryInfo = session.getRepositoryInfo();
2054
2055 RepositoryCapabilities repositoryCapabilities =
2056 repositoryInfo.getCapabilities();
2057
2058 return repositoryCapabilities.isAllVersionsSearchableSupported();
2059 }
2060
2061 protected void processException(Exception e) throws PortalException {
2062 if ((e instanceof CmisRuntimeException &&
2063 e.getMessage().contains("authorized")) ||
2064 (e instanceof CmisPermissionDeniedException)) {
2065
2066 String message = e.getMessage();
2067
2068 try {
2069 message =
2070 "Unable to login with user " +
2071 _cmisRepositoryHandler.getLogin();
2072 }
2073 catch (Exception e2) {
2074 }
2075
2076 throw new PrincipalException(message, e);
2077 }
2078 }
2079
2080 protected void setCachedSession(Session session) {
2081 HttpSession httpSession = PortalSessionThreadLocal.getHttpSession();
2082
2083 if (httpSession == null) {
2084 if (_log.isWarnEnabled()) {
2085 _log.warn("Unable to get HTTP session");
2086 }
2087
2088 return;
2089 }
2090
2091 httpSession.setAttribute(
2092 _sessionKey, new TransientValue<Session>(session));
2093 }
2094
2095 protected <E> List<E> subList(
2096 List<E> list, int start, int end, OrderByComparator obc) {
2097
2098 if (obc != null) {
2099 if ((obc instanceof RepositoryModelCreateDateComparator) ||
2100 (obc instanceof RepositoryModelModifiedDateComparator) ||
2101 (obc instanceof RepositoryModelSizeComparator)) {
2102
2103 list = ListUtil.sort(list, obc);
2104 }
2105 else if (obc instanceof RepositoryModelNameComparator) {
2106 if (!obc.isAscending()) {
2107 list = ListUtil.sort(list, obc);
2108 }
2109 }
2110 }
2111
2112 if ((start == QueryUtil.ALL_POS) && (end == QueryUtil.ALL_POS)) {
2113 return list;
2114 }
2115 else {
2116 return ListUtil.subList(list, start, end);
2117 }
2118 }
2119
2120 protected FileEntry toFileEntry(Document document, boolean strict)
2121 throws PortalException, SystemException {
2122
2123 Object[] ids = null;
2124
2125 if (isDocumentRetrievableByVersionSeriesId()) {
2126 ids = getRepositoryEntryIds(document.getVersionSeriesId());
2127 }
2128 else {
2129 ids = getRepositoryEntryIds(document.getId());
2130 }
2131
2132 long fileEntryId = (Long)ids[0];
2133 String uuid = (String)ids[1];
2134
2135 FileEntry fileEntry = new CMISFileEntry(
2136 this, uuid, fileEntryId, document);
2137
2138 FileVersion fileVersion = null;
2139
2140 try {
2141 fileVersion = fileEntry.getFileVersion();
2142 }
2143 catch (Exception e) {
2144 if (strict) {
2145 if ((Boolean)ids[2]) {
2146 RepositoryEntryUtil.remove(fileEntryId);
2147 }
2148
2149 if (e instanceof CmisObjectNotFoundException) {
2150 throw new NoSuchFileVersionException(
2151 "No CMIS file version with CMIS file entry {objectId=" +
2152 document.getId() + "}",
2153 e);
2154 }
2155 else if (e instanceof SystemException) {
2156 throw (SystemException)e;
2157 }
2158 else {
2159 processException(e);
2160
2161 throw new RepositoryException(e);
2162 }
2163 }
2164 else {
2165 _log.error("Unable to update asset", e);
2166 }
2167 }
2168
2169 dlAppHelperLocalService.checkAssetEntry(
2170 PrincipalThreadLocal.getUserId(), fileEntry, fileVersion);
2171
2172 return fileEntry;
2173 }
2174
2175 protected FileEntry toFileEntry(String objectId, boolean strict)
2176 throws PortalException, SystemException {
2177
2178 try {
2179 Session session = getSession();
2180
2181 Document document = (Document)session.getObject(objectId);
2182
2183 return toFileEntry(document, strict);
2184 }
2185 catch (CmisObjectNotFoundException confe) {
2186 throw new NoSuchFileEntryException(
2187 "No CMIS file entry with {objectId=" + objectId + "}", confe);
2188 }
2189 catch (SystemException se) {
2190 throw se;
2191 }
2192 catch (Exception e) {
2193 processException(e);
2194
2195 throw new RepositoryException(e);
2196 }
2197 }
2198
2199 protected String toFileEntryId(long fileEntryId)
2200 throws PortalException, SystemException {
2201
2202 RepositoryEntry repositoryEntry = RepositoryEntryUtil.fetchByPrimaryKey(
2203 fileEntryId);
2204
2205 if (repositoryEntry == null) {
2206 throw new NoSuchFileEntryException(
2207 "No CMIS file entry with {fileEntryId=" + fileEntryId + "}");
2208 }
2209
2210 return repositoryEntry.getMappedId();
2211 }
2212
2213 protected String toFileVersionId(long fileVersionId)
2214 throws PortalException, SystemException {
2215
2216 RepositoryEntry repositoryEntry = RepositoryEntryUtil.fetchByPrimaryKey(
2217 fileVersionId);
2218
2219 if (repositoryEntry == null) {
2220 throw new NoSuchFileVersionException(
2221 "No CMIS file version with {fileVersionId=" + fileVersionId +
2222 "}");
2223 }
2224
2225 return repositoryEntry.getMappedId();
2226 }
2227
2228 protected String toFolderId(Session session, long folderId)
2229 throws PortalException, SystemException {
2230
2231 RepositoryEntry repositoryEntry = RepositoryEntryUtil.fetchByPrimaryKey(
2232 folderId);
2233
2234 if (repositoryEntry != null) {
2235 return repositoryEntry.getMappedId();
2236 }
2237
2238 DLFolder dlFolder = DLFolderUtil.fetchByPrimaryKey(folderId);
2239
2240 if (dlFolder == null) {
2241 throw new NoSuchFolderException(
2242 "No CMIS folder with {folderId=" + folderId + "}");
2243 }
2244 else if (!dlFolder.isMountPoint()) {
2245 throw new RepositoryException(
2246 "CMIS repository should not be used with {folderId=" +
2247 folderId + "}");
2248 }
2249
2250 RepositoryInfo repositoryInfo = session.getRepositoryInfo();
2251
2252 String rootFolderId = repositoryInfo.getRootFolderId();
2253
2254 repositoryEntry = RepositoryEntryUtil.fetchByR_M(
2255 getRepositoryId(), rootFolderId);
2256
2257 if (repositoryEntry == null) {
2258 long repositoryEntryId = counterLocalService.increment();
2259
2260 repositoryEntry = RepositoryEntryUtil.create(repositoryEntryId);
2261
2262 repositoryEntry.setGroupId(getGroupId());
2263 repositoryEntry.setRepositoryId(getRepositoryId());
2264 repositoryEntry.setMappedId(rootFolderId);
2265
2266 RepositoryEntryUtil.update(repositoryEntry);
2267 }
2268
2269 return repositoryEntry.getMappedId();
2270 }
2271
2272 protected Object toFolderOrFileEntry(CmisObject cmisObject)
2273 throws PortalException, SystemException {
2274
2275 if (cmisObject instanceof Document) {
2276 FileEntry fileEntry = toFileEntry((Document)cmisObject);
2277
2278 return fileEntry;
2279 }
2280 else if (cmisObject instanceof
2281 org.apache.chemistry.opencmis.client.api.Folder) {
2282
2283 org.apache.chemistry.opencmis.client.api.Folder cmisFolder =
2284 (org.apache.chemistry.opencmis.client.api.Folder)cmisObject;
2285
2286 Folder folder = toFolder(cmisFolder);
2287
2288 return folder;
2289 }
2290 else {
2291 return null;
2292 }
2293 }
2294
2295 protected void updateMappedId(long repositoryEntryId, String mappedId)
2296 throws NoSuchRepositoryEntryException, SystemException {
2297
2298 RepositoryEntry repositoryEntry = RepositoryEntryUtil.findByPrimaryKey(
2299 repositoryEntryId);
2300
2301 if (!mappedId.equals(repositoryEntry.getMappedId())) {
2302 repositoryEntry.setMappedId(mappedId);
2303
2304 RepositoryEntryUtil.update(repositoryEntry);
2305 }
2306 }
2307
2308 protected void validateTitle(Session session, long folderId, String title)
2309 throws PortalException, SystemException {
2310
2311 String objectId = getObjectId(session, folderId, true, title);
2312
2313 if (objectId != null) {
2314 throw new DuplicateFileException(title);
2315 }
2316
2317 objectId = getObjectId(session, folderId, false, title);
2318
2319 if (objectId != null) {
2320 throw new DuplicateFolderNameException(title);
2321 }
2322 }
2323
2324 private static final int _DELETE_DEEP = -1;
2325
2326 private static final int _DELETE_NONE = 0;
2327
2328 private static Log _log = LogFactoryUtil.getLog(CMISRepository.class);
2329
2330 private static ThreadLocal<Map<Long, List<FileEntry>>> _fileEntriesCache =
2331 new AutoResetThreadLocal<Map<Long, List<FileEntry>>>(
2332 CMISRepository.class + "._fileEntriesCache",
2333 new HashMap<Long, List<FileEntry>>());
2334 private static ThreadLocal<Map<Long, List<Object>>>
2335 _foldersAndFileEntriesCache =
2336 new AutoResetThreadLocal<Map<Long, List<Object>>>(
2337 CMISRepository.class + "._foldersAndFileEntriesCache",
2338 new HashMap<Long, List<Object>>());
2339 private static ThreadLocal<Map<Long, List<Folder>>> _foldersCache =
2340 new AutoResetThreadLocal<Map<Long, List<Folder>>>(
2341 CMISRepository.class + "._foldersCache",
2342 new HashMap<Long, List<Folder>>());
2343
2344 private CMISRepositoryHandler _cmisRepositoryHandler;
2345 private String _sessionKey;
2346
2347 }