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