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