public class ImageResizeAction extends CachedAction
An action that reads images from a source directory and resizes them to fit specified dimensions. Can optionally also watermark the images. One or more image profiles are defined in the initialisation parameters, images may then be resized to fit any of the defined profiles. Typically you will use the caching with this action so that the fairly costly resize operation is only done once for each image and profile.
Images are read from one or more image directories. Each directory is specified as a source. Typically the source directories themselves should not be open to the internet, they should only be accessible locally to the servlet. Images are retrieved using an image id, which can really be any string uniquely defining the image file. Typically it is some part or the full file name. One or more sources can be specified which translate the image id into an actual full file path for the image. This is done using regular expression matching and replacement. More complicated image file resolution requires extending this action.
In the initialisation parameters, you can specify the default profile with a parameter named defaultProfile. This defaults to null, i.e. no default profile. The profile used must be specified in the request or an error is generated. If a default profile is specified, that will be used if the request doesn't specify otherwise.
profileParamKey parameter can be used to specify which HTTP request parameter contains the profile name. This defaults to "profile".
imageIdParamKey parameter can be used to specify which HTTP request parameter contains the image id. This defaults to "imageid".
Image sources are defined using parameter names "source.sourcekey.pattern" and "source.sourcekey.replacement". The sourcekey part in the middle is replaced with any alphanumeric string identifying the source. It has no other significance except to link the two different parameters. For example, to define two different sources, you would use a total of four keys:
source.source1.pattern = ... source.source1.replacement = ... source.source2.pattern = ... source.source2.replacement = ...
The pattern is a regular expression that the image id needs to match for this source to be applicable. Replacement is a replacement string, with back references to the matching done with dollar sign and number combination. The replacement is done using default Java String.replaceAll. The result of this should be a URL to the actual image. Typically a URL to a local file but not necessarily.
Sources are tried in the order they are specified in initialisation parameters until one is found where the pattern matches and the replacement results in a URL from which an actual image can be read. It is not considered to be an error if the URL points to nothing and nothing can be read from there, in such a case the next source will simply be tried.
Image profiles are defined in a similar manner. The pattern for the parameter names is "profile.profilename.property" where profilename is substituted for the profile name and property for the property you want to define for the profile. Unlike the sources, the profile name is significant here in the sense that it is referred to with this name in the HTTP requests and the defaultProfile parameter.
Supported profile properties are width, height, crop, noextracanvas, bgcolor, quality, watermark, watermarkmode and errorimage.
Width and height specify the dimensions of the image. If either one is -1, or left undefined, then the image is scaled according to the other dimension retaining aspect ratio. You can also leave both undefined to do no scaling at all. If both are defined, the image is scaled down to fit the dimension so that it's at most their size. If noextracanvas is set to true, this is the image that is returned. Otherwise blank bars are added as needed to make the image exactly the size of the specified dimensions. These bars are black by default but can be changed to other colour with the bgcolor parameter. the returned image will have exactly those dimensions. If crop is set to true, original image is scaled and cropped so that it completely fills the specified dimensions. Otherwise the image is scaled to fit the dimensions with black bars at edges as needed. The colour of the bars can but can be changed to other colour with the bgcolor parameter, which is specified with the #XXXXXX format. Quality of the returned jpeg image can be specified with the quality parameter.
A watermark can be added by specifying the watermark image URL in the watermark parameter. The only supported watermarkmode currently is "lowerright". In the future this parameter could be used to specify other placements for the watermark.
You can also specify an error image for the profile which will be used if no source image was found, or any other error occurred while processing the image. The error image is not scaled according to the profile settings, it should be preprocessed to be exactly as it needs to be.
To change the image source resolution to something more complicated, override the init method and add an ImageSource object in the imageSources map. ImageSource is a simple interface which just transforms an image id into a URL pointing to the image. If needed, you can also override readImage to change how the image is read. You could use a custom ad-hoc URL scheme and do your own handling for that here if the image cannot be retrieved using a normal URL.
Modifier and Type | Class and Description |
---|---|
static class |
ImageResizeAction.DefaultImageMaker |
static interface |
ImageResizeAction.ImageMaker |
static class |
ImageResizeAction.ImageProfile
A data structure that holds information about the image profile.
|
static interface |
ImageResizeAction.ImageSource
A simple interface for image sources.
|
static class |
ImageResizeAction.PatternImageSource
An image source that does the image id translation using regular
expressions.
|
CachedAction.OutputProvider
Modifier and Type | Field and Description |
---|---|
protected java.lang.String |
defaultProfile |
protected boolean |
exceptionOnImageRead |
protected java.lang.String |
imageIdParamKey |
protected java.util.HashMap<java.lang.String,ImageResizeAction.ImageProfile> |
imageProfiles |
protected java.util.LinkedHashMap<java.lang.String,ImageResizeAction.ImageSource> |
imageSources |
protected java.lang.String |
profileParamKey |
cache, caching, threadPool
actionParamKey, handledActions, httpHeaders, isDefaultAction, replacements, replacementsInitialized, servletModule
engine, initScript, persistentObjects, scriptManager, startScript, stopScript
autoStart, isInitialized, isRunning, logging, loggingModule, moduleManager
Constructor and Description |
---|
ImageResizeAction() |
Modifier and Type | Method and Description |
---|---|
protected boolean |
doOutput(javax.servlet.http.HttpServletRequest req,
ModulesServlet.HttpMethod method,
java.lang.String action,
CachedAction.OutputProvider out,
User user)
Does the output that might be either cached or returned directly.
|
protected java.lang.String |
getCacheKey(javax.servlet.http.HttpServletRequest req,
ModulesServlet.HttpMethod method,
java.lang.String action)
Should return a string that uniquely identifies this request.
|
private java.util.LinkedHashMap<java.lang.String,java.lang.String> |
getCacheKeyParams(javax.servlet.http.HttpServletRequest req,
ModulesServlet.HttpMethod method,
java.lang.String action) |
java.util.Collection<Module> |
getDependencies(ModuleManager manager)
Returns all the modules this module depends on.
|
void |
init(ModuleManager manager,
java.util.HashMap<java.lang.String,java.lang.Object> settings)
Initialises the module.
|
protected java.awt.image.BufferedImage |
readImage(java.lang.String url)
Reads an image from the specified URL and returns it as a
BufferedImage.
|
protected void |
returnOutput(java.io.InputStream cacheIn,
javax.servlet.http.HttpServletResponse resp)
Writes a page read from an input stream into an HTTP servlet response.
|
void |
start(ModuleManager manager)
Starts the module.
|
void |
stop(ModuleManager manager)
Stops the module.
|
protected void |
writeImage(java.awt.image.BufferedImage img,
ImageResizeAction.ImageProfile profile,
java.io.OutputStream out)
Writes the image into the given output stream.
|
buildCacheKey, handleAction, readMetadata, writeMetadata
addHandledAction, doReplacements, handleRequest, isHandleAction, setActionParamKey, setHttpHeaders
getScriptEngine
isInitialized, isRunning, requireLogging, toString
protected boolean exceptionOnImageRead
protected java.lang.String defaultProfile
protected java.lang.String imageIdParamKey
protected java.lang.String profileParamKey
protected java.util.HashMap<java.lang.String,ImageResizeAction.ImageProfile> imageProfiles
protected java.util.LinkedHashMap<java.lang.String,ImageResizeAction.ImageSource> imageSources
public java.util.Collection<Module> getDependencies(ModuleManager manager) throws ModuleException
Module
getDependencies
in interface Module
getDependencies
in class CachedAction
manager
- The module manager handling this module.ModuleException
protected void returnOutput(java.io.InputStream cacheIn, javax.servlet.http.HttpServletResponse resp) throws java.io.IOException
CachedAction
Writes a page read from an input stream into an HTTP servlet response. The input stream might be coming from a cached file, or directly from the doOutput method if caching is not in use. In any case, the contents of it need to be written to the response object. Note that any HTTP headers must be set before writing anything else.
If you used writeMetadata in doOutput, you have to override this method and use readMetadata correspondingly to read the metadata from the start of the stream. You can then, for example, set any HTTP headers you read from the metadata. After this, you can call this super implementation which will do the rest of the stream copying.
Make absolutely certain that the input stream is closed before returning from this method. Failing to do so may cause the caching service to become locked which can then lock the whole application. It is best to put the contents in a try-finally block and then call cacheIn.close in the finally part. Do this even if you call the super implementation as your code could possibly fail before reaching that part.
returnOutput
in class CachedAction
java.io.IOException
public void init(ModuleManager manager, java.util.HashMap<java.lang.String,java.lang.Object> settings) throws ModuleException
Module
Initialises the module. After constructor, this is the first method called in the life cycle of a module. It should not perform anything time consuming or anything with notable outside side effects. It should only read the parameters and initialise the module so that it can later be started. Note that a module being initialised doesn't mean that it necessarily will ever be started.
A ModuleException may be thrown if something vital is missing from the parameters or they are not sensible. In some cases you may not want to throw an exception even if vital initialisation information is missing. If, for example, it is possible that the module is initialised in some other way between the init and the start method calls. A ModuleException may also be thrown at the start method if the module is still not initialised.
init
in interface Module
init
in class CachedAction
manager
- The module manager handling this module. You may keep a
reference to it if needed.ModuleException
public void start(ModuleManager manager) throws ModuleException
Module
start
in interface Module
start
in class CachedAction
manager
- The module manager handling this module.ModuleException
public void stop(ModuleManager manager)
Module
stop
in interface Module
stop
in class CachedAction
manager
- The module manager handling this module.protected java.awt.image.BufferedImage readImage(java.lang.String url) throws java.io.IOException
url
- The URL pointing to the image.java.io.IOException
protected void writeImage(java.awt.image.BufferedImage img, ImageResizeAction.ImageProfile profile, java.io.OutputStream out) throws java.io.IOException
img
- The image that must be written.profile
- The profile used for the image.out
- The output stream where the image is written.java.io.IOException
protected boolean doOutput(javax.servlet.http.HttpServletRequest req, ModulesServlet.HttpMethod method, java.lang.String action, CachedAction.OutputProvider out, User user) throws javax.servlet.ServletException, java.io.IOException
CachedAction
Does the output that might be either cached or returned directly. The OutputProvider is used to get the output stream where the output should be written. Before you get this stream, you may abort the action by returning false but after the output stream is retrieved, you are committed to outputting the page that then might be cached for future use. Therefore you should do all the preparations first, and only then get the output stream when you know that you will be able to output something sensible.
If you opened the output stream using the output provider, you must make sure that the stream is properly closed. It is best to place all your code after this in a try-finally block and close the stream in the finally part. Failing to do this may cause the caching service to become locked, which in turn could potentially lock the whole application.
doOutput
in class CachedAction
javax.servlet.ServletException
java.io.IOException
private java.util.LinkedHashMap<java.lang.String,java.lang.String> getCacheKeyParams(javax.servlet.http.HttpServletRequest req, ModulesServlet.HttpMethod method, java.lang.String action)
protected java.lang.String getCacheKey(javax.servlet.http.HttpServletRequest req, ModulesServlet.HttpMethod method, java.lang.String action)
CachedAction
getCacheKey
in class CachedAction
req
- The HTTP request which, result of which is to be cached.method
- The method of the HTTP request.action
- The parsed action parameter from the request.Copyright 2004-2015 Wandora Team