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