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