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