View Javadoc

1   /**
2    * This file Copyright (c) 2003-2011 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.module.admininterface.pages;
35  
36  import info.magnolia.cms.core.Path;
37  import info.magnolia.cms.core.SystemProperty;
38  import info.magnolia.module.admininterface.TemplatedMVCHandler;
39  
40  import java.io.File;
41  import java.io.FileInputStream;
42  import java.io.FileNotFoundException;
43  import java.io.FileReader;
44  import java.io.LineNumberReader;
45  import java.io.PrintWriter;
46  import java.io.StringWriter;
47  import java.util.ArrayList;
48  import java.util.Collection;
49  import java.util.Iterator;
50  
51  import javax.servlet.ServletOutputStream;
52  import javax.servlet.http.HttpServletRequest;
53  import javax.servlet.http.HttpServletResponse;
54  
55  import org.apache.commons.io.FileUtils;
56  import org.apache.commons.io.IOUtils;
57  import org.apache.commons.io.filefilter.TrueFileFilter;
58  import org.apache.commons.io.filefilter.WildcardFileFilter;
59  import org.apache.commons.lang.StringEscapeUtils;
60  import org.apache.commons.lang.StringUtils;
61  import org.slf4j.Logger;
62  import org.slf4j.LoggerFactory;
63  
64  public class LogViewerPage extends TemplatedMVCHandler {
65      private static final Logger log = LoggerFactory.getLogger(LogViewerPage.class);
66  
67      private final static String LOGS_FOLDER_PROPERTY = "magnolia.logs.dir";
68  
69      public LogViewerPage(String name, HttpServletRequest request, HttpServletResponse response) {
70          super(name, request, response);
71  
72          // initialize the folder variable
73          String temp = SystemProperty.getProperty(LOGS_FOLDER_PROPERTY);
74          if (temp != null) {
75              logsFolder = Path.getAbsoluteFileSystemPath(temp);
76          }
77      }
78  
79      private String logsFolder = "";
80  
81      private String fileName = "";
82  
83      private String text = "";
84  
85      private Collection namesList = null;
86  
87      private long maxNumLinesPerPage = 50;
88  
89      private long pageNumber = 0;
90  
91      private long totalPages = 0;
92  
93      private long currentPosition = 0;
94  
95      private long fileSizeInLines = 0;
96  
97      /**
98       * the content of the select
99       *
100      * @return
101      */
102     public Collection getLogFiles() {
103 
104         ArrayList urls = new ArrayList();
105 
106         File logDir = new File(this.logsFolder);
107         Collection files = null;
108         if (logDir.exists()) {
109             files = FileUtils.listFiles(logDir, new WildcardFileFilter("*.log*"), TrueFileFilter.TRUE);
110 
111             Iterator filesIterator = files.iterator();
112             String name = "";
113             while (filesIterator.hasNext()) {
114                 name = ((File) filesIterator.next()).getName();
115                 urls.add(name);
116             }
117         }
118         return urls;
119     }
120 
121     public String refresh() {
122         displayFileContent();
123         return VIEW_SHOW;
124     }
125 
126     public String next() {
127         this.currentPosition = Math.min(this.currentPosition + this.maxNumLinesPerPage, this.fileSizeInLines - 1);
128         displayFileContent();
129         return VIEW_SHOW;
130     }
131 
132     public String previous() {
133         this.currentPosition = Math.max(0, this.currentPosition - this.maxNumLinesPerPage);
134         displayFileContent();
135         return VIEW_SHOW;
136     }
137 
138     public String begin() {
139         this.currentPosition = 0;
140         displayFileContent();
141         return VIEW_SHOW;
142     }
143 
144     public String end() {
145         if (this.fileSizeInLines > this.maxNumLinesPerPage) {
146             this.currentPosition = this.fileSizeInLines - (this.fileSizeInLines % this.maxNumLinesPerPage);
147         } else {
148             currentPosition = 0;
149         }
150         displayFileContent();
151         return VIEW_SHOW;
152     }
153 
154     public String download() throws FileNotFoundException {
155         // set mime/type
156         File file = getFile();
157         this.getResponse().setContentType("html/text");
158         this.getResponse().setHeader("Content-Disposition", "attachment; filename=" + fileName);
159 
160         FileInputStream is = new FileInputStream(file);
161         this.getResponse().setContentLength((int) file.length());
162 
163         try {
164             sendUnCompressed(is, this.getResponse());
165         } catch (Exception e) {
166             log.info("File download failed [{}]: {}", fileName, e.getMessage());
167         } finally {
168             IOUtils.closeQuietly(is);
169         }
170 
171         return "";
172     }
173 
174     private void sendUnCompressed(java.io.InputStream is, HttpServletResponse res) throws Exception {
175         ServletOutputStream os = res.getOutputStream();
176         byte[] buffer = new byte[8192];
177         int read = 0;
178         while ((read = is.read(buffer)) > 0) {
179             os.write(buffer, 0, read);
180         }
181         os.flush();
182         os.close();
183     }
184 
185     public String displayFileContent() {
186 
187         StringWriter str = new StringWriter();
188         if (StringUtils.isNotEmpty(this.fileName)) {
189             FileReader logFile = null;
190             LineNumberReader input = null;
191             try {
192                 // need file to get size
193                 File file = getFile();
194 
195                 logFile = new FileReader(file);
196                 this.fileSizeInLines = countLines(file);
197                 PrintWriter writer = new PrintWriter(str);
198 
199                 input = new LineNumberReader(logFile);
200 
201                 String line;
202                 int numLines = 0;
203                 while ((line = input.readLine()) != null) {
204 
205                     if (input.getLineNumber() >= this.currentPosition) {
206                         writer.write(StringEscapeUtils.escapeHtml(line));
207                         writer.write("<br/>");
208                         numLines++;
209                     }
210                     if (numLines >= this.maxNumLinesPerPage) {
211                         break;
212                     }
213                 }
214                 writer.flush();
215                 this.text = str.toString();
216                 writer.close();
217 
218                 setFieldValues();
219 
220             } catch (Exception e) {
221                 this.text = e.getMessage();
222                 log.error("Error can't read file:", e);
223                 return VIEW_SHOW;
224             } finally {
225 
226                 closeFile(logFile, input);
227             }
228         }
229 
230         return VIEW_SHOW;
231     }
232 
233     private File getFile() {
234         if (this.fileName.length() > 0) {
235             File file = new File(this.logsFolder + "/" + this.fileName);
236             return file;
237         }
238         return null;
239     }
240 
241     private void setFieldValues() {
242         this.pageNumber = (this.currentPosition / this.maxNumLinesPerPage) + 1;
243         this.totalPages = (this.fileSizeInLines / this.maxNumLinesPerPage) + 1;
244         long mod = this.currentPosition % this.maxNumLinesPerPage;
245         if (mod > 0) {
246             // someone switched page size in between the exact multiples of the pages or there is only one page in total
247             this.pageNumber++;
248             this.totalPages++;
249         }
250     }
251 
252     /* gets the number of lines for pagination */
253     private long countLines(File file) {
254         int count = 0;
255         FileReader fileReader = null;
256         LineNumberReader lineReader = null;
257         try {
258             fileReader = new FileReader(file);
259             lineReader = new LineNumberReader(fileReader);
260 
261             lineReader.skip(file.length() );
262             count = lineReader.getLineNumber() + 1;
263 
264         } catch (Exception e) {
265             count = 0;
266         } finally {
267 
268             closeFile(fileReader, lineReader);
269         }
270 
271         return count;
272     }
273 
274     private void closeFile(FileReader fileReader, LineNumberReader lineReader) {
275         try {
276             if (fileReader != null) {
277                 fileReader.close();
278 
279             }
280             if (lineReader != null) {
281                 lineReader.close();
282             }
283         } catch (Exception e) {
284 
285         }
286     }
287 
288     public String getFileName() {
289         return this.fileName;
290     }
291 
292     public void setFileName(String fileName) {
293         this.fileName = fileName;
294     }
295 
296     public Collection getNamesList() {
297         if (this.namesList == null) {
298             this.namesList = getLogFiles();
299         }
300         return this.namesList;
301     }
302 
303     public String getText() {
304         return this.text;
305     }
306 
307     public long getCurrentPosition() {
308         return this.currentPosition;
309     }
310 
311     public void setCurrentPosition(long currentPosition) {
312         // make sure number never exceeds bounds
313         this.currentPosition = Math.max(0, Math.min(currentPosition, this.fileSizeInLines - (this.fileSizeInLines % this.maxNumLinesPerPage)));
314     }
315 
316     public long getFileSizeInLines() {
317         return this.fileSizeInLines;
318     }
319 
320     public void setFileSizeInLines(long fileSizeInLines) {
321         this.fileSizeInLines = fileSizeInLines;
322     }
323 
324     public long getPageNumber() {
325         return this.pageNumber;
326     }
327 
328     public long getTotalPages() {
329         return this.totalPages;
330     }
331 
332     public long getMaxNumLinesPerPage() {
333         return this.maxNumLinesPerPage;
334     }
335 
336     /**
337      * Sets new maximum value in the range <1, LONG_MAX>. 0 or negative values are ignored.
338      * @param maxNumLinesPerPage
339      */
340     public void setMaxNumLinesPerPage(long maxNumLinesPerPage) {
341         if (maxNumLinesPerPage < 1) {
342             return;
343         }
344         this.maxNumLinesPerPage = maxNumLinesPerPage;
345     }
346 
347 }