Codeverbesserungen, Dokumentation, Prefetch von Bildern in Originalgröße konfigurierbar gemacht.

git-svn-id: https://svn.libreccm.org/ccm/trunk@1837 8810af33-2d31-482b-a856-94f89814c4df
master
quasi 2012-08-28 10:56:17 +00:00
parent 16636b8d43
commit 3ffa2d01cc
5 changed files with 263 additions and 172 deletions

View File

@ -511,7 +511,7 @@ public final class CMSConfig extends AbstractConfig {
// ///////////////////////////////////////////
// Content Section config related parameters
// ///////////////////////////////////////////
// Nolonger used,
// Nolonger used,
// replaced by c.ad.cms.ContentSection.getDefaultSection().getName()
// private final Parameter m_defaultSection = new StringParameter(
// "com.arsdigita.cms.default_content_section",
@ -546,12 +546,12 @@ public final class CMSConfig extends AbstractConfig {
// private final Parameter m_itemSearchFlatBrowsePaneEnable = new BooleanParameter(
// "com.arsdigita.cms.item_search.flat_browse_pane.enable",
// Parameter.REQUIRED,
// true);
// true);
private final Parameter m_itemSearchFlatBrowsePanePageSize = new IntegerParameter(
"com.arsdigita.cms.item_search.flat_browse_pane.page_size",
Parameter.REQUIRED,
20);
/////////////////////////////////////////////
// FolderBrowse
/////////////////////////////////////////////
@ -567,7 +567,7 @@ public final class CMSConfig extends AbstractConfig {
Parameter.REQUIRED,
100);
//////////////////////////////////////////////
//If set to true the old style ItemLifecycleItemPane (allows you to
//If set to true the old style ItemLifecycleItemPane (allows you to
//republish and withdraw items) is used. Otherwise the new style form is
//used, which is more secure against wrong clicks.
//////////////////////////////////////////////
@ -577,9 +577,9 @@ public final class CMSConfig extends AbstractConfig {
Parameter.REQUIRED,
false);
////////////////////////////////////////////////
//Actives threaded publishing. If active, the publish process for
//Actives threaded publishing. If active, the publish process for
//content items will run in a separate thread. May useful if you have
//large objects.
//large objects.
////////////////////////////////////////////////////
private final Parameter m_threadPublishing = new BooleanParameter(
"com.arsdigita.cms.lifecycle.threaded_publishing",
@ -604,15 +604,19 @@ public final class CMSConfig extends AbstractConfig {
private final Parameter m_imageBrowserThumbnailMaxHeight = new IntegerParameter(
"com.arsdigita.cms.image_browser.thumbnail_max_height",
Parameter.REQUIRED,
50);
50);
/////////////////////////////////////////////////
// ImageCache Parameter
/////////////////////////////////////////////////
private final Parameter m_imageCache = new BooleanParameter(
private final Parameter m_imageCacheEnabled = new BooleanParameter(
"com.arsdigita.cms.image_cache.enable",
Parameter.REQUIRED,
true);
private final Parameter m_imageCachePrefetchEnabled = new BooleanParameter(
"com.arsdigita.cms.image_cache.prefetch_enable",
Parameter.REQUIRED,
false);
private final Parameter m_imageCacheMaxSize = new IntegerParameter(
"com.arsdigita.cms.image_cache.max_size",
Parameter.REQUIRED,
@ -620,16 +624,16 @@ public final class CMSConfig extends AbstractConfig {
private final Parameter m_imageCacheMaxAge = new IntegerParameter(
"com.arsdigita.cms.image_cache.max_age",
Parameter.REQUIRED,
300);
300);
// ///////////////////////////////////////////
// publishToFile package related parameter
// ///////////////////////////////////////////
// Moved to publishToFile.PublishToFileConfig as of version 6.0.2
// private final Parameter m_disableItemPfs;
// private final Parameter m_publishToFileClass;
/**
* Constructor, but do NOT instantiate this class directly.
*
@ -690,7 +694,7 @@ public final class CMSConfig extends AbstractConfig {
register(m_hideTextAssetUploadFile);
register(m_allowCategoryCreateUseContext);
register(m_allowContentCreateInSectionListing);
register(m_hideLegacyPublicSiteLink);
register(m_hideLegacyPublicSiteLink);
// Content Center (Workspace) config related parameters
register(m_contentCenterMap);
@ -715,9 +719,10 @@ public final class CMSConfig extends AbstractConfig {
// ImageBrowser
register(m_imageBrowserThumbnailMaxWidth);
register(m_imageBrowserThumbnailMaxHeight);
// ImageCache Parameter
register(m_imageCache);
register(m_imageCacheEnabled);
register(m_imageCachePrefetchEnabled);
register(m_imageCacheMaxSize);
register(m_imageCacheMaxAge);
@ -726,9 +731,9 @@ public final class CMSConfig extends AbstractConfig {
// register(m_disableItemPfs);
// register(m_publishToFileClass);
// register(m_itemSearchFlatBrowsePaneEnable);
// register(m_itemSearchFlatBrowsePaneEnable);
register(m_itemSearchFlatBrowsePanePageSize);
loadInfo();
}
@ -945,7 +950,7 @@ public final class CMSConfig extends AbstractConfig {
}
// Store class reference so it can be recreated for each page.
// This requires a fix to all components using extraXMLGenerators,
// for example see the currently only one in core/cms: GreetingItemExtraXML
// for example see the currently only one in core/cms: GreetingItemExtraXML
gens.add(gen.getClass()); // XXX assumes default ctor
}
@ -1115,8 +1120,8 @@ public final class CMSConfig extends AbstractConfig {
}
/**
* Retrieve whether to allow creation of a new Use Context in category tab
* of content sections. "Use Context" is used to constitute a category
* Retrieve whether to allow creation of a new Use Context in category tab
* of content sections. "Use Context" is used to constitute a category
* hierarchy in core. It is superseded by the construct "Category Domain"
* in Terms (ccm-ldn-terms).
* Global parameter for all content sections. Default is false because all
@ -1176,9 +1181,13 @@ public final class CMSConfig extends AbstractConfig {
public Integer getImageBrowserThumbnailMaxHeight() {
return (Integer) get(m_imageBrowserThumbnailMaxHeight);
}
public Boolean getImageCacheEnable() {
return (Boolean) get(m_imageCache);
public Boolean getImageCacheEnabled() {
return (Boolean) get(m_imageCacheEnabled);
}
public Boolean getImageCachePrefetchEnabled() {
return (Boolean) get(m_imageCachePrefetchEnabled);
}
public Integer getImageCacheMaxSize() {
@ -1188,11 +1197,11 @@ public final class CMSConfig extends AbstractConfig {
public Integer getImageCacheMaxAge() {
return (Integer) get(m_imageCacheMaxAge);
}
// public Boolean getItemSearchFlatBrowsePaneEnable() {
// return (Boolean) get(m_itemSearchFlatBrowsePaneEnable);
// }
public Integer getItemSearchFlatBrowsePanePageSize() {
return (Integer) get(m_itemSearchFlatBrowsePanePageSize);
}

View File

@ -86,7 +86,7 @@ com.arsdigita.cms.hide_udct_ui.format=[boolean]
com.arsdigita.cms.dhtml_editor_config.title=DHTML Editor Configuration
com.arsdigita.cms.dhtml_editor_config.purpose=LIsts the config object name and Javascript source location for its definition
com.arsdigita.cms.dhtml_editor_config.example=HTMLArea.Config.CMSStyled,/assets/htmlarea/config/Styled.js
com.arsdigita.cms.dhtml_editor_config.example=HTMLArea.Config.CMSStyled,/assets/htmlarea/config/Styled.js
com.arsdigita.cms.dhtml_editor_config.format=[string]
com.arsdigita.cms.dhtml_editor_plugins.title=DHTML Editor Plugins
@ -94,7 +94,7 @@ com.arsdigita.cms.dhtml_editor_plugins.purpose=Defines which plugins to use
com.arsdigita.cms.dhtml_editor_plugins.example=TableOperations,CSS
com.arsdigita.cms.dhtml_editor_plugins.format=[string,string,string]
com.arsdigita.cms.dhtml_editor_hidden_buttons.title=DHTML Editor buttons to hide
com.arsdigita.cms.dhtml_editor_hidden_buttons.title=DHTML Editor buttons to hide
com.arsdigita.cms.dhtml_editor_hidden_buttons.purpose=Prevent undesirable functions from being made available, eg images should only be added through the cms, not the html area
com.arsdigita.cms.dhtml_editor_hidden_buttons.example=insertimage
com.arsdigita.cms.dhtml_editor_hidden_buttons.format=[string,string,string]
@ -119,7 +119,7 @@ com.arsdigita.cms.save_text_cleans_word_tags.purpose=Wether the Wysiwyg editor s
com.arsdigita.cms.save_text_cleans_word_tags.example=false
com.arsdigita.cms.save_text_cleans_word_tags.format=[boolean]
com.arsdigita.cms.contentassets.ui.RelatedLinkPropertyForm.hideAdditionalResourceFields.title=Hide Additional Resource Fields
com.arsdigita.cms.contentassets.ui.RelatedLinkPropertyForm.hideAdditionalResourceFields.title=Hide Additional Resource Fields
com.arsdigita.cms.contentassets.ui.RelatedLinkPropertyForm.hideAdditionalResourceFields.purpose=Hide Additional Resource Fields on RelatedLinkPropertyForm
com.arsdigita.cms.contentassets.ui.RelatedLinkPropertyForm.hideAdditionalResourceFields.example=false
com.arsdigita.cms.contentassets.ui.RelatedLinkPropertyForm.hideAdditionalResourceFields.format=[boolean]
@ -271,7 +271,7 @@ com.arsdigita.cms.lifecycle.use_old_style_item_lifecycle_item_pane.example = fal
com.arsdigita.cms.lifecycle.use_old_style_item_lifecycle_item_pane.format = [Boolean]
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.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]
@ -300,6 +300,11 @@ com.arsdigita.cms.image_cache.enable.purpose=Enable server-side coherent image c
com.arsdigita.cms.image_cache.enable.example=true|false
com.arsdigita.cms.image_cache.enable.format=[boolean]
com.arsdigita.cms.image_cache.prefetch_enable.title=Enable prefetching image cache
com.arsdigita.cms.image_cache.prefetch_enable.purpose=Enable image cache to store original sized images for resized images. This will need lots of RAM and you probably won't see a difference.
com.arsdigita.cms.image_cache.prefetch_enable.example=true|false
com.arsdigita.cms.image_cache.prefetch_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

View File

@ -11,15 +11,16 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import javax.imageio.ImageIO;
import org.apache.log4j.Logger;
import org.imgscalr.Scalr;
import org.imgscalr.Scalr.*;
/**
* This is an in-memory copy of an {@link ImageAsset} to be stored in the image
* cache of {@link BaseImage}. Also, this class is able to create server-side
* resized versions of ImageAssets.
*
* @author Sören Bernstein (quasimodo) <sbernstein@zes.uni-bremen.de>
*/
@ -34,11 +35,23 @@ public class CachedImage {
private BigDecimal height;
private static final Logger s_log = Logger.getLogger(CachedImage.class);
public CachedImage(ImageAsset imageAsset, int width, int height) {
/**
* Create a resized version of an ImageAsset for dispatching
*
* @param imageAsset the ImageAsset to save
* @param maxWidth the max width to resize the image to
* @param maxHeight the max height to resize the image to
*/
public CachedImage(ImageAsset imageAsset, int maxWidth, int maxHeight) {
this(imageAsset);
this.resizeImage(width, height);
this.resizeImage(maxWidth, maxHeight);
}
/**
* Create a original size version of an ImageAsset for dispatching
*
* @param imageAsset The ImageAsset to save
*/
public CachedImage(ImageAsset imageAsset) {
this.hash = imageAsset.getOID().toString();
@ -50,11 +63,20 @@ public class CachedImage {
this.height = imageAsset.getHeight();
}
/**
* Create a resized version of another CachedImage. This is a convienience
* constructor to handle the maxWidth and maxHeight param in a single
* String.
*
* @param cachedImage the cachedImage to resize
* @param resizeParam the resize paramter as
* "&maxWidth=<int>&maxHeight=<int>"
*/
public CachedImage(CachedImage cachedImage, String resizeParam) {
this(cachedImage);
int width = 0;
int height = 0;
int maxWidth = 0;
int maxHeight = 0;
String[] params = resizeParam.split("&");
for (int i = 0; i < params.length; i++) {
@ -65,23 +87,35 @@ public class CachedImage {
String key = params[i].substring(0, params[i].indexOf("="));
String value = params[i].substring(params[i].indexOf("=") + 1);
if (key.equalsIgnoreCase("width")) {
width = Integer.parseInt(value);
if (key.equalsIgnoreCase("maxWidth")) {
maxWidth = Integer.parseInt(value);
}
if (key.equalsIgnoreCase("height")) {
height = Integer.parseInt(value);
if (key.equalsIgnoreCase("maxHeight")) {
maxHeight = Integer.parseInt(value);
}
}
this.resizeImage(width, height);
this.resizeImage(maxWidth, maxHeight);
}
public CachedImage(CachedImage cachedImage, int width, int height) {
/**
* Create a resized version aof another CacheImage.
*
* @param cachedImage the CachedImage to resize
* @param maxWidth max width of the image after resizing
* @param height max height of the image after resizing
*/
public CachedImage(CachedImage cachedImage, int maxWidth, int height) {
this(cachedImage);
this.resizeImage(width, height);
this.resizeImage(maxWidth, height);
}
/**
* This is just for internal use to set all the fields.
*
* @param cachedImage the CacheImage
*/
private CachedImage(CachedImage cachedImage) {
this.hash = cachedImage.hash;
this.name = cachedImage.getName();
@ -92,61 +126,79 @@ public class CachedImage {
this.height = cachedImage.getHeight();
}
/**
* Get filename
*
* @return the filename
*/
public String getName() {
return this.name;
}
/**
* Get actual width of this instance
*
* @return image width
*/
public BigDecimal getWidth() {
return this.width;
}
/**
* Get actual height of this instance
*
* @return image height
*/
public BigDecimal getHeight() {
return this.height;
}
/**
* Get actual size of this instance
*
* @return image size
*/
public int getSize() {
return this.image.length;
}
/**
* Get version (aka live of draft)
*/
public String getVersion() {
return this.version;
}
/**
* Get {@link MimeType}
*
* @return the {@MimeType}
*/
public MimeType getMimeType() {
return this.mimetype;
}
/**
* Get the image data
*
* @return the image data
*/
public byte[] getImage() {
return this.image;
}
/**
* Retrieves the Blob content.
* Write the image to an OutputStream
*
* @return the Blob content
* @param os OutputStream to be written to
*
* @return number of bytes written
*
* @throws IOException
*/
/*
protected byte[] getContent() {
byte[] content = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
ImageIO.write(image, "JPEG", out);
content = out.toByteArray();
} catch (IOException ioEx) {
s_log.warn("Could not write byte array", ioEx);
} catch (IllegalArgumentException illEx) {
s_log.warn("image is not initialized", illEx);
} finally {
return content;
}
}
*/
public long writeBytes(OutputStream os) throws IOException {
byte[] bytes = this.getImage();
os.write(bytes);
return (long) (bytes.length);
os.write(this.getImage());
return (long) (this.getSize());
}
/**
@ -154,8 +206,7 @@ public class CachedImage {
*
* @param file The file on the server to write to.
*/
public void writeToFile(File file)
throws IOException {
public void writeToFile(File file) throws IOException {
FileOutputStream fs = new FileOutputStream(file);
try {
fs.write(this.getImage());
@ -167,6 +218,16 @@ public class CachedImage {
}
}
/**
* Method to proportional resize an image into the defined boundaries.
* Either width or height can be 0.
* If height is 0, the image will be fit to width.
* If width is 0, the image will be fit to height.
* If both paramters are 0, this method will not do anything.
*
* @param width max width of the image after resizing
* @param height max height of the image after resizing
*/
private void resizeImage(int width, int height) {
// No valid resizing imformation
@ -182,7 +243,7 @@ public class CachedImage {
} catch (IOException ioEx) {
s_log.warn("Could not read image", ioEx);
}
// Resize image with imagescalr
if (width > 0 && height > 0) {
bufferedImage = Scalr.resize(bufferedImage, Scalr.Method.QUALITY, width, height);
@ -197,9 +258,9 @@ public class CachedImage {
// Set Dimensions
this.width = new BigDecimal(bufferedImage.getWidth());
this.height = new BigDecimal(bufferedImage.getHeight());
this.hash = this.hash + "&width=" + this.width + "&height=" + this.height;
// Write BufferedImage to byte array
ByteArrayOutputStream out = new ByteArrayOutputStream();
@ -217,5 +278,19 @@ public class CachedImage {
public int hashCode() {
return this.hash.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final CachedImage other = (CachedImage) obj;
if ((this.hash == null) ? (other.hash != null) : !this.hash.equals(other.hash)) {
return false;
}
return true;
}
}

View File

@ -22,8 +22,8 @@ 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.cms.ImageAsset;
import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.dispatcher.RequestContext;
import com.arsdigita.domain.DataObjectNotFoundException;
@ -31,21 +31,24 @@ import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.mimetypes.MimeType;
import com.arsdigita.persistence.OID;
import com.arsdigita.toolbox.ui.OIDParameter;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
/**
* A resource handler which streams out a blob from the database.
* This class can use a special image cache to speed up image dispatching. Also,
* during dispatch this class will create server-side resized images depending
* on the URL parameter. Resizing is done by ImageScalr. The image cahce can be
* activated and configured by com.arsdigita.cms.image_cache.* parameters.
*
* @author Stanislav Freidin (sfreidin@arsdigita.com)
* @author Michael Pih (pihman@arsdigita.com)
* @author Sören Bernstein <sbernstein@zes.uni-bremen.de>
* @version $Revision: #20 $ $DateTime: 2004/08/17 23:15:09 $
* @version $Id: BaseImage.java 1571 2007-04-20 15:57:54Z apevec $
*/
@ -62,12 +65,13 @@ public class BaseImage extends ResourceHandlerImpl {
private static CacheTable s_imageCache = null;
static {
if (CMS.getConfig().getImageCacheEnable()) {
if (CMS.getConfig().getImageCacheEnabled()) {
s_imageCache = new CacheTable("BaseImageCache",
CMS.getConfig().getImageCacheMaxAge(),
CMS.getConfig().getImageCacheMaxSize());
}
}
private final bool IMAGE_CACHE_PREFETCH = CMS.getConfig().getImageCachePrefetchEnabled();
private static final Logger s_log = Logger.getLogger(BaseImage.class);
/**
@ -142,9 +146,9 @@ public class BaseImage extends ResourceHandlerImpl {
/**
* Streams an image from the database.
*
* @param request The servlet request object
* @param request The servlet request object
* @param response the servlet response object
* @param actx The request context
* @param actx The request context
*/
@Override
public void dispatch(HttpServletRequest request,
@ -158,8 +162,8 @@ public class BaseImage extends ResourceHandlerImpl {
String resizeParam = "";
// Get URL parameters
String widthParam = request.getParameter("width");
String heightParam = request.getParameter("height");
String maxWidthParam = request.getParameter("maxWidth");
String maxHeightParam = request.getParameter("maxHeight");
// Need the OID, but can work with imageId
try {
@ -185,114 +189,56 @@ public class BaseImage extends ResourceHandlerImpl {
// Finally, we have a valid OID
// Process URL parameter
if (widthParam != null && heightParam != null) {
if (maxWidthParam != null && maxHeightParam != null) {
try {
// Set width
if (!widthParam.isEmpty() && widthParam.matches("^[0-9]*$")) {
resizeParam += "&width=" + widthParam;
// Set width if supplied by URL parameter
if (!maxWidthParam.isEmpty() && maxWidthParam.matches("^[0-9]*$")) {
resizeParam += "&maxWidth=" + maxWidthParam;
}
} catch (NumberFormatException numberEx) {
s_log.warn("width parameter invalid " + widthParam);
s_log.warn("maxWidth parameter invalid " + maxWidthParam);
}
try {
// Set height
if (!heightParam.isEmpty() && heightParam.matches("^[0-9]*$")) {
resizeParam += "&height=" + heightParam;
// Set height if supplied by URL parameter
if (!maxHeightParam.isEmpty() && maxHeightParam.matches("^[0-9]*$")) {
resizeParam += "&maxHeight=" + maxHeightParam;
}
} catch (NumberFormatException numberEx) {
s_log.warn("height parameter invalid " + heightParam);
s_log.warn("maxHeight parameter invalid " + maxHeightParam);
}
}
// Now, we have all information we need to proceed
if (!resizeParam.isEmpty()) {
// Try to get the CachedImage with the OID from the imageCache
cachedImage = (CachedImage) s_imageCache.get(oid.toString() + resizeParam);
// If cachedImage is still null, the resized version of this oid is
// not in the cache. So, we try to find the original version to
// avoid unnesseccary database access
if (cachedImage == null) {
// Get the original version
cachedImage = (CachedImage) s_imageCache.get(oid.toString());
// If cachedImage is still null, it is not in the imageCache
if (cachedImage == null) {
// Get it from the database
cachedImage = this.getImageAssetFromDB(response, oid);
// If cachedImage is still null, we can't find the oid in the DB either
// There is something broken. Bail out.
if (cachedImage == null) {
return;
}
// Put the CachedImage into the imageCache
s_imageCache.put(oid.toString(), cachedImage);
}
// 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 {
// Try to get the CachedImage with the OID from the imageCache
cachedImage = (CachedImage) (s_imageCache.get(oid.toString()));
// If cachedImage is still null, it is not in the imageCache
if (cachedImage == null) {
// Get it from the database
cachedImage = this.getImageAssetFromDB(response, oid);
// If cachedImage is still null, we can't find the oid in the DB either
// There is something broken. Bail out.
if (cachedImage == null) {
return;
}
}
// Put the CacheImageAsset into the imageCache
s_imageCache.put(oid.toString(), cachedImage);
// Get the image
cachedImage = this.getImage(response, oid, resizeParam);
if (cachedImage == null) {
// ok, something is really weird now. Can't find image with this oid. Bailing out.
return;
}
setHeaders(response, cachedImage);
send(response, cachedImage);
}
private CachedImage getCachedImage(HttpServletResponse response, OID oid, String resizeParam) throws IOException {
private CachedImage getImage(HttpServletResponse response, OID oid, String resizeParam) throws IOException {
CachedImage cachedImage = null;
// Test for cache
if (s_imageCache != null) {
cachedImage = (CachedImage) s_imageCache.get(oid.toString() + resizeParam);
if (cachedImage == null) {
// Image cache is enabled, try to fetch images from cache
cachedImage = getImageFromCache(response, oid, resizeParam);
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);
// Image cache is disabled
// Get the original image from db
cachedImage = getImageFromDB(response, oid);
if (cachedImage != null && !resizeParam.isEmpty()) {
cachedImage = new CachedImage(cachedImage, resizeParam);
}
@ -301,7 +247,61 @@ public class BaseImage extends ResourceHandlerImpl {
return cachedImage;
}
private CachedImage getImageAssetFromDB(HttpServletResponse response, OID oid) throws IOException {
/**
* Fetches the {@link CachedImage} from the image cache. If tge object
* could not be found in the cache, this method falls back to
* {@link #getImageFromDB(javax.servlet.http.HttpServletResponse, com.arsdigita.persistence.OID)}.
* This method will also store the CachedImage in the image cache for future
* use.
*
* @param response The HttpServletResponse
* @param oid the {@link OID} of the wanted object
* @param resizeParam the resize paramters of the wanted object
* @return the wanted {@link CachedImage} in the correct size or null, if the object could not be found
* @throws IOException
*/
private CachedImage getImageFromCache(HttpServletResponse response, OID oid, String resizeParam) throws IOException {
CachedImage cachedImage;
cachedImage = (CachedImage) s_imageCache.get(oid.toString() + resizeParam);
// If we coundn't find the specific version
if (cachedImage == null) {
// If we were looking for a resized version
if (!resizeParam.isEmpty()) {
// try to find the original version in the cache by recursion
cachedImage = this.getImageFromCache(response, oid, "");
if (cachedImage != null) {
cachedImage = new CachedImage(cachedImage, resizeParam);
s_imageCache.put(oid.toString() + resizeParam, cachedImage);
}
} else {
// look for the original version in the database
cachedImage = getImageFromDB(response, oid);
// If we found the image, put it into the image cache
if (cachedImage != null && IMAGE_CACHE_PREFETCH) {
s_imageCache.put(oid.toString(), cachedImage);
}
}
}
return cachedImage;
}
/**
* Fetches the {@link ImageAsset} with the supplied {@link OID} from the database
* and converts it to a {@CachedImage}.
*
* @param response the HttpServletResponse
* @param oid the {@link OID} to the ImageAsset
* @return the ImageAsset with the oid as CachedImage or null, if not found
* @throws IOException
*/
private CachedImage getImageFromDB(HttpServletResponse response, OID oid) throws IOException {
ImageAsset imageAsset = null;
@ -311,6 +311,7 @@ public class BaseImage extends ResourceHandlerImpl {
try {
Asset a = (Asset) DomainObjectFactory.newInstance(oid);
// Make sure we have an ImageAsset
if (a instanceof ImageAsset) {
imageAsset = (ImageAsset) a;
} else {
@ -319,8 +320,7 @@ public class BaseImage extends ResourceHandlerImpl {
}
}
} catch (DataObjectNotFoundException nfe) {
response.sendError(HttpServletResponse.SC_NOT_FOUND,
"no ImageAsset with oid " + oid);
response.sendError(HttpServletResponse.SC_NOT_FOUND, "no ImageAsset with oid " + oid);
return null;
}

View File

@ -83,7 +83,7 @@ public class ImageBrowser extends Table {
* Construct a new ImageBrowser with default mode.
*
* @param builder the {@link ImageBrowserModelBuilder} that will supply this
* component with its {@link ImageBrowserModel} during each request
* component with its {@link ImageBrowserModel} during each request
*/
public ImageBrowser(ImageBrowserModelBuilder b) {
@ -94,14 +94,14 @@ public class ImageBrowser extends Table {
* Construct a new ImageBrowser with requested mode.
*
* @param builder the {@link ImageBrowserModelBuilder} that will supply this
* component with its {@link ImageBrowserModel} during each request
* @param mode the component mode (see {@link ImageComponent})
* component with its {@link ImageBrowserModel} during each request
* @param mode the component mode (see {@link ImageComponent})
*/
public ImageBrowser(ImageBrowserModelBuilder b, int mode) {
super(new BuilderAdapter(b), HEADERS);
m_mode = mode;
setThumbnailSize(CMS.getConfig().getImageBrowserThumbnailMaxWidth(),
CMS.getConfig().getImageBrowserThumbnailMaxHeight());
CMS.getConfig().getImageBrowserThumbnailMaxHeight());
m_builder = b;
getHeader().setDefaultRenderer(new DefaultTableCellRenderer(false));
@ -123,9 +123,9 @@ public class ImageBrowser extends Table {
}
public int getNumColumns() {
return m_numColumns;
return m_numColumns;
}
/**
* @return the size, in pixels, of the thumbnail images
*/
@ -151,6 +151,7 @@ public class ImageBrowser extends Table {
/**
* @param state The current page state
*
* @return the {@link ImageBrowserModel} used in the current request
*/
public ImageBrowserModel getImageBrowserModel(PageState state) {
@ -189,7 +190,8 @@ public class ImageBrowser extends Table {
ImageAsset a = (ImageAsset) value;
String url = Service.getImageURL(a);
String resizeParam = "&width=" + new Double(m_thumbSize.getWidth()).intValue() + "&height=" + new Double(m_thumbSize.getHeight()).intValue();
// Sets url paramter to resize the images server-side
String resizeParam = "&maxWidth=" + new Double(m_thumbSize.getWidth()).intValue() + "&maxHeight=" + new Double(m_thumbSize.getHeight()).intValue();
Image img = new Image(URL.getDispatcherPath() + url + resizeParam, a.getName());
img.setBorder("0");
@ -249,7 +251,7 @@ public class ImageBrowser extends Table {
}
}
// can delete image because it's not in use
if (canDelete) {
return super.getComponent(table, state, value, isSelected, key, row, column);
@ -293,7 +295,7 @@ public class ImageBrowser extends Table {
@Override
public int getColumnCount() {
return ((ImageBrowser)m_model).getNumColumns();
return ((ImageBrowser) m_model).getNumColumns();
// return ImageBrowser.s_numColumns;
}
@ -343,7 +345,7 @@ public class ImageBrowser extends Table {
return m.getMimeType();
case ImageBrowser.LINK:
return "select";
return "select";
case ImageBrowser.DELETE:
return "delete";