KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > loader > CmsImageLoader


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/loader/CmsImageLoader.java,v $
3  * Date : $Date: 2006/09/22 15:17:03 $
4  * Version: $Revision: 1.4 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (C) 2002 - 2005 Alkacon Software (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package org.opencms.loader;
33
34 import org.opencms.cache.CmsVfsNameBasedDiskCache;
35 import org.opencms.file.CmsFile;
36 import org.opencms.file.CmsObject;
37 import org.opencms.file.CmsResource;
38 import org.opencms.main.CmsException;
39 import org.opencms.main.CmsLog;
40 import org.opencms.main.OpenCms;
41 import org.opencms.util.CmsStringUtil;
42
43 import java.io.IOException JavaDoc;
44 import java.util.Map JavaDoc;
45 import java.util.TreeMap JavaDoc;
46
47 import javax.servlet.http.HttpServletRequest JavaDoc;
48 import javax.servlet.http.HttpServletResponse JavaDoc;
49
50 import org.apache.commons.logging.Log;
51
52 /**
53  * Loader for images from the OpenCms VSF with integrated image scaling and processing capabilites.<p>
54  *
55  * To scale or process an image, the parameter <code>{@link org.opencms.loader.CmsImageScaler#PARAM_SCALE}</code>
56  * has to be appended to the image URI. The value for the parameter needs to be composed from the <code>SCALE_PARAM</code>
57  * options provided by the constants in the <code>{@link org.opencms.file.types.CmsResourceTypeImage}</code> class.<p>
58  *
59  * For example, to scale an image to exact 800x600 pixel with center fitting and a background color of grey,
60  * the following parameter String can be used: <code>w:800,h:600,t:0,c:c0c0c0</code>.<p>
61  *
62  * @author Alexander Kandzior
63  *
64  * @version $Revision: 1.4 $
65  *
66  * @since 6.2.0
67  */

68 public class CmsImageLoader extends CmsDumpLoader {
69
70     /** The configuration parameter for the OpenCms XML configuration to set the image downscale operation. */
71     public static final String JavaDoc CONFIGURATION_DOWNSCALE = "image.scaling.downscale";
72
73     /** The configuration parameter for the OpenCms XML configuration to set the image cache respository. */
74     public static final String JavaDoc CONFIGURATION_IMAGE_FOLDER = "image.folder";
75
76     /** The configuration parameter for the OpenCms XML configuration to set the maximum image blur size. */
77     public static final String JavaDoc CONFIGURATION_MAX_BLUR_SIZE = "image.scaling.maxblursize";
78
79     /** The configuration parameter for the OpenCms XML configuration to set the maximum image scale size. */
80     public static final String JavaDoc CONFIGURATION_MAX_SCALE_SIZE = "image.scaling.maxsize";
81
82     /** The configuration parameter for the OpenCms XML configuration to enable the image scaling. */
83     public static final String JavaDoc CONFIGURATION_SCALING_ENABLED = "image.scaling.enabled";
84
85     /** Default name for the image cache repository. */
86     public static final String JavaDoc IMAGE_REPOSITORY_DEFAULT = "/WEB-INF/imagecache/";
87
88     /** The id of this loader. */
89     public static final int RESOURCE_LOADER_ID_IMAGE_LOADER = 2;
90
91     /** The log object for this class. */
92     protected static final Log LOG = CmsLog.getLog(CmsImageLoader.class);
93
94     /** The (optional) image downscale parameters for image write operations. */
95     protected static String JavaDoc m_downScaleParams;
96
97     /** Indicates if image scaling is active. */
98     protected static boolean m_enabled;
99
100     /** The maximum image size (width * height) to apply image blurring when downscaling (setting this to high may cause "out of memory" errors). */
101     protected static int m_maxBlurSize = CmsImageScaler.SCALE_DEFAULT_MAX_BLUR_SIZE;
102
103     /** The disk cache to use for saving scaled image versions. */
104     protected static CmsVfsNameBasedDiskCache m_vfsDiskCache;
105
106     /** The name of the configured image cache repository. */
107     protected String JavaDoc m_imageRepositoryFolder;
108
109     /** The maximum image size (width or height) to allow when upscaling an image using request parameters. */
110     protected int m_maxScaleSize = CmsImageScaler.SCALE_DEFAULT_MAX_SIZE;
111
112     /**
113      * Creates a new image loader.<p>
114      */

115     public CmsImageLoader() {
116
117         super();
118     }
119
120     /**
121      * Returns the image downscale paramerters,
122      * which is set with the {@link #CONFIGURATION_DOWNSCALE} configuration option.<p>
123      *
124      * If no downscale parameters have been set in the configuration, this will return <code>null</code>.
125      *
126      * @return the image downscale paramerters
127      */

128     public static String JavaDoc getDownScaleParams() {
129
130         return m_downScaleParams;
131     }
132
133     /**
134      * Returns the path of the image cache repository folder in the RFS,
135      * which is set with the {@link #CONFIGURATION_IMAGE_FOLDER} configuration option.<p>
136      *
137      * @return the path of the image cache repository folder in the RFS
138      */

139     public static String JavaDoc getImageRepositoryPath() {
140
141         return m_vfsDiskCache.getRepositoryPath();
142     }
143
144     /**
145      * The maximum blur size for image rescale operations,
146      * which is set with the {@link #CONFIGURATION_MAX_BLUR_SIZE} configuration option.<p>
147      *
148      * The default is 2500 * 2500 pixel.<p>
149      *
150      * @return the maximum blur size for image rescale operations
151      */

152     public static int getMaxBlurSize() {
153
154         return m_maxBlurSize;
155     }
156
157     /**
158      * Returns <code>true</code> if the image scaling and processing capablities for the
159      * OpenCms VFS images have been enabled, <code>false</code> if not.<p>
160      *
161      * Image scaling is enabled by setting the loader parameter <code>image.scaling.enabled</code>
162      * to the value <code>true</code> in the configuration file <code>opencms-vfs.xml</code>.<p>
163      *
164      * Enabling image processing in OpenCms may require several additional configuration steps
165      * on the server running OpenCms, especially in UNIX systems. Here it is often required to have an X window server
166      * configured and accessible so that the required Java ImageIO operations work.
167      * Therefore the image scaling capablities in OpenCms are disabled by default.<p>
168      *
169      * @return <code>true</code> if the image scaling and processing capablities for the
170      * OpenCms VFS images have been enabled
171      */

172     public static boolean isEnabled() {
173
174         return m_enabled;
175     }
176
177     /**
178      * @see org.opencms.configuration.I_CmsConfigurationParameterHandler#addConfigurationParameter(java.lang.String, java.lang.String)
179      */

180     public void addConfigurationParameter(String JavaDoc paramName, String JavaDoc paramValue) {
181
182         if (CmsStringUtil.isNotEmpty(paramName) && CmsStringUtil.isNotEmpty(paramValue)) {
183             if (CONFIGURATION_SCALING_ENABLED.equals(paramName)) {
184                 m_enabled = Boolean.valueOf(paramValue).booleanValue();
185             }
186             if (CONFIGURATION_IMAGE_FOLDER.equals(paramName)) {
187                 m_imageRepositoryFolder = paramValue.trim();
188             }
189             if (CONFIGURATION_MAX_SCALE_SIZE.equals(paramName)) {
190                 m_maxScaleSize = CmsStringUtil.getIntValue(paramValue, CmsImageScaler.SCALE_DEFAULT_MAX_SIZE, paramName);
191             }
192             if (CONFIGURATION_MAX_BLUR_SIZE.equals(paramName)) {
193                 m_maxBlurSize = CmsStringUtil.getIntValue(
194                     paramValue,
195                     CmsImageScaler.SCALE_DEFAULT_MAX_BLUR_SIZE,
196                     paramName);
197             }
198             if (CONFIGURATION_DOWNSCALE.equals(paramName)) {
199                 m_downScaleParams = paramValue.trim();
200             }
201         }
202         super.addConfigurationParameter(paramName, paramValue);
203     }
204
205     /**
206      * @see org.opencms.loader.I_CmsResourceLoader#destroy()
207      */

208     public void destroy() {
209
210         m_enabled = false;
211         m_imageRepositoryFolder = null;
212         m_vfsDiskCache = null;
213     }
214
215     /**
216      * @see org.opencms.configuration.I_CmsConfigurationParameterHandler#getConfiguration()
217      */

218     public Map JavaDoc getConfiguration() {
219
220         Map JavaDoc config = super.getConfiguration();
221         TreeMap JavaDoc result = new TreeMap JavaDoc();
222         if (config != null) {
223             result.putAll(config);
224         }
225         result.put(CONFIGURATION_SCALING_ENABLED, String.valueOf(m_enabled));
226         result.put(CONFIGURATION_IMAGE_FOLDER, m_imageRepositoryFolder);
227         return result;
228     }
229
230     /**
231      * @see org.opencms.loader.I_CmsResourceLoader#getLoaderId()
232      */

233     public int getLoaderId() {
234
235         return RESOURCE_LOADER_ID_IMAGE_LOADER;
236     }
237
238     /**
239      * @see org.opencms.configuration.I_CmsConfigurationParameterHandler#initConfiguration()
240      */

241     public void initConfiguration() {
242
243         if (CmsStringUtil.isEmpty(m_imageRepositoryFolder)) {
244             m_imageRepositoryFolder = IMAGE_REPOSITORY_DEFAULT;
245         }
246         // initialize the image cache
247
if (m_vfsDiskCache == null) {
248             m_vfsDiskCache = new CmsVfsNameBasedDiskCache(
249                 OpenCms.getSystemInfo().getWebApplicationRfsPath(),
250                 m_imageRepositoryFolder);
251         }
252         // output setup information
253
if (CmsLog.INIT.isInfoEnabled()) {
254             CmsLog.INIT.info(Messages.get().getBundle().key(
255                 Messages.INIT_IMAGE_REPOSITORY_PATH_1,
256                 m_vfsDiskCache.getRepositoryPath()));
257             CmsLog.INIT.info(Messages.get().getBundle().key(
258                 Messages.INIT_IMAGE_SCALING_ENABLED_1,
259                 Boolean.valueOf(m_enabled)));
260         }
261     }
262
263     /**
264      * @see org.opencms.loader.I_CmsResourceLoader#load(org.opencms.file.CmsObject, org.opencms.file.CmsResource, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
265      */

266     public void load(CmsObject cms, CmsResource resource, HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res)
267     throws IOException JavaDoc, CmsException {
268
269         if (m_enabled) {
270             if (canSendLastModifiedHeader(resource, req, res)) {
271                 // no image processing required at all
272
return;
273             }
274             // get the scale information from the request
275
CmsImageScaler scaler = new CmsImageScaler(req, m_maxScaleSize, m_maxBlurSize);
276             // load the file from the cache
277
CmsFile file = getScaledImage(cms, resource, scaler);
278             // now perform standarad load operation inherited from dump loader
279
super.load(cms, file, req, res);
280         } else {
281             // scaling is disabled
282
super.load(cms, resource, req, res);
283         }
284     }
285
286     /**
287      * Returns a scaled version of the given OpenCms VFS image resource.<p>
288      *
289      * All results are cached in disk.
290      * If the scaled version does not exist in the cache, it is created.
291      * Unscaled versions of the images are also stored in the cache.<p>
292      *
293      * @param cms the current users OpenCms context
294      * @param resource the base VFS resource for the image
295      * @param scaler the configured image scaler
296      *
297      * @return a scaled version of the given OpenCms VFS image resource
298      *
299      * @throws IOException in case of errors acessing the disk based cache
300      * @throws CmsException in case of errors accessing the OpenCms VFS
301      */

302     protected CmsFile getScaledImage(CmsObject cms, CmsResource resource, CmsImageScaler scaler)
303     throws IOException JavaDoc, CmsException {
304
305         String JavaDoc cacheParam = scaler.isValid() ? scaler.toString() : null;
306         String JavaDoc cacheName = m_vfsDiskCache.getCacheName(resource, cacheParam);
307         byte[] content = m_vfsDiskCache.getCacheContent(cacheName);
308
309         CmsFile file;
310         if (content != null) {
311             if (resource instanceof CmsFile) {
312                 // the original file content must be modified (required e.g. for static export)
313
file = (CmsFile)resource;
314             } else {
315                 // this is no file, but we don't want to use "upgrade" since we don't need to read the content from the VFS
316
file = new CmsFile(resource);
317             }
318             // save the content in the file
319
file.setContents(content);
320         } else {
321             // we must read the content from the VFS (if this has not been done yet)
322
file = CmsFile.upgrade(resource, cms);
323             // upgrade the file (load the content)
324
if (scaler.isValid()) {
325                 // valid scaling parameters found, scale the content
326
content = scaler.scaleImage(file);
327                 // exchange the content of the file with the scaled version
328
file.setContents(content);
329             }
330             // save the file content in the cache
331
m_vfsDiskCache.saveCacheFile(cacheName, file.getContents());
332         }
333         return file;
334     }
335 }
Popular Tags