📄 cmsrfsfileviewer.java
字号:
/*
* File : $Source: /usr/local/cvs/opencms/src/org/opencms/util/CmsRfsFileViewer.java,v $
* Date : $Date: 2006/11/23 16:59:38 $
* Version: $Revision: 1.19 $
*
* This library is part of OpenCms -
* the Open Source Content Mananagement System
*
* Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* For further information about Alkacon Software GmbH, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.opencms.util;
import org.opencms.i18n.CmsEncoder;
import org.opencms.main.CmsIllegalArgumentException;
import org.opencms.main.CmsLog;
import org.opencms.main.CmsRuntimeException;
import org.opencms.main.OpenCms;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import org.apache.commons.logging.Log;
/**
* The representation of a RFS file along with the settings to provide
* access to certain portions (amount of lines) of it. <p>
*
* Most often the underlying file will be the OpenCms logfile. <p>
*
* The portion of the file that is shown is defined by a "window" of "windowSize" lines of text
* at a position "windowPosition" which is an enumeration of windows in ascending order. <p>
*
* @author Achim Westermann
*
* @version $Revision: 1.19 $
*
* @since 6.0.0
*/
public class CmsRfsFileViewer implements Cloneable {
/** The log object for this class. */
protected static final Log LOG = CmsLog.getLog(CmsRfsFileViewer.class);
/** Decides whethter the view onto the underlying file via readFilePortion is enabled. */
private boolean m_enabled;
/** The character encoding of the underlying file. */
private Charset m_fileEncoding;
/** Maps file paths to internal info instances. */
protected Map m_fileName2lineIndex;
/** The path to the underlying file. */
protected String m_filePath;
/**
* If value is <code>true</code>, all setter methods will throw a
* <code>{@link CmsRuntimeException}</code><p>.
*
* Only the method <code>{@link #clone()}</code> returns a clone that has set this
* member to <code>false</code> allowing modification to take place.<p>
*/
private boolean m_frozen;
/**
* If true the represented file is a standard OpenCms log file and may be displayed
* in more convenient ways (in future versions) because the format is known.
*/
private boolean m_isLogfile;
/** The current window (numbered from zero to amount of possible different windows). */
protected int m_windowPos;
/** The amount of lines to show. */
protected int m_windowSize;
/**
* Creates an instance with default settings that tries to use the log file path obtained
* from <code>{@link OpenCms}'s {@link org.opencms.main.CmsSystemInfo}</code> instance.<p>
*
* If the log file path is invalid or not configured correctly a logging is performed and the
* path remains empty to allow user-specified file selection.<p>
*/
public CmsRfsFileViewer() {
m_isLogfile = true;
m_fileName2lineIndex = new HashMap();
// system default charset: see http://java.sun.com/j2se/corejava/intl/reference/faqs/index.html#default-encoding
m_fileEncoding = Charset.forName(new OutputStreamWriter(new ByteArrayOutputStream()).getEncoding());
m_enabled = true;
m_windowSize = 200;
}
/**
* Internal helper that throws a <code>{@link CmsRuntimeException}</code> if the
* configuration of this instance has been frozen ({@link #setFrozen(boolean)}).<p>
*
* @throws CmsRuntimeException if the configuration of this instance has been frozen
* ({@link #setFrozen(boolean)})
*/
private void checkFrozen() throws CmsRuntimeException {
if (m_frozen) {
throw new CmsRuntimeException(Messages.get().container(Messages.ERR_FILE_VIEW_SETTINGS_FROZEN_0));
}
}
/**
* Returns a clone of this file view settings that is not "frozen" and therefore allows modifications.<p>
*
* Every instance that plans to modify settings has to obtain a clone first that may be
* modified. The original instance returned from
* (<code>{@link org.opencms.workplace.CmsWorkplaceManager#getFileViewSettings()}</code>) will throw
* a <code>{@link CmsRuntimeException}</code> for each setter invocation. <p>
*
* @return a clone of this file view settings that is not "frozen" and therefore allows modifications
*/
public Object clone() {
// first run after installation: filePath is null:
if (m_filePath == null) {
// below that runlevel the following call will fail (not initialized from config yet):
if (OpenCms.getRunLevel() >= OpenCms.RUNLEVEL_3_SHELL_ACCESS) {
m_filePath = OpenCms.getSystemInfo().getLogFileRfsPath();
}
}
CmsRfsFileViewer clone = new CmsRfsFileViewer();
try {
// strings are immutable: no outside modification possible.
clone.setFilePath(m_filePath);
} catch (CmsRfsException e) {
// will never happen because m_filePath was verified in setFilePath of this instance.
} catch (CmsRuntimeException e) {
// will never happen because m_filePath was verified in setFilePath of this instance.
}
clone.m_fileEncoding = m_fileEncoding;
clone.m_isLogfile = m_isLogfile;
clone.m_enabled = m_enabled;
//clone.m_windowPos = m_windowPos;
clone.setWindowSize(m_windowSize);
clone.m_fileName2lineIndex = m_fileName2lineIndex;
// allow clone-modifications.
clone.m_frozen = false;
return clone;
}
/**
* Returns the canonical name of the character encoding of the underlying file.<p>
*
* If no special choice is fed into
* <code>{@link #setFileEncoding(String)}</code> before this call
* always the system default character encoding is returned.<p>
*
* This value may be ignored outside and will be ignored inside if the
* underlying does not contain textual content.<p>
*
* @return the canonical name of the character encoding of the underlying file
*/
public String getFileEncoding() {
return m_fileEncoding.name();
}
/**
* Returns the path denoting the file that is accessed.<p>
*
* @return the path denoting the file that is accessed
*/
public String getFilePath() {
return m_filePath;
}
/**
* Returns true if the view's internal file path points to a log file in standard OpenCms format.<p>
*
* @return true if the view's internal file path points to a log file in standard OpenCms format
*/
public boolean getIsLogfile() {
// method name is bean-convention of apache.commons.beanutils (unlike eclipse's convention for booleans)
return m_isLogfile;
}
/**
* Returns the start position of the current display.<p>
*
* This is a count of "windows" that
* consist of viewable text with "windowSize" lines of text (for a non-standard log file) or
* log-entries (for a standard log file).<p>
*
* @return the start position of the current display
*/
public int getWindowPos() {
return m_windowPos;
}
/**
* Get the amount of lines (or entries depending on wether a standard log file is shown)
* to display per page. <p>
*
* @return the amount of lines to display per page
*/
public int getWindowSize() {
return m_windowSize;
}
/**
* Returns true if this view upon the underlying file via
* <code>{@link #readFilePortion()}</code> is enabled.<p>
*
*
* @return true if this view upon the underlying file via
* <code>{@link #readFilePortion()}</code> is enabled.<p>
*/
public boolean isEnabled() {
return m_enabled;
}
/**
* Return the view portion of lines of text from the underlying file or an
* empty String if <code>{@link #isEnabled()}</code> returns <code>false</code>.<p>
*
* @return the view portion of lines of text from the underlying file or an
* empty String if <code>{@link #isEnabled()}</code> returns <code>false</code>
* @throws CmsRfsException if something goes wrong
*/
public String readFilePortion() throws CmsRfsException {
if (m_enabled) {
// if we want to view the logfile we have to set the internal m_windowPos to the last window
// to view the end:
int lines = -1;
int startLine;
if (m_isLogfile) {
lines = scrollToFileEnd();
// for logfile mode we show the last window of window size:
// it could be possible that only 4 lines are in the last window
// (e.g.: 123 lines with windowsize 10 -> last window has 3 lines)
// so we ignore the window semantics and show the n last lines:
startLine = lines - m_windowSize;
} else {
m_windowPos = 0;
startLine = m_windowPos * m_windowSize;
}
LineNumberReader reader = null;
try {
// don't make the buffer too big, just big enough for windowSize lines (estimation: avg. of 200 characters per line)
// to save reading too much (this optimizes to read the first windows, much later windows will be slower...)
reader = new LineNumberReader(new BufferedReader(new InputStreamReader(
new FileInputStream(m_filePath),
m_fileEncoding)), (int)m_windowSize * 200);
int currentLine = 0;
// skip the lines to the current window:
while (startLine > currentLine) {
reader.readLine();
currentLine++;
}
StringBuffer result = new StringBuffer();
String read = reader.readLine();
// logfile treatment is different
// we invert the lines: latest come first
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -