001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.ui.apps.cacheadmin; 029 030import com.alkacon.simapi.Simapi; 031 032import org.opencms.file.CmsObject; 033import org.opencms.file.CmsProject; 034import org.opencms.file.CmsResource; 035import org.opencms.file.CmsResourceFilter; 036import org.opencms.loader.CmsImageLoader; 037import org.opencms.main.CmsException; 038import org.opencms.main.OpenCms; 039import org.opencms.util.CmsFileUtil; 040import org.opencms.util.CmsStringUtil; 041 042import java.awt.image.BufferedImage; 043import java.io.File; 044import java.io.IOException; 045import java.util.ArrayList; 046import java.util.Collections; 047import java.util.HashMap; 048import java.util.List; 049import java.util.Map; 050 051/** 052 * Image Cache helper.<p> 053 * 054 * @since 7.0.5 055 */ 056public class CmsImageCacheHelper { 057 058 /**File path map. */ 059 private Map<String, String> m_filePaths = new HashMap<String, String>(); 060 061 /** Lengths map. */ 062 private Map m_lengths = new HashMap(); 063 064 /** Sizes map. */ 065 private Map m_sizes = new HashMap(); 066 067 /** Variations map. */ 068 private Map m_variations = new HashMap(); 069 070 /** The total number of variations. */ 071 private int m_variationsCount; 072 073 /** The total size of all variations. */ 074 private int m_variationsSize; 075 076 /** 077 * Default constructor.<p> 078 * 079 * @param cms the cms context 080 * @param withVariations if also variations should be read 081 * @param showSize if it is needed to compute the image size 082 * @param statsOnly if only statistical information should be retrieved 083 */ 084 public CmsImageCacheHelper(CmsObject cms, boolean withVariations, boolean showSize, boolean statsOnly) { 085 086 init(cms, withVariations, showSize, statsOnly); 087 } 088 089 /** 090 * Returns all cached images.<p> 091 * 092 * @return a list of root paths 093 */ 094 public List getAllCachedImages() { 095 096 List ret = new ArrayList(m_variations.keySet()); 097 Collections.sort(ret); 098 return ret; 099 } 100 101 /** 102 * Returns the total number of files.<p> 103 * 104 * @return the total number of files 105 */ 106 public int getFilesCount() { 107 108 return m_variations.keySet().size(); 109 } 110 111 /** 112 * Returns the length of the given image.<p> 113 * 114 * @param imgName the image name 115 * 116 * @return the length of the given image 117 */ 118 public String getLength(String imgName) { 119 120 String ret = (String)m_lengths.get(imgName); 121 if (ret == null) { 122 return ""; 123 } 124 return ret; 125 } 126 127 /** 128 * Reads the size of a single image.<p> 129 * 130 * @param cms CmsObejct 131 * @param resPath Path of image (uri) 132 * @return a String representation of the dimension of the given image 133 * @throws CmsException if something goes wrong 134 */ 135 public String getSingleSize(CmsObject cms, String resPath) throws CmsException { 136 137 CmsResource res = getClonedCmsObject(cms).readResource(resPath); 138 return getSingleSize(cms, res); 139 } 140 141 /** 142 * Returns the size of the given image.<p> 143 * 144 * @param imgName the image name 145 * 146 * @return the size of the given image 147 */ 148 public String getSize(String imgName) { 149 150 String ret = (String)m_sizes.get(imgName); 151 if (ret == null) { 152 return ""; 153 } 154 return ret; 155 } 156 157 /** 158 * Returns the variations for the given image.<p> 159 * 160 * @param imgName the image name 161 * 162 * @return the variations for the given image 163 */ 164 public List getVariations(String imgName) { 165 166 List ret = (List)m_variations.get(imgName); 167 if (ret == null) { 168 return new ArrayList(); 169 } 170 Collections.sort(ret); 171 return ret; 172 } 173 174 /** 175 * Returns the total number of variations.<p> 176 * 177 * @return the total number of variations 178 */ 179 public int getVariationsCount() { 180 181 return m_variationsCount; 182 } 183 184 /** 185 * Returns the total size of all variations.<p> 186 * 187 * @return the total size of all variations 188 */ 189 public int getVariationsSize() { 190 191 return m_variationsSize; 192 } 193 194 /** 195 * Reads out the path of a given image (by its name).<p> 196 * 197 * @param resName name of image 198 * @return path to it on Server 199 */ 200 String getFilePath(String resName) { 201 202 return m_filePaths.get(resName); 203 } 204 205 /** 206 * Clones a CmsObject.<p> 207 * 208 * @param cms the CmsObject to be cloned. 209 * @return a clones CmsObject 210 * @throws CmsException if something goes wrong 211 */ 212 private CmsObject getClonedCmsObject(CmsObject cms) throws CmsException { 213 214 CmsObject clonedCms = OpenCms.initCmsObject(cms); 215 // only online images get caches 216 clonedCms.getRequestContext().setCurrentProject(clonedCms.readProject(CmsProject.ONLINE_PROJECT_ID)); 217 // paths are always root path 218 clonedCms.getRequestContext().setSiteRoot(""); 219 220 return clonedCms; 221 } 222 223 /** 224 * Reads the size of a single image.<p> 225 * 226 * @param cms CmsObejct 227 * @param res CmsResource to be read 228 * @return a String representation of the dimension of the given image 229 */ 230 private String getSingleSize(CmsObject cms, CmsResource res) { 231 232 try { 233 BufferedImage img = Simapi.read(cms.readFile(res).getContents()); 234 return "" + img.getWidth() + " x " + img.getHeight() + "px"; 235 } catch (CmsException | IOException e) { 236 return ""; 237 } 238 } 239 240 /** 241 * Reads all cached images.<p> 242 * 243 * @param cms the cms context 244 * @param withVariations if also variations should be read 245 * @param showSize if it is needed to compute the image size 246 * @param statsOnly if only statistical information should be retrieved 247 */ 248 private void init(CmsObject cms, boolean withVariations, boolean showSize, boolean statsOnly) { 249 250 File basedir = new File(CmsImageLoader.getImageRepositoryPath()); 251 try { 252 CmsObject clonedCms = getClonedCmsObject(cms); 253 visitImages(clonedCms, basedir, withVariations, showSize, statsOnly); 254 } catch (CmsException e) { 255 // should never happen 256 } 257 m_variations = Collections.unmodifiableMap(m_variations); 258 m_sizes = Collections.unmodifiableMap(m_sizes); 259 m_lengths = Collections.unmodifiableMap(m_lengths); 260 } 261 262 /** 263 * Visits a single image.<p> 264 * 265 * @param cms CmsObject 266 * @param f a File to be read out 267 * @param withVariations boolean 268 * @param showSize boolean 269 * @param statsOnly boolean 270 */ 271 private void visitImage(CmsObject cms, File f, boolean withVariations, boolean showSize, boolean statsOnly) { 272 273 m_variationsCount++; 274 m_variationsSize += f.length(); 275 String oName = f.getAbsolutePath().substring(CmsImageLoader.getImageRepositoryPath().length()); 276 oName = CmsStringUtil.substitute(oName, "\\", "/"); 277 if (!oName.startsWith("/")) { 278 oName = "/" + oName; 279 } 280 String imgName = oName; 281 CmsResource res = null; 282 boolean found = false; 283 while (!found) { 284 String path = CmsResource.getParentFolder(imgName); 285 String name = imgName.substring(path.length()); 286 String ext = CmsFileUtil.getExtension(imgName); 287 String nameWoExt = name.substring(0, name.length() - ext.length()); 288 int pos = nameWoExt.lastIndexOf("_"); 289 String newName = path; 290 found = (pos < 0); 291 if (!found) { 292 newName += nameWoExt.substring(0, pos); 293 } else { 294 newName += nameWoExt; 295 } 296 newName += ext; 297 try { 298 res = cms.readResource(newName, CmsResourceFilter.ALL); 299 found = true; 300 } catch (Exception e) { 301 // it could be a variation 302 } 303 imgName = newName; 304 } 305 306 if (res != null) { 307 oName = res.getRootPath(); 308 } 309 m_filePaths.put(oName, f.getAbsolutePath()); 310 List variations = (List)m_variations.get(oName); 311 if (variations == null) { 312 variations = new ArrayList(); 313 m_variations.put(oName, variations); 314 if (statsOnly) { 315 return; 316 } 317 if (res != null) { 318 m_lengths.put(oName, "" + res.getLength() + " Bytes"); 319 if (showSize) { 320 m_sizes.put(oName, getSingleSize(cms, res)); 321 } 322 } else { 323 m_lengths.put(oName, "" + f.length() + " Bytes"); 324 if (showSize) { 325 try { 326 BufferedImage img = Simapi.read(f); 327 m_sizes.put(oName, "" + img.getWidth() + " x " + img.getHeight() + "px"); 328 } catch (Throwable e) { 329 // ignore 330 } 331 } 332 } 333 } 334 if (!withVariations) { 335 return; 336 } 337 oName += " ("; 338 if (showSize) { 339 try { 340 BufferedImage img = Simapi.read(f); 341 oName += "" + img.getWidth() + " x " + img.getHeight() + "px - "; 342 } catch (Throwable e) { 343 // ignore 344 } 345 } 346 oName += f.length() + " Bytes)"; 347 variations.add(oName); 348 } 349 350 /** 351 * Visits all cached images in the given directory.<p> 352 * 353 * @param cms the cms context 354 * @param directory the directory to visit 355 * @param withVariations if also variations should be read 356 * @param showSize if it is needed to compute the image size 357 * @param statsOnly if only statistical information should be retrieved 358 */ 359 private void visitImages( 360 CmsObject cms, 361 File directory, 362 boolean withVariations, 363 boolean showSize, 364 boolean statsOnly) { 365 366 if (!directory.canRead() || !directory.isDirectory()) { 367 return; 368 } 369 File[] files = directory.listFiles(); 370 for (int i = 0; i < files.length; i++) { 371 File f = files[i]; 372 if (f.isDirectory()) { 373 visitImages(cms, f, withVariations, showSize, statsOnly); 374 continue; 375 } 376 visitImage(cms, f, withVariations, showSize, statsOnly); 377 } 378 } 379 380}