/** * OpenKM, Open Document Management System (http://www.openkm.com) * Copyright (c) 2006-2011 Paco Avila & Josep Llort * * No bytes were intentionally harmed during the development of this application. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package com.openkm.servlet.admin; import java.awt.Color; import java.awt.Font; import java.io.File; import java.io.IOException; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.block.BlockBorder; import org.jfree.chart.block.ColumnArrangement; import org.jfree.chart.plot.PiePlot; import org.jfree.chart.title.LegendTitle; import org.jfree.data.general.DefaultPieDataset; import org.jfree.ui.RectangleEdge; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.openkm.bean.StatsInfo; import com.openkm.core.Config; import com.openkm.core.RepositoryInfo; import com.openkm.util.FormatUtil; import com.openkm.util.WebUtils; /** * Stats graphical servlet */ public class StatsGraphServlet extends BaseServlet { private static final long serialVersionUID = 1L; private static Logger log = LoggerFactory.getLogger(StatsGraphServlet.class); private static final String DOCUMENTS = "0"; private static final String DOCUMENTS_SIZE = "1"; private static final String FOLDERS = "2"; private static final String MEMORY = "3"; private static final String DISK = "4"; public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String type = WebUtils.getString(request, "t"); JFreeChart chart = null; updateSessionManager(request); try { response.setContentType("image/png"); OutputStream out = response.getOutputStream(); if (DOCUMENTS.equals(type) || DOCUMENTS_SIZE.equals(type) || FOLDERS.equals(type)) { chart = repoStats(type); } else if (DISK.equals(type)) { chart = diskStats(); } else if (MEMORY.equals(type)) { chart = memStats(); } if (chart != null) { // Customize title font chart.getTitle().setFont(new Font("Tahoma", Font.BOLD, 16)); // Match body { background-color:#F6F6EE; } chart.setBackgroundPaint(new Color(246, 246, 238)); // Customize no data PiePlot plot = (PiePlot) chart.getPlot(); plot.setNoDataMessage("No data to display"); // Customize labels plot.setLabelGenerator(null); // Customize legend LegendTitle legend = new LegendTitle(plot, new ColumnArrangement(), new ColumnArrangement()); legend.setPosition(RectangleEdge.BOTTOM); legend.setFrame(BlockBorder.NONE); legend.setItemFont(new Font("Tahoma", Font.PLAIN, 12)); chart.removeLegend(); chart.addLegend(legend); if (DISK.equals(type) || MEMORY.equals(type)) { ChartUtilities.writeChartAsPNG(out, chart, 225, 225); } else { ChartUtilities.writeChartAsPNG(out, chart, 250, 250); } } out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); } } /** * Generate disk statistics */ public JFreeChart diskStats() throws IOException, ServletException { String title = "Disk usage"; String repHome = null; // Allow absolute repository path if ((new File(Config.REPOSITORY_HOME)).isAbsolute()) { repHome = Config.REPOSITORY_HOME; } else { repHome = Config.HOME_DIR + File.separator + Config.REPOSITORY_HOME; } File df = new File(repHome); long total = df.getTotalSpace(); long usable = df.getUsableSpace(); long used = total - usable; log.debug("Total space: {}", FormatUtil.formatSize(total)); log.debug("Usable space: {}", FormatUtil.formatSize(usable)); log.debug("Used space: {}", FormatUtil.formatSize(used)); DefaultPieDataset dataset = new DefaultPieDataset(); dataset.setValue("Available (" + FormatUtil.formatSize(usable) + ")", usable * 100 / total); dataset.setValue("Used (" + FormatUtil.formatSize(used) + ")", used * 100 / total); return ChartFactory.createPieChart(title, dataset, true, false, false); } /** * Generate memory statistics * http://blog.codebeach.com/2008/02/determine-available-memory-in-java.html */ public JFreeChart memStats() throws IOException, ServletException { String title = "Memory usage"; Runtime runtime = Runtime.getRuntime(); long max = runtime.maxMemory(); // maximum amount of memory that the JVM will attempt to use long available = runtime.totalMemory(); // total amount of memory in the JVM long free = runtime.freeMemory(); // amount of free memory in the JVM long used = max - available; long total = free + used; log.debug("Maximun memory: {}", FormatUtil.formatSize(max)); log.debug("Available memory: {}", FormatUtil.formatSize(available)); log.debug("Free memory: {}", FormatUtil.formatSize(free)); log.debug("Used memory: {}", FormatUtil.formatSize(used)); log.debug("Total memory: {}", FormatUtil.formatSize(total)); DefaultPieDataset dataset = new DefaultPieDataset(); dataset.setValue("Available (" + FormatUtil.formatSize(free) + ")", free * 100 / total); dataset.setValue("Used (" + FormatUtil.formatSize(used) + ")", used * 100 / total); return ChartFactory.createPieChart(title, dataset, true, false, false); } /** * Generate repository statistics */ public JFreeChart repoStats(String type) throws IOException, ServletException { String title = null; String[] sizes = null; double[] percents = null; DefaultPieDataset dataset = new DefaultPieDataset(); if (DOCUMENTS.equals(type)) { StatsInfo si = RepositoryInfo.getDocumentsByContext(); percents = si.getPercents(); sizes = si.getSizes(); title = "Documents by context"; } else if (DOCUMENTS_SIZE.equals(type)) { StatsInfo si = RepositoryInfo.getDocumentsSizeByContext(); percents = si.getPercents(); sizes = si.getSizes().clone(); for (int i = 0; i < sizes.length; i++) { sizes[i] = FormatUtil.formatSize(Long.parseLong(sizes[i])); } title = "Documents size by context"; } else if (FOLDERS.equals(type)) { StatsInfo si = RepositoryInfo.getFoldersByContext(); percents = si.getPercents(); sizes = si.getSizes(); title = "Folders by context"; } if (title != null && sizes.length > 0 && percents.length > 0) { dataset.setValue("Taxonomy (" + sizes[0] + ")", percents[0]); dataset.setValue("Personal (" + sizes[1] + ")", percents[1]); dataset.setValue("Template (" + sizes[2] + ")", percents[2]); dataset.setValue("Trash (" + sizes[3] + ")", percents[3]); } return ChartFactory.createPieChart(title, dataset, true, false, false); } /** * Convert a piechartdata to xml * * @author puspendu.banerjee@gmail.com */ public String repoStatsXML(final String title, final DefaultPieDataset dataset) throws IOException, ServletException { Document document = DocumentHelper.createDocument(); Element root = document.addElement("RepoStats"); root.addElement("Title").addCDATA(title); Element dataSetElement =root.addElement("DataSet"); for (int i=0; i<dataset.getItemCount(); i++) { Element itemElement= dataSetElement.addElement("Item"); itemElement.addElement("name").addCDATA(dataset.getKey(i).toString()); itemElement.addAttribute("percent", dataset.getValue(i).toString()); dataSetElement.add(itemElement); } return document.asXML(); } }