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