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 queryString = CMISSearchQueryBuilderUtil.buildQuery(
1672 searchContext, query);
1673
1674 String productName = repositoryInfo.getProductName();
1675 String productVersion = repositoryInfo.getProductVersion();
1676
1677 if (productName.contains("Nuxeo") && productVersion.contains("5.4")) {
1678 queryString +=
1679 " AND (" + PropertyIds.IS_LATEST_VERSION + " = true)";
1680 }
1681
1682 if (_log.isDebugEnabled()) {
1683 _log.debug("CMIS search query: " + queryString);
1684 }
1685
1686 ItemIterable<QueryResult> queryResults = session.query(
1687 queryString, false);
1688
1689 int start = searchContext.getStart();
1690 int end = searchContext.getEnd();
1691
1692 if ((start == QueryUtil.ALL_POS) && (end == QueryUtil.ALL_POS)) {
1693 start = 0;
1694 }
1695
1696 int total = 0;
1697
1698 List<com.liferay.portal.kernel.search.Document> documents =
1699 new ArrayList<com.liferay.portal.kernel.search.Document>();
1700 List<String> snippets = new ArrayList<String>();
1701 List<Float> scores = new ArrayList<Float>();
1702
1703 for (QueryResult queryResult : queryResults) {
1704 total++;
1705
1706 if (total <= start) {
1707 continue;
1708 }
1709
1710 if ((total > end) && (end != QueryUtil.ALL_POS)) {
1711 continue;
1712 }
1713
1714 com.liferay.portal.kernel.search.Document document =
1715 new DocumentImpl();
1716
1717 String objectId = queryResult.getPropertyValueByQueryName(
1718 PropertyIds.OBJECT_ID);
1719
1720 if (_log.isDebugEnabled()) {
1721 _log.debug("Search result object ID " + objectId);
1722 }
1723
1724 FileEntry fileEntry = null;
1725
1726 try {
1727 fileEntry = toFileEntry(objectId, true);
1728 }
1729 catch (Exception e) {
1730 if (_log.isDebugEnabled()) {
1731 Throwable cause = e.getCause();
1732
1733 if (cause != null) {
1734 cause = cause.getCause();
1735 }
1736
1737 if (cause instanceof CmisObjectNotFoundException) {
1738 _log.debug(
1739 "Search result ignored for CMIS document which " +
1740 "has a version with an invalid object ID " +
1741 cause.getMessage());
1742 }
1743 else {
1744 _log.debug(
1745 "Search result ignored for invalid object ID", e);
1746 }
1747 }
1748
1749 total--;
1750
1751 continue;
1752 }
1753
1754 document.addKeyword(
1755 Field.ENTRY_CLASS_NAME, fileEntry.getModelClassName());
1756 document.addKeyword(
1757 Field.ENTRY_CLASS_PK, fileEntry.getFileEntryId());
1758 document.addKeyword(Field.TITLE, fileEntry.getTitle());
1759
1760 documents.add(document);
1761
1762 if (queryConfig.isScoreEnabled()) {
1763 Object scoreObj = queryResult.getPropertyValueByQueryName(
1764 "HITS");
1765
1766 if (scoreObj != null) {
1767 scores.add(Float.valueOf(scoreObj.toString()));
1768 }
1769 else {
1770 scores.add(1.0f);
1771 }
1772 }
1773 else {
1774 scores.add(1.0f);
1775 }
1776
1777 snippets.add(StringPool.BLANK);
1778 }
1779
1780 float searchTime =
1781 (float)(System.currentTimeMillis() - startTime) / Time.SECOND;
1782
1783 Hits hits = new HitsImpl();
1784
1785 hits.setDocs(
1786 documents.toArray(
1787 new com.liferay.portal.kernel.search.Document[
1788 documents.size()]));
1789 hits.setLength(total);
1790 hits.setQuery(query);
1791 hits.setQueryTerms(new String[0]);
1792 hits.setScores(scores.toArray(new Float[scores.size()]));
1793 hits.setSearchTime(searchTime);
1794 hits.setSnippets(snippets.toArray(new String[snippets.size()]));
1795 hits.setStart(startTime);
1796
1797 return hits;
1798 }
1799
1800 protected Session getCachedSession() {
1801 HttpSession httpSession = PortalSessionThreadLocal.getHttpSession();
1802
1803 if (httpSession == null) {
1804 return null;
1805 }
1806
1807 TransientValue<Session> transientValue =
1808 (TransientValue<Session>)httpSession.getAttribute(_sessionKey);
1809
1810 if (transientValue == null) {
1811 return null;
1812 }
1813
1814 return transientValue.getValue();
1815 }
1816
1817 protected org.apache.chemistry.opencmis.client.api.Folder getCmisFolder(
1818 Session session, long folderId)
1819 throws PortalException, SystemException {
1820
1821 Folder folder = getFolder(session, folderId);
1822
1823 org.apache.chemistry.opencmis.client.api.Folder cmisFolder =
1824 (org.apache.chemistry.opencmis.client.api.Folder)folder.getModel();
1825
1826 return cmisFolder;
1827 }
1828
1829 protected List<String> getCmisFolderIds(Session session, long folderId)
1830 throws PortalException, SystemException {
1831
1832 StringBundler sb = new StringBundler(4);
1833
1834 sb.append("SELECT cmis:objectId FROM cmis:folder");
1835
1836 if (folderId > 0) {
1837 sb.append(" WHERE IN_FOLDER(");
1838
1839 String objectId = toFolderId(session, folderId);
1840
1841 sb.append(StringUtil.quote(objectId));
1842 sb.append(StringPool.CLOSE_PARENTHESIS);
1843 }
1844
1845 String query = sb.toString();
1846
1847 if (_log.isDebugEnabled()) {
1848 _log.debug("Calling query " + query);
1849 }
1850
1851 ItemIterable<QueryResult> queryResults = session.query(
1852 query, isAllVersionsSearchableSupported(session));
1853
1854 List<String> cmsFolderIds = new ArrayList<String>();
1855
1856 for (QueryResult queryResult : queryResults) {
1857 PropertyData<String> propertyData = queryResult.getPropertyById(
1858 PropertyIds.OBJECT_ID);
1859
1860 List<String> values = propertyData.getValues();
1861
1862 String value = values.get(0);
1863
1864 cmsFolderIds.add(value);
1865 }
1866
1867 return cmsFolderIds;
1868 }
1869
1870 protected Document getDocument(Session session, long fileEntryId)
1871 throws PortalException, SystemException {
1872
1873 try {
1874 String versionSeriesId = toFileEntryId(fileEntryId);
1875
1876 Document document = (Document)session.getObject(versionSeriesId);
1877
1878 return document;
1879 }
1880 catch (CmisObjectNotFoundException confe) {
1881 throw new NoSuchFileEntryException(
1882 "No CMIS file entry with {fileEntryId=" + fileEntryId+ "}",
1883 confe);
1884 }
1885 }
1886
1887 protected List<String> getDocumentIds(
1888 Session session, long folderId, String[] mimeTypes)
1889 throws PortalException, SystemException {
1890
1891 StringBundler sb = new StringBundler();
1892
1893 sb.append("SELECT cmis:objectId FROM cmis:document");
1894
1895 if (ArrayUtil.isNotEmpty(mimeTypes)) {
1896 sb.append(" WHERE cmis:contentStreamMimeType IN (");
1897
1898 for (int i = 0; i < mimeTypes.length; i++) {
1899 sb.append(StringUtil.quote(mimeTypes[i]));
1900
1901 if ((i + 1) < mimeTypes.length) {
1902 sb.append(", ");
1903 }
1904 }
1905
1906 sb.append(StringPool.CLOSE_PARENTHESIS);
1907 }
1908
1909 if (folderId > 0) {
1910 if (ArrayUtil.isNotEmpty(mimeTypes)) {
1911 sb.append(" AND ");
1912 }
1913 else {
1914 sb.append(" WHERE ");
1915 }
1916
1917 sb.append("IN_FOLDER(");
1918
1919 String objectId = toFolderId(session, folderId);
1920
1921 sb.append(StringUtil.quote(objectId));
1922 sb.append(StringPool.CLOSE_PARENTHESIS);
1923 }
1924
1925 String query = sb.toString();
1926
1927 if (_log.isDebugEnabled()) {
1928 _log.debug("Calling query " + query);
1929 }
1930
1931 ItemIterable<QueryResult> queryResults = session.query(query, false);
1932
1933 List<String> cmisDocumentIds = new ArrayList<String>();
1934
1935 for (QueryResult queryResult : queryResults) {
1936 String objectId = queryResult.getPropertyValueByQueryName(
1937 PropertyIds.OBJECT_ID);
1938
1939 cmisDocumentIds.add(objectId);
1940 }
1941
1942 return cmisDocumentIds;
1943 }
1944
1945 protected List<FileEntry> getFileEntries(long folderId)
1946 throws SystemException {
1947
1948 cacheFoldersAndFileEntries(folderId);
1949
1950 Map<Long, List<FileEntry>> fileEntriesCache = _fileEntriesCache.get();
1951
1952 return fileEntriesCache.get(folderId);
1953 }
1954
1955 protected List<FileEntry> getFileEntries(long folderId, long repositoryId) {
1956 return new ArrayList<FileEntry>();
1957 }
1958
1959 protected FileVersion getFileVersion(Session session, long fileVersionId)
1960 throws PortalException, SystemException {
1961
1962 try {
1963 String objectId = toFileVersionId(fileVersionId);
1964
1965 return toFileVersion((Document)session.getObject(objectId));
1966 }
1967 catch (CmisObjectNotFoundException confe) {
1968 throw new NoSuchFileVersionException(
1969 "No CMIS file version with {fileVersionId=" + fileVersionId +
1970 "}",
1971 confe);
1972 }
1973 }
1974
1975 protected Folder getFolder(Session session, long folderId)
1976 throws PortalException, SystemException {
1977
1978 try {
1979 String objectId = toFolderId(session, folderId);
1980
1981 CmisObject cmisObject = session.getObject(objectId);
1982
1983 return (Folder)toFolderOrFileEntry(cmisObject);
1984 }
1985 catch (CmisObjectNotFoundException confe) {
1986 throw new NoSuchFolderException(
1987 "No CMIS folder with {folderId=" + folderId + "}", confe);
1988 }
1989 }
1990
1991 protected List<Folder> getFolders(long parentFolderId)
1992 throws PortalException, SystemException {
1993
1994 Map<Long, List<Folder>> foldersCache = _foldersCache.get();
1995
1996 List<Folder> folders = foldersCache.get(parentFolderId);
1997
1998 if (folders == null) {
1999 List<String> folderIds = getCmisFolderIds(
2000 getSession(), parentFolderId);
2001
2002 folders = new ArrayList<Folder>(folderIds.size());
2003
2004 for (String folderId : folderIds) {
2005 folders.add(toFolder(folderId));
2006 }
2007
2008 foldersCache.put(parentFolderId, folders);
2009 }
2010
2011 return folders;
2012 }
2013
2014 protected List<Object> getFoldersAndFileEntries(long folderId)
2015 throws SystemException {
2016
2017 cacheFoldersAndFileEntries(folderId);
2018
2019 Map<Long, List<Object>> foldersAndFileEntriesCache =
2020 _foldersAndFileEntriesCache.get();
2021
2022 return foldersAndFileEntriesCache.get(folderId);
2023 }
2024
2025 protected String getObjectId(
2026 Session session, long folderId, boolean fileEntry, String name)
2027 throws PortalException, SystemException {
2028
2029 String objectId = toFolderId(session, folderId);
2030
2031 StringBundler sb = new StringBundler(7);
2032
2033 sb.append("SELECT cmis:objectId FROM ");
2034
2035 if (fileEntry) {
2036 sb.append("cmis:document ");
2037 }
2038 else {
2039 sb.append("cmis:folder ");
2040 }
2041
2042 sb.append("WHERE cmis:name = '");
2043 sb.append(name);
2044 sb.append("' AND IN_FOLDER('");
2045 sb.append(objectId);
2046 sb.append("')");
2047
2048 String query = sb.toString();
2049
2050 if (_log.isDebugEnabled()) {
2051 _log.debug("Calling query " + query);
2052 }
2053
2054 ItemIterable<QueryResult> queryResults = session.query(query, false);
2055
2056 Iterator<QueryResult> itr = queryResults.iterator();
2057
2058 if (itr.hasNext()) {
2059 QueryResult queryResult = itr.next();
2060
2061 PropertyData<String> propertyData = queryResult.getPropertyById(
2062 PropertyIds.OBJECT_ID);
2063
2064 List<String> values = propertyData.getValues();
2065
2066 return values.get(0);
2067 }
2068
2069 return null;
2070 }
2071
2072 protected void getSubfolderIds(
2073 List<Long> subfolderIds, List<Folder> subfolders, boolean recurse)
2074 throws PortalException, SystemException {
2075
2076 for (Folder subfolder : subfolders) {
2077 long subfolderId = subfolder.getFolderId();
2078
2079 subfolderIds.add(subfolderId);
2080
2081 if (recurse) {
2082 List<Folder> subSubFolders = getFolders(
2083 subfolderId, false, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
2084 null);
2085
2086 getSubfolderIds(subfolderIds, subSubFolders, recurse);
2087 }
2088 }
2089 }
2090
2091 protected boolean isActionAllowable(String objectId, Action action)
2092 throws PortalException, SystemException {
2093
2094 Session session = getSession();
2095
2096 Document document = (Document)session.getObject(objectId);
2097
2098 AllowableActions allowableActions = document.getAllowableActions();
2099
2100 Set<Action> allowableActionsSet =
2101 allowableActions.getAllowableActions();
2102
2103 if (allowableActionsSet.contains(action)) {
2104 return true;
2105 }
2106 else {
2107 return false;
2108 }
2109 }
2110
2111 protected boolean isAllVersionsSearchableSupported(Session session) {
2112 RepositoryInfo repositoryInfo = session.getRepositoryInfo();
2113
2114 RepositoryCapabilities repositoryCapabilities =
2115 repositoryInfo.getCapabilities();
2116
2117 return repositoryCapabilities.isAllVersionsSearchableSupported();
2118 }
2119
2120 protected void processException(Exception e) throws PortalException {
2121 if ((e instanceof CmisRuntimeException &&
2122 e.getMessage().contains("authorized")) ||
2123 (e instanceof CmisPermissionDeniedException)) {
2124
2125 String message = e.getMessage();
2126
2127 try {
2128 message =
2129 "Unable to login with user " +
2130 _cmisRepositoryHandler.getLogin();
2131 }
2132 catch (Exception e2) {
2133 }
2134
2135 throw new PrincipalException(message, e);
2136 }
2137 }
2138
2139 protected void setCachedSession(Session session) {
2140 HttpSession httpSession = PortalSessionThreadLocal.getHttpSession();
2141
2142 if (httpSession == null) {
2143 if (_log.isWarnEnabled()) {
2144 _log.warn("Unable to get HTTP session");
2145 }
2146
2147 return;
2148 }
2149
2150 httpSession.setAttribute(
2151 _sessionKey, new TransientValue<Session>(session));
2152 }
2153
2154 protected <E> List<E> subList(
2155 List<E> list, int start, int end, OrderByComparator obc) {
2156
2157 if ((obc != null) &&
2158 ((obc instanceof RepositoryModelCreateDateComparator) ||
2159 (obc instanceof RepositoryModelModifiedDateComparator) ||
2160 (obc instanceof RepositoryModelNameComparator) ||
2161 (obc instanceof RepositoryModelSizeComparator))) {
2162
2163 list = ListUtil.sort(list, obc);
2164 }
2165
2166 return ListUtil.subList(list, start, end);
2167 }
2168
2169 protected FileEntry toFileEntry(Document document, boolean strict)
2170 throws PortalException, SystemException {
2171
2172 Object[] ids = null;
2173
2174 if (isDocumentRetrievableByVersionSeriesId()) {
2175 ids = getRepositoryEntryIds(document.getVersionSeriesId());
2176 }
2177 else {
2178 ids = getRepositoryEntryIds(document.getId());
2179 }
2180
2181 long fileEntryId = (Long)ids[0];
2182 String uuid = (String)ids[1];
2183
2184 FileEntry fileEntry = new CMISFileEntry(
2185 this, uuid, fileEntryId, document);
2186
2187 FileVersion fileVersion = null;
2188
2189 try {
2190 fileVersion = fileEntry.getFileVersion();
2191 }
2192 catch (Exception e) {
2193 if (strict) {
2194 if ((Boolean)ids[2]) {
2195 RepositoryEntryUtil.remove(fileEntryId);
2196 }
2197
2198 if (e instanceof CmisObjectNotFoundException) {
2199 throw new NoSuchFileVersionException(
2200 "No CMIS file version with CMIS file entry {objectId=" +
2201 document.getId() + "}",
2202 e);
2203 }
2204 else if (e instanceof SystemException) {
2205 throw (SystemException)e;
2206 }
2207 else {
2208 processException(e);
2209
2210 throw new RepositoryException(e);
2211 }
2212 }
2213 else {
2214 _log.error("Unable to update asset", e);
2215 }
2216 }
2217
2218 dlAppHelperLocalService.checkAssetEntry(
2219 PrincipalThreadLocal.getUserId(), fileEntry, fileVersion);
2220
2221 return fileEntry;
2222 }
2223
2224 protected FileEntry toFileEntry(String objectId, boolean strict)
2225 throws PortalException, SystemException {
2226
2227 try {
2228 Session session = getSession();
2229
2230 Document document = (Document)session.getObject(objectId);
2231
2232 return toFileEntry(document, strict);
2233 }
2234 catch (CmisObjectNotFoundException confe) {
2235 throw new NoSuchFileEntryException(
2236 "No CMIS file entry with {objectId=" + objectId + "}", confe);
2237 }
2238 catch (SystemException se) {
2239 throw se;
2240 }
2241 catch (Exception e) {
2242 processException(e);
2243
2244 throw new RepositoryException(e);
2245 }
2246 }
2247
2248 protected String toFileEntryId(long fileEntryId)
2249 throws PortalException, SystemException {
2250
2251 RepositoryEntry repositoryEntry = RepositoryEntryUtil.fetchByPrimaryKey(
2252 fileEntryId);
2253
2254 if (repositoryEntry == null) {
2255 throw new NoSuchFileEntryException(
2256 "No CMIS file entry with {fileEntryId=" + fileEntryId + "}");
2257 }
2258
2259 return repositoryEntry.getMappedId();
2260 }
2261
2262 protected String toFileVersionId(long fileVersionId)
2263 throws PortalException, SystemException {
2264
2265 RepositoryEntry repositoryEntry = RepositoryEntryUtil.fetchByPrimaryKey(
2266 fileVersionId);
2267
2268 if (repositoryEntry == null) {
2269 throw new NoSuchFileVersionException(
2270 "No CMIS file version with {fileVersionId=" + fileVersionId +
2271 "}");
2272 }
2273
2274 return repositoryEntry.getMappedId();
2275 }
2276
2277 protected String toFolderId(Session session, long folderId)
2278 throws PortalException, SystemException {
2279
2280 RepositoryEntry repositoryEntry = RepositoryEntryUtil.fetchByPrimaryKey(
2281 folderId);
2282
2283 if (repositoryEntry != null) {
2284 return repositoryEntry.getMappedId();
2285 }
2286
2287 DLFolder dlFolder = DLFolderUtil.fetchByPrimaryKey(folderId);
2288
2289 if (dlFolder == null) {
2290 throw new NoSuchFolderException(
2291 "No CMIS folder with {folderId=" + folderId + "}");
2292 }
2293 else if (!dlFolder.isMountPoint()) {
2294 throw new RepositoryException(
2295 "CMIS repository should not be used with {folderId=" +
2296 folderId + "}");
2297 }
2298
2299 RepositoryInfo repositoryInfo = session.getRepositoryInfo();
2300
2301 String rootFolderId = repositoryInfo.getRootFolderId();
2302
2303 repositoryEntry = RepositoryEntryUtil.fetchByR_M(
2304 getRepositoryId(), rootFolderId);
2305
2306 if (repositoryEntry == null) {
2307 repositoryEntry =
2308 RepositoryEntryLocalServiceUtil.addRepositoryEntry(
2309 dlFolder.getUserId(), getGroupId(), getRepositoryId(),
2310 rootFolderId, new ServiceContext());
2311 }
2312
2313 return repositoryEntry.getMappedId();
2314 }
2315
2316 protected Object toFolderOrFileEntry(CmisObject cmisObject)
2317 throws PortalException, SystemException {
2318
2319 if (cmisObject instanceof Document) {
2320 FileEntry fileEntry = toFileEntry((Document)cmisObject);
2321
2322 return fileEntry;
2323 }
2324 else if (cmisObject instanceof
2325 org.apache.chemistry.opencmis.client.api.Folder) {
2326
2327 org.apache.chemistry.opencmis.client.api.Folder cmisFolder =
2328 (org.apache.chemistry.opencmis.client.api.Folder)cmisObject;
2329
2330 Folder folder = toFolder(cmisFolder);
2331
2332 return folder;
2333 }
2334 else {
2335 return null;
2336 }
2337 }
2338
2339 protected void updateMappedId(long repositoryEntryId, String mappedId)
2340 throws PortalException, SystemException {
2341
2342 RepositoryEntry repositoryEntry = RepositoryEntryUtil.findByPrimaryKey(
2343 repositoryEntryId);
2344
2345 if (!mappedId.equals(repositoryEntry.getMappedId())) {
2346 RepositoryEntryLocalServiceUtil.updateRepositoryEntry(
2347 repositoryEntryId, mappedId);
2348 }
2349 }
2350
2351 protected void validateTitle(Session session, long folderId, String title)
2352 throws PortalException, SystemException {
2353
2354 String objectId = getObjectId(session, folderId, true, title);
2355
2356 if (objectId != null) {
2357 throw new DuplicateFileException(title);
2358 }
2359
2360 objectId = getObjectId(session, folderId, false, title);
2361
2362 if (objectId != null) {
2363 throw new DuplicateFolderNameException(title);
2364 }
2365 }
2366
2367 private static final int _DELETE_DEEP = -1;
2368
2369 private static final int _DELETE_NONE = 0;
2370
2371 private static Log _log = LogFactoryUtil.getLog(CMISRepository.class);
2372
2373 private static ThreadLocal<Map<Long, List<FileEntry>>> _fileEntriesCache =
2374 new AutoResetThreadLocal<Map<Long, List<FileEntry>>>(
2375 CMISRepository.class + "._fileEntriesCache",
2376 new HashMap<Long, List<FileEntry>>());
2377 private static ThreadLocal<Map<Long, List<Object>>>
2378 _foldersAndFileEntriesCache =
2379 new AutoResetThreadLocal<Map<Long, List<Object>>>(
2380 CMISRepository.class + "._foldersAndFileEntriesCache",
2381 new HashMap<Long, List<Object>>());
2382 private static ThreadLocal<Map<Long, List<Folder>>> _foldersCache =
2383 new AutoResetThreadLocal<Map<Long, List<Folder>>>(
2384 CMISRepository.class + "._foldersCache",
2385 new HashMap<Long, List<Folder>>());
2386
2387 private CMISRepositoryHandler _cmisRepositoryHandler;
2388 private String _sessionKey;
2389
2390 }