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.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.exception.SystemException;
026    import com.liferay.portal.kernel.json.JSONFactoryUtil;
027    import com.liferay.portal.kernel.json.JSONObject;
028    import com.liferay.portal.kernel.lar.ExportImportHelper;
029    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
030    import com.liferay.portal.kernel.lar.MissingReference;
031    import com.liferay.portal.kernel.lar.MissingReferences;
032    import com.liferay.portal.kernel.log.Log;
033    import com.liferay.portal.kernel.log.LogFactoryUtil;
034    import com.liferay.portal.kernel.repository.model.FileEntry;
035    import com.liferay.portal.kernel.servlet.ServletResponseUtil;
036    import com.liferay.portal.kernel.servlet.SessionErrors;
037    import com.liferay.portal.kernel.staging.StagingUtil;
038    import com.liferay.portal.kernel.upload.UploadException;
039    import com.liferay.portal.kernel.upload.UploadPortletRequest;
040    import com.liferay.portal.kernel.util.Constants;
041    import com.liferay.portal.kernel.util.ContentTypes;
042    import com.liferay.portal.kernel.util.ParamUtil;
043    import com.liferay.portal.kernel.util.StreamUtil;
044    import com.liferay.portal.security.auth.PrincipalException;
045    import com.liferay.portal.service.LayoutServiceUtil;
046    import com.liferay.portal.struts.PortletAction;
047    import com.liferay.portal.theme.ThemeDisplay;
048    import com.liferay.portal.util.PortalUtil;
049    import com.liferay.portal.util.WebKeys;
050    import com.liferay.portlet.documentlibrary.FileSizeException;
051    import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
052    import com.liferay.portlet.sites.action.ActionUtil;
053    
054    import java.io.InputStream;
055    
056    import java.util.Map;
057    
058    import javax.portlet.ActionRequest;
059    import javax.portlet.ActionResponse;
060    import javax.portlet.PortletConfig;
061    import javax.portlet.PortletContext;
062    import javax.portlet.PortletRequestDispatcher;
063    import javax.portlet.RenderRequest;
064    import javax.portlet.RenderResponse;
065    import javax.portlet.ResourceRequest;
066    import javax.portlet.ResourceResponse;
067    
068    import javax.servlet.http.HttpServletRequest;
069    import javax.servlet.http.HttpServletResponse;
070    
071    import org.apache.commons.fileupload.FileUploadBase;
072    import org.apache.struts.action.ActionForm;
073    import org.apache.struts.action.ActionForward;
074    import org.apache.struts.action.ActionMapping;
075    
076    /**
077     * @author Alexander Chow
078     * @author Raymond Aug??
079     */
080    public class ImportLayoutsAction 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_TEMP)) {
093                                    addTempFileEntry(
094                                            actionRequest, 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, String folderName)
202                    throws Exception {
203    
204                    UploadPortletRequest uploadPortletRequest =
205                            PortalUtil.getUploadPortletRequest(actionRequest);
206    
207                    checkExceededSizeLimit(uploadPortletRequest);
208    
209                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
210    
211                    deleteTempFileEntry(groupId, folderName);
212    
213                    InputStream inputStream = null;
214    
215                    try {
216                            String sourceFileName = uploadPortletRequest.getFileName("file");
217    
218                            inputStream = uploadPortletRequest.getFileAsStream("file");
219    
220                            String contentType = uploadPortletRequest.getContentType("file");
221    
222                            LayoutServiceUtil.addTempFileEntry(
223                                    groupId, sourceFileName, folderName, inputStream, contentType);
224                    }
225                    catch (Exception e) {
226                            UploadException uploadException =
227                                    (UploadException)actionRequest.getAttribute(
228                                            WebKeys.UPLOAD_EXCEPTION);
229    
230                            if ((uploadException != null) &&
231                                    (uploadException.getCause()
232                                            instanceof FileUploadBase.IOFileUploadException)) {
233    
234                                    // Cancelled a temporary upload
235    
236                            }
237                            else if ((uploadException != null) &&
238                                             uploadException.isExceededSizeLimit()) {
239    
240                                    throw new FileSizeException(uploadException.getCause());
241                            }
242                            else {
243                                    throw e;
244                            }
245                    }
246                    finally {
247                            StreamUtil.cleanUp(inputStream);
248                    }
249            }
250    
251            protected void checkExceededSizeLimit(HttpServletRequest request)
252                    throws PortalException {
253    
254                    UploadException uploadException = (UploadException)request.getAttribute(
255                            WebKeys.UPLOAD_EXCEPTION);
256    
257                    if (uploadException != null) {
258                            if (uploadException.isExceededSizeLimit()) {
259                                    throw new LARFileSizeException(uploadException.getCause());
260                            }
261    
262                            throw new PortalException(uploadException.getCause());
263                    }
264            }
265    
266            protected void deleteTempFileEntry(
267                            ActionRequest actionRequest, ActionResponse actionResponse,
268                            String folderName)
269                    throws Exception {
270    
271                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
272                            WebKeys.THEME_DISPLAY);
273    
274                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
275    
276                    try {
277                            String fileName = ParamUtil.getString(actionRequest, "fileName");
278    
279                            LayoutServiceUtil.deleteTempFileEntry(
280                                    themeDisplay.getScopeGroupId(), fileName, folderName);
281    
282                            jsonObject.put("deleted", Boolean.TRUE);
283                    }
284                    catch (Exception e) {
285                            String errorMessage = themeDisplay.translate(
286                                    "an-unexpected-error-occurred-while-deleting-the-file");
287    
288                            jsonObject.put("deleted", Boolean.FALSE);
289                            jsonObject.put("errorMessage", errorMessage);
290                    }
291    
292                    writeJSON(actionRequest, actionResponse, jsonObject);
293            }
294    
295            protected void deleteTempFileEntry(long groupId, String folderName)
296                    throws PortalException, SystemException {
297    
298                    String[] tempFileEntryNames = LayoutServiceUtil.getTempFileEntryNames(
299                            groupId, folderName);
300    
301                    for (String tempFileEntryName : tempFileEntryNames) {
302                            LayoutServiceUtil.deleteTempFileEntry(
303                                    groupId, tempFileEntryName, folderName);
304                    }
305            }
306    
307            protected void handleUploadException(
308                            PortletConfig portletConfig, ActionRequest actionRequest,
309                            ActionResponse actionResponse, String folderName, Exception e)
310                    throws Exception {
311    
312                    HttpServletResponse response = PortalUtil.getHttpServletResponse(
313                            actionResponse);
314    
315                    response.setContentType(ContentTypes.TEXT_HTML);
316                    response.setStatus(HttpServletResponse.SC_OK);
317    
318                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
319                            WebKeys.THEME_DISPLAY);
320    
321                    deleteTempFileEntry(themeDisplay.getScopeGroupId(), folderName);
322    
323                    JSONObject jsonObject = StagingUtil.getExceptionMessagesJSONObject(
324                            themeDisplay.getLocale(), e, null);
325    
326                    writeJSON(actionRequest, actionResponse, jsonObject);
327    
328                    ServletResponseUtil.write(
329                            response, String.valueOf(jsonObject.getInt("status")));
330            }
331    
332            protected void importData(
333                            ActionRequest actionRequest, ActionResponse actionResponse,
334                            String folderName)
335                    throws Exception {
336    
337                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
338                            WebKeys.THEME_DISPLAY);
339    
340                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
341    
342                    FileEntry fileEntry = ExportImportHelperUtil.getTempFileEntry(
343                            groupId, themeDisplay.getUserId(), folderName);
344    
345                    InputStream inputStream = null;
346    
347                    try {
348                            inputStream = DLFileEntryLocalServiceUtil.getFileAsStream(
349                                    fileEntry.getFileEntryId(), fileEntry.getVersion(), false);
350    
351                            importData(actionRequest, fileEntry.getTitle(), inputStream);
352    
353                            deleteTempFileEntry(groupId, folderName);
354    
355                            addSuccessMessage(actionRequest, actionResponse);
356                    }
357                    finally {
358                            StreamUtil.cleanUp(inputStream);
359                    }
360            }
361    
362            protected void importData(
363                            ActionRequest actionRequest, String fileName,
364                            InputStream inputStream)
365                    throws Exception {
366    
367                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
368                    boolean privateLayout = ParamUtil.getBoolean(
369                            actionRequest, "privateLayout");
370    
371                    LayoutServiceUtil.importLayoutsInBackground(
372                            fileName, groupId, privateLayout, actionRequest.getParameterMap(),
373                            inputStream);
374            }
375    
376            protected void validateFile(
377                            ActionRequest actionRequest, ActionResponse actionResponse,
378                            String folderName)
379                    throws Exception {
380    
381                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
382                            WebKeys.THEME_DISPLAY);
383    
384                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
385    
386                    FileEntry fileEntry = ExportImportHelperUtil.getTempFileEntry(
387                            groupId, themeDisplay.getUserId(), folderName);
388    
389                    InputStream inputStream = null;
390    
391                    try {
392                            inputStream = DLFileEntryLocalServiceUtil.getFileAsStream(
393                                    fileEntry.getFileEntryId(), fileEntry.getVersion(), false);
394    
395                            MissingReferences missingReferences = validateFile(
396                                    actionRequest, inputStream);
397    
398                            Map<String, MissingReference> weakMissingReferences =
399                                    missingReferences.getWeakMissingReferences();
400    
401                            if (weakMissingReferences.isEmpty()) {
402                                    return;
403                            }
404    
405                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
406    
407                            if ((weakMissingReferences != null) &&
408                                    !weakMissingReferences.isEmpty()) {
409    
410                                    jsonObject.put(
411                                            "warningMessages",
412                                            StagingUtil.getWarningMessagesJSONArray(
413                                                    themeDisplay.getLocale(), weakMissingReferences, null));
414                            }
415    
416                            writeJSON(actionRequest, actionResponse, jsonObject);
417                    }
418                    finally {
419                            StreamUtil.cleanUp(inputStream);
420                    }
421            }
422    
423            protected MissingReferences validateFile(
424                            ActionRequest actionRequest, InputStream inputStream)
425                    throws Exception {
426    
427                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
428                    boolean privateLayout = ParamUtil.getBoolean(
429                            actionRequest, "privateLayout");
430    
431                    return LayoutServiceUtil.validateImportLayoutsFile(
432                            groupId, privateLayout, actionRequest.getParameterMap(),
433                            inputStream);
434            }
435    
436            private static Log _log = LogFactoryUtil.getLog(ImportLayoutsAction.class);
437    
438    }