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