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