001
014
015 package com.liferay.portlet.imageuploader.action;
016
017 import com.liferay.portal.ImageTypeException;
018 import com.liferay.portal.NoSuchRepositoryException;
019 import com.liferay.portal.kernel.exception.PortalException;
020 import com.liferay.portal.kernel.image.ImageBag;
021 import com.liferay.portal.kernel.image.ImageToolUtil;
022 import com.liferay.portal.kernel.json.JSONFactoryUtil;
023 import com.liferay.portal.kernel.json.JSONObject;
024 import com.liferay.portal.kernel.log.Log;
025 import com.liferay.portal.kernel.log.LogFactoryUtil;
026 import com.liferay.portal.kernel.portlet.PortletResponseUtil;
027 import com.liferay.portal.kernel.repository.model.FileEntry;
028 import com.liferay.portal.kernel.servlet.SessionErrors;
029 import com.liferay.portal.kernel.servlet.SessionMessages;
030 import com.liferay.portal.kernel.upload.UploadException;
031 import com.liferay.portal.kernel.upload.UploadPortletRequest;
032 import com.liferay.portal.kernel.util.Constants;
033 import com.liferay.portal.kernel.util.FileUtil;
034 import com.liferay.portal.kernel.util.MimeTypesUtil;
035 import com.liferay.portal.kernel.util.ParamUtil;
036 import com.liferay.portal.kernel.util.PropsKeys;
037 import com.liferay.portal.kernel.util.StreamUtil;
038 import com.liferay.portal.kernel.util.StringPool;
039 import com.liferay.portal.kernel.util.StringUtil;
040 import com.liferay.portal.kernel.util.TempFileEntryUtil;
041 import com.liferay.portal.kernel.util.TextFormatter;
042 import com.liferay.portal.kernel.util.Validator;
043 import com.liferay.portal.security.auth.PrincipalException;
044 import com.liferay.portal.struts.PortletAction;
045 import com.liferay.portal.theme.ThemeDisplay;
046 import com.liferay.portal.util.PortalUtil;
047 import com.liferay.portal.util.PrefsPropsUtil;
048 import com.liferay.portal.util.PropsValues;
049 import com.liferay.portal.util.WebKeys;
050 import com.liferay.portlet.documentlibrary.FileExtensionException;
051 import com.liferay.portlet.documentlibrary.FileSizeException;
052 import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
053 import com.liferay.portlet.documentlibrary.NoSuchFileException;
054 import com.liferay.portlet.documentlibrary.antivirus.AntivirusScannerException;
055
056 import java.awt.image.RenderedImage;
057
058 import java.io.File;
059 import java.io.InputStream;
060
061 import javax.portlet.ActionRequest;
062 import javax.portlet.ActionResponse;
063 import javax.portlet.MimeResponse;
064 import javax.portlet.PortletConfig;
065 import javax.portlet.PortletRequest;
066 import javax.portlet.RenderRequest;
067 import javax.portlet.RenderResponse;
068 import javax.portlet.ResourceRequest;
069 import javax.portlet.ResourceResponse;
070
071 import org.apache.struts.action.ActionForm;
072 import org.apache.struts.action.ActionForward;
073 import org.apache.struts.action.ActionMapping;
074
075
079 public class UploadImageAction 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 long maxFileSize = ParamUtil.getLong(actionRequest, "maxFileSize");
091
092 try {
093 UploadException uploadException =
094 (UploadException)actionRequest.getAttribute(
095 WebKeys.UPLOAD_EXCEPTION);
096
097 if (uploadException != null) {
098 if (uploadException.isExceededSizeLimit()) {
099 throw new FileSizeException(uploadException.getCause());
100 }
101
102 throw new PortalException(uploadException.getCause());
103 }
104 else if (cmd.equals(Constants.ADD_TEMP)) {
105 FileEntry tempImageFileEntry = addTempImageFileEntry(
106 actionRequest);
107
108 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
109
110 jsonObject.put(
111 "tempImageFileName", tempImageFileEntry.getTitle());
112
113 writeJSON(actionRequest, actionResponse, jsonObject);
114 }
115 else {
116 FileEntry fileEntry = null;
117
118 boolean imageUploaded = ParamUtil.getBoolean(
119 actionRequest, "imageUploaded");
120
121 if (imageUploaded) {
122 fileEntry = saveTempImageFileEntry(actionRequest);
123
124 if (fileEntry.getSize() > maxFileSize) {
125 throw new FileSizeException();
126 }
127 }
128
129 SessionMessages.add(actionRequest, "imageUploaded", fileEntry);
130
131 sendRedirect(actionRequest, actionResponse);
132 }
133 }
134 catch (Exception e) {
135 handleUploadException(
136 actionRequest, actionResponse, cmd, maxFileSize, e);
137 }
138 }
139
140 @Override
141 public ActionForward render(
142 ActionMapping actionMapping, ActionForm actionForm,
143 PortletConfig portletConfig, RenderRequest renderRequest,
144 RenderResponse renderResponse)
145 throws Exception {
146
147 return actionMapping.findForward(
148 getForward(renderRequest, "portlet.image_uploader.view"));
149 }
150
151 @Override
152 public void serveResource(
153 ActionMapping actionMapping, ActionForm actionForm,
154 PortletConfig portletConfig, ResourceRequest resourceRequest,
155 ResourceResponse resourceResponse)
156 throws Exception {
157
158 try {
159 String cmd = ParamUtil.getString(resourceRequest, Constants.CMD);
160
161 if (cmd.equals(Constants.GET_TEMP)) {
162 FileEntry tempFileEntry = getTempImageFileEntry(
163 resourceRequest);
164
165 serveTempImageFile(
166 resourceResponse, tempFileEntry.getContentStream());
167 }
168 }
169 catch (NoSuchFileEntryException nsfee) {
170 }
171 catch (Exception e) {
172 _log.error(e);
173 }
174 }
175
176 protected FileEntry addTempImageFileEntry(PortletRequest portletRequest)
177 throws Exception {
178
179 UploadPortletRequest uploadPortletRequest =
180 PortalUtil.getUploadPortletRequest(portletRequest);
181
182 ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
183 WebKeys.THEME_DISPLAY);
184
185 String contentType = uploadPortletRequest.getContentType("fileName");
186
187 if (!MimeTypesUtil.isWebImage(contentType)) {
188 throw new ImageTypeException();
189 }
190
191 String fileName = uploadPortletRequest.getFileName("fileName");
192
193 try {
194 TempFileEntryUtil.deleteTempFileEntry(
195 themeDisplay.getScopeGroupId(), themeDisplay.getUserId(),
196 getTempImageFolderName(), fileName);
197 }
198 catch (Exception e) {
199 }
200
201 InputStream inputStream = null;
202
203 try {
204 inputStream = uploadPortletRequest.getFileAsStream("fileName");
205
206 return TempFileEntryUtil.addTempFileEntry(
207 themeDisplay.getScopeGroupId(), themeDisplay.getUserId(),
208 getTempImageFolderName(), fileName, inputStream, contentType);
209 }
210 finally {
211 StreamUtil.cleanUp(inputStream);
212 }
213 }
214
215 protected FileEntry getTempImageFileEntry(PortletRequest portletRequest)
216 throws PortalException {
217
218 ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
219 WebKeys.THEME_DISPLAY);
220
221 return TempFileEntryUtil.getTempFileEntry(
222 themeDisplay.getScopeGroupId(), themeDisplay.getUserId(),
223 getTempImageFolderName(), getTempImageFileName(portletRequest));
224 }
225
226 protected String getTempImageFileName(PortletRequest portletRequest) {
227 return ParamUtil.getString(portletRequest, "tempImageFileName");
228 }
229
230 protected String getTempImageFolderName() {
231 Class<?> clazz = getClass();
232
233 return clazz.getName();
234 }
235
236 protected void handleUploadException(
237 ActionRequest actionRequest, ActionResponse actionResponse,
238 String cmd, long maxFileSize, Exception e)
239 throws Exception {
240
241 if (e instanceof PrincipalException) {
242 SessionErrors.add(actionRequest, e.getClass());
243
244 setForward(actionRequest, "portal.error");
245 }
246 else if (e instanceof AntivirusScannerException ||
247 e instanceof FileExtensionException ||
248 e instanceof FileSizeException ||
249 e instanceof ImageTypeException ||
250 e instanceof NoSuchFileException ||
251 e instanceof UploadException) {
252
253 if (cmd.equals(Constants.ADD_TEMP)) {
254 hideDefaultErrorMessage(actionRequest);
255
256 ThemeDisplay themeDisplay =
257 (ThemeDisplay)actionRequest.getAttribute(
258 WebKeys.THEME_DISPLAY);
259
260 String errorMessage = StringPool.BLANK;
261
262 if (e instanceof AntivirusScannerException) {
263 AntivirusScannerException ase =
264 (AntivirusScannerException)e;
265
266 errorMessage = themeDisplay.translate(ase.getMessageKey());
267 }
268 else if (e instanceof FileExtensionException) {
269 errorMessage = themeDisplay.translate(
270 "please-enter-a-file-with-a-valid-extension-x",
271 StringUtil.merge(
272 PropsValues.DL_FILE_EXTENSIONS, StringPool.COMMA));
273 }
274 else if (e instanceof FileSizeException) {
275 if (maxFileSize == 0) {
276 maxFileSize = PrefsPropsUtil.getLong(
277 PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_MAX_SIZE);
278 }
279
280 errorMessage = themeDisplay.translate(
281 "please-enter-a-file-with-a-valid-file-size-no" +
282 "-larger-than-x",
283 TextFormatter.formatStorageSize(
284 maxFileSize, themeDisplay.getLocale()));
285 }
286 else if (e instanceof ImageTypeException) {
287 errorMessage = themeDisplay.translate(
288 "please-enter-a-file-with-a-valid-file-type");
289 }
290 else if (e instanceof NoSuchFileException ||
291 e instanceof UploadException) {
292
293 errorMessage = themeDisplay.translate(
294 "an-unexpected-error-occurred-while-uploading" +
295 "-your-file");
296 }
297
298 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
299
300 jsonObject.put("errorMessage", errorMessage);
301
302 writeJSON(actionRequest, actionResponse, jsonObject);
303 }
304 else {
305 SessionErrors.add(actionRequest, e.getClass(), e);
306 }
307 }
308 else {
309 throw e;
310 }
311 }
312
313 protected FileEntry saveTempImageFileEntry(ActionRequest actionRequest)
314 throws Exception {
315
316 FileEntry tempFileEntry = null;
317
318 InputStream tempImageStream = null;
319
320 try {
321 tempFileEntry = getTempImageFileEntry(actionRequest);
322
323 tempImageStream = tempFileEntry.getContentStream();
324
325 ImageBag imageBag = ImageToolUtil.read(tempImageStream);
326
327 RenderedImage renderedImage = imageBag.getRenderedImage();
328
329 String cropRegionJSON = ParamUtil.getString(
330 actionRequest, "cropRegion");
331
332 if (Validator.isNotNull(cropRegionJSON)) {
333 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(
334 cropRegionJSON);
335
336 int height = jsonObject.getInt("height");
337 int width = jsonObject.getInt("width");
338 int x = jsonObject.getInt("x");
339 int y = jsonObject.getInt("y");
340
341 if ((x == 0) && (y == 0) &&
342 (renderedImage.getHeight() == height) &&
343 (renderedImage.getWidth() == width)) {
344
345 return tempFileEntry;
346 }
347
348 if ((height + y) > renderedImage.getHeight()) {
349 height = renderedImage.getHeight() - y;
350 }
351
352 if ((width + x) > renderedImage.getWidth()) {
353 width = renderedImage.getWidth() - x;
354 }
355
356 renderedImage = ImageToolUtil.crop(
357 renderedImage, height, width, x, y);
358 }
359
360 byte[] bytes = ImageToolUtil.getBytes(
361 renderedImage, imageBag.getType());
362
363 ThemeDisplay themeDisplay =
364 (ThemeDisplay)actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
365
366 File file = FileUtil.createTempFile(bytes);
367
368 try {
369 TempFileEntryUtil.deleteTempFileEntry(
370 themeDisplay.getScopeGroupId(), themeDisplay.getUserId(),
371 getTempImageFolderName(),
372 getTempImageFileName(actionRequest));
373 }
374 catch (Exception e) {
375 }
376
377 return TempFileEntryUtil.addTempFileEntry(
378 themeDisplay.getScopeGroupId(), themeDisplay.getUserId(),
379 getTempImageFolderName(), getTempImageFileName(actionRequest),
380 file, tempFileEntry.getMimeType());
381 }
382 catch (NoSuchFileEntryException nsfee) {
383 throw new UploadException(nsfee);
384 }
385 catch (NoSuchRepositoryException nsre) {
386 throw new UploadException(nsre);
387 }
388 finally {
389 StreamUtil.cleanUp(tempImageStream);
390 }
391 }
392
393 protected void serveTempImageFile(
394 MimeResponse mimeResponse, InputStream tempImageStream)
395 throws Exception {
396
397 ImageBag imageBag = ImageToolUtil.read(tempImageStream);
398
399 byte[] bytes = ImageToolUtil.getBytes(
400 imageBag.getRenderedImage(), imageBag.getType());
401
402 String contentType = MimeTypesUtil.getExtensionContentType(
403 imageBag.getType());
404
405 mimeResponse.setContentType(contentType);
406
407 PortletResponseUtil.write(mimeResponse, bytes);
408 }
409
410 private static final Log _log = LogFactoryUtil.getLog(
411 UploadImageAction.class);
412
413 }