Java tutorial
/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.portal.image; import java.awt.image.BufferedImage; import java.io.File; import java.util.concurrent.locks.Lock; import org.apache.commons.codec.digest.DigestUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.google.common.base.Preconditions; import com.enonic.cms.framework.blob.BlobKey; import com.enonic.cms.framework.blob.BlobRecord; import com.enonic.cms.framework.blob.BlobStore; import com.enonic.cms.framework.util.GenericConcurrencyLock; import com.enonic.cms.framework.util.ImageHelper; import com.enonic.cms.core.content.access.ContentAccessResolver; import com.enonic.cms.core.content.binary.AttachmentNotFoundException; import com.enonic.cms.core.content.binary.BinaryDataEntity; import com.enonic.cms.core.image.ImageRequest; import com.enonic.cms.core.image.ImageResponse; import com.enonic.cms.core.image.cache.ImageCache; import com.enonic.cms.core.portal.livetrace.ImageRequestTrace; import com.enonic.cms.core.portal.livetrace.ImageRequestTracer; import com.enonic.cms.core.portal.livetrace.LivePortalTraceService; import com.enonic.cms.core.preview.PreviewService; import com.enonic.cms.core.security.user.UserEntity; import com.enonic.cms.core.security.user.UserKey; import com.enonic.cms.core.time.TimeService; import com.enonic.cms.store.dao.ContentDao; import com.enonic.cms.store.dao.GroupDao; import com.enonic.cms.store.dao.UserDao; @Service public final class ImageServiceImpl implements ImageService { private static final Logger LOG = LoggerFactory.getLogger(ImageServiceImpl.class); private ImageCache imageCache; private final ImageProcessor processor; private ContentDao contentDao; private GroupDao groupDao; private UserDao userDao; private BlobStore blobStore; private TimeService timeService; private PreviewService previewService; @Autowired private LivePortalTraceService livePortalTraceService; private static GenericConcurrencyLock<String> concurrencyLock = GenericConcurrencyLock.create(); private File directory; public ImageServiceImpl() { this.processor = new ImageProcessor(); } public boolean accessibleInPortal(ImageRequest req) { ImageRequestAccessResolver imageRequestAccessResolver = new ImageRequestAccessResolver(contentDao, new ContentAccessResolver(groupDao)); imageRequestAccessResolver.imageRequester(userDao.findByKey(req.getRequester().getKey())); imageRequestAccessResolver.requireMainVersion(); imageRequestAccessResolver.requireOnlineNow(timeService.getNowAsDateTime(), previewService); ImageRequestAccessResolver.Access access = imageRequestAccessResolver.isAccessible(req); return access == ImageRequestAccessResolver.Access.OK; } public ImageResponse process(ImageRequest imageRequest) { Preconditions.checkNotNull(imageRequest, "imageRequest cannot be null"); final ImageRequestTrace imageRequestTrace = livePortalTraceService.getCurrentTrace().getImageRequestTrace(); String blobKey = getBlobKey(imageRequest); if (blobKey == null) { return ImageResponse.notFound(); } imageRequest.setBlobKey(blobKey); final Lock locker = concurrencyLock.getLock(imageRequest.getCacheKey()); try { ImageRequestTracer.startConcurrencyBlockTimer(imageRequestTrace); locker.lock(); ImageRequestTracer.stopConcurrencyBlockTimer(imageRequestTrace); ImageResponse res = imageCache.get(imageRequest); if (res != null) { ImageRequestTracer.traceImageResponse(imageRequestTrace, res); ImageRequestTracer.traceUsedCachedResult(imageRequestTrace, true); return res; } try { res = doProcess(imageRequest); ImageRequestTracer.traceImageResponse(imageRequestTrace, res); ImageRequestTracer.traceUsedCachedResult(imageRequestTrace, false); return res; } catch (AttachmentNotFoundException e) { LOG.error( "Cannot read image with key {} from configured BLOB directory ( {} ). Check your CMS configuration.", blobKey, directory.getAbsolutePath()); return ImageResponse.notFound(); } catch (Exception e) { throw new ImageProcessorException("Failed to process image [contentKey=" + imageRequest.getContentKey() + "] : " + e.getMessage(), e); } } finally { locker.unlock(); } } public Long getImageTimestamp(final ImageRequest req) { final UserKey userKey = req.getUserKey(); if (userKey != null) { final UserEntity user = this.userDao.findByKey(userKey.toString()); if (user != null) { return user.getTimestamp().getMillis(); } return null; } final BinaryDataEntity binaryData = new BinaryDataForImageRequestResolver(contentDao) .resolveBinaryData(req); if (binaryData == null) { throw new ImageProcessorException( "Image not found (Content key = " + req.getContentKey().toString() + ")", null); } return binaryData.getCreatedAt().getTime(); } private String getBlobKey(ImageRequest req) { if (req.getUserKey() != null) { return getBlobKeyForUser(req.getUserKey()); } BinaryDataEntity binaryData = new BinaryDataForImageRequestResolver(contentDao).resolveBinaryData(req); if (binaryData == null) { return null; } req.setBinaryDataKey(binaryData.getBinaryDataKey()); return binaryData.getBlobKey(); } private String getBlobKeyForUser(UserKey key) { UserEntity entity = this.userDao.findByKey(key.toString()); if (entity == null) { return null; } byte[] photo = entity.getPhoto(); if (photo == null) { return null; } return DigestUtils.shaHex(photo); } private byte[] fetchImage(ImageRequest req) { if (req.getUserKey() != null) { UserEntity entity = this.userDao.findByKey(req.getUserKey().toString()); if (entity == null) { return null; } return entity.getPhoto(); } BlobRecord binary = this.blobStore.getRecord(new BlobKey(req.getBlobKey())); if (binary == null) { throw AttachmentNotFoundException.notFound(req.getBlobKey()); } return binary.getAsBytes(); } private ImageResponse doProcess(ImageRequest req) throws Exception { byte[] bytes = fetchImage(req); BufferedImage image = ImageHelper.readImage(bytes); ImageResponse imageResponse = processor.process(req, image); imageCache.put(req, imageResponse); return imageResponse; } @Autowired public void setImageCache(ImageCache imageCache) { this.imageCache = imageCache; } @Autowired public void setContentDao(ContentDao contentDao) { this.contentDao = contentDao; } @Autowired public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Autowired public void setBlobStore(BlobStore blobStore) { this.blobStore = blobStore; } @Autowired public void setTimeService(TimeService timeService) { this.timeService = timeService; } @Autowired public void setPreviewService(PreviewService previewService) { this.previewService = previewService; } @Autowired public void setGroupDao(GroupDao groupDao) { this.groupDao = groupDao; } @Value("${cms.blobstore.dir}") public void setDirectory(File directory) { this.directory = directory; } }