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.layoutsadmin.action;
016    
017    import com.liferay.portal.LARFileException;
018    import com.liferay.portal.LARFileSizeException;
019    import com.liferay.portal.LARTypeException;
020    import com.liferay.portal.LayoutImportException;
021    import com.liferay.portal.LayoutPrototypeException;
022    import com.liferay.portal.LocaleException;
023    import com.liferay.portal.NoSuchGroupException;
024    import com.liferay.portal.kernel.exception.PortalException;
025    import com.liferay.portal.kernel.json.JSONFactoryUtil;
026    import com.liferay.portal.kernel.json.JSONObject;
027    import com.liferay.portal.kernel.lar.ExportImportHelper;
028    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
029    import com.liferay.portal.kernel.lar.MissingReference;
030    import com.liferay.portal.kernel.lar.MissingReferences;
031    import com.liferay.portal.kernel.log.Log;
032    import com.liferay.portal.kernel.log.LogFactoryUtil;
033    import com.liferay.portal.kernel.repository.model.FileEntry;
034    import com.liferay.portal.kernel.servlet.ServletResponseUtil;
035    import com.liferay.portal.kernel.servlet.SessionErrors;
036    import com.liferay.portal.kernel.staging.StagingUtil;
037    import com.liferay.portal.kernel.upload.UploadException;
038    import com.liferay.portal.kernel.upload.UploadPortletRequest;
039    import com.liferay.portal.kernel.util.Constants;
040    import com.liferay.portal.kernel.util.ContentTypes;
041    import com.liferay.portal.kernel.util.ParamUtil;
042    import com.liferay.portal.kernel.util.StreamUtil;
043    import com.liferay.portal.security.auth.PrincipalException;
044    import com.liferay.portal.service.LayoutServiceUtil;
045    import com.liferay.portal.struts.PortletAction;
046    import com.liferay.portal.theme.ThemeDisplay;
047    import com.liferay.portal.util.PortalUtil;
048    import com.liferay.portal.util.WebKeys;
049    import com.liferay.portlet.documentlibrary.FileSizeException;
050    import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
051    import com.liferay.portlet.sites.action.ActionUtil;
052    
053    import java.io.InputStream;
054    
055    import java.util.Map;
056    
057    import javax.portlet.ActionRequest;
058    import javax.portlet.ActionResponse;
059    import javax.portlet.PortletConfig;
060    import javax.portlet.PortletContext;
061    import javax.portlet.PortletRequestDispatcher;
062    import javax.portlet.RenderRequest;
063    import javax.portlet.RenderResponse;
064    import javax.portlet.ResourceRequest;
065    import javax.portlet.ResourceResponse;
066    
067    import javax.servlet.http.HttpServletRequest;
068    import javax.servlet.http.HttpServletResponse;
069    
070    import org.apache.commons.fileupload.FileUploadBase;
071    import org.apache.struts.action.ActionForm;
072    import org.apache.struts.action.ActionForward;
073    import org.apache.struts.action.ActionMapping;
074    
075    /**
076     * @author Alexander Chow
077     * @author Raymond Aug??
078     */
079    public class ImportLayoutsAction extends PortletAction {
080    
081            @Override
082            public void processAction(
083                            ActionMapping actionMapping, ActionForm actionForm,
084                            PortletConfig portletConfig, ActionRequest actionRequest,
085                            ActionResponse actionResponse)
086                    throws Exception {
087    
088                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
089    
090                    try {
091                            if (cmd.equals(Constants.ADD_TEMP)) {
092                                    addTempFileEntry(
093                                            actionRequest, actionResponse,
094                                            ExportImportHelper.TEMP_FOLDER_NAME);
095    
096                                    validateFile(
097                                            actionRequest, actionResponse,
098                                            ExportImportHelper.TEMP_FOLDER_NAME);
099                            }
100                            else if (cmd.equals(Constants.DELETE_TEMP)) {
101                                    deleteTempFileEntry(
102                                            actionRequest, actionResponse,
103                                            ExportImportHelper.TEMP_FOLDER_NAME);
104                            }
105                            else if (cmd.equals(Constants.IMPORT)) {
106                                    hideDefaultSuccessMessage(actionRequest);
107    
108                                    importData(
109                                            actionRequest, actionResponse,
110                                            ExportImportHelper.TEMP_FOLDER_NAME);
111    
112                                    String redirect = ParamUtil.getString(
113                                            actionRequest, "redirect");
114    
115                                    sendRedirect(actionRequest, actionResponse, redirect);
116                            }
117                    }
118                    catch (Exception e) {
119                            if (cmd.equals(Constants.ADD_TEMP) ||
120                                    cmd.equals(Constants.DELETE_TEMP)) {
121    
122                                    handleUploadException(
123                                            portletConfig, actionRequest, actionResponse,
124                                            ExportImportHelper.TEMP_FOLDER_NAME, e);
125                            }
126                            else {
127                                    if ((e instanceof LARFileException) ||
128                                            (e instanceof LARFileSizeException) ||
129                                            (e instanceof LARTypeException)) {
130    
131                                            SessionErrors.add(actionRequest, e.getClass());
132                                    }
133                                    else if ((e instanceof LayoutPrototypeException) ||
134                                                     (e instanceof LocaleException)) {
135    
136                                            SessionErrors.add(actionRequest, e.getClass(), e);
137                                    }
138                                    else {
139                                            _log.error(e, e);
140    
141                                            SessionErrors.add(
142                                                    actionRequest, LayoutImportException.class.getName());
143                                    }
144                            }
145                    }
146            }
147    
148            @Override
149            public ActionForward render(
150                            ActionMapping actionMapping, ActionForm actionForm,
151                            PortletConfig portletConfig, RenderRequest renderRequest,
152                            RenderResponse renderResponse)
153                    throws Exception {
154    
155                    try {
156                            ActionUtil.getGroup(renderRequest);
157                    }
158                    catch (Exception e) {
159                            if (e instanceof NoSuchGroupException ||
160                                    e instanceof PrincipalException) {
161    
162                                    SessionErrors.add(renderRequest, e.getClass());
163    
164                                    return actionMapping.findForward("portlet.layouts_admin.error");
165                            }
166                            else {
167                                    throw e;
168                            }
169                    }
170    
171                    return actionMapping.findForward(
172                            getForward(renderRequest, "portlet.layouts_admin.import_layouts"));
173            }
174    
175            @Override
176            public void serveResource(
177                            ActionMapping actionMapping, ActionForm actionForm,
178                            PortletConfig portletConfig, ResourceRequest resourceRequest,
179                            ResourceResponse resourceResponse)
180                    throws Exception {
181    
182                    String cmd = ParamUtil.getString(resourceRequest, Constants.CMD);
183    
184                    PortletContext portletContext = portletConfig.getPortletContext();
185    
186                    PortletRequestDispatcher portletRequestDispatcher = null;
187    
188                    if (cmd.equals(Constants.IMPORT)) {
189                            portletRequestDispatcher = portletContext.getRequestDispatcher(
190                                    "/html/portlet/layouts_admin/import_layouts_processes.jsp");
191                    }
192                    else {
193                            portletRequestDispatcher = portletContext.getRequestDispatcher(
194                                    "/html/portlet/layouts_admin/import_layouts_resources.jsp");
195                    }
196    
197                    portletRequestDispatcher.include(resourceRequest, resourceResponse);
198            }
199    
200            protected void addTempFileEntry(
201                            ActionRequest actionRequest, ActionResponse actionResponse,
202                            String folderName)
203                    throws Exception {
204    
205                    UploadPortletRequest uploadPortletRequest =
206                            PortalUtil.getUploadPortletRequest(actionRequest);
207    
208                    checkExceededSizeLimit(uploadPortletRequest);
209    
210                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
211    
212                    deleteTempFileEntry(groupId, folderName);
213    
214                    InputStream inputStream = null;
215    
216                    try {
217                            String sourceFileName = uploadPortletRequest.getFileName("file");
218    
219                            inputStream = uploadPortletRequest.getFileAsStream("file");
220    
221                            String contentType = uploadPortletRequest.getContentType("file");
222    
223                            LayoutServiceUtil.addTempFileEntry(
224                                    groupId, folderName, sourceFileName, inputStream, contentType);
225                    }
226                    catch (Exception e) {
227                            UploadException uploadException =
228                                    (UploadException)actionRequest.getAttribute(
229                                            WebKeys.UPLOAD_EXCEPTION);
230    
231                            if ((uploadException != null) &&
232                                    (uploadException.getCause()
233                                            instanceof FileUploadBase.IOFileUploadException)) {
234    
235                                    // Cancelled a temporary upload
236    
237                            }
238                            else if ((uploadException != null) &&
239                                             uploadException.isExceededSizeLimit()) {
240    
241                                    throw new FileSizeException(uploadException.getCause());
242                            }
243                            else {
244                                    throw e;
245                            }
246                    }
247                    finally {
248                            StreamUtil.cleanUp(inputStream);
249                    }
250            }
251    
252            protected void checkExceededSizeLimit(HttpServletRequest request)
253                    throws PortalException {
254    
255                    UploadException uploadException = (UploadException)request.getAttribute(
256                            WebKeys.UPLOAD_EXCEPTION);
257    
258                    if (uploadException != null) {
259                            if (uploadException.isExceededSizeLimit()) {
260                                    throw new LARFileSizeException(uploadException.getCause());
261                            }
262    
263                            throw new PortalException(uploadException.getCause());
264                    }
265            }
266    
267            protected void deleteTempFileEntry(
268                            ActionRequest actionRequest, ActionResponse actionResponse,
269                            String folderName)
270                    throws Exception {
271    
272                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
273                            WebKeys.THEME_DISPLAY);
274    
275                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
276    
277                    try {
278                            String fileName = ParamUtil.getString(actionRequest, "fileName");
279    
280                            LayoutServiceUtil.deleteTempFileEntry(
281                                    themeDisplay.getScopeGroupId(), folderName, fileName);
282    
283                            jsonObject.put("deleted", Boolean.TRUE);
284                    }
285                    catch (Exception e) {
286                            String errorMessage = themeDisplay.translate(
287                                    "an-unexpected-error-occurred-while-deleting-the-file");
288    
289                            jsonObject.put("deleted", Boolean.FALSE);
290                            jsonObject.put("errorMessage", errorMessage);
291                    }
292    
293                    writeJSON(actionRequest, actionResponse, jsonObject);
294            }
295    
296            protected void deleteTempFileEntry(long groupId, String folderName)
297                    throws PortalException {
298    
299                    String[] tempFileNames = LayoutServiceUtil.getTempFileNames(
300                            groupId, folderName);
301    
302                    for (String tempFileEntryName : tempFileNames) {
303                            LayoutServiceUtil.deleteTempFileEntry(
304                                    groupId, folderName, tempFileEntryName);
305                    }
306            }
307    
308            protected void handleUploadException(
309                            PortletConfig portletConfig, ActionRequest actionRequest,
310                            ActionResponse actionResponse, String folderName, Exception e)
311                    throws Exception {
312    
313                    HttpServletResponse response = PortalUtil.getHttpServletResponse(
314                            actionResponse);
315    
316                    response.setContentType(ContentTypes.TEXT_HTML);
317                    response.setStatus(HttpServletResponse.SC_OK);
318    
319                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
320                            WebKeys.THEME_DISPLAY);
321    
322                    deleteTempFileEntry(themeDisplay.getScopeGroupId(), folderName);
323    
324                    JSONObject jsonObject = StagingUtil.getExceptionMessagesJSONObject(
325                            themeDisplay.getLocale(), e, null);
326    
327                    writeJSON(actionRequest, actionResponse, jsonObject);
328    
329                    ServletResponseUtil.write(
330                            response, String.valueOf(jsonObject.getInt("status")));
331            }
332    
333            protected void importData(
334                            ActionRequest actionRequest, ActionResponse actionResponse,
335                            String folderName)
336                    throws Exception {
337    
338                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
339                            WebKeys.THEME_DISPLAY);
340    
341                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
342    
343                    FileEntry fileEntry = ExportImportHelperUtil.getTempFileEntry(
344                            groupId, themeDisplay.getUserId(), folderName);
345    
346                    InputStream inputStream = null;
347    
348                    try {
349                            inputStream = DLFileEntryLocalServiceUtil.getFileAsStream(
350                                    fileEntry.getFileEntryId(), fileEntry.getVersion(), false);
351    
352                            importData(actionRequest, fileEntry.getTitle(), inputStream);
353    
354                            deleteTempFileEntry(groupId, folderName);
355    
356                            addSuccessMessage(actionRequest, actionResponse);
357                    }
358                    finally {
359                            StreamUtil.cleanUp(inputStream);
360                    }
361            }
362    
363            protected void importData(
364                            ActionRequest actionRequest, String fileName,
365                            InputStream inputStream)
366                    throws Exception {
367    
368                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
369                    boolean privateLayout = ParamUtil.getBoolean(
370                            actionRequest, "privateLayout");
371    
372                    LayoutServiceUtil.importLayoutsInBackground(
373                            fileName, groupId, privateLayout, actionRequest.getParameterMap(),
374                            inputStream);
375            }
376    
377            protected void validateFile(
378                            ActionRequest actionRequest, ActionResponse actionResponse,
379                            String folderName)
380                    throws Exception {
381    
382                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
383                            WebKeys.THEME_DISPLAY);
384    
385                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
386    
387                    FileEntry fileEntry = ExportImportHelperUtil.getTempFileEntry(
388                            groupId, themeDisplay.getUserId(), folderName);
389    
390                    InputStream inputStream = null;
391    
392                    try {
393                            inputStream = DLFileEntryLocalServiceUtil.getFileAsStream(
394                                    fileEntry.getFileEntryId(), fileEntry.getVersion(), false);
395    
396                            MissingReferences missingReferences = validateFile(
397                                    actionRequest, inputStream);
398    
399                            Map<String, MissingReference> weakMissingReferences =
400                                    missingReferences.getWeakMissingReferences();
401    
402                            if (weakMissingReferences.isEmpty()) {
403                                    return;
404                            }
405    
406                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
407    
408                            if ((weakMissingReferences != null) &&
409                                    !weakMissingReferences.isEmpty()) {
410    
411                                    jsonObject.put(
412                                            "warningMessages",
413                                            StagingUtil.getWarningMessagesJSONArray(
414                                                    themeDisplay.getLocale(), weakMissingReferences, null));
415                            }
416    
417                            writeJSON(actionRequest, actionResponse, jsonObject);
418                    }
419                    finally {
420                            StreamUtil.cleanUp(inputStream);
421                    }
422            }
423    
424            protected MissingReferences validateFile(
425                            ActionRequest actionRequest, InputStream inputStream)
426                    throws Exception {
427    
428                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
429                    boolean privateLayout = ParamUtil.getBoolean(
430                            actionRequest, "privateLayout");
431    
432                    return LayoutServiceUtil.validateImportLayoutsFile(
433                            groupId, privateLayout, actionRequest.getParameterMap(),
434                            inputStream);
435            }
436    
437            private static final Log _log = LogFactoryUtil.getLog(
438                    ImportLayoutsAction.class);
439    
440    }