1 10 package org.mmbase.module.builders; 11 12 import java.util.*; 13 14 import org.mmbase.core.event.NodeEvent; 15 import org.mmbase.module.core.*; 16 import org.mmbase.util.*; 17 import org.mmbase.util.images.*; 18 import org.mmbase.util.functions.*; 19 import org.mmbase.util.logging.*; 20 import org.mmbase.util.xml.UtilReader; 21 22 import javax.servlet.http.HttpServletResponse ; 23 import javax.servlet.http.HttpServletRequest ; 24 import javax.servlet.ServletContext ; 25 26 38 public class Images extends AbstractImages { 39 40 private static final Logger log = Logging.getLoggerInstance(Images.class); 41 42 private CKeyCache templateCacheNumberCache = new CKeyCache(500) { 45 public String getName() { return "CkeyNumberCache"; } 46 public String getDescription() { return "Connection between image conversion templates and icache node numbers"; } 47 }; 48 49 public final static Parameter[] CACHE_PARAMETERS = { 50 new Parameter("template", String .class) 51 }; 52 53 54 public final static Parameter[] CACHEDNODE_PARAMETERS = CACHE_PARAMETERS; 55 public final static Parameter[] HEIGHT_PARAMETERS = CACHE_PARAMETERS; 56 public final static Parameter[] WIDTH_PARAMETERS = CACHE_PARAMETERS; 57 public final static Parameter[] DIMENSION_PARAMETERS = CACHE_PARAMETERS; 58 59 60 public final static Parameter[] GUI_PARAMETERS = { 61 new Parameter.Wrapper(MMObjectBuilder.GUI_PARAMETERS), 62 new Parameter("template", String .class) 63 }; 64 65 66 public Images() { 67 templateCacheNumberCache.putCache(); 68 } 69 70 73 protected String defaultImageType = "jpg"; 74 75 76 80 public boolean init() { 81 if (oType != -1) return true; 83 if (!super.init()) return false; 84 85 String tmp = getInitParameter("DefaultImageType"); 86 87 if (tmp != null) { 88 defaultImageType = tmp; 89 } 90 91 ImageCaches imageCaches = (ImageCaches) mmb.getMMObject("icaches"); 92 if(imageCaches == null) { 93 log.warn("Builder with name 'icaches' wasn't loaded. Cannot do image-conversions."); 94 } 95 96 Map map = getInitParameters("mmbase/imaging"); 97 map.put("configfile", getConfigResource()); 98 99 Factory.init(map, imageCaches); 100 101 return true; 102 } 103 104 111 protected Object executeFunction(MMObjectNode node, String function, List args) { 112 if (log.isDebugEnabled()) { 113 log.debug("executeFunction " + function + "(" + args + ") of images builder on node " + node.getNumber()); 114 } 115 if ("info".equals(function)) { 116 List empty = new ArrayList(); 117 Map info = (Map) super.executeFunction(node, function, empty); 118 info.put("cache", "" + CACHE_PARAMETERS + " The node number of the cached converted image (icaches node)"); 119 if (args == null || args.size() == 0) { 120 return info; 121 } else { 122 return info.get(args.get(0)); 123 } 124 } else if ("cache".equals(function)) { 125 if (args == null || args.size() < 1) { 126 throw new RuntimeException ("Images cache functions needs 1 argument (now: " + args + ")"); 127 } 128 return new Integer (getCachedNode(node, (String ) args.get(0)).getNumber()); 129 } else if ("cachednode".equals(function)) { 130 try { 131 return getCachedNode(node, (String ) args.get(0)); 132 } catch (Exception e) { 133 log.error(e.getMessage()); 134 log.error(Logging.stackTrace(e)); 135 return null; 136 } 137 } else if ("height".equals(function)) { 138 if (args.size() == 0) { 139 return new Integer (getDimension(node).getHeight()); 140 } else { 141 return new Integer (getDimension(node, (String ) args.get(0)).getHeight()); 142 } 143 } else if ("width".equals(function)) { 144 if (args.size() == 0) { 145 return new Integer (getDimension(node).getWidth()); 146 } else { 147 return new Integer (getDimension(node, (String ) args.get(0)).getWidth()); 148 } 149 } else if ("dimension".equals(function)) { 150 if (args.size() == 0) { 151 return getDimension(node); 152 } else { 153 return getDimension(node, (String ) args.get(0)); 154 } 155 } else { 156 return super.executeFunction(node, function, args); 157 } 158 } 159 162 protected Dimension getDimension(MMObjectNode node, String template) { 163 if (template == null || template.equals("")) { return getDimension(node); 165 } 166 ImageCaches imageCaches = (ImageCaches) mmb.getMMObject("icaches"); 167 if(imageCaches == null) { 168 throw new UnsupportedOperationException ("The 'icaches' builder is not availabe"); 169 } 170 MMObjectNode icacheNode = imageCaches.getCachedNode(node.getNumber(), template); 171 if (icacheNode != null) { 172 return imageCaches.getDimension(icacheNode); 173 } else { 174 return Imaging.predictDimension(getDimension(node), Imaging.parseTemplate(template)); 176 } 177 } 178 179 180 185 public MMObjectNode getCachedNode(MMObjectNode node, String template) { 186 ImageCaches imageCaches = (ImageCaches) mmb.getMMObject("icaches"); 187 if(imageCaches == null) { 188 throw new UnsupportedOperationException ("The 'icaches' builder is not availabe"); 189 } 190 191 MMObjectNode icacheNode = imageCaches.getCachedNode(node.getNumber(), template); 192 193 if (icacheNode == null) { 194 icacheNode = imageCaches.getNewNode("imagesmodule"); 195 String ckey = Factory.getCKey(node.getNumber(), template).toString(); 196 icacheNode.setValue(Imaging.FIELD_CKEY, ckey); 197 icacheNode.setValue(ImageCaches.FIELD_ID, node.getNumber()); 198 if (imageCaches.storesDimension() || imageCaches.storesFileSize()) { 199 Dimension dimension = getDimension(node); 200 Dimension predictedDimension = Imaging.predictDimension(dimension, Imaging.parseTemplate(template)); 201 log.debug("" + dimension + " " + template + " --> " + predictedDimension); 202 if (imageCaches.storesDimension()) { 203 icacheNode.setValue(FIELD_HEIGHT, predictedDimension.getHeight()); 204 icacheNode.setValue(FIELD_WIDTH, predictedDimension.getWidth()); 205 } 206 if (imageCaches.storesFileSize()) { 207 icacheNode.setValue(FIELD_FILESIZE, Imaging.predictFileSize(dimension, getFileSize(node), predictedDimension)); 208 } 209 } 210 int icacheNumber = icacheNode.insert("imagesmodule"); 211 log.debug("Inserted " + icacheNode); 212 if (icacheNumber < 0) { 213 throw new RuntimeException ("Can't insert cache entry id=" + node.getNumber() + " key=" + template); 214 } 215 } 216 return icacheNode; 217 } 218 219 220 224 protected String getGUIIndicatorWithAlt(MMObjectNode node, String alt, Parameters args) { 225 int num = node.getNumber(); 226 if (num < 0) { return "..."; 228 } 229 230 String ses = getSession(args, num); 231 StringBuffer servlet = new StringBuffer (); 232 HttpServletRequest req = (HttpServletRequest ) args.get(Parameter.REQUEST); 233 if (req != null) { 234 ServletContext sx = MMBaseContext.getServletContext(); 235 if (sx != null && "true".equals(sx.getInitParameter("mmbase.taglib.url.makerelative"))) { 236 servlet.append(getServletPath(UriParser.makeRelative(new java.io.File (req.getServletPath()).getParent(), "/"))); 237 } else { 238 servlet.append(getServletPath()); 239 } 240 } else { 241 servlet.append(getServletPath()); 242 } 243 servlet.append(usesBridgeServlet && ses != null ? "session=" + ses + "+" : ""); 244 String template = (String ) args.get("template"); 245 if (template == null) template = ImageCaches.GUI_IMAGETEMPLATE; 246 MMObjectNode icache = getCachedNode(node, template); 247 if (icache == null) { 248 throw new RuntimeException ("No icache found!"); 249 } 250 String imageThumb = servlet.toString() + (icache != null ? "" + icache.getNumber() : ""); 251 252 servlet.append(node.getNumber()); 253 String image; 254 HttpServletResponse res = (HttpServletResponse ) args.get(Parameter.RESPONSE); 255 if (res != null) { 256 imageThumb = res.encodeURL(imageThumb); 257 image = res.encodeURL(servlet.toString()); 258 } else { 259 image = servlet.toString(); 260 } 261 String heightAndWidth; 262 ImageCaches imageCaches = (ImageCaches) mmb.getMMObject("icaches"); 263 if (imageCaches != null && imageCaches.storesDimension()) { 264 Dimension dim = imageCaches.getDimension(icache); 265 StringBuffer buf = new StringBuffer (); 266 if(dim.getHeight() > 0) { 267 buf.append("height=\"").append(dim.getHeight()).append("\" "); 268 } else { 269 log.warn("Found non-positive height."); 270 } 271 if (dim.getWidth() > 0) { 272 buf.append("width=\"").append(dim.getWidth()).append("\" "); 273 } else { 274 log.warn("Found non-positive width."); 275 } 276 heightAndWidth = buf.toString(); 277 } else { 278 heightAndWidth = ""; 279 } 280 281 String title; 282 String field = (String ) args.get("field"); 283 if (field == null || field.equals("")) { 284 title = ""; 286 } else { 287 if (storesDimension()) { 288 title = " title=\"" + getMimeType(node) + " " + getDimension(node) + "\""; 289 } else { 290 title = " title=\"" + getMimeType(node) + "\""; 291 } 292 } 293 294 return 295 "<a HREF=\"" + image + "\" class=\"mm_gui\" onclick=\"window.open(this.href); return false;\"><img SRC=\"" + imageThumb + "\" " + 296 heightAndWidth + 297 "border=\"0\" alt=\"" + 298 org.mmbase.util.transformers.Xml.XMLAttributeEscape(alt, '\"') + 299 "\"" + title + " /></a>"; 300 } 301 302 protected String getSGUIIndicatorForNode(MMObjectNode node, Parameters args) { 304 return getGUIIndicatorWithAlt(node, node.getStringValue("title"), args); 305 } 306 307 308 public String getDefaultImageType() { 310 return defaultImageType; 311 } 312 313 public boolean commit(MMObjectNode node) { 315 Collection changed = node.getChanged(); 316 boolean imageCacheInvalid = changed.contains("handle"); 318 if(super.commit(node)) { 320 if(imageCacheInvalid) { 322 invalidateImageCache(node); 323 templateCacheNumberCache.remove(node.getNumber()); 324 } 325 return true; 326 } 327 return false; 328 } 329 330 336 public void removeNode(MMObjectNode node) { 337 invalidateImageCache(node); 338 templateCacheNumberCache.remove(node.getNumber()); 339 super.removeNode(node); 340 } 341 342 343 344 347 public void notify(NodeEvent event) { 348 if (log.isDebugEnabled()) { 349 log.debug("Changed " + event.getMachine() + " " + event.getNodeNumber() + 350 " " + event.getBuilderName() + " "+ NodeEvent.newTypeToOldType(event.getType())); 351 } 352 invalidateTemplateCacheNumberCache(event.getNodeNumber()); 353 super.notify(event); 354 } 355 356 357 361 private void invalidateImageCache(MMObjectNode node) { 362 ImageCaches icache = (ImageCaches) mmb.getMMObject("icaches"); 363 if(icache != null) { 364 icache.invalidate(node); 366 } 367 } 368 369 372 void invalidateTemplateCacheNumberCache(int number) { 373 templateCacheNumberCache.remove(number); 374 } 375 376 379 void invalidateTemplateCacheNumberCache(String ckey) { 380 templateCacheNumberCache.remove(ckey); 381 } 382 383 384 385 386 } 387 388 | Popular Tags |