001    /**
002     * Copyright (c) 2000-present 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.portlet.documentlibrary.trash;
016    
017    import com.liferay.portal.InvalidRepositoryException;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.repository.Repository;
020    import com.liferay.portal.kernel.repository.RepositoryProviderUtil;
021    import com.liferay.portal.kernel.repository.capabilities.TrashCapability;
022    import com.liferay.portal.kernel.repository.model.FileEntry;
023    import com.liferay.portal.kernel.repository.util.RepositoryTrashUtil;
024    import com.liferay.portal.kernel.search.Field;
025    import com.liferay.portal.kernel.search.SearchContext;
026    import com.liferay.portal.kernel.search.filter.BooleanFilter;
027    import com.liferay.portal.kernel.search.filter.Filter;
028    import com.liferay.portal.kernel.trash.TrashActionKeys;
029    import com.liferay.portal.kernel.trash.TrashHandler;
030    import com.liferay.portal.kernel.trash.TrashHandlerRegistryUtil;
031    import com.liferay.portal.kernel.util.Validator;
032    import com.liferay.portal.model.ContainerModel;
033    import com.liferay.portal.model.TrashedModel;
034    import com.liferay.portal.security.permission.ActionKeys;
035    import com.liferay.portal.security.permission.PermissionChecker;
036    import com.liferay.portal.service.ServiceContext;
037    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
038    import com.liferay.portlet.documentlibrary.model.DLFileEntryConstants;
039    import com.liferay.portlet.documentlibrary.model.DLFileVersion;
040    import com.liferay.portlet.documentlibrary.model.DLFolder;
041    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
042    import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
043    import com.liferay.portlet.documentlibrary.service.DLFileVersionLocalServiceUtil;
044    import com.liferay.portlet.documentlibrary.service.DLFolderLocalServiceUtil;
045    import com.liferay.portlet.documentlibrary.service.permission.DLFileEntryPermission;
046    import com.liferay.portlet.documentlibrary.service.permission.DLFolderPermission;
047    import com.liferay.portlet.documentlibrary.util.DLUtil;
048    import com.liferay.portlet.documentlibrary.util.DLValidatorUtil;
049    import com.liferay.portlet.trash.RestoreEntryException;
050    import com.liferay.portlet.trash.TrashEntryConstants;
051    import com.liferay.portlet.trash.model.TrashEntry;
052    
053    import javax.portlet.PortletRequest;
054    
055    /**
056     * Implements trash handling for the file entry entity.
057     *
058     * @author Alexander Chow
059     * @author Manuel de la Pe??a
060     * @author Zsolt Berentey
061     */
062    public class DLFileEntryTrashHandler extends DLBaseTrashHandler {
063    
064            @Override
065            public void checkRestorableEntry(
066                            long classPK, long containerModelId, String newName)
067                    throws PortalException {
068    
069                    DLFileEntry dlFileEntry = getDLFileEntry(classPK);
070    
071                    checkRestorableEntry(
072                            classPK, 0, containerModelId, dlFileEntry.getFileName(),
073                            dlFileEntry.getTitle(), newName);
074            }
075    
076            @Override
077            public void checkRestorableEntry(
078                            TrashEntry trashEntry, long containerModelId, String newName)
079                    throws PortalException {
080    
081                    checkRestorableEntry(
082                            trashEntry.getClassPK(), trashEntry.getEntryId(), containerModelId,
083                            trashEntry.getTypeSettingsProperty("fileName"),
084                            trashEntry.getTypeSettingsProperty("title"), newName);
085            }
086    
087            @Override
088            public void deleteTrashEntry(long classPK) throws PortalException {
089                    Repository repository = getRepository(classPK);
090    
091                    TrashCapability trashCapability = repository.getCapability(
092                            TrashCapability.class);
093    
094                    trashCapability.deleteFileEntry(repository.getFileEntry(classPK));
095            }
096    
097            @Override
098            public String getClassName() {
099                    return DLFileEntry.class.getName();
100            }
101    
102            @Override
103            public Filter getExcludeFilter(SearchContext searchContext) {
104                    BooleanFilter excludeBooleanFilter = new BooleanFilter();
105    
106                    excludeBooleanFilter.addRequiredTerm(
107                            Field.ENTRY_CLASS_NAME, DLFileEntryConstants.getClassName());
108                    excludeBooleanFilter.addRequiredTerm(Field.HIDDEN, true);
109    
110                    return excludeBooleanFilter;
111            }
112    
113            @Override
114            public ContainerModel getParentContainerModel(long classPK)
115                    throws PortalException {
116    
117                    DLFileEntry dlFileEntry = getDLFileEntry(classPK);
118    
119                    long parentFolderId = dlFileEntry.getFolderId();
120    
121                    if (parentFolderId <= 0) {
122                            return null;
123                    }
124    
125                    return getContainerModel(parentFolderId);
126            }
127    
128            @Override
129            public ContainerModel getParentContainerModel(TrashedModel trashedModel)
130                    throws PortalException {
131    
132                    DLFileEntry dlFileEntry = (DLFileEntry)trashedModel;
133    
134                    return getContainerModel(dlFileEntry.getFolderId());
135            }
136    
137            @Override
138            public String getRestoreContainedModelLink(
139                            PortletRequest portletRequest, long classPK)
140                    throws PortalException {
141    
142                    DLFileEntry dlFileEntry = getDLFileEntry(classPK);
143    
144                    return DLUtil.getDLFileEntryControlPanelLink(
145                            portletRequest, dlFileEntry.getFileEntryId());
146            }
147    
148            @Override
149            public String getRestoreContainerModelLink(
150                            PortletRequest portletRequest, long classPK)
151                    throws PortalException {
152    
153                    DLFileEntry dlFileEntry = getDLFileEntry(classPK);
154    
155                    return DLUtil.getDLFolderControlPanelLink(
156                            portletRequest, dlFileEntry.getFolderId());
157            }
158    
159            @Override
160            public String getRestoreMessage(PortletRequest portletRequest, long classPK)
161                    throws PortalException {
162    
163                    DLFileEntry dlFileEntry = getDLFileEntry(classPK);
164    
165                    DLFolder dlFolder = dlFileEntry.getFolder();
166    
167                    return DLUtil.getAbsolutePath(portletRequest, dlFolder.getFolderId());
168            }
169    
170            @Override
171            public String getSystemEventClassName() {
172                    return DLFileEntryConstants.getClassName();
173            }
174    
175            @Override
176            public TrashEntry getTrashEntry(long classPK) throws PortalException {
177                    DLFileEntry dlFileEntry = getDLFileEntry(classPK);
178    
179                    return dlFileEntry.getTrashEntry();
180            }
181    
182            @Override
183            public boolean hasTrashPermission(
184                            PermissionChecker permissionChecker, long groupId, long classPK,
185                            String trashActionId)
186                    throws PortalException {
187    
188                    if (trashActionId.equals(TrashActionKeys.MOVE)) {
189                            return DLFolderPermission.contains(
190                                    permissionChecker, groupId, classPK, ActionKeys.ADD_DOCUMENT);
191                    }
192    
193                    return super.hasTrashPermission(
194                            permissionChecker, groupId, classPK, trashActionId);
195            }
196    
197            @Override
198            public boolean isInTrash(long classPK) throws PortalException {
199                    try {
200                            DLFileEntry dlFileEntry = getDLFileEntry(classPK);
201    
202                            return dlFileEntry.isInTrash();
203                    }
204                    catch (InvalidRepositoryException ire) {
205                            return false;
206                    }
207            }
208    
209            @Override
210            public boolean isInTrashContainer(long classPK) throws PortalException {
211                    try {
212                            DLFileEntry dlFileEntry = getDLFileEntry(classPK);
213    
214                            return dlFileEntry.isInTrashContainer();
215                    }
216                    catch (InvalidRepositoryException ire) {
217                            return false;
218                    }
219            }
220    
221            @Override
222            public boolean isRestorable(long classPK) throws PortalException {
223                    DLFileEntry dlFileEntry = fetchDLFileEntry(classPK);
224    
225                    if ((dlFileEntry == null) ||
226                            ((dlFileEntry.getFolderId() > 0) &&
227                             (DLFolderLocalServiceUtil.fetchFolder(
228                                     dlFileEntry.getFolderId()) == null))) {
229    
230                            return false;
231                    }
232    
233                    return !dlFileEntry.isInTrashContainer();
234            }
235    
236            @Override
237            public void moveEntry(
238                            long userId, long classPK, long containerModelId,
239                            ServiceContext serviceContext)
240                    throws PortalException {
241    
242                    DLAppLocalServiceUtil.moveFileEntry(
243                            userId, classPK, containerModelId, serviceContext);
244            }
245    
246            @Override
247            public void moveTrashEntry(
248                            long userId, long classPK, long containerModelId,
249                            ServiceContext serviceContext)
250                    throws PortalException {
251    
252                    Repository repository = getRepository(classPK);
253    
254                    RepositoryTrashUtil.moveFileEntryFromTrash(
255                            userId, repository.getRepositoryId(), classPK, containerModelId,
256                            serviceContext);
257            }
258    
259            @Override
260            public void restoreTrashEntry(long userId, long classPK)
261                    throws PortalException {
262    
263                    DLFileEntry dlFileEntry = getDLFileEntry(classPK);
264    
265                    if ((dlFileEntry.getClassNameId() > 0) &&
266                            (dlFileEntry.getClassPK() > 0)) {
267    
268                            TrashHandler trashHandler =
269                                    TrashHandlerRegistryUtil.getTrashHandler(
270                                            dlFileEntry.getClassName());
271    
272                            trashHandler.restoreRelatedTrashEntry(getClassName(), classPK);
273    
274                            return;
275                    }
276    
277                    RepositoryTrashUtil.restoreFileEntryFromTrash(
278                            userId, dlFileEntry.getRepositoryId(), classPK);
279            }
280    
281            @Override
282            public void updateTitle(long classPK, String name) throws PortalException {
283                    DLFileEntry dlFileEntry = getDLFileEntry(classPK);
284    
285                    String fileName = DLUtil.getSanitizedFileName(
286                            name, dlFileEntry.getExtension());
287    
288                    dlFileEntry.setFileName(fileName);
289                    dlFileEntry.setTitle(name);
290    
291                    DLFileEntryLocalServiceUtil.updateDLFileEntry(dlFileEntry);
292    
293                    DLFileVersion dlFileVersion = dlFileEntry.getFileVersion();
294    
295                    dlFileVersion.setFileName(fileName);
296    
297                    dlFileVersion.setTitle(name);
298    
299                    DLFileVersionLocalServiceUtil.updateDLFileVersion(dlFileVersion);
300            }
301    
302            protected void checkRestorableEntry(
303                            long classPK, long entryId, long containerModelId,
304                            String originalFileName, String originalTitle, String newName)
305                    throws PortalException {
306    
307                    if (Validator.isNotNull(newName) &&
308                            !DLValidatorUtil.isValidName(newName)) {
309    
310                            RestoreEntryException ree = new RestoreEntryException(
311                                    RestoreEntryException.INVALID_NAME);
312    
313                            ree.setErrorMessage("please-enter-a-valid-name");
314                            ree.setTrashEntryId(entryId);
315    
316                            throw ree;
317                    }
318    
319                    DLFileEntry dlFileEntry = getDLFileEntry(classPK);
320    
321                    if (containerModelId == TrashEntryConstants.DEFAULT_CONTAINER_ID) {
322                            containerModelId = dlFileEntry.getFolderId();
323                    }
324    
325                    if (Validator.isNotNull(newName)) {
326                            originalFileName = DLUtil.getSanitizedFileName(
327                                    newName, dlFileEntry.getExtension());
328                            originalTitle = newName;
329                    }
330    
331                    DLFolder duplicateDLFolder = DLFolderLocalServiceUtil.fetchFolder(
332                            dlFileEntry.getGroupId(), containerModelId, originalTitle);
333    
334                    if (duplicateDLFolder != null) {
335                            RestoreEntryException ree = new RestoreEntryException(
336                                    RestoreEntryException.DUPLICATE);
337    
338                            ree.setDuplicateEntryId(duplicateDLFolder.getFolderId());
339                            ree.setOldName(duplicateDLFolder.getName());
340                            ree.setOverridable(false);
341                            ree.setTrashEntryId(entryId);
342    
343                            throw ree;
344                    }
345    
346                    DLFileEntry duplicateDLFileEntry =
347                            DLFileEntryLocalServiceUtil.fetchFileEntry(
348                                    dlFileEntry.getGroupId(), containerModelId, originalTitle);
349    
350                    if (duplicateDLFileEntry == null) {
351                            duplicateDLFileEntry =
352                                    DLFileEntryLocalServiceUtil.fetchFileEntryByFileName(
353                                            dlFileEntry.getGroupId(), containerModelId,
354                                            originalFileName);
355                    }
356    
357                    if (duplicateDLFileEntry != null) {
358                            RestoreEntryException ree = new RestoreEntryException(
359                                    RestoreEntryException.DUPLICATE);
360    
361                            ree.setDuplicateEntryId(duplicateDLFileEntry.getFileEntryId());
362                            ree.setOldName(duplicateDLFileEntry.getTitle());
363                            ree.setTrashEntryId(entryId);
364    
365                            throw ree;
366                    }
367            }
368    
369            protected DLFileEntry fetchDLFileEntry(long classPK)
370                    throws PortalException {
371    
372                    Repository repository = RepositoryProviderUtil.getFileEntryRepository(
373                            classPK);
374    
375                    if (!repository.isCapabilityProvided(TrashCapability.class)) {
376                            return null;
377                    }
378    
379                    FileEntry fileEntry = repository.getFileEntry(classPK);
380    
381                    return (DLFileEntry)fileEntry.getModel();
382            }
383    
384            protected DLFileEntry getDLFileEntry(long classPK) throws PortalException {
385                    Repository repository = RepositoryProviderUtil.getFileEntryRepository(
386                            classPK);
387    
388                    if (!repository.isCapabilityProvided(TrashCapability.class)) {
389                            throw new InvalidRepositoryException(
390                                    "Repository " + repository.getRepositoryId() +
391                                            " does not support trash operations");
392                    }
393    
394                    FileEntry fileEntry = repository.getFileEntry(classPK);
395    
396                    return (DLFileEntry)fileEntry.getModel();
397            }
398    
399            @Override
400            protected Repository getRepository(long classPK) throws PortalException {
401                    Repository repository = RepositoryProviderUtil.getFileEntryRepository(
402                            classPK);
403    
404                    if (!repository.isCapabilityProvided(TrashCapability.class)) {
405                            throw new InvalidRepositoryException(
406                                    "Repository " + repository.getRepositoryId() +
407                                            " does not support trash operations");
408                    }
409    
410                    return repository;
411            }
412    
413            @Override
414            protected boolean hasPermission(
415                            PermissionChecker permissionChecker, long classPK, String actionId)
416                    throws PortalException {
417    
418                    DLFileEntry dlFileEntry = getDLFileEntry(classPK);
419    
420                    if (dlFileEntry.isInHiddenFolder() &&
421                            actionId.equals(ActionKeys.VIEW)) {
422    
423                            return false;
424                    }
425    
426                    return DLFileEntryPermission.contains(
427                            permissionChecker, classPK, actionId);
428            }
429    
430    }