diff --git a/ccm-cms/src/com/arsdigita/cms/CMSConfig.java b/ccm-cms/src/com/arsdigita/cms/CMSConfig.java index 457d86b82..0f563cb0b 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMSConfig.java +++ b/ccm-cms/src/com/arsdigita/cms/CMSConfig.java @@ -606,6 +606,22 @@ public final class CMSConfig extends AbstractConfig { Parameter.REQUIRED, 50); + ///////////////////////////////////////////////// + // ImageCache Parameter + ///////////////////////////////////////////////// + private final Parameter m_imageCache = new BooleanParameter( + "com.arsdigita.cms.image_cache.enable", + Parameter.REQUIRED, + true); + private final Parameter m_imageCacheMaxSize = new IntegerParameter( + "com.arsdigita.cms.image_cache.max_size", + Parameter.REQUIRED, + 100); + private final Parameter m_imageCacheMaxAge = new IntegerParameter( + "com.arsdigita.cms.image_cache.max_age", + Parameter.REQUIRED, + 300); + // /////////////////////////////////////////// // publishToFile package related parameter @@ -700,6 +716,11 @@ public final class CMSConfig extends AbstractConfig { register(m_imageBrowserThumbnailMaxWidth); register(m_imageBrowserThumbnailMaxHeight); + // ImageCache Parameter + register(m_imageCache); + register(m_imageCacheMaxSize); + register(m_imageCacheMaxAge); + // publishToFile package related parameter // Moved to publishToFile.PublishToFileConfig as of version 6.0.2 // register(m_disableItemPfs); @@ -1156,6 +1177,18 @@ public final class CMSConfig extends AbstractConfig { return (Integer) get(m_imageBrowserThumbnailMaxHeight); } + public Boolean getImageCacheEnable() { + return (Boolean) get(m_imageCache); + } + + public Integer getImageCacheMaxSize() { + return (Integer) get(m_imageCacheMaxSize); + } + + public Integer getImageCacheMaxAge() { + return (Integer) get(m_imageCacheMaxAge); + } + // public Boolean getItemSearchFlatBrowsePaneEnable() { // return (Boolean) get(m_itemSearchFlatBrowsePaneEnable); // } diff --git a/ccm-cms/src/com/arsdigita/cms/CMSConfig_parameter.properties b/ccm-cms/src/com/arsdigita/cms/CMSConfig_parameter.properties index c3bdf9e51..6d8afb691 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMSConfig_parameter.properties +++ b/ccm-cms/src/com/arsdigita/cms/CMSConfig_parameter.properties @@ -273,24 +273,39 @@ com.arsdigita.cms.lifecycle.use_old_style_item_lifecycle_item_pane.format = [Boo com.arsdigita.cms.lifecycle.threaded_publishing.title = Threaded publishing com.arsdigita.cms.lifecycle.threaded_publishing.purpose = Decides if publishing is done in a thread (new behaviour) or directly (old, well tested behaviour). com.arsdigita.cms.lifecycle.threaded_publishing.example = false -com.arsdigita.cms.lifecycle.threaded_com.arsdigita.cms.lifecycle.threaded_publishingpublishing.format = [Boolean] +com.arsdigita.cms.lifecycle.threaded_com.arsdigita.cms.lifecycle.threaded_publishingpublishing.format = [boolean] cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.from.title = Publishing failed notification sender cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.from.purpose = Sender e-mail address for notificiation on error while publishing cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.from.example = webmaster@example.org -cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.from.format = [String] +cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.from.format = [string] cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.to.title = Publishing failed notification receiver cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.to.purpose = email address to send failure notifications to cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.to.example = webmaster@example.org -cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.to.format = [String] +cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.to.format = [string] com.arsdigita.cms.image_browser.thumbnail_max_width.title=Max thumbnails width for ImageBrowser -com.arsdigita.cms.image_browser.thumbnail_max_width.purpose=Set the maximum width of the thumbnail in ImageBrowserr +com.arsdigita.cms.image_browser.thumbnail_max_width.purpose=Set the maximum width of the thumbnail in ImageBrowser com.arsdigita.cms.image_browser.thumbnail_max_width.example=200 com.arsdigita.cms.image_browser.thumbnail_max_width.format=[interger] com.arsdigita.cms.image_browser.thumbnail_max_height.title=Max thumbnails height for ImageBrowser -com.arsdigita.cms.image_browser.thumbnail_max_height.purpose=Set the maximum height of the thumbnail in ImageBrowserr +com.arsdigita.cms.image_browser.thumbnail_max_height.purpose=Set the maximum height of the thumbnail in ImageBrowser com.arsdigita.cms.image_browser.thumbnail_max_height.example=150 com.arsdigita.cms.image_browser.thumbnail_max_height.format=[integer] + +com.arsdigita.cms.image_cache.enable.title=Enable server-side image cache +com.arsdigita.cms.image_cache.enable.purpose=Enable server-side coherent image cache, which will speed up server-side image resizing +com.arsdigita.cms.image_cache.enable.example=true|false +com.arsdigita.cms.image_cache.enable.format=[boolean] + +com.arsdigita.cms.image_cache.max_size.title=Image cache max elements +com.arsdigita.cms.image_cache.max_size.purpose=Max count of items in the image cache, keep this low to prevent filling your memory with unused images +com.arsdigita.cms.image_cache.max_size.example=100 +com.arsdigita.cms.image_cache.max_size.format=[integer] + +com.arsdigita.cms.image_cache.max_age.title=Image cache max age +com.arsdigita.cms.image_cache.max_age.purpose=Max unused item age in seconds, keep this low to prevent filling you memory with unsused images +com.arsdigita.cms.image_cache.max_age.example=300 +com.arsdigita.cms.image_cache.max_age.format=[integer] diff --git a/ccm-cms/src/com/arsdigita/cms/CachedImage.java b/ccm-cms/src/com/arsdigita/cms/CachedImage.java index c04b3b69e..e40c6582d 100644 --- a/ccm-cms/src/com/arsdigita/cms/CachedImage.java +++ b/ccm-cms/src/com/arsdigita/cms/CachedImage.java @@ -185,13 +185,13 @@ public class CachedImage { // Resize image with imagescalr if (width > 0 && height > 0) { - bufferedImage = Scalr.resize(bufferedImage, Scalr.Method.SPEED, width, height); + bufferedImage = Scalr.resize(bufferedImage, Scalr.Method.QUALITY, width, height); } if (width > 0 && height <= 0) { - bufferedImage = Scalr.resize(bufferedImage, Scalr.Method.SPEED, Scalr.Mode.FIT_TO_WIDTH, width); + bufferedImage = Scalr.resize(bufferedImage, Scalr.Method.QUALITY, Scalr.Mode.FIT_TO_WIDTH, width); } if (width <= 0 && height > 0) { - bufferedImage = Scalr.resize(bufferedImage, Scalr.Method.SPEED, Scalr.Mode.FIT_TO_HEIGHT, height); + bufferedImage = Scalr.resize(bufferedImage, Scalr.Method.QUALITY, Scalr.Mode.FIT_TO_HEIGHT, height); } // Set Dimensions @@ -213,6 +213,7 @@ public class CachedImage { } } + @Override public int hashCode() { return this.hash.hashCode(); } diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseImage.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseImage.java index 4273cd2bb..1475439b1 100755 --- a/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseImage.java +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseImage.java @@ -21,6 +21,7 @@ package com.arsdigita.cms.dispatcher; import com.arsdigita.bebop.parameters.BigDecimalParameter; import com.arsdigita.caching.CacheTable; import com.arsdigita.cms.Asset; +import com.arsdigita.cms.CMS; import com.arsdigita.cms.ImageAsset; import com.arsdigita.cms.CachedImage; import com.arsdigita.dispatcher.DispatcherHelper; @@ -53,21 +54,21 @@ public class BaseImage extends ResourceHandlerImpl { public static final String IMAGE_ID = "image_id"; public static final String OID_PARAM = "oid"; private final static String s_defaultName = "Image"; - // the transactionID and objectID allow us to rollback to a specific - // version of an image. If we only have a transactionID and - // the item is its own master then we can also roll it back -// public static final String TRANSACTION_ID = "transID"; -// public static final String OBJECT_ID = "objectID"; private BigDecimalParameter m_imageId; private OIDParameter m_oid; -// private BigDecimalParameter m_transactionID; -// private BigDecimalParameter m_objectID; private final boolean m_download; private String m_disposition; // ImageCache - private static CacheTable s_imageCache = new CacheTable("BaseImageCache"); - private static final Logger s_log = - Logger.getLogger(BaseImage.class); + private static CacheTable s_imageCache = null; + + static { + if (CMS.getConfig().getImageCacheEnable()) { + s_imageCache = new CacheTable("BaseImageCache", + CMS.getConfig().getImageCacheMaxAge(), + CMS.getConfig().getImageCacheMaxSize()); + } + } + private static final Logger s_log = Logger.getLogger(BaseImage.class); /** * Construct the resource handler @@ -75,8 +76,6 @@ public class BaseImage extends ResourceHandlerImpl { public BaseImage(boolean download) { m_imageId = new BigDecimalParameter(IMAGE_ID); m_oid = new OIDParameter(OID_PARAM); -// m_transactionID = new BigDecimalParameter(TRANSACTION_ID); -// m_objectID = new BigDecimalParameter(OBJECT_ID); m_download = download; if (m_download) { @@ -243,7 +242,7 @@ public class BaseImage extends ResourceHandlerImpl { cachedImage = new CachedImage(cachedImage, resizeParam); // Put the CacheImageAsset into the imageCache - s_imageCache.put(oid.toString(), cachedImage + resizeParam); + s_imageCache.put(oid.toString() + resizeParam, cachedImage); } } else { @@ -272,6 +271,36 @@ public class BaseImage extends ResourceHandlerImpl { send(response, cachedImage); } + private CachedImage getCachedImage(HttpServletResponse response, OID oid, String resizeParam) throws IOException { + + CachedImage cachedImage = null; + + if (s_imageCache != null) { + cachedImage = (CachedImage) s_imageCache.get(oid.toString() + resizeParam); + + if (cachedImage == null) { + + if (!resizeParam.isEmpty()) { + cachedImage = (CachedImage) s_imageCache.get(oid.toString()); + + // Create a resized version of the cachedImage + cachedImage = new CachedImage(cachedImage, resizeParam); + + // Put the CacheImageAsset into the imageCache + s_imageCache.put(oid.toString() + resizeParam, cachedImage); + } + } + } else { + cachedImage = getImageAssetFromDB(response, oid); + + if (cachedImage != null && !resizeParam.isEmpty()) { + cachedImage = new CachedImage(cachedImage, resizeParam); + } + } + + return cachedImage; + } + private CachedImage getImageAssetFromDB(HttpServletResponse response, OID oid) throws IOException { ImageAsset imageAsset = null;