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