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.action;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryUtil;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.language.LanguageUtil;
020    import com.liferay.portal.kernel.portlet.PortletResponseUtil;
021    import com.liferay.portal.kernel.repository.LocalRepository;
022    import com.liferay.portal.kernel.repository.RepositoryProviderUtil;
023    import com.liferay.portal.kernel.repository.capabilities.TemporaryFileEntriesCapability;
024    import com.liferay.portal.kernel.repository.model.FileEntry;
025    import com.liferay.portal.kernel.repository.model.Folder;
026    import com.liferay.portal.kernel.servlet.SessionErrors;
027    import com.liferay.portal.kernel.util.Constants;
028    import com.liferay.portal.kernel.util.ContentTypes;
029    import com.liferay.portal.kernel.util.HtmlUtil;
030    import com.liferay.portal.kernel.util.ParamUtil;
031    import com.liferay.portal.kernel.util.StreamUtil;
032    import com.liferay.portal.kernel.util.StringPool;
033    import com.liferay.portal.kernel.util.StringUtil;
034    import com.liferay.portal.kernel.workflow.WorkflowConstants;
035    import com.liferay.portal.kernel.zip.ZipWriter;
036    import com.liferay.portal.kernel.zip.ZipWriterFactoryUtil;
037    import com.liferay.portal.model.TrashedModel;
038    import com.liferay.portal.security.auth.PrincipalException;
039    import com.liferay.portal.service.ServiceContext;
040    import com.liferay.portal.service.ServiceContextFactory;
041    import com.liferay.portal.struts.PortletAction;
042    import com.liferay.portal.theme.ThemeDisplay;
043    import com.liferay.portal.util.WebKeys;
044    import com.liferay.portlet.documentlibrary.DuplicateFileException;
045    import com.liferay.portlet.documentlibrary.DuplicateFolderNameException;
046    import com.liferay.portlet.documentlibrary.FolderNameException;
047    import com.liferay.portlet.documentlibrary.NoSuchFolderException;
048    import com.liferay.portlet.documentlibrary.RequiredFileEntryTypeException;
049    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
050    import com.liferay.portlet.documentlibrary.model.DLFolder;
051    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
052    import com.liferay.portlet.documentlibrary.service.DLAppServiceUtil;
053    import com.liferay.portlet.trash.util.TrashUtil;
054    
055    import java.io.File;
056    import java.io.FileInputStream;
057    import java.io.InputStream;
058    
059    import java.util.ArrayList;
060    import java.util.List;
061    
062    import javax.portlet.ActionRequest;
063    import javax.portlet.ActionResponse;
064    import javax.portlet.PortletConfig;
065    import javax.portlet.RenderRequest;
066    import javax.portlet.RenderResponse;
067    import javax.portlet.ResourceRequest;
068    import javax.portlet.ResourceResponse;
069    
070    import org.apache.struts.action.ActionForm;
071    import org.apache.struts.action.ActionForward;
072    import org.apache.struts.action.ActionMapping;
073    
074    /**
075     * @author Brian Wing Shun Chan
076     * @author Alexander Chow
077     * @author Sergio Gonz??lez
078     * @author Levente Hud??k
079     */
080    public class EditFolderAction extends PortletAction {
081    
082            @Override
083            public void processAction(
084                            ActionMapping actionMapping, ActionForm actionForm,
085                            PortletConfig portletConfig, ActionRequest actionRequest,
086                            ActionResponse actionResponse)
087                    throws Exception {
088    
089                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
090    
091                    try {
092                            if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
093                                    updateFolder(actionRequest);
094                            }
095                            else if (cmd.equals(Constants.DELETE)) {
096                                    deleteFolders(actionRequest, false);
097                            }
098                            else if (cmd.equals(Constants.MOVE_TO_TRASH)) {
099                                    deleteFolders(actionRequest, true);
100                            }
101                            else if (cmd.equals(Constants.SUBSCRIBE)) {
102                                    subscribeFolder(actionRequest);
103                            }
104                            else if (cmd.equals(Constants.UNSUBSCRIBE)) {
105                                    unsubscribeFolder(actionRequest);
106                            }
107                            else if (cmd.equals("deleteExpiredTemporaryFileEntries")) {
108                                    deleteExpiredTemporaryFileEntries(actionRequest);
109                            }
110                            else if (cmd.equals("updateWorkflowDefinitions")) {
111                                    updateWorkflowDefinitions(actionRequest);
112                            }
113    
114                            sendRedirect(actionRequest, actionResponse);
115                    }
116                    catch (Exception e) {
117                            if (e instanceof NoSuchFolderException ||
118                                    e instanceof PrincipalException) {
119    
120                                    SessionErrors.add(actionRequest, e.getClass());
121    
122                                    setForward(actionRequest, "portlet.document_library.error");
123                            }
124                            else if (e instanceof DuplicateFileException ||
125                                             e instanceof DuplicateFolderNameException ||
126                                             e instanceof FolderNameException ||
127                                             e instanceof RequiredFileEntryTypeException) {
128    
129                                    SessionErrors.add(actionRequest, e.getClass());
130                            }
131                            else {
132                                    throw e;
133                            }
134                    }
135            }
136    
137            @Override
138            public ActionForward render(
139                            ActionMapping actionMapping, ActionForm actionForm,
140                            PortletConfig portletConfig, RenderRequest renderRequest,
141                            RenderResponse renderResponse)
142                    throws Exception {
143    
144                    try {
145                            ActionUtil.getFolder(renderRequest);
146                    }
147                    catch (Exception e) {
148                            if (e instanceof NoSuchFolderException ||
149                                    e instanceof PrincipalException) {
150    
151                                    SessionErrors.add(renderRequest, e.getClass());
152    
153                                    return actionMapping.findForward(
154                                            "portlet.document_library.error");
155                            }
156                            else {
157                                    throw e;
158                            }
159                    }
160    
161                    return actionMapping.findForward(
162                            getForward(renderRequest, "portlet.document_library.edit_folder"));
163            }
164    
165            @Override
166            public void serveResource(
167                            ActionMapping actionMapping, ActionForm actionForm,
168                            PortletConfig portletConfig, ResourceRequest resourceRequest,
169                            ResourceResponse resourceResponse)
170                    throws Exception {
171    
172                    downloadFolder(resourceRequest, resourceResponse);
173            }
174    
175            protected void deleteExpiredTemporaryFileEntries(
176                            ActionRequest actionRequest)
177                    throws PortalException {
178    
179                    long repositoryId = ParamUtil.getLong(actionRequest, "repositoryId");
180    
181                    LocalRepository localRepository =
182                            RepositoryProviderUtil.getLocalRepository(repositoryId);
183    
184                    if (localRepository.isCapabilityProvided(
185                                    TemporaryFileEntriesCapability.class)) {
186    
187                            TemporaryFileEntriesCapability temporaryFileEntriesCapability =
188                                    localRepository.getCapability(
189                                            TemporaryFileEntriesCapability.class);
190    
191                            temporaryFileEntriesCapability.deleteExpiredTemporaryFileEntries();
192                    }
193            }
194    
195            protected void deleteFolders(
196                            ActionRequest actionRequest, boolean moveToTrash)
197                    throws Exception {
198    
199                    long[] deleteFolderIds = null;
200    
201                    long folderId = ParamUtil.getLong(actionRequest, "folderId");
202    
203                    if (folderId > 0) {
204                            deleteFolderIds = new long[] {folderId};
205                    }
206                    else {
207                            deleteFolderIds = StringUtil.split(
208                                    ParamUtil.getString(actionRequest, "folderIds"), 0L);
209                    }
210    
211                    List<TrashedModel> trashedModels = new ArrayList<>();
212    
213                    for (long deleteFolderId : deleteFolderIds) {
214                            if (moveToTrash) {
215                                    Folder folder = DLAppServiceUtil.moveFolderToTrash(
216                                            deleteFolderId);
217    
218                                    if (folder.getModel() instanceof DLFolder) {
219                                            trashedModels.add((DLFolder)folder.getModel());
220                                    }
221                            }
222                            else {
223                                    DLAppServiceUtil.deleteFolder(deleteFolderId);
224                            }
225                    }
226    
227                    if (moveToTrash && (deleteFolderIds.length > 0)) {
228                            TrashUtil.addTrashSessionMessages(actionRequest, trashedModels);
229    
230                            hideDefaultSuccessMessage(actionRequest);
231                    }
232            }
233    
234            protected void downloadFolder(
235                            ResourceRequest resourceRequest, ResourceResponse resourceResponse)
236                    throws Exception {
237    
238                    ThemeDisplay themeDisplay = (ThemeDisplay)resourceRequest.getAttribute(
239                            WebKeys.THEME_DISPLAY);
240    
241                    long repositoryId = ParamUtil.getLong(resourceRequest, "repositoryId");
242                    long folderId = ParamUtil.getLong(resourceRequest, "folderId");
243    
244                    File file = null;
245                    InputStream inputStream = null;
246    
247                    try {
248                            String zipFileName = LanguageUtil.get(
249                                    themeDisplay.getLocale(), "documents-and-media");
250    
251                            if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
252                                    Folder folder = DLAppServiceUtil.getFolder(folderId);
253    
254                                    zipFileName = folder.getName();
255                            }
256    
257                            ZipWriter zipWriter = ZipWriterFactoryUtil.getZipWriter();
258    
259                            zipFolder(repositoryId, folderId, StringPool.SLASH, zipWriter);
260    
261                            file = zipWriter.getFile();
262    
263                            inputStream = new FileInputStream(file);
264    
265                            PortletResponseUtil.sendFile(
266                                    resourceRequest, resourceResponse, zipFileName, inputStream,
267                                    ContentTypes.APPLICATION_ZIP);
268                    }
269                    finally {
270                            StreamUtil.cleanUp(inputStream);
271    
272                            if (file != null) {
273                                    file.delete();
274                            }
275                    }
276            }
277    
278            protected void subscribeFolder(ActionRequest actionRequest)
279                    throws Exception {
280    
281                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
282                            WebKeys.THEME_DISPLAY);
283    
284                    long folderId = ParamUtil.getLong(actionRequest, "folderId");
285    
286                    DLAppServiceUtil.subscribeFolder(
287                            themeDisplay.getScopeGroupId(), folderId);
288            }
289    
290            protected void unsubscribeFolder(ActionRequest actionRequest)
291                    throws Exception {
292    
293                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
294                            WebKeys.THEME_DISPLAY);
295    
296                    long folderId = ParamUtil.getLong(actionRequest, "folderId");
297    
298                    DLAppServiceUtil.unsubscribeFolder(
299                            themeDisplay.getScopeGroupId(), folderId);
300            }
301    
302            protected void updateFolder(ActionRequest actionRequest) throws Exception {
303                    long folderId = ParamUtil.getLong(actionRequest, "folderId");
304    
305                    long repositoryId = ParamUtil.getLong(actionRequest, "repositoryId");
306                    long parentFolderId = ParamUtil.getLong(
307                            actionRequest, "parentFolderId");
308                    String name = ParamUtil.getString(actionRequest, "name");
309                    String description = ParamUtil.getString(actionRequest, "description");
310    
311                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
312                            DLFolder.class.getName(), actionRequest);
313    
314                    if (folderId <= 0) {
315    
316                            // Add folder
317    
318                            DLAppServiceUtil.addFolder(
319                                    repositoryId, parentFolderId, name, description,
320                                    serviceContext);
321                    }
322                    else {
323    
324                            // Update folder
325    
326                            DLAppServiceUtil.updateFolder(
327                                    folderId, name, description, serviceContext);
328                    }
329            }
330    
331            protected void updateWorkflowDefinitions(ActionRequest actionRequest)
332                    throws Exception {
333    
334                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
335                            DLFileEntry.class.getName(), actionRequest);
336    
337                    DLAppServiceUtil.updateFolder(
338                            DLFolderConstants.DEFAULT_PARENT_FOLDER_ID, null, null,
339                            serviceContext);
340            }
341    
342            protected void zipFolder(
343                            long repositoryId, long folderId, String path, ZipWriter zipWriter)
344                    throws Exception {
345    
346                    List<Object> foldersAndFileEntriesAndFileShortcuts =
347                            DLAppServiceUtil.getFoldersAndFileEntriesAndFileShortcuts(
348                                    repositoryId, folderId, WorkflowConstants.STATUS_APPROVED,
349                                    false, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
350    
351                    for (Object entry : foldersAndFileEntriesAndFileShortcuts) {
352                            if (entry instanceof Folder) {
353                                    Folder folder = (Folder)entry;
354    
355                                    zipFolder(
356                                            folder.getRepositoryId(), folder.getFolderId(),
357                                            path.concat(StringPool.SLASH).concat(folder.getName()),
358                                            zipWriter);
359                            }
360                            else if (entry instanceof FileEntry) {
361                                    FileEntry fileEntry = (FileEntry)entry;
362    
363                                    zipWriter.addEntry(
364                                            path + StringPool.SLASH +
365                                                    HtmlUtil.escapeURL(fileEntry.getTitle()),
366                                            fileEntry.getContentStream());
367                            }
368                    }
369            }
370    
371    }