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, 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 org.opencms.cache.CmsLruCache; 031import org.opencms.flex.CmsFlexCache; 032import org.opencms.loader.CmsImageLoader; 033import org.opencms.main.OpenCms; 034import org.opencms.monitor.CmsMemoryStatus; 035import org.opencms.ui.A_CmsUI; 036import org.opencms.ui.CmsVaadinUtils; 037import org.opencms.ui.FontOpenCms; 038import org.opencms.ui.apps.A_CmsWorkplaceApp; 039import org.opencms.ui.apps.CmsFileExplorer; 040import org.opencms.ui.apps.Messages; 041import org.opencms.ui.components.CmsInfoButton; 042import org.opencms.util.CmsFileUtil; 043import org.opencms.util.CmsStringUtil; 044 045import java.io.File; 046import java.util.LinkedHashMap; 047import java.util.List; 048import java.util.Map; 049 050import org.apache.commons.io.FileUtils; 051 052import com.vaadin.server.Sizeable.Unit; 053import com.vaadin.ui.Component; 054import com.vaadin.ui.HorizontalSplitPanel; 055import com.vaadin.ui.UI; 056import com.vaadin.ui.themes.ValoTheme; 057import com.vaadin.v7.event.FieldEvents.TextChangeEvent; 058import com.vaadin.v7.event.FieldEvents.TextChangeListener; 059import com.vaadin.v7.shared.ui.label.ContentMode; 060import com.vaadin.v7.ui.Label; 061import com.vaadin.v7.ui.ProgressBar; 062import com.vaadin.v7.ui.TextField; 063import com.vaadin.v7.ui.VerticalLayout; 064 065/** 066 * Class for the app which shows the content of caches.<p> 067 */ 068public class CmsCacheViewApp extends A_CmsWorkplaceApp { 069 070 /** 071 * Modes to run this app. 072 */ 073 public static enum Mode { 074 /**Shows FlexCache.*/ 075 FlexCache, 076 /**Shows ImageCache.*/ 077 ImageCache; 078 } 079 080 /**Mode.*/ 081 private Mode m_mode; 082 083 /** The file table filter input. */ 084 private TextField m_siteTableFilter; 085 086 /** 087 * public constructor.<p> 088 * 089 * @param mode of app 090 */ 091 public CmsCacheViewApp(Mode mode) { 092 093 m_mode = mode; 094 } 095 096 /** 097 * Creates in info button for java cache statistics.<p> 098 * 099 * @return CmsInfoButton 100 */ 101 public static CmsInfoButton getJavaStatisticButton() { 102 103 return getJavaStatisticButton(OpenCms.getMemoryMonitor().getMemoryStatus()); 104 105 } 106 107 /** 108 * Creates in info button for java cache statistics.<p> 109 * @param memory memory object 110 * 111 * @return CmsInfoButton 112 */ 113 public static CmsInfoButton getJavaStatisticButton(CmsMemoryStatus memory) { 114 115 Map<String, String> infoMap = new LinkedHashMap<String, String>(); 116 117 infoMap.put( 118 CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_JAVA_HEAP_MAX_0), 119 CmsFileUtil.formatFilesize( 120 memory.getMaxMemory() * 1048576, 121 A_CmsUI.getCmsObject().getRequestContext().getLocale())); 122 infoMap.put( 123 CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_JAVA_HEAP_TOTAL_0), 124 CmsFileUtil.formatFilesize( 125 memory.getTotalMemory() * 1048576, 126 A_CmsUI.getCmsObject().getRequestContext().getLocale())); 127 infoMap.put( 128 CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_JAVA_HEAP_USED_0), 129 CmsFileUtil.formatFilesize( 130 memory.getUsedMemory() * 1048576, 131 A_CmsUI.getCmsObject().getRequestContext().getLocale())); 132 infoMap.put( 133 CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_JAVA_HEAP_FREE_0), 134 CmsFileUtil.formatFilesize( 135 memory.getFreeMemory() * 1048576, 136 A_CmsUI.getCmsObject().getRequestContext().getLocale())); 137 138 CmsInfoButton info = new CmsInfoButton(infoMap); 139 VerticalLayout prog = new VerticalLayout(); 140 Label label = new Label(); 141 label.setContentMode(ContentMode.HTML); 142 label.setValue( 143 "<p>" + CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_FLEXCACHE_LABEL_MEMORY_BLOCK_0) + "</p>"); 144 prog.addComponent(label); 145 prog.addComponent(getProgressBar((((float)memory.getUsage() / 100)))); 146 info.addAdditionalElement(prog, 0); 147 info.setWindowCaption(CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_FLEX_0)); 148 info.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_FLEX_0)); 149 return info; 150 } 151 152 /** 153 * Gets a Progressbar with css style set.<p> 154 * 155 * @param value of the bar 156 * @return vaadin ProgressBar 157 */ 158 public static ProgressBar getProgressBar(float value) { 159 160 ProgressBar res = new ProgressBar(value); 161 String style = ""; 162 if (value > 0.75) { 163 style = "o-nearlyfull"; 164 } 165 if (value > 0.9) { 166 style = "o-full"; 167 } 168 res.addStyleName(style); 169 return res; 170 } 171 172 /** 173 * Creates in info button for flex cache statistics.<p> 174 * 175 * @return CmsInfoButton 176 */ 177 protected static CmsInfoButton getFlexStatisticButton() { 178 179 Map<String, String> infoMap = new LinkedHashMap<String, String>(); 180 181 CmsFlexCache cache = OpenCms.getFlexCache(); 182 CmsLruCache entryLruCache = cache.getEntryLruCache(); 183 184 infoMap.put( 185 CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_FLEXCACHE_LABEL_STATS_KEYS_0), 186 String.valueOf(cache.keySize())); 187 infoMap.put( 188 CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_FLEXCACHE_LABEL_STATS_VARIATIONS_0), 189 String.valueOf(cache.size())); 190 infoMap.put( 191 CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_FLEXCACHE_LABEL_MEMORY_MAXSIZE_0), 192 CmsFileUtil.formatFilesize( 193 entryLruCache.getMaxCacheCosts(), 194 A_CmsUI.getCmsObject().getRequestContext().getLocale())); 195 infoMap.put( 196 CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_FLEXCACHE_LABEL_MEMORY_CURSIZE_0), 197 CmsFileUtil.formatFilesize( 198 entryLruCache.getObjectCosts(), 199 A_CmsUI.getCmsObject().getRequestContext().getLocale())); 200 CmsInfoButton info = new CmsInfoButton(infoMap); 201 VerticalLayout prog = new VerticalLayout(); 202 Label label = new Label(); 203 label.setContentMode(ContentMode.HTML); 204 label.setValue( 205 "<p>" + CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_FLEXCACHE_LABEL_MEMORY_BLOCK_0) + "</p>"); 206 prog.addComponent(label); 207 208 prog.addComponent( 209 getProgressBar((float)entryLruCache.getObjectCosts() / (float)entryLruCache.getMaxCacheCosts())); 210 info.addAdditionalElement(prog, 0); 211 info.setWindowCaption(CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_FLEX_0)); 212 info.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_FLEX_0)); 213 return info; 214 } 215 216 /** 217 * Creates in info button for image cache statistics.<p> 218 * 219 * @return CmsInfoButton 220 */ 221 protected static CmsInfoButton getImageStatisticButton() { 222 223 long size = 0L; 224 if (new File(CmsImageLoader.getImageRepositoryPath()).exists()) { 225 size = FileUtils.sizeOfDirectory(new File(CmsImageLoader.getImageRepositoryPath())); 226 } 227 228 Map<String, String> infoMap = new LinkedHashMap<String, String>(); 229 230 infoMap.put( 231 CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_IMAGECACHE_LABEL_MEMORY_BLOCK_0), 232 CmsFileUtil.formatFilesize(size, A_CmsUI.getCmsObject().getRequestContext().getLocale())); 233 234 CmsInfoButton info = new CmsInfoButton(infoMap); 235 236 info.setWindowCaption(CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_IMAGE_0)); 237 info.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_IMAGE_0)); 238 return info; 239 } 240 241 /** 242 * @see org.opencms.ui.apps.A_CmsWorkplaceApp#getBreadCrumbForState(java.lang.String) 243 */ 244 @Override 245 protected LinkedHashMap<String, String> getBreadCrumbForState(String state) { 246 247 LinkedHashMap<String, String> crumbs = new LinkedHashMap<String, String>(); 248 249 if (CmsStringUtil.isEmptyOrWhitespaceOnly(state)) { 250 if (Mode.FlexCache.equals(m_mode)) { 251 crumbs.put("", CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_VIEW_FLEX_0)); 252 } else { 253 crumbs.put("", CmsVaadinUtils.getMessageText(Messages.GUI_CACHE_VIEW_IMAGE_0)); 254 } 255 return crumbs; 256 } 257 return new LinkedHashMap<String, String>(); //size==1 & state was not empty -> state doesn't match to known path 258 } 259 260 /** 261 * @see org.opencms.ui.apps.A_CmsWorkplaceApp#getComponentForState(java.lang.String) 262 */ 263 @Override 264 protected Component getComponentForState(String state) { 265 266 //remove filter field 267 if (m_siteTableFilter != null) { 268 m_infoLayout.removeComponent(m_siteTableFilter); 269 m_siteTableFilter = null; 270 } 271 272 if (Mode.FlexCache.equals(m_mode)) { 273 m_rootLayout.setMainHeightFull(true); 274 return getFlexViewComponent(); 275 } 276 277 if (Mode.ImageCache.equals(m_mode)) { 278 m_rootLayout.setMainHeightFull(true); 279 return getImageViewComponent(); 280 } 281 return null; 282 } 283 284 /** 285 * @see org.opencms.ui.apps.A_CmsWorkplaceApp#getSubNavEntries(java.lang.String) 286 */ 287 @Override 288 protected List<NavEntry> getSubNavEntries(String state) { 289 290 return null; 291 292 } 293 294 /** 295 * Layout for the Flex Cache View includings statistics and cache table.<p> 296 * 297 * @return vaadin component 298 */ 299 private Component getFlexViewComponent() { 300 301 final CmsFlexCacheTable table = new CmsFlexCacheTable(); 302 m_siteTableFilter = new TextField(); 303 m_siteTableFilter.setIcon(FontOpenCms.FILTER); 304 m_siteTableFilter.setInputPrompt( 305 Messages.get().getBundle(UI.getCurrent().getLocale()).key(Messages.GUI_EXPLORER_FILTER_0)); 306 m_siteTableFilter.addStyleName(ValoTheme.TEXTFIELD_INLINE_ICON); 307 m_siteTableFilter.setWidth("200px"); 308 m_siteTableFilter.addTextChangeListener(new TextChangeListener() { 309 310 private static final long serialVersionUID = 1L; 311 312 public void textChange(TextChangeEvent event) { 313 314 table.filterTable(event.getText()); 315 } 316 }); 317 m_infoLayout.addComponent(m_siteTableFilter); 318 319 m_uiContext.addToolbarButton(getFlexStatisticButton()); 320 m_uiContext.addToolbarButton(CmsFlushCache.getFlushToolButton()); 321 322 table.setSizeFull(); 323 return table; 324 } 325 326 /** 327 * Creates the view for the image cache.<p> 328 * 329 * @return a vaadin vertical layout with the information about the image cache 330 */ 331 private Component getImageViewComponent() { 332 333 m_siteTableFilter = new TextField(); 334 335 HorizontalSplitPanel sp = new HorizontalSplitPanel(); 336 sp.setSizeFull(); 337 VerticalLayout intro = CmsVaadinUtils.getInfoLayout(Messages.GUI_CACHE_IMAGE_INTRODUCTION_0); 338 VerticalLayout nullResult = CmsVaadinUtils.getInfoLayout(Messages.GUI_CACHE_IMAGE_NO_RESULTS_0); 339 final CmsImageCacheTable table = new CmsImageCacheTable(intro, nullResult, m_siteTableFilter); 340 341 sp.setFirstComponent(new CmsImageCacheInput(table)); 342 343 VerticalLayout secC = new VerticalLayout(); 344 secC.setSizeFull(); 345 secC.addComponent(intro); 346 secC.addComponent(nullResult); 347 secC.addComponent(table); 348 349 m_siteTableFilter.setIcon(FontOpenCms.FILTER); 350 m_siteTableFilter.setInputPrompt( 351 Messages.get().getBundle(UI.getCurrent().getLocale()).key(Messages.GUI_EXPLORER_FILTER_0)); 352 m_siteTableFilter.addStyleName(ValoTheme.TEXTFIELD_INLINE_ICON); 353 m_siteTableFilter.setWidth("200px"); 354 m_siteTableFilter.addTextChangeListener(new TextChangeListener() { 355 356 private static final long serialVersionUID = 1L; 357 358 public void textChange(TextChangeEvent event) { 359 360 table.filterTable(event.getText()); 361 } 362 }); 363 m_infoLayout.addComponent(m_siteTableFilter); 364 365 m_uiContext.addToolbarButton(getImageStatisticButton()); 366 m_uiContext.addToolbarButton(CmsFlushCache.getFlushToolButton()); 367 table.setSizeFull(); 368 sp.setSecondComponent(secC); 369 sp.setSplitPosition(CmsFileExplorer.LAYOUT_SPLIT_POSITION, Unit.PIXELS); 370 371 table.setVisible(false); 372 nullResult.setVisible(false); 373 m_siteTableFilter.setVisible(false); 374 375 return sp; 376 } 377}