001/*
002 * SonarQube
003 * Copyright (C) 2009-2017 SonarSource SA
004 * mailto:info AT sonarsource DOT com
005 *
006 * This program is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019 */
020package org.sonar.api.batch.fs.internal.charhandler;
021
022import java.nio.charset.Charset;
023
024import org.sonar.api.CoreProperties;
025import org.sonar.api.utils.log.Logger;
026import org.sonar.api.utils.log.Loggers;
027
028public class LineCounter extends CharHandler {
029  private static final Logger LOG = Loggers.get(LineCounter.class);
030    
031  private int lines = 1;
032  private int nonBlankLines = 0;
033  private boolean blankLine = true;
034  boolean alreadyLoggedInvalidCharacter = false;
035  private final String filePath;
036  private final Charset encoding;
037
038  public LineCounter(String filePath, Charset encoding) {
039    this.filePath = filePath;
040    this.encoding = encoding;
041  }
042
043  @Override
044  public void handleAll(char c) {
045    if (!alreadyLoggedInvalidCharacter && c == '\ufffd') {
046      LOG.warn("Invalid character encountered in file {} at line {} for encoding {}. Please fix file content or configure the encoding to be used using property '{}'.", filePath,
047        lines, encoding, CoreProperties.ENCODING_PROPERTY);
048      alreadyLoggedInvalidCharacter = true;
049    }
050  }
051
052  @Override
053  public void newLine() {
054    lines++;
055    if (!blankLine) {
056      nonBlankLines++;
057    }
058    blankLine = true;
059  }
060
061  @Override
062  public void handleIgnoreEoL(char c) {
063    if (!Character.isWhitespace(c)) {
064      blankLine = false;
065    }
066  }
067
068  @Override
069  public void eof() {
070    if (!blankLine) {
071      nonBlankLines++;
072    }
073  }
074
075  public int lines() {
076    return lines;
077  }
078
079  public int nonBlankLines() {
080    return nonBlankLines;
081  }
082
083}