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