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.IOException;
016 import java.io.InputStream;
017 import java.io.OutputStream;
018
019 import org.apache.log4j.Logger;
020 import org.jdom.Element;
021 import org.jdom.JDOMException;
022 import org.mycore.common.MCRException;
023 import org.mycore.datamodel.ifs.MCRDirectory;
024 import org.mycore.datamodel.ifs.MCRFile;
025 import org.mycore.datamodel.ifs.MCRFilesystemNode;
026
027 /*******************************************************************************
028 * The MCRImgCacheManager deliver the method for getting data into and out of
029 * the cache structure which lies in the IFS.<br>
030 * The cache structure is just an one level flat tree:<br>
031 * |--> [imgCache] --> [cached Image File] --> [versions of image]<br>
032 * <br>
033 *
034 * Cached image file is a subfolder of the root node imgCache in IFS. The name
035 * is composed the following:<br>
036 * ownerID + absolute path + filename<br>
037 * in absolute path the "/" is replaced by "%20"
038 *
039 *
040 * @version 0.01pre 03/01/2006<br>
041 * 1.00 08/08/2006
042 * @author Vu Huu Chi
043 *
044 */
045
046 public class MCRImgCacheManager implements CacheManager {
047 public static final String THUMB = "Thumb";
048
049 public static final String CACHE = "Cache";
050
051 public static final String ORIG = "Orig";
052
053 public static final String CACHE_FOLDER = "imgCache";
054
055 private Logger LOGGER = Logger.getLogger(MCRImgCacheManager.class.getName());
056
057 private static MCRDirectory cacheInIFS = null;
058
059 private static MCRImgCacheManager cacheManager;
060
061 public synchronized static MCRImgCacheManager instance() {
062 if (cacheManager == null)
063 cacheManager = new MCRImgCacheManager();
064
065 return cacheManager;
066 }
067
068 private MCRImgCacheManager() {
069 cacheInIFS = (MCRDirectory) MCRFilesystemNode.getRootNode(CACHE_FOLDER);
070
071 if (cacheInIFS == null) {
072 LOGGER.info("Img Cache not exist, creating new one");
073 try {
074 cacheInIFS = new MCRDirectory(CACHE_FOLDER, CACHE_FOLDER);
075 } catch (Exception e) {
076 throw new MCRException(e.getMessage());
077 }
078 }
079 }
080
081 public void getImage(MCRFile image, String filename, OutputStream imageData) {
082 MCRFilesystemNode cachedImg = cacheInIFS.getChildByPath(buildPath(image) + "/" + filename);
083 LOGGER.debug("Path in cache: " + cachedImg.getAbsolutePath());
084
085 if (cachedImg != null && cachedImg instanceof MCRFile) {
086 Stopwatch timer = new Stopwatch();
087
088 timer.start();
089 ((MCRFile) cachedImg).getContentTo(imageData);
090 timer.stop();
091 LOGGER.info("getContentTo: " + timer.getElapsedTime());
092 } else
093 throw new MCRException("Could not load " + image.getName() + "from cache!");
094 }
095
096 public InputStream getImageAsInputStream(MCRFile image, String filename) throws IOException {
097 MCRFilesystemNode cachedImg = cacheInIFS.getChildByPath(buildPath(image) + "/" + filename);
098 LOGGER.debug("Path in cache: " + cachedImg.getAbsolutePath());
099
100 if (cachedImg != null && cachedImg instanceof MCRFile) {
101 LOGGER.debug("Return Image from Cache as InputStream.");
102 return ((MCRFile) cachedImg).getContentAsInputStream();
103 } else {
104 LOGGER.debug("Return Null.");
105 return null;
106 }
107 }
108
109 public void saveImage(MCRFile image, Dimension size, InputStream imageData) {
110 saveImage(image, dimToString(size), imageData);
111 }
112
113 public void saveImage(MCRFile image, String filename, InputStream imageData) {
114
115 MCRDirectory cachedImg = getCacheDir(image);
116
117 if (cachedImg == null)
118 cachedImg = setCacheDir(image);
119
120 try {
121 MCRFile cachedImgIFS = new MCRFile(filename + "lock", cachedImg);
122
123 cachedImgIFS.setContentFrom(imageData);
124 cachedImgIFS.setName(filename);
125 } catch (Exception e) {
126 throw new MCRException("Could not save Image " + image.getName() + " as " + filename + " in cache!");
127 }
128 }
129
130 public void deleteImage(MCRFile image, Dimension size) {
131 deleteImage(image, dimToString(size));
132 }
133
134 public void deleteImage(MCRFile image, String filename) {
135 MCRFilesystemNode cachedImg = cacheInIFS.getChildByPath(buildPath(image) + "/" + filename);
136
137 if (cachedImg != null && cachedImg instanceof MCRFile)
138 ((MCRFile) cachedImg).delete();
139 else
140 LOGGER.debug("Could not delete " + image.getName() + "from cache!");
141 // throw new MCRException("Could not delete " + image.getName() + "from
142 // cache!");
143
144 }
145
146 public void deleteImage(MCRFile image) {
147 MCRFilesystemNode cachedImg = cacheInIFS.getChildByPath(buildPath(image));
148
149 if (cachedImg != null && cachedImg instanceof MCRDirectory) {
150 LOGGER.debug("MCRImgCacheManager - deleteImage");
151 LOGGER.debug("Delte : " + cachedImg.getName());
152 ((MCRDirectory) cachedImg).delete();
153 } else
154 LOGGER.debug("Could not delete " + image.getName() + "from cache!");
155 // throw new MCRException("Could not delete " + image.getName() + "from
156 // cache!");
157
158 }
159
160 public boolean existInCache(MCRFile image, String filename) {
161 MCRFilesystemNode cachedImg = cacheInIFS.getChildByPath(buildPath(image) + "/" + filename);
162
163 if (cachedImg != null && cachedImg instanceof MCRFile) {
164
165 return true;
166 } else
167 return false;
168 }
169
170 public boolean existInCache(MCRFile image) {
171 return (existInCache(image, THUMB) || existInCache(image, ORIG) || existInCache(image, CACHE));
172 }
173
174 public Dimension getImgDimension(MCRFile image) {
175 Dimension dim = new Dimension();
176 try {
177 Element addData = image.getAdditionalData("ImageMetaData");
178
179 if (addData != null) {
180 dim.width = Integer.parseInt(addData.getChild("imageSize").getChild("width").getText());
181 dim.height = Integer.parseInt(addData.getChild("imageSize").getChild("height").getText());
182 }
183 } catch (Exception e) {
184 e.printStackTrace();
185 }
186 return dim;
187 }
188
189 public int getImgWidth(MCRFile image) {
190 int width = 0;
191
192 try {
193 Element addData = image.getAdditionalData("ImageMetaData");
194
195 if (addData != null) {
196 width = (new Integer(addData.getChild("imageSize").getChild("width").getText())).intValue();
197 }
198 } catch (IOException e) {
199 // TODO Auto-generated catch block
200 e.printStackTrace();
201 } catch (JDOMException e) {
202 // TODO Auto-generated catch block
203 e.printStackTrace();
204 }
205
206 return width;
207 }
208
209 public int getImgHeight(MCRFile image) {
210 int height = 0;
211
212 try {
213 Element addData = image.getAdditionalData("ImageMetaData");
214
215 if (addData != null) {
216 height = (new Integer(addData.getChild("imageSize").getChild("height").getText())).intValue();
217 }
218 } catch (IOException e) {
219 // TODO Auto-generated catch block
220 e.printStackTrace();
221 } catch (JDOMException e) {
222 // TODO Auto-generated catch block
223 e.printStackTrace();
224 }
225
226 return height;
227 }
228
229 public void setImgSize(MCRFile image, int width, int height) {
230 try {
231 Element addData = image.getAdditionalData("ImageMetaData");
232 if (addData == null) {
233 addData = new Element("ImageMetaData").addContent(new Element("imageSize"));
234 Element elem = addData.getChild("imageSize");
235 elem.addContent((new Element("width")).setText(String.valueOf(width)));
236 elem.addContent((new Element("height")).setText(String.valueOf(height)));
237 image.setAdditionalData(addData);
238
239 LOGGER.info("Writing additional data for " + image.getName() + " complete!");
240 } else
241 LOGGER.info("Additional data for " + image.getName() + " allready exists!");
242 } catch (IOException e) {
243 // TODO Auto-generated catch block
244 e.printStackTrace();
245 } catch (JDOMException e) {
246 // TODO Auto-generated catch block
247 e.printStackTrace();
248 }
249 }
250
251 /* *********************************************************************************************** */
252 /* End implement interface */
253 /* *********************************************************************************************** */
254
255 private MCRDirectory getCacheDir(MCRFile image) {
256 String path = buildPath(image);
257 MCRFilesystemNode node = cacheInIFS.getChildByPath(path);
258 MCRDirectory cachedImg = null;
259
260 LOGGER.info("PATH for img in Cache: " + path);
261 LOGGER.info("Node: " + node);
262 LOGGER.info("Directory: " + (node instanceof MCRDirectory));
263
264 if (node != null && node instanceof MCRDirectory) {
265 cachedImg = (MCRDirectory) node;
266 LOGGER.debug("Path in cache found: " + cachedImg.getAbsolutePath());
267 } else {
268 // cachedImg = new MCRDirectory(path, cacheInIFS);
269 LOGGER.debug("No path in cache!" + path);
270 }
271 return cachedImg;
272 }
273
274 private MCRDirectory setCacheDir(MCRFile image) {
275 String path = buildPath(image);
276 MCRDirectory dir = new MCRDirectory(path, cacheInIFS);
277
278 return dir;
279 }
280
281 private String buildPath(MCRFile image) {
282 String ownerID = image.getOwnerID();
283 String absPath = image.getAbsolutePath().replaceAll("/", "%20");
284
285 return ownerID + absPath;
286 }
287
288 // return 'width'x'height' as String
289 private String dimToString(Dimension size) {
290 return size.width + "x" + size.height;
291 }
292
293 public boolean existInCache(MCRFile image, Dimension size) {
294 return existInCache(image, dimToString(size));
295 }
296
297 public void deleteCache() {
298 MCRFilesystemNode[] children = cacheInIFS.getChildren();
299
300 for (int i = 0; i < children.length; i++) {
301 children[i].delete();
302 }
303 }
304 }