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