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