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