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