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