1
22
23 package com.liferay.portlet.imagegallery.service.impl;
24
25 import com.liferay.portal.PortalException;
26 import com.liferay.portal.SystemException;
27 import com.liferay.portal.kernel.image.ImageProcessor;
28 import com.liferay.portal.kernel.image.ImageProcessorUtil;
29 import com.liferay.portal.kernel.log.Log;
30 import com.liferay.portal.kernel.log.LogFactoryUtil;
31 import com.liferay.portal.kernel.search.SearchEngineUtil;
32 import com.liferay.portal.kernel.search.SearchException;
33 import com.liferay.portal.kernel.util.ByteArrayMaker;
34 import com.liferay.portal.kernel.util.FileUtil;
35 import com.liferay.portal.kernel.util.GetterUtil;
36 import com.liferay.portal.kernel.util.OrderByComparator;
37 import com.liferay.portal.kernel.util.StringPool;
38 import com.liferay.portal.kernel.util.StringUtil;
39 import com.liferay.portal.kernel.util.Validator;
40 import com.liferay.portal.model.Image;
41 import com.liferay.portal.model.ResourceConstants;
42 import com.liferay.portal.model.User;
43 import com.liferay.portal.util.PrefsPropsUtil;
44 import com.liferay.portal.util.PropsKeys;
45 import com.liferay.portal.util.PropsValues;
46 import com.liferay.portlet.imagegallery.DuplicateImageNameException;
47 import com.liferay.portlet.imagegallery.ImageNameException;
48 import com.liferay.portlet.imagegallery.ImageSizeException;
49 import com.liferay.portlet.imagegallery.NoSuchImageException;
50 import com.liferay.portlet.imagegallery.model.IGFolder;
51 import com.liferay.portlet.imagegallery.model.IGImage;
52 import com.liferay.portlet.imagegallery.model.impl.IGImageImpl;
53 import com.liferay.portlet.imagegallery.service.base.IGImageLocalServiceBaseImpl;
54 import com.liferay.portlet.imagegallery.social.IGActivityKeys;
55 import com.liferay.portlet.imagegallery.util.Indexer;
56 import com.liferay.portlet.imagegallery.util.comparator.ImageModifiedDateComparator;
57
58 import com.sun.media.jai.codec.ImageCodec;
59 import com.sun.media.jai.codec.ImageEncoder;
60
61 import java.awt.image.RenderedImage;
62
63 import java.io.File;
64 import java.io.IOException;
65
66 import java.util.Date;
67 import java.util.List;
68
69 import javax.imageio.ImageIO;
70
71
76 public class IGImageLocalServiceImpl extends IGImageLocalServiceBaseImpl {
77
78 public IGImage addImage(
79 long userId, long folderId, String name, String description,
80 File file, String contentType, String[] tagsEntries,
81 boolean addCommunityPermissions, boolean addGuestPermissions)
82 throws PortalException, SystemException {
83
84 return addImage(
85 null, userId, folderId, name, description, file, contentType,
86 tagsEntries, Boolean.valueOf(addCommunityPermissions),
87 Boolean.valueOf(addGuestPermissions), null, null);
88 }
89
90 public IGImage addImage(
91 String uuid, long userId, long folderId, String name,
92 String description, File file, String contentType,
93 String[] tagsEntries, boolean addCommunityPermissions,
94 boolean addGuestPermissions)
95 throws PortalException, SystemException {
96
97 return addImage(
98 uuid, userId, folderId, name, description, file, contentType,
99 tagsEntries, Boolean.valueOf(addCommunityPermissions),
100 Boolean.valueOf(addGuestPermissions), null, null);
101 }
102
103 public IGImage addImage(
104 long userId, long folderId, String name, String description,
105 File file, String contentType, String[] tagsEntries,
106 String[] communityPermissions, String[] guestPermissions)
107 throws PortalException, SystemException {
108
109 return addImage(
110 null, userId, folderId, name, description, file, contentType,
111 tagsEntries, null, null, communityPermissions, guestPermissions);
112 }
113
114 public IGImage addImage(
115 String uuid, long userId, long folderId, String name,
116 String description, File file, String contentType,
117 String[] tagsEntries, Boolean addCommunityPermissions,
118 Boolean addGuestPermissions, String[] communityPermissions,
119 String[] guestPermissions)
120 throws PortalException, SystemException {
121
122 try {
123
124
126 String extension = FileUtil.getExtension(file.getName());
127
128 if (Validator.isNotNull(name) &&
129 StringUtil.endsWith(name, extension)) {
130
131 name = FileUtil.stripExtension(name);
132 }
133
134 String nameWithExtension = name + StringPool.PERIOD + extension;
135 byte[] bytes = FileUtil.getBytes(file);
136
137 validate(folderId, nameWithExtension, file, bytes);
138
139 User user = userPersistence.findByPrimaryKey(userId);
140 IGFolder folder = igFolderPersistence.findByPrimaryKey(folderId);
141 RenderedImage renderedImage = ImageProcessorUtil.read(
142 file).getRenderedImage();
143 Date now = new Date();
144
145 long imageId = counterLocalService.increment();
146
147 if (Validator.isNull(name)) {
148 name = String.valueOf(imageId);
149 }
150
151 IGImage image = igImagePersistence.create(imageId);
152
153 image.setUuid(uuid);
154 image.setGroupId(folder.getGroupId());
155 image.setCompanyId(user.getCompanyId());
156 image.setUserId(user.getUserId());
157 image.setCreateDate(now);
158 image.setModifiedDate(now);
159 image.setFolderId(folderId);
160 image.setName(name);
161 image.setDescription(description);
162 image.setSmallImageId(counterLocalService.increment());
163 image.setLargeImageId(counterLocalService.increment());
164
165 if (PropsValues.IG_IMAGE_CUSTOM_1_MAX_DIMENSION > 0) {
166 image.setCustom1ImageId(counterLocalService.increment());
167 }
168
169 if (PropsValues.IG_IMAGE_CUSTOM_2_MAX_DIMENSION > 0) {
170 image.setCustom2ImageId(counterLocalService.increment());
171 }
172
173 igImagePersistence.update(image, false);
174
175
177 saveImages(
178 image.getLargeImageId(), renderedImage, image.getSmallImageId(),
179 image.getCustom1ImageId(), image.getCustom2ImageId(), file,
180 bytes, contentType);
181
182
184 if ((addCommunityPermissions != null) &&
185 (addGuestPermissions != null)) {
186
187 addImageResources(
188 image, addCommunityPermissions.booleanValue(),
189 addGuestPermissions.booleanValue());
190 }
191 else {
192 addImageResources(
193 image, communityPermissions, guestPermissions);
194 }
195
196
198 updateTagsAsset(userId, image, tagsEntries);
199
200
202 socialActivityLocalService.addActivity(
203 userId, image.getGroupId(), IGImage.class.getName(), imageId,
204 IGActivityKeys.ADD_IMAGE, StringPool.BLANK, 0);
205
206
208 reIndex(image);
209
210 return image;
211 }
212 catch (IOException ioe) {
213 throw new ImageSizeException(ioe);
214 }
215 }
216
217 public void addImageResources(
218 long imageId, boolean addCommunityPermissions,
219 boolean addGuestPermissions)
220 throws PortalException, SystemException {
221
222 IGImage image = igImagePersistence.findByPrimaryKey(imageId);
223
224 addImageResources(image, addCommunityPermissions, addGuestPermissions);
225 }
226
227 public void addImageResources(
228 IGImage image, boolean addCommunityPermissions,
229 boolean addGuestPermissions)
230 throws PortalException, SystemException {
231
232 resourceLocalService.addResources(
233 image.getCompanyId(), image.getGroupId(), image.getUserId(),
234 IGImage.class.getName(), image.getImageId(), false,
235 addCommunityPermissions, addGuestPermissions);
236 }
237
238 public void addImageResources(
239 long imageId, String[] communityPermissions,
240 String[] guestPermissions)
241 throws PortalException, SystemException {
242
243 IGImage image = igImagePersistence.findByPrimaryKey(imageId);
244
245 addImageResources(image, communityPermissions, guestPermissions);
246 }
247
248 public void addImageResources(
249 IGImage image, String[] communityPermissions,
250 String[] guestPermissions)
251 throws PortalException, SystemException {
252
253 resourceLocalService.addModelResources(
254 image.getCompanyId(), image.getGroupId(), image.getUserId(),
255 IGImage.class.getName(), image.getImageId(), communityPermissions,
256 guestPermissions);
257 }
258
259 public void deleteImage(long imageId)
260 throws PortalException, SystemException {
261
262 IGImage image = igImagePersistence.findByPrimaryKey(imageId);
263
264 deleteImage(image);
265 }
266
267 public void deleteImage(IGImage image)
268 throws PortalException, SystemException {
269
270
272 try {
273 Indexer.deleteImage(image.getCompanyId(), image.getImageId());
274 }
275 catch (SearchException se) {
276 _log.error("Deleting index " + image.getImageId(), se);
277 }
278
279
281 tagsAssetLocalService.deleteAsset(
282 IGImage.class.getName(), image.getImageId());
283
284
286 socialActivityLocalService.deleteActivities(
287 IGImage.class.getName(), image.getImageId());
288
289
291 resourceLocalService.deleteResource(
292 image.getCompanyId(), IGImage.class.getName(),
293 ResourceConstants.SCOPE_INDIVIDUAL, image.getImageId());
294
295
297 imageLocalService.deleteImage(image.getSmallImageId());
298 imageLocalService.deleteImage(image.getLargeImageId());
299
300
302 igImagePersistence.remove(image);
303 }
304
305 public void deleteImages(long folderId)
306 throws PortalException, SystemException {
307
308 List<IGImage> images = igImagePersistence.findByFolderId(folderId);
309
310 for (IGImage image : images) {
311 deleteImage(image);
312 }
313 }
314
315 public int getFoldersImagesCount(List<Long> folderIds)
316 throws SystemException {
317
318 return igImageFinder.countByFolderIds(folderIds);
319 }
320
321 public List<IGImage> getGroupImages(long groupId, int start, int end)
322 throws SystemException {
323
324 return igImagePersistence.findByGroupId(
325 groupId, start, end, new ImageModifiedDateComparator());
326 }
327
328 public List<IGImage> getGroupImages(
329 long groupId, long userId, int start, int end)
330 throws SystemException {
331
332 OrderByComparator orderByComparator = new ImageModifiedDateComparator();
333
334 if (userId <= 0) {
335 return igImagePersistence.findByGroupId(
336 groupId, start, end, orderByComparator);
337 }
338 else {
339 return igImagePersistence.findByG_U(
340 groupId, userId, start, end, orderByComparator);
341 }
342 }
343
344 public int getGroupImagesCount(long groupId) throws SystemException {
345 return igImagePersistence.countByGroupId(groupId);
346 }
347
348 public int getGroupImagesCount(long groupId, long userId)
349 throws SystemException {
350
351 if (userId <= 0) {
352 return igImagePersistence.countByGroupId(groupId);
353 }
354 else {
355 return igImagePersistence.countByG_U(groupId, userId);
356 }
357 }
358
359 public IGImage getImage(long imageId)
360 throws PortalException, SystemException {
361
362 return igImagePersistence.findByPrimaryKey(imageId);
363 }
364
365 public IGImage getImageByCustom1ImageId(long custom1ImageId)
366 throws PortalException, SystemException {
367
368 return igImagePersistence.findByCustom1ImageId(custom1ImageId);
369 }
370
371 public IGImage getImageByCustom2ImageId(long custom2ImageId)
372 throws PortalException, SystemException {
373
374 return igImagePersistence.findByCustom2ImageId(custom2ImageId);
375 }
376
377 public IGImage getImageByFolderIdAndNameWithExtension(
378 long folderId, String nameWithExtension)
379 throws PortalException, SystemException {
380
381 String name = FileUtil.stripExtension(nameWithExtension);
382
383 List<IGImage> images = igImagePersistence.findByF_N(folderId, name);
384
385 if ((images.size() <= 0) && Validator.isNumber(name)) {
386 long imageId = GetterUtil.getLong(name);
387
388 IGImage image = igImagePersistence.fetchByPrimaryKey(imageId);
389
390 if (image != null) {
391 images.add(image);
392 }
393 }
394
395 for (IGImage image : images) {
396 if (nameWithExtension.equals(image.getNameWithExtension())) {
397 return image;
398 }
399 }
400
401 throw new NoSuchImageException();
402 }
403
404 public IGImage getImageByLargeImageId(long largeImageId)
405 throws PortalException, SystemException {
406
407 return igImagePersistence.findByLargeImageId(largeImageId);
408 }
409
410 public IGImage getImageBySmallImageId(long smallImageId)
411 throws PortalException, SystemException {
412
413 return igImagePersistence.findBySmallImageId(smallImageId);
414 }
415
416 public IGImage getImageByUuidAndGroupId(String uuid, long groupId)
417 throws PortalException, SystemException {
418
419 return igImagePersistence.findByUUID_G(uuid, groupId);
420 }
421
422 public List<IGImage> getImages(long folderId) throws SystemException {
423 return igImagePersistence.findByFolderId(folderId);
424 }
425
426 public List<IGImage> getImages(long folderId, int start, int end)
427 throws SystemException {
428
429 return igImagePersistence.findByFolderId(folderId, start, end);
430 }
431
432 public List<IGImage> getImages(
433 long folderId, int start, int end, OrderByComparator obc)
434 throws SystemException {
435
436 return igImagePersistence.findByFolderId(folderId, start, end, obc);
437 }
438
439 public int getImagesCount(long folderId) throws SystemException {
440 return igImagePersistence.countByFolderId(folderId);
441 }
442
443 public List<IGImage> getNoAssetImages() throws SystemException {
444 return igImageFinder.findByNoAssets();
445 }
446
447 public void reIndex(long imageId) throws SystemException {
448 if (SearchEngineUtil.isIndexReadOnly()) {
449 return;
450 }
451
452 IGImage image = igImagePersistence.fetchByPrimaryKey(imageId);
453
454 if (image == null) {
455 return;
456 }
457
458 reIndex(image);
459 }
460
461 public void reIndex(IGImage image) throws SystemException {
462 long companyId = image.getCompanyId();
463 long groupId = image.getGroupId();
464 long folderId = image.getFolderId();
465 long imageId = image.getImageId();
466 String name = image.getName();
467 String description = image.getDescription();
468 Date modifiedDate = image.getModifiedDate();
469
470 String[] tagsEntries = tagsEntryLocalService.getEntryNames(
471 IGImage.class.getName(), imageId);
472
473 try {
474 Indexer.updateImage(
475 companyId, groupId, folderId, imageId, name, description,
476 modifiedDate, tagsEntries);
477 }
478 catch (SearchException se) {
479 _log.error("Reindexing " + imageId, se);
480 }
481 }
482
483 public IGImage updateImage(
484 long userId, long imageId, long folderId, String name,
485 String description, File file, String contentType,
486 String[] tagsEntries)
487 throws PortalException, SystemException {
488
489 try {
490
491
493 IGImage image = igImagePersistence.findByPrimaryKey(imageId);
494
495 IGFolder folder = getFolder(image, folderId);
496
497 RenderedImage renderedImage = null;
498 byte[] bytes = null;
499
500 if ((file != null) && file.exists()) {
501 renderedImage = ImageProcessorUtil.read(
502 file).getRenderedImage();
503 bytes = FileUtil.getBytes(file);
504
505 validate(bytes);
506 }
507
508 if (Validator.isNotNull(name) && !name.equals(image.getName())) {
509 String nameWithExtension = IGImageImpl.getNameWithExtension(
510 name, image.getImageType());
511
512 validate(folderId, nameWithExtension);
513 }
514 else {
515 name = image.getName();
516 }
517
518 image.setModifiedDate(new Date());
519 image.setFolderId(folder.getFolderId());
520 image.setName(name);
521 image.setDescription(description);
522
523 igImagePersistence.update(image, false);
524
525
527 if (renderedImage != null) {
528 saveImages(
529 image.getLargeImageId(), renderedImage,
530 image.getSmallImageId(), image.getCustom1ImageId(),
531 image.getCustom2ImageId(), file, bytes, contentType);
532 }
533
534
536 updateTagsAsset(userId, image, tagsEntries);
537
538
540 socialActivityLocalService.addActivity(
541 userId, image.getGroupId(), IGImage.class.getName(), imageId,
542 IGActivityKeys.UPDATE_IMAGE, StringPool.BLANK, 0);
543
544
546 reIndex(image);
547
548 return image;
549 }
550 catch (IOException ioe) {
551 throw new ImageSizeException(ioe);
552 }
553 }
554
555 public void updateTagsAsset(
556 long userId, IGImage image, String[] tagsEntries)
557 throws PortalException, SystemException {
558
559 Image largeImage = imageLocalService.getImage(image.getLargeImageId());
560
561 if (largeImage == null) {
562 return;
563 }
564
565 tagsAssetLocalService.updateAsset(
566 userId, image.getGroupId(), IGImage.class.getName(),
567 image.getImageId(), tagsEntries, null, null, null, null,
568 largeImage.getType(), image.getName(), image.getDescription(),
569 null, null, largeImage.getHeight(), largeImage.getWidth(), null,
570 false);
571 }
572
573 protected IGFolder getFolder(IGImage image, long folderId)
574 throws PortalException, SystemException {
575
576 if (image.getFolderId() != folderId) {
577 IGFolder oldFolder = igFolderPersistence.findByPrimaryKey(
578 image.getFolderId());
579
580 IGFolder newFolder = igFolderPersistence.fetchByPrimaryKey(
581 folderId);
582
583 if ((newFolder == null) ||
584 (oldFolder.getGroupId() != newFolder.getGroupId())) {
585
586 folderId = image.getFolderId();
587 }
588 }
589
590 return igFolderPersistence.findByPrimaryKey(folderId);
591 }
592
593 protected void saveImages(
594 long largeImageId, RenderedImage renderedImage, long smallImageId,
595 long custom1ImageId, long custom2ImageId, File file, byte[] bytes,
596 String contentType)
597 throws SystemException {
598
599 try {
600
601
603 imageLocalService.updateImage(largeImageId, bytes);
604
605
607 saveScaledImage(
608 renderedImage, smallImageId, contentType,
609 PrefsPropsUtil.getInteger(
610 PropsKeys.IG_IMAGE_THUMBNAIL_MAX_DIMENSION));
611
612 if (custom1ImageId > 0) {
613 saveScaledImage(
614 renderedImage, custom1ImageId, contentType,
615 PropsValues.IG_IMAGE_CUSTOM_1_MAX_DIMENSION);
616 }
617
618 if (custom2ImageId > 0) {
619 saveScaledImage(
620 renderedImage, custom2ImageId, contentType,
621 PropsValues.IG_IMAGE_CUSTOM_2_MAX_DIMENSION);
622 }
623 }
624 catch (IOException ioe) {
625 throw new SystemException(ioe);
626 }
627 }
628
629 protected void saveScaledImage(
630 RenderedImage renderedImage, long imageId, String contentType,
631 int dimension)
632 throws IOException, SystemException {
633
634 RenderedImage thumbnail = ImageProcessorUtil.scale(
635 renderedImage, dimension, dimension);
636
637 ByteArrayMaker bam = new ByteArrayMaker();
638
639 if (contentType.indexOf("bmp") != -1) {
640 ImageEncoder encoder = ImageCodec.createImageEncoder(
641 "BMP", bam, null);
642
643 encoder.encode(thumbnail);
644 }
645 else if (contentType.indexOf("gif") != -1) {
646 ImageProcessorUtil.encodeGIF(thumbnail, bam);
647 }
648 else if (contentType.indexOf("jpg") != -1 ||
649 contentType.indexOf("jpeg") != -1) {
650
651 ImageIO.write(thumbnail, "jpeg", bam);
652 }
653 else if (contentType.indexOf("png") != -1) {
654 ImageIO.write(thumbnail, "png", bam);
655 }
656 else if (contentType.indexOf("tif") != -1) {
657 ImageEncoder encoder = ImageCodec.createImageEncoder(
658 "TIFF", bam, null);
659
660 encoder.encode(thumbnail);
661 }
662
663 imageLocalService.updateImage(imageId, bam.toByteArray());
664 }
665
666 protected void validate(byte[] bytes)
667 throws ImageSizeException, SystemException {
668
669 if ((PrefsPropsUtil.getLong(PropsKeys.IG_IMAGE_MAX_SIZE) > 0) &&
670 ((bytes == null) ||
671 (bytes.length >
672 PrefsPropsUtil.getLong(PropsKeys.IG_IMAGE_MAX_SIZE)))) {
673
674 throw new ImageSizeException();
675 }
676 }
677
678 protected void validate(long folderId, String nameWithExtension)
679 throws PortalException, SystemException {
680
681 if ((nameWithExtension.indexOf("\\\\") != -1) ||
682 (nameWithExtension.indexOf("//") != -1) ||
683 (nameWithExtension.indexOf(":") != -1) ||
684 (nameWithExtension.indexOf("*") != -1) ||
685 (nameWithExtension.indexOf("?") != -1) ||
686 (nameWithExtension.indexOf("\"") != -1) ||
687 (nameWithExtension.indexOf("<") != -1) ||
688 (nameWithExtension.indexOf(">") != -1) ||
689 (nameWithExtension.indexOf("|") != -1) ||
690 (nameWithExtension.indexOf("&") != -1) ||
691 (nameWithExtension.indexOf("[") != -1) ||
692 (nameWithExtension.indexOf("]") != -1) ||
693 (nameWithExtension.indexOf("'") != -1)) {
694
695 throw new ImageNameException();
696 }
697
698 boolean validImageExtension = false;
699
700 String[] imageExtensions = PrefsPropsUtil.getStringArray(
701 PropsKeys.IG_IMAGE_EXTENSIONS, StringPool.COMMA);
702
703 for (int i = 0; i < imageExtensions.length; i++) {
704 if (StringPool.STAR.equals(imageExtensions[i]) ||
705 StringUtil.endsWith(nameWithExtension, imageExtensions[i])) {
706
707 validImageExtension = true;
708
709 break;
710 }
711 }
712
713 if (!validImageExtension) {
714 throw new ImageNameException();
715 }
716
717 String name = FileUtil.stripExtension(nameWithExtension);
718 String imageType = FileUtil.getExtension(nameWithExtension);
719
720 List<IGImage> images = igImagePersistence.findByF_N(folderId, name);
721
722 if (imageType.equals("jpeg")) {
723 imageType = ImageProcessor.TYPE_JPEG;
724 }
725 else if (imageType.equals("tif")) {
726 imageType = ImageProcessor.TYPE_TIFF;
727 }
728
729 for (IGImage image : images) {
730 if (imageType.equals(image.getImageType())) {
731 throw new DuplicateImageNameException();
732 }
733 }
734 }
735
736 protected void validate(
737 long folderId, String nameWithExtension, File file, byte[] bytes)
738 throws PortalException, SystemException {
739
740 if (file != null) {
741 String fileName = file.getName();
742 String extension = FileUtil.getExtension(fileName);
743
744 if (Validator.isNull(nameWithExtension)) {
745 nameWithExtension = fileName;
746 }
747 else if (!StringUtil.endsWith(nameWithExtension, extension)) {
748 throw new ImageNameException();
749 }
750 }
751
752 validate(folderId, nameWithExtension);
753 validate(bytes);
754 }
755
756 private static Log _log =
757 LogFactoryUtil.getLog(IGImageLocalServiceImpl.class);
758
759 }