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