001 // ==============================================
002 //
003 // Module-Imaging 1.0, 05-2006
004 // +++++++++++++++++++++++++++++++++++++
005 //
006 // Andreas Trappe - idea, concept
007 // Chi Vu Huu - concept, development
008 //
009 // $Revision$ $Date$
010 // ==============================================
011
012 package org.mycore.services.imaging;
013
014 import java.awt.Dimension;
015 import java.io.ByteArrayInputStream;
016 import java.io.ByteArrayOutputStream;
017 import java.io.IOException;
018 import java.io.InputStream;
019 import java.util.ArrayList;
020 import java.util.List;
021
022 import org.apache.log4j.Logger;
023 import org.hibernate.Session;
024
025 import org.mycore.backend.hibernate.MCRHIBConnection;
026 import org.mycore.common.MCRConfiguration;
027 import org.mycore.common.MCRException;
028 import org.mycore.datamodel.common.MCRXMLTableManager;
029 import org.mycore.datamodel.ifs.MCRDirectory;
030 import org.mycore.datamodel.ifs.MCRFile;
031 import org.mycore.datamodel.ifs.MCRFilesystemNode;
032 import org.mycore.frontend.cli.MCRAbstractCommands;
033 import org.mycore.frontend.cli.MCRCommand;
034
035 public class MCRImgCacheCommands extends MCRAbstractCommands {
036 private static final MCRConfiguration CONFIG = MCRConfiguration.instance();
037
038 private static Logger LOGGER = Logger.getLogger(MCRImgCacheCommands.class.getName());
039
040 private static String SUPPORTED_CONTENT_TYPES = CONFIG.getString("MCR.Module-iview.SupportedContentTypes").toLowerCase();
041
042 private static final int CACHE_WIDTH = CONFIG.getInt("MCR.Module-iview.cache.size.width");
043
044 private static final int THUMB_WIDTH = CONFIG.getInt("MCR.Module-iview.thumbnail.size.width");
045
046 private static final int THUMB_HEIGHT = CONFIG.getInt("MCR.Module-iview.thumbnail.size.height");
047
048 /**
049 * The empty constructor.
050 */
051 public MCRImgCacheCommands() {
052 super();
053 MCRCommand com = null;
054
055 com = new MCRCommand("delete image cache for all derivates", "org.mycore.services.imaging.MCRImgCacheCommands.deleteCache",
056 "The command deletes the whole image cache.");
057 command.add(com);
058
059 com = new MCRCommand("create image cache for file {0}", "org.mycore.services.imaging.MCRImgCacheCommands.cacheFile String",
060 "The command create the image cache version for the given File.");
061 command.add(com);
062
063 com = new MCRCommand("delete image cache for file {0}", "org.mycore.services.imaging.MCRImgCacheCommands.deleteCachedFile String",
064 "The command delete the image cache version for the given File.");
065 command.add(com);
066
067 com = new MCRCommand("create image cache for derivate {0}", "org.mycore.services.imaging.MCRImgCacheCommands.cacheDerivate String",
068 "The command create the image cache version for the given Derivate.");
069 command.add(com);
070 com = new MCRCommand("create image cache for all derivates", "org.mycore.services.imaging.MCRImgCacheCommands.createCache",
071 "The command create the the complete image cache for all derivates in the MyCore System. Caution this will take a lot of time!");
072 command.add(com);
073
074 com = new MCRCommand("delete image cache for derivate {0}", "org.mycore.services.imaging.MCRImgCacheCommands.deleteCachedDerivate String",
075 "The command delete the image cache version for the given Derivate.");
076 command.add(com);
077
078 }
079
080 public static final List<String> createCache() {
081 MCRXMLTableManager xmlTableManager = MCRXMLTableManager.instance();
082 List<String> derivateList = xmlTableManager.retrieveAllIDs("derivate");
083 List<String> returns = new ArrayList<String>(derivateList.size());
084 for (String derivateID : derivateList) {
085 returns.add("create image cache for derivate " + derivateID);
086 }
087 return returns;
088 }
089
090 public static List<String> deleteCache() {
091 MCRXMLTableManager xmlTableManager = MCRXMLTableManager.instance();
092 List<String> derivateList = xmlTableManager.retrieveAllIDs("derivate");
093 List<String> returns = new ArrayList<String>(derivateList.size());
094 for (String derivateID : derivateList) {
095 returns.add("delete image cache for derivate " + derivateID);
096 }
097 return returns;
098 }
099
100 public static List<String> cacheDerivate(String ID) {
101 List<String> returns = new ArrayList<String>();
102 MCRDirectory derivate = null;
103
104 MCRFilesystemNode node = MCRFilesystemNode.getRootNode(ID);
105
106 if (node == null || !(node instanceof MCRDirectory))
107 throw new MCRException("Derivate " + ID + " does not exist or is not a directory!");
108 derivate = (MCRDirectory) node;
109
110 List<MCRFile> supportedFiles = getSuppFiles(derivate);
111 for (MCRFile image : supportedFiles) {
112 returns.add("create image cache for file " + image.getID());
113 }
114 return returns;
115 }
116
117 public static List<String> deleteCachedDerivate(String ID) throws Exception {
118 List<String> returns = new ArrayList<String>();
119 MCRDirectory derivate = null;
120
121 MCRFilesystemNode node = MCRFilesystemNode.getRootNode(ID);
122
123 if (node == null || !(node instanceof MCRDirectory))
124 throw new MCRException("Derivate " + ID + " does not exist or is not a directory!");
125 derivate = (MCRDirectory) node;
126
127 List<MCRFile> supportedFiles = getSuppFiles(derivate);
128
129 for (MCRFile image : supportedFiles) {
130 returns.add("delete image cache for file " + image.getID());
131 }
132 return returns;
133 }
134
135 public static void cacheFile(String ID) throws Exception {
136 MCRFilesystemNode node = MCRFilesystemNode.getNode(ID);
137 MCRFile imgFile = null;
138
139 if (node != null && node instanceof MCRFile) {
140 imgFile = (MCRFile) node;
141 cacheFile(imgFile);
142 } else {
143 LOGGER.info("File " + ID + " does not exist!");
144 }
145
146 }
147
148 public static void deleteCachedFile(String ID) throws Exception {
149 MCRFile imgFile = null;
150 MCRFilesystemNode node = MCRFilesystemNode.getNode(ID);
151
152 if (LOGGER.isDebugEnabled()) {
153 LOGGER.debug("MCRImgCacheCommands - removeCachedFile ");
154 LOGGER.debug("The node: " + node.getAbsolutePath());
155 }
156
157 if (node != null && node instanceof MCRFile)
158 imgFile = (MCRFile) node;
159 else
160 throw new MCRException("File " + ID + " does not exist!");
161
162 if (isSupported(imgFile.getContentTypeID())) {
163 MCRImgCacheManager cache = MCRImgCacheManager.instance();
164 imgFile.removeAdditionalData("ImageMetaData");
165 cache.deleteImage(imgFile);
166 }
167 LOGGER.info("Remove cache version for image " + imgFile.getName() + " finished successfull!");
168
169 }
170
171 private static List<MCRFile> getSuppFiles(MCRDirectory rootNode) {
172 ArrayList<MCRFile> files = new ArrayList<MCRFile>();
173 MCRFilesystemNode[] nodes = rootNode.getChildren();
174 for (MCRFilesystemNode node : nodes) {
175 if (node instanceof MCRDirectory) {
176 MCRDirectory dir = (MCRDirectory) node;
177 files.addAll(getSuppFiles(dir));
178 } else {
179 MCRFile file = (MCRFile) node;
180 if (isSupported(file.getContentTypeID())) {
181 files.add(file);
182 }
183 }
184 }
185 return files;
186 }
187
188 private static void cacheFile(MCRFile imgFile) throws Exception {
189 cacheFile(imgFile, false);
190 }
191
192 public static void cacheFile(MCRFile image, boolean cacheSizeOnly) {
193 boolean useCache = CONFIG.getBoolean("MCR.Module-iview.useCache");
194 String fileType = image.getContentTypeID();
195 String filename = image.getName();
196
197 try {
198 InputStream imgInputStream = image.getContentAsInputStream();
199
200 if (isSupported(fileType)) {
201 if (LOGGER.isDebugEnabled()) {
202 LOGGER.debug("MCRImgCacheCommands - " + filename);
203 LOGGER.debug("File type " + fileType + " supported in file list - " + SUPPORTED_CONTENT_TYPES);
204 }
205 CacheManager cache = MCRImgCacheManager.instance();
206 MCRImgProcessor processor = new MCRImgProcessor();
207
208 if (cacheSizeOnly)
209 processor.loadImage(imgInputStream);
210 else
211 processor.loadImageFileCache(imgInputStream);
212
213 Dimension imgSize = new Dimension(0, 0);
214 try {
215 imgSize = processor.getOrigSize();
216 cache.setImgSize(image, imgSize.width, imgSize.height);
217 } catch (Exception e) {
218 useCache = false;
219 LOGGER.error("Could not get image size for " + image.getName() + " will not cached!", e);
220 }
221
222 if (useCache && !cacheSizeOnly) {
223 // cache.setLock(image);
224 boolean cacheOrig = CONFIG.getBoolean("MCR.Module-iview.cacheOrig");
225 // cache Original
226 if (cacheOrig && !processor.hasCorrectTileSize()) {
227 if (!cache.existInCache(image, MCRImgCacheManager.ORIG)) {
228 ByteArrayOutputStream imgData = new ByteArrayOutputStream();
229 processor.tiffEncode(imgData);
230 if ((fileType.equals("tiff") || fileType.equals("tif"))) {
231 LOGGER.debug("MCRImgCacheCommands - cacheFile");
232 LOGGER.debug("is TIFF");
233 image.setContentFrom(imgData.toByteArray());
234 } else {
235 LOGGER.debug("MCRImgCacheCommands - cacheFile");
236 LOGGER.debug("not TIFF");
237 ByteArrayInputStream input = new ByteArrayInputStream(imgData.toByteArray());
238 cache.saveImage(image, MCRImgCacheManager.ORIG, input);
239 imgData.reset();
240 }
241 } else {
242 LOGGER.info("Image " + image.getName() + " as version " + MCRImgCacheManager.ORIG + " allready exists in Cache!");
243 }
244
245 } else {
246 LOGGER.info("Image " + image.getName() + " is to small for caching as version " + MCRImgCacheManager.ORIG + " !");
247 }
248
249 int factor = 2;
250
251 if (imgSize.width < imgSize.height)
252 factor = 1;
253 // cache small version
254 if ((imgSize.width > factor * CACHE_WIDTH)) {
255 LOGGER.debug("MCRImgCacheCommands - cacheFile");
256 if (!cache.existInCache(image, MCRImgCacheManager.CACHE)) {
257 ByteArrayOutputStream imgData = new ByteArrayOutputStream();
258 processor.resizeFitWidth(CACHE_WIDTH);
259 processor.encode(imgData, MCRImgProcessor.TIFF_ENC);
260 ByteArrayInputStream input = new ByteArrayInputStream(imgData.toByteArray());
261 cache.saveImage(image, MCRImgCacheManager.CACHE, input);
262 imgData.reset();
263
264 LOGGER.info("Image " + image.getName() + " cached successfull under the name " + MCRImgCacheManager.CACHE + " !");
265 } else {
266 LOGGER.info("Image " + image.getName() + " as version " + MCRImgCacheManager.CACHE + " allready exists in Cache!");
267 }
268
269 } else {
270 LOGGER.info("Image " + image.getName() + " is to small for caching as version " + MCRImgCacheManager.CACHE + " !");
271 }
272
273 // cache Thumbnail
274 if (!cache.existInCache(image, MCRImgCacheManager.THUMB)) {
275 ByteArrayOutputStream imgData = new ByteArrayOutputStream();
276 processor.resize(THUMB_WIDTH, THUMB_HEIGHT);
277 processor.encode(imgData, MCRImgProcessor.JPEG_ENC);
278 ByteArrayInputStream input = new ByteArrayInputStream(imgData.toByteArray());
279 cache.saveImage(image, MCRImgCacheManager.THUMB, input);
280 imgData.reset();
281
282 LOGGER.info("Image " + image.getName() + " cached successfull under the name " + MCRImgCacheManager.THUMB + " !");
283 } else {
284 LOGGER.info("Image " + image.getName() + " as version " + MCRImgCacheManager.THUMB + " allready exists in Cache!");
285 }
286
287 LOGGER.info("Caching image " + image.getName() + " finished successfull!");
288 } else {
289 if (LOGGER.isDebugEnabled()) {
290 LOGGER.debug("MCRImgCacheCommands - " + filename);
291 LOGGER.debug("File type " + fileType + " not supported in file list - " + SUPPORTED_CONTENT_TYPES);
292 }
293 }
294 }
295
296 imgInputStream.close();
297 } catch (IOException e) {
298 LOGGER.error(e);
299 LOGGER.info("Loading image " + image.getName() + " failed!");
300 }
301 }
302
303 private static boolean isSupported(String fileType) {
304 return SUPPORTED_CONTENT_TYPES.indexOf(fileType.toLowerCase()) > -1;
305 }
306 }