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    }