001: ////////////////////////////////////////////////////////////////////////////////
002: // checkstyle: Checks Java source code for adherence to a set of rules.
003: // Copyright (C) 2001-2007 Oliver Burn
004: //
005: // This library is free software; you can redistribute it and/or
006: // modify it under the terms of the GNU Lesser General Public
007: // License as published by the Free Software Foundation; either
008: // version 2.1 of the License, or (at your option) any later version.
009: //
010: // This library is distributed in the hope that it will be useful,
011: // but WITHOUT ANY WARRANTY; without even the implied warranty of
012: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: // Lesser General Public License for more details.
014: //
015: // You should have received a copy of the GNU Lesser General Public
016: // License along with this library; if not, write to the Free Software
017: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: ////////////////////////////////////////////////////////////////////////////////
019: package com.puppycrawl.tools.checkstyle;
020:
021: import java.io.OutputStream;
022: import java.io.PrintWriter;
023:
024: import com.puppycrawl.tools.checkstyle.api.AuditEvent;
025: import com.puppycrawl.tools.checkstyle.api.AuditListener;
026: import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
027: import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
028:
029: /**
030: * Simple plain logger for text output.
031: * This is maybe not very suitable for a text output into a file since it
032: * does not need all 'audit finished' and so on stuff, but it looks good on
033: * stdout anyway. If there is really a problem this is what XMLLogger is for.
034: * It gives structure.
035: *
036: * @author <a href="mailto:stephane.bailliez@wanadoo.fr">Stephane Bailliez</a>
037: * @see XMLLogger
038: */
039: public class DefaultLogger extends AutomaticBean implements
040: AuditListener {
041: /** cushion for avoiding StringBuffer.expandCapacity */
042: private static final int BUFFER_CUSHION = 12;
043:
044: /** where to write info messages **/
045: private final PrintWriter mInfoWriter;
046: /** close info stream after use */
047: private final boolean mCloseInfo;
048:
049: /** where to write error messages **/
050: private final PrintWriter mErrorWriter;
051: /** close error stream after use */
052: private final boolean mCloseError;
053:
054: /**
055: * Creates a new <code>DefaultLogger</code> instance.
056: * @param aOS where to log infos and errors
057: * @param aCloseStreamsAfterUse if aOS should be closed in auditFinished()
058: */
059: public DefaultLogger(OutputStream aOS, boolean aCloseStreamsAfterUse) {
060: // no need to close aOS twice
061: this (aOS, aCloseStreamsAfterUse, aOS, false);
062: }
063:
064: /**
065: * Creates a new <code>DefaultLogger</code> instance.
066: *
067: * @param aInfoStream the <code>OutputStream</code> for info messages
068: * @param aCloseInfoAfterUse auditFinished should close aInfoStream
069: * @param aErrorStream the <code>OutputStream</code> for error messages
070: * @param aCloseErrorAfterUse auditFinished should close aErrorStream
071: */
072: public DefaultLogger(OutputStream aInfoStream,
073: boolean aCloseInfoAfterUse, OutputStream aErrorStream,
074: boolean aCloseErrorAfterUse) {
075: mCloseInfo = aCloseInfoAfterUse;
076: mCloseError = aCloseErrorAfterUse;
077: mInfoWriter = new PrintWriter(aInfoStream);
078: mErrorWriter = (aInfoStream == aErrorStream) ? mInfoWriter
079: : new PrintWriter(aErrorStream);
080: }
081:
082: /**
083: * Print an Emacs compliant line on the error stream.
084: * If the column number is non zero, then also display it.
085: * @param aEvt {@inheritDoc}
086: * @see AuditListener
087: **/
088: public void addError(AuditEvent aEvt) {
089: final SeverityLevel severityLevel = aEvt.getSeverityLevel();
090: if (!SeverityLevel.IGNORE.equals(severityLevel)) {
091:
092: final String fileName = aEvt.getFileName();
093: final String message = aEvt.getMessage();
094:
095: // avoid StringBuffer.expandCapacity
096: final int bufLen = fileName.length() + message.length()
097: + BUFFER_CUSHION;
098: final StringBuffer sb = new StringBuffer(bufLen);
099:
100: sb.append(fileName);
101: sb.append(':').append(aEvt.getLine());
102: if (aEvt.getColumn() > 0) {
103: sb.append(':').append(aEvt.getColumn());
104: }
105: if (SeverityLevel.WARNING.equals(severityLevel)) {
106: sb.append(": warning");
107: }
108: sb.append(": ").append(message);
109: mErrorWriter.println(sb.toString());
110: }
111: }
112:
113: /** {@inheritDoc} */
114: public void addException(AuditEvent aEvt, Throwable aThrowable) {
115: synchronized (mErrorWriter) {
116: mErrorWriter
117: .println("Error auditing " + aEvt.getFileName());
118: aThrowable.printStackTrace(mErrorWriter);
119: }
120: }
121:
122: /** {@inheritDoc} */
123: public void auditStarted(AuditEvent aEvt) {
124: mInfoWriter.println("Starting audit...");
125: }
126:
127: /** {@inheritDoc} */
128: public void fileFinished(AuditEvent aEvt) {
129: }
130:
131: /** {@inheritDoc} */
132: public void fileStarted(AuditEvent aEvt) {
133: }
134:
135: /** {@inheritDoc} */
136: public void auditFinished(AuditEvent aEvt) {
137: mInfoWriter.println("Audit done.");
138: closeStreams();
139: }
140:
141: /**
142: * Flushes the output streams and closes them if needed.
143: */
144: protected void closeStreams() {
145: mInfoWriter.flush();
146: if (mCloseInfo) {
147: mInfoWriter.close();
148: }
149:
150: mErrorWriter.flush();
151: if (mCloseError) {
152: mErrorWriter.close();
153: }
154: }
155: }
|