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