Coverage Report - com.puppycrawl.tools.checkstyle.DefaultLogger
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultLogger
100%
60/60
100%
14/14
1.385
 
 1  
 ////////////////////////////////////////////////////////////////////////////////
 2  
 // checkstyle: Checks Java source code for adherence to a set of rules.
 3  
 // Copyright (C) 2001-2017 the original author or authors.
 4  
 //
 5  
 // This library is free software; you can redistribute it and/or
 6  
 // modify it under the terms of the GNU Lesser General Public
 7  
 // License as published by the Free Software Foundation; either
 8  
 // version 2.1 of the License, or (at your option) any later version.
 9  
 //
 10  
 // This library is distributed in the hope that it will be useful,
 11  
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
 // Lesser General Public License for more details.
 14  
 //
 15  
 // You should have received a copy of the GNU Lesser General Public
 16  
 // License along with this library; if not, write to the Free Software
 17  
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 18  
 ////////////////////////////////////////////////////////////////////////////////
 19  
 
 20  
 package com.puppycrawl.tools.checkstyle;
 21  
 
 22  
 import java.io.OutputStream;
 23  
 import java.io.OutputStreamWriter;
 24  
 import java.io.PrintWriter;
 25  
 import java.io.Writer;
 26  
 import java.nio.charset.StandardCharsets;
 27  
 
 28  
 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
 29  
 import com.puppycrawl.tools.checkstyle.api.AuditListener;
 30  
 import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
 31  
 import com.puppycrawl.tools.checkstyle.api.LocalizedMessage;
 32  
 import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
 33  
 
 34  
 /**
 35  
  * Simple plain logger for text output.
 36  
  * This is maybe not very suitable for a text output into a file since it
 37  
  * does not need all 'audit finished' and so on stuff, but it looks good on
 38  
  * stdout anyway. If there is really a problem this is what XMLLogger is for.
 39  
  * It gives structure.
 40  
  *
 41  
  * @author <a href="mailto:stephane.bailliez@wanadoo.fr">Stephane Bailliez</a>
 42  
  * @see XMLLogger
 43  
  * @noinspection ClassWithTooManyConstructors
 44  
  */
 45  
 public class DefaultLogger extends AutomaticBean implements AuditListener {
 46  
 
 47  
     /**
 48  
      * A key pointing to the add exception
 49  
      * message in the "messages.properties" file.
 50  
      */
 51  
     public static final String ADD_EXCEPTION_MESSAGE = "DefaultLogger.addException";
 52  
     /**
 53  
      * A key pointing to the started audit
 54  
      * message in the "messages.properties" file.
 55  
      */
 56  
     public static final String AUDIT_STARTED_MESSAGE = "DefaultLogger.auditStarted";
 57  
     /**
 58  
      * A key pointing to the finished audit
 59  
      * message in the "messages.properties" file.
 60  
      */
 61  
     public static final String AUDIT_FINISHED_MESSAGE = "DefaultLogger.auditFinished";
 62  
 
 63  
     /** Where to write info messages. **/
 64  
     private final PrintWriter infoWriter;
 65  
     /** Close info stream after use. */
 66  
     private final boolean closeInfo;
 67  
 
 68  
     /** Where to write error messages. **/
 69  
     private final PrintWriter errorWriter;
 70  
     /** Close error stream after use. */
 71  
     private final boolean closeError;
 72  
 
 73  
     /** Formatter for the log message. */
 74  
     private final AuditEventFormatter formatter;
 75  
 
 76  
     /**
 77  
      * Creates a new {@code DefaultLogger} instance.
 78  
      * @param outputStream where to log infos and errors
 79  
      * @param closeStreamsAfterUse if oS should be closed in auditFinished()
 80  
      * @deprecated in order to fullfil demands of BooleanParameter IDEA check.
 81  
      * @noinspection BooleanParameter
 82  
      */
 83  
     @Deprecated
 84  
     public DefaultLogger(OutputStream outputStream, boolean closeStreamsAfterUse) {
 85  
         // no need to close oS twice
 86  1
         this(outputStream, closeStreamsAfterUse, outputStream, false);
 87  1
     }
 88  
 
 89  
     /**
 90  
      * Creates a new {@code DefaultLogger} instance.
 91  
      * @param infoStream the {@code OutputStream} for info messages.
 92  
      * @param closeInfoAfterUse auditFinished should close infoStream.
 93  
      * @param errorStream the {@code OutputStream} for error messages.
 94  
      * @param closeErrorAfterUse auditFinished should close errorStream
 95  
      * @deprecated in order to fullfil demands of BooleanParameter IDEA check.
 96  
      * @noinspection BooleanParameter
 97  
      */
 98  
     @Deprecated
 99  
     public DefaultLogger(OutputStream infoStream,
 100  
                          boolean closeInfoAfterUse,
 101  
                          OutputStream errorStream,
 102  
                          boolean closeErrorAfterUse) {
 103  3
         this(infoStream, closeInfoAfterUse, errorStream, closeErrorAfterUse,
 104  
             new AuditEventDefaultFormatter());
 105  3
     }
 106  
 
 107  
     /**
 108  
      * Creates a new {@code DefaultLogger} instance.
 109  
      *
 110  
      * @param infoStream the {@code OutputStream} for info messages
 111  
      * @param closeInfoAfterUse auditFinished should close infoStream
 112  
      * @param errorStream the {@code OutputStream} for error messages
 113  
      * @param closeErrorAfterUse auditFinished should close errorStream
 114  
      * @param messageFormatter formatter for the log message.
 115  
      * @deprecated in order to fullfil demands of BooleanParameter IDEA check.
 116  
      * @noinspection BooleanParameter, WeakerAccess
 117  
      */
 118  
     @Deprecated
 119  
     public DefaultLogger(OutputStream infoStream,
 120  
                          boolean closeInfoAfterUse,
 121  
                          OutputStream errorStream,
 122  
                          boolean closeErrorAfterUse,
 123  1515
                          AuditEventFormatter messageFormatter) {
 124  1515
         closeInfo = closeInfoAfterUse;
 125  1515
         closeError = closeErrorAfterUse;
 126  1515
         final Writer infoStreamWriter = new OutputStreamWriter(infoStream, StandardCharsets.UTF_8);
 127  1515
         infoWriter = new PrintWriter(infoStreamWriter);
 128  
 
 129  1515
         if (infoStream == errorStream) {
 130  1513
             errorWriter = infoWriter;
 131  
         }
 132  
         else {
 133  2
             final Writer errorStreamWriter = new OutputStreamWriter(errorStream,
 134  
                     StandardCharsets.UTF_8);
 135  2
             errorWriter = new PrintWriter(errorStreamWriter);
 136  
         }
 137  1515
         formatter = messageFormatter;
 138  1515
     }
 139  
 
 140  
     /**
 141  
      * Creates a new {@code DefaultLogger} instance.
 142  
      * @param outputStream where to log infos and errors
 143  
      * @param outputStreamOptions if {@code CLOSE} that should be closed in auditFinished()
 144  
      */
 145  
     public DefaultLogger(OutputStream outputStream, OutputStreamOptions outputStreamOptions) {
 146  
         // no need to close oS twice
 147  1
         this(outputStream, outputStreamOptions, outputStream, OutputStreamOptions.NONE);
 148  1
     }
 149  
 
 150  
     /**
 151  
      * Creates a new {@code DefaultLogger} instance.
 152  
      * @param infoStream the {@code OutputStream} for info messages.
 153  
      * @param infoStreamOptions if {@code CLOSE} info should be closed in auditFinished()
 154  
      * @param errorStream the {@code OutputStream} for error messages.
 155  
      * @param errorStreamOptions if {@code CLOSE} error should be closed in auditFinished()
 156  
      */
 157  
     public DefaultLogger(OutputStream infoStream,
 158  
                          OutputStreamOptions infoStreamOptions,
 159  
                          OutputStream errorStream,
 160  
                          OutputStreamOptions errorStreamOptions) {
 161  46
         this(infoStream, infoStreamOptions, errorStream, errorStreamOptions,
 162  
                 new AuditEventDefaultFormatter());
 163  46
     }
 164  
 
 165  
     /**
 166  
      * Creates a new {@code DefaultLogger} instance.
 167  
      *
 168  
      * @param infoStream the {@code OutputStream} for info messages
 169  
      * @param infoStreamOptions if {@code CLOSE} info should be closed in auditFinished()
 170  
      * @param errorStream the {@code OutputStream} for error messages
 171  
      * @param errorStreamOptions if {@code CLOSE} error should be closed in auditFinished()
 172  
      * @param messageFormatter formatter for the log message.
 173  
      * @noinspection WeakerAccess
 174  
      */
 175  
     public DefaultLogger(OutputStream infoStream,
 176  
                          OutputStreamOptions infoStreamOptions,
 177  
                          OutputStream errorStream,
 178  
                          OutputStreamOptions errorStreamOptions,
 179  46
                          AuditEventFormatter messageFormatter) {
 180  46
         closeInfo = infoStreamOptions == OutputStreamOptions.CLOSE;
 181  46
         closeError = errorStreamOptions == OutputStreamOptions.CLOSE;
 182  46
         final Writer infoStreamWriter = new OutputStreamWriter(infoStream, StandardCharsets.UTF_8);
 183  46
         infoWriter = new PrintWriter(infoStreamWriter);
 184  
 
 185  46
         if (infoStream == errorStream) {
 186  27
             errorWriter = infoWriter;
 187  
         }
 188  
         else {
 189  19
             final Writer errorStreamWriter = new OutputStreamWriter(errorStream,
 190  
                     StandardCharsets.UTF_8);
 191  19
             errorWriter = new PrintWriter(errorStreamWriter);
 192  
         }
 193  46
         formatter = messageFormatter;
 194  46
     }
 195  
 
 196  
     /**
 197  
      * Print an Emacs compliant line on the error stream.
 198  
      * If the column number is non zero, then also display it.
 199  
      * @see AuditListener
 200  
      **/
 201  
     @Override
 202  
     public void addError(AuditEvent event) {
 203  72044
         final SeverityLevel severityLevel = event.getSeverityLevel();
 204  72044
         if (severityLevel != SeverityLevel.IGNORE) {
 205  72041
             final String errorMessage = formatter.format(event);
 206  72041
             errorWriter.println(errorMessage);
 207  
         }
 208  72044
     }
 209  
 
 210  
     @Override
 211  
     public void addException(AuditEvent event, Throwable throwable) {
 212  4
         synchronized (errorWriter) {
 213  4
             final LocalizedMessage addExceptionMessage = new LocalizedMessage(0,
 214  
                 Definitions.CHECKSTYLE_BUNDLE, ADD_EXCEPTION_MESSAGE,
 215  4
                 new String[] {event.getFileName()}, null,
 216  
                 LocalizedMessage.class, null);
 217  4
             errorWriter.println(addExceptionMessage.getMessage());
 218  4
             throwable.printStackTrace(errorWriter);
 219  4
         }
 220  4
     }
 221  
 
 222  
     @Override
 223  
     public void auditStarted(AuditEvent event) {
 224  22
         final LocalizedMessage auditStartMessage = new LocalizedMessage(0,
 225  
             Definitions.CHECKSTYLE_BUNDLE, AUDIT_STARTED_MESSAGE, null, null,
 226  
             LocalizedMessage.class, null);
 227  22
         infoWriter.println(auditStartMessage.getMessage());
 228  22
         infoWriter.flush();
 229  22
     }
 230  
 
 231  
     @Override
 232  
     public void auditFinished(AuditEvent event) {
 233  1507
         final LocalizedMessage auditFinishMessage = new LocalizedMessage(0,
 234  
             Definitions.CHECKSTYLE_BUNDLE, AUDIT_FINISHED_MESSAGE, null, null,
 235  
             LocalizedMessage.class, null);
 236  1507
         infoWriter.println(auditFinishMessage.getMessage());
 237  1507
         closeStreams();
 238  1507
     }
 239  
 
 240  
     @Override
 241  
     public void fileStarted(AuditEvent event) {
 242  
         // No need to implement this method in this class
 243  1572
     }
 244  
 
 245  
     @Override
 246  
     public void fileFinished(AuditEvent event) {
 247  1587
         infoWriter.flush();
 248  1587
     }
 249  
 
 250  
     /**
 251  
      * Flushes the output streams and closes them if needed.
 252  
      */
 253  
     private void closeStreams() {
 254  1507
         infoWriter.flush();
 255  1507
         if (closeInfo) {
 256  1499
             infoWriter.close();
 257  
         }
 258  
 
 259  1507
         errorWriter.flush();
 260  1507
         if (closeError) {
 261  7
             errorWriter.close();
 262  
         }
 263  1507
     }
 264  
 }