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.logfile; 029 030import org.opencms.file.CmsResource; 031import org.opencms.main.CmsLog; 032import org.opencms.ui.CmsVaadinUtils; 033import org.opencms.ui.components.CmsBasicDialog; 034import org.opencms.util.CmsStringUtil; 035 036import java.io.File; 037import java.io.FileInputStream; 038import java.io.IOException; 039import java.io.OutputStream; 040import java.util.ArrayList; 041import java.util.HashSet; 042import java.util.List; 043import java.util.Set; 044import java.util.zip.ZipEntry; 045import java.util.zip.ZipOutputStream; 046 047import org.apache.commons.logging.Log; 048 049import com.vaadin.server.FileDownloader; 050import com.vaadin.server.Resource; 051import com.vaadin.server.StreamResource; 052import com.vaadin.ui.Button; 053import com.vaadin.ui.Button.ClickEvent; 054import com.vaadin.ui.Button.ClickListener; 055import com.vaadin.ui.Window; 056import com.vaadin.v7.data.Property.ValueChangeEvent; 057import com.vaadin.v7.data.Property.ValueChangeListener; 058import com.vaadin.v7.shared.ui.combobox.FilteringMode; 059import com.vaadin.v7.ui.CheckBox; 060import com.vaadin.v7.ui.ComboBox; 061 062/** 063 * Class for the Download dialog.<p> 064 */ 065public class CmsLogDownloadDialog extends CmsBasicDialog { 066 067 /** 068 * Helper class for generating the zip file for the log download.<p> 069 */ 070 public static class ZipGenerator { 071 072 /** The set of generated parent directories. */ 073 private Set<String> m_directories = new HashSet<>(); 074 075 /** The zip output. */ 076 private ZipOutputStream m_zos; 077 078 /** 079 * Creates a new instance.<p> 080 * 081 * @param output the output stream to write to 082 */ 083 public ZipGenerator(OutputStream output) { 084 085 m_zos = new ZipOutputStream(output); 086 } 087 088 /** 089 * Adds a file to a zip-stream.<p> 090 * 091 * @param directory to be zipped 092 * @param file to be added zo zip 093 * @throws IOException exception 094 */ 095 public void addToZip(File directory, File file) throws IOException { 096 097 FileInputStream fis = new FileInputStream(file); 098 String dirPath = directory.getCanonicalPath(); 099 String filePath = file.getCanonicalPath(); 100 String zipFilePath; 101 if (CmsStringUtil.isPrefixPath(dirPath, filePath)) { 102 zipFilePath = filePath.substring(dirPath.length() + 1, filePath.length()); 103 } else { 104 String parentName = generateParentName(file); 105 if (!m_directories.contains(parentName)) { 106 m_zos.putNextEntry(new ZipEntry(parentName)); 107 } 108 m_directories.add(parentName); 109 zipFilePath = CmsStringUtil.joinPaths(parentName, file.getName()); 110 } 111 ZipEntry zipEntry = new ZipEntry(zipFilePath); 112 m_zos.putNextEntry(zipEntry); 113 114 byte[] bytes = new byte[1024]; 115 int length; 116 while ((length = fis.read(bytes)) >= 0) { 117 m_zos.write(bytes, 0, length); 118 } 119 m_zos.closeEntry(); 120 fis.close(); 121 } 122 123 /** 124 * Closes the zip stream.<p> 125 * 126 * @throws IOException if something goes wrong 127 */ 128 public void close() throws IOException { 129 130 m_zos.close(); 131 } 132 133 /** 134 * Generates the name of the parent directory in the zip file for a non-standard log file location.<p> 135 * 136 * @param file the log file 137 * @return the generated parent directory name 138 */ 139 String generateParentName(File file) { 140 141 // we might be on Windows, so we can't just assume path is /foo/bar/baz 142 List<String> pathComponents = new ArrayList<>(); 143 for (int i = 0; i < (file.toPath().getNameCount() - 1); i++) { 144 pathComponents.add(file.toPath().getName(i).toString()); 145 } 146 // need trailing slash when writing directory entries to ZipOutputStream 147 return CmsStringUtil.listAsString(pathComponents, "_") + "/"; 148 } 149 150 } 151 152 /** Logger.*/ 153 private static Log LOG = CmsLog.getLog(CmsLogDownloadDialog.class.getName()); 154 155 /**vaadin serial id.*/ 156 private static final long serialVersionUID = -7447640082260176245L; 157 158 /** Path to zip file.*/ 159 private static final String ZIP_PATH = CmsLogFileApp.LOG_FOLDER + "logs.zip"; 160 161 /**File downloader. */ 162 protected FileDownloader m_downloader; 163 164 /**Vaadin component.*/ 165 private Button m_cancel; 166 167 /**Vaadin component.**/ 168 private CheckBox m_donwloadAll; 169 170 /**Vaadin component.*/ 171 private ComboBox m_file; 172 173 /**Vaadin component.*/ 174 private Button m_ok; 175 176 /**total size of log files in MB.*/ 177 private double m_totalSize; 178 179 /** The download provider to be used for this dialog. */ 180 private I_CmsLogDownloadProvider m_logProvider; 181 182 /** 183 * public constructor.<p> 184 * 185 * @param window to hold the dialog 186 * @param filePath path of currently shown file 187 */ 188 public CmsLogDownloadDialog(final Window window, String filePath, I_CmsLogDownloadProvider logProvider) { 189 190 CmsVaadinUtils.readAndLocalizeDesign(this, CmsVaadinUtils.getWpMessagesForCurrentLocale(), null); 191 m_logProvider = logProvider; 192 193 for (String path : m_logProvider.getLogFiles()) { 194 m_file.addItem(path); 195 } 196 197 m_donwloadAll.setVisible(m_logProvider.canDownloadAllLogs()); 198 199 m_file.setFilteringMode(FilteringMode.CONTAINS); 200 m_file.setNullSelectionAllowed(false); 201 m_file.setNewItemsAllowed(false); 202 203 m_file.select(filePath); 204 205 m_cancel.addClickListener(new ClickListener() { 206 207 private static final long serialVersionUID = 4336654148546091114L; 208 209 public void buttonClick(ClickEvent event) { 210 211 window.close(); 212 213 } 214 215 }); 216 m_downloader = new FileDownloader(getDownloadResource()); 217 m_downloader.extend(m_ok); 218 219 ValueChangeListener listener = new ValueChangeListener() { 220 221 private static final long serialVersionUID = -1127012396158402096L; 222 223 public void valueChange(ValueChangeEvent event) { 224 225 m_downloader.setFileDownloadResource(getDownloadResource()); 226 setComboBoxEnable(); 227 228 } 229 }; 230 231 m_file.addValueChangeListener(listener); 232 m_donwloadAll.addValueChangeListener(listener); 233 234 } 235 236 /** 237 * Creates log-file resource for download.<p> 238 * 239 * @return vaadin resource 240 */ 241 protected Resource getDownloadResource() { 242 243 String pathToDownload = (String)m_file.getValue(); 244 if (pathToDownload == null) { 245 return null; 246 } 247 248 if (m_donwloadAll.getValue().booleanValue()) { 249 250 return new StreamResource( 251 () -> m_logProvider.readAllLogs(), 252 m_logProvider.getDownloadPrefix() + "logs.zip"); 253 } 254 255 return new StreamResource( 256 () -> m_logProvider.readLog(pathToDownload), 257 m_logProvider.getDownloadPrefix() + CmsResource.getName(pathToDownload)); 258 } 259 260 /** 261 * En/ disables the combo box for files.<p> 262 */ 263 protected void setComboBoxEnable() { 264 265 m_file.setEnabled(!m_donwloadAll.getValue().booleanValue()); 266 } 267 268}