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