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