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.wiki.action;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.json.JSONFactoryUtil;
019    import com.liferay.portal.kernel.json.JSONObject;
020    import com.liferay.portal.kernel.repository.model.FileEntry;
021    import com.liferay.portal.kernel.servlet.SessionErrors;
022    import com.liferay.portal.kernel.upload.UploadException;
023    import com.liferay.portal.kernel.upload.UploadPortletRequest;
024    import com.liferay.portal.kernel.util.Constants;
025    import com.liferay.portal.kernel.util.KeyValuePair;
026    import com.liferay.portal.kernel.util.ObjectValuePair;
027    import com.liferay.portal.kernel.util.ParamUtil;
028    import com.liferay.portal.kernel.util.StreamUtil;
029    import com.liferay.portal.kernel.util.StringUtil;
030    import com.liferay.portal.kernel.util.TempFileEntryUtil;
031    import com.liferay.portal.model.TrashedModel;
032    import com.liferay.portal.portletfilerepository.PortletFileRepositoryUtil;
033    import com.liferay.portal.security.auth.PrincipalException;
034    import com.liferay.portal.struts.ActionConstants;
035    import com.liferay.portal.theme.ThemeDisplay;
036    import com.liferay.portal.util.PortalUtil;
037    import com.liferay.portal.util.WebKeys;
038    import com.liferay.portlet.documentlibrary.FileSizeException;
039    import com.liferay.portlet.documentlibrary.action.EditFileEntryAction;
040    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
041    import com.liferay.portlet.trash.model.TrashEntry;
042    import com.liferay.portlet.trash.service.TrashEntryLocalServiceUtil;
043    import com.liferay.portlet.trash.util.TrashUtil;
044    import com.liferay.portlet.wiki.NoSuchNodeException;
045    import com.liferay.portlet.wiki.NoSuchPageException;
046    import com.liferay.portlet.wiki.model.WikiPage;
047    import com.liferay.portlet.wiki.service.WikiPageServiceUtil;
048    import com.liferay.portlet.wiki.util.WikiPageAttachmentsUtil;
049    
050    import java.io.InputStream;
051    
052    import java.util.ArrayList;
053    import java.util.List;
054    
055    import javax.portlet.ActionRequest;
056    import javax.portlet.ActionResponse;
057    import javax.portlet.PortletConfig;
058    import javax.portlet.RenderRequest;
059    import javax.portlet.RenderResponse;
060    
061    import org.apache.struts.action.ActionForm;
062    import org.apache.struts.action.ActionForward;
063    import org.apache.struts.action.ActionMapping;
064    
065    /**
066     * @author Jorge Ferrer
067     */
068    public class EditPageAttachmentsAction extends EditFileEntryAction {
069    
070            @Override
071            public void processAction(
072                            ActionMapping actionMapping, ActionForm actionForm,
073                            PortletConfig portletConfig, ActionRequest actionRequest,
074                            ActionResponse actionResponse)
075                    throws Exception {
076    
077                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
078    
079                    try {
080                            UploadException uploadException =
081                                    (UploadException)actionRequest.getAttribute(
082                                            WebKeys.UPLOAD_EXCEPTION);
083    
084                            if (uploadException != null) {
085                                    if (uploadException.isExceededSizeLimit()) {
086                                            throw new FileSizeException(uploadException.getCause());
087                                    }
088    
089                                    throw new PortalException(uploadException.getCause());
090                            }
091                            else if (cmd.equals(Constants.ADD)) {
092                                    addAttachment(actionRequest);
093                            }
094                            else if (cmd.equals(Constants.ADD_MULTIPLE)) {
095                                    addMultipleFileEntries(
096                                            portletConfig, actionRequest, actionResponse);
097                            }
098                            else if (cmd.equals(Constants.ADD_TEMP)) {
099                                    addTempAttachment(actionRequest);
100                            }
101                            else if (cmd.equals(Constants.DELETE)) {
102                                    deleteAttachment(actionRequest, false);
103                            }
104                            else if (cmd.equals(Constants.DELETE_TEMP)) {
105                                    deleteTempAttachment(actionRequest, actionResponse);
106                            }
107                            else if (cmd.equals(Constants.EMPTY_TRASH)) {
108                                    emptyTrash(actionRequest);
109                            }
110                            else if (cmd.equals(Constants.MOVE_TO_TRASH)) {
111                                    deleteAttachment(actionRequest, true);
112                            }
113                            else if (cmd.equals(Constants.RESTORE)) {
114                                    restoreAttachment(actionRequest);
115                            }
116    
117                            if (cmd.equals(Constants.ADD_TEMP) ||
118                                    cmd.equals(Constants.DELETE_TEMP)) {
119    
120                                    setForward(actionRequest, ActionConstants.COMMON_NULL);
121                            }
122                            else {
123                                    sendRedirect(actionRequest, actionResponse);
124                            }
125                    }
126                    catch (Exception e) {
127                            if (e instanceof NoSuchNodeException ||
128                                    e instanceof NoSuchPageException ||
129                                    e instanceof PrincipalException) {
130    
131                                    SessionErrors.add(actionRequest, e.getClass());
132    
133                                    setForward(actionRequest, "portlet.wiki.error");
134                            }
135                            else {
136                                    handleUploadException(
137                                            portletConfig, actionRequest, actionResponse, cmd, e);
138                            }
139                    }
140            }
141    
142            @Override
143            public ActionForward render(
144                            ActionMapping actionMapping, ActionForm actionForm,
145                            PortletConfig portletConfig, RenderRequest renderRequest,
146                            RenderResponse renderResponse)
147                    throws Exception {
148    
149                    try {
150                            ActionUtil.getNode(renderRequest);
151                            ActionUtil.getPage(renderRequest);
152                    }
153                    catch (Exception e) {
154                            if (e instanceof NoSuchNodeException ||
155                                    e instanceof NoSuchPageException ||
156                                    e instanceof PrincipalException) {
157    
158                                    SessionErrors.add(renderRequest, e.getClass());
159    
160                                    return actionMapping.findForward("portlet.wiki.error");
161                            }
162                            else {
163                                    throw e;
164                            }
165                    }
166    
167                    return actionMapping.findForward(
168                            getForward(renderRequest, "portlet.wiki.edit_page_attachment"));
169            }
170    
171            protected void addAttachment(ActionRequest actionRequest) throws Exception {
172                    UploadPortletRequest uploadPortletRequest =
173                            PortalUtil.getUploadPortletRequest(actionRequest);
174    
175                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
176                    String title = ParamUtil.getString(actionRequest, "title");
177    
178                    int numOfFiles = ParamUtil.getInteger(actionRequest, "numOfFiles");
179    
180                    List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
181                            new ArrayList<ObjectValuePair<String, InputStream>>();
182    
183                    try {
184                            if (numOfFiles == 0) {
185                                    String fileName = uploadPortletRequest.getFileName("file");
186                                    InputStream inputStream = uploadPortletRequest.getFileAsStream(
187                                            "file");
188    
189                                    if (inputStream != null) {
190                                            ObjectValuePair<String, InputStream> inputStreamOVP =
191                                                    new ObjectValuePair<String, InputStream>(
192                                                            fileName, inputStream);
193    
194                                            inputStreamOVPs.add(inputStreamOVP);
195                                    }
196                            }
197                            else {
198                                    for (int i = 1; i <= numOfFiles; i++) {
199                                            String fileName = uploadPortletRequest.getFileName(
200                                                    "file" + i);
201                                            InputStream inputStream =
202                                                    uploadPortletRequest.getFileAsStream("file" + i);
203    
204                                            if (inputStream == null) {
205                                                    continue;
206                                            }
207    
208                                            ObjectValuePair<String, InputStream> inputStreamOVP =
209                                                    new ObjectValuePair<String, InputStream>(
210                                                            fileName, inputStream);
211    
212                                            inputStreamOVPs.add(inputStreamOVP);
213                                    }
214                            }
215    
216                            WikiPageServiceUtil.addPageAttachments(
217                                    nodeId, title, inputStreamOVPs);
218                    }
219                    finally {
220                            for (ObjectValuePair<String, InputStream> inputStreamOVP :
221                                            inputStreamOVPs) {
222    
223                                    InputStream inputStream = inputStreamOVP.getValue();
224    
225                                    StreamUtil.cleanUp(inputStream);
226                            }
227                    }
228            }
229    
230            @Override
231            protected void addMultipleFileEntries(
232                            PortletConfig portletConfig, ActionRequest actionRequest,
233                            ActionResponse actionResponse, String selectedFileName,
234                            List<KeyValuePair> validFileNameKVPs,
235                            List<KeyValuePair> invalidFileNameKVPs)
236                    throws Exception {
237    
238                    String originalSelectedFileName = selectedFileName;
239    
240                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
241                            WebKeys.THEME_DISPLAY);
242    
243                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
244                    String title = ParamUtil.getString(actionRequest, "title");
245    
246                    FileEntry tempFileEntry = null;
247    
248                    try {
249                            tempFileEntry = TempFileEntryUtil.getTempFileEntry(
250                                    themeDisplay.getScopeGroupId(), themeDisplay.getUserId(),
251                                    _TEMP_FOLDER_NAME, selectedFileName);
252    
253                            InputStream inputStream = tempFileEntry.getContentStream();
254                            String mimeType = tempFileEntry.getMimeType();
255    
256                            WikiPageServiceUtil.addPageAttachment(
257                                    nodeId, title, selectedFileName, inputStream, mimeType);
258    
259                            validFileNameKVPs.add(
260                                    new KeyValuePair(selectedFileName, originalSelectedFileName));
261                    }
262                    catch (Exception e) {
263                            String errorMessage = getAddMultipleFileEntriesErrorMessage(
264                                    portletConfig, actionRequest, actionResponse, e);
265    
266                            KeyValuePair invalidFileNameKVP = new KeyValuePair(
267                                    selectedFileName, errorMessage);
268    
269                            invalidFileNameKVPs.add(invalidFileNameKVP);
270                    }
271                    finally {
272                            if (tempFileEntry != null) {
273                                    TempFileEntryUtil.deleteTempFileEntry(
274                                            tempFileEntry.getFileEntryId());
275                            }
276                    }
277            }
278    
279            protected void addTempAttachment(ActionRequest actionRequest)
280                    throws Exception {
281    
282                    UploadPortletRequest uploadPortletRequest =
283                            PortalUtil.getUploadPortletRequest(actionRequest);
284    
285                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
286                    String sourceFileName = uploadPortletRequest.getFileName("file");
287    
288                    InputStream inputStream = null;
289    
290                    try {
291                            inputStream = uploadPortletRequest.getFileAsStream("file");
292    
293                            String mimeType = uploadPortletRequest.getContentType("file");
294    
295                            WikiPageServiceUtil.addTempFileEntry(
296                                    nodeId, _TEMP_FOLDER_NAME, sourceFileName, inputStream,
297                                    mimeType);
298                    }
299                    finally {
300                            StreamUtil.cleanUp(inputStream);
301                    }
302            }
303    
304            protected void deleteAttachment(
305                            ActionRequest actionRequest, boolean moveToTrash)
306                    throws Exception {
307    
308                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
309                    String title = ParamUtil.getString(actionRequest, "title");
310                    String attachment = ParamUtil.getString(actionRequest, "fileName");
311    
312                    TrashedModel trashedModel = null;
313    
314                    if (moveToTrash) {
315                            FileEntry fileEntry = WikiPageServiceUtil.movePageAttachmentToTrash(
316                                    nodeId, title, attachment);
317    
318                            if (fileEntry.getModel() instanceof DLFileEntry) {
319                                    trashedModel = (DLFileEntry)fileEntry.getModel();
320                            }
321                    }
322                    else {
323                            WikiPageServiceUtil.deletePageAttachment(nodeId, title, attachment);
324                    }
325    
326                    if (moveToTrash && (trashedModel != null)) {
327                            TrashUtil.addTrashSessionMessages(
328                                    actionRequest, trashedModel, Constants.REMOVE);
329    
330                            hideDefaultSuccessMessage(actionRequest);
331                    }
332            }
333    
334            protected void deleteTempAttachment(
335                            ActionRequest actionRequest, ActionResponse actionResponse)
336                    throws Exception {
337    
338                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
339                            WebKeys.THEME_DISPLAY);
340    
341                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
342                    String fileName = ParamUtil.getString(actionRequest, "fileName");
343    
344                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
345    
346                    try {
347                            WikiPageServiceUtil.deleteTempFileEntry(
348                                    nodeId, fileName, _TEMP_FOLDER_NAME);
349    
350                            jsonObject.put("deleted", Boolean.TRUE);
351                    }
352                    catch (Exception e) {
353                            String errorMessage = themeDisplay.translate(
354                                    "an-unexpected-error-occurred-while-deleting-the-file");
355    
356                            jsonObject.put("deleted", Boolean.FALSE);
357                            jsonObject.put("errorMessage", errorMessage);
358                    }
359    
360                    writeJSON(actionRequest, actionResponse, jsonObject);
361            }
362    
363            protected void emptyTrash(ActionRequest actionRequest) throws Exception {
364                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
365                    String title = ParamUtil.getString(actionRequest, "title");
366    
367                    WikiPageServiceUtil.deleteTrashPageAttachments(nodeId, title);
368            }
369    
370            protected void restoreAttachment(ActionRequest actionRequest)
371                    throws Exception {
372    
373                    long[] restoreEntryIds = StringUtil.split(
374                            ParamUtil.getString(actionRequest, "restoreTrashEntryIds"), 0L);
375    
376                    for (long restoreEntryId : restoreEntryIds) {
377                            TrashEntry trashEntry = TrashEntryLocalServiceUtil.getTrashEntry(
378                                    restoreEntryId);
379    
380                            FileEntry fileEntry = PortletFileRepositoryUtil.getPortletFileEntry(
381                                    trashEntry.getClassPK());
382    
383                            WikiPage page = WikiPageAttachmentsUtil.getPage(
384                                    fileEntry.getFileEntryId());
385    
386                            WikiPageServiceUtil.restorePageAttachmentFromTrash(
387                                    page.getNodeId(), page.getTitle(), fileEntry.getTitle());
388                    }
389            }
390    
391            private static final String _TEMP_FOLDER_NAME =
392                    EditPageAttachmentsAction.class.getName();
393    
394    }