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