Package org.sonar.plugins.scm.svn

Source Code of org.sonar.plugins.scm.svn.SvnBlameConsumer

/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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 3 of the License, or (at your option) any later version.
*
* SonarQube 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
package org.sonar.plugins.scm.svn;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.scm.BlameLine;
import org.sonar.api.utils.command.StreamConsumer;

import javax.annotation.CheckForNull;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SvnBlameConsumer implements StreamConsumer {

  private static final Logger LOG = LoggerFactory.getLogger(SvnBlameConsumer.class);

  private static final String SVN_TIMESTAMP_PATTERN = "yyyy-MM-dd HH:mm:ss";

  private static final Pattern LINE_PATTERN = Pattern.compile("line-number=\"(.*)\"");

  private static final Pattern REVISION_PATTERN = Pattern.compile("revision=\"(.*)\"");

  private static final Pattern AUTHOR_PATTERN = Pattern.compile("<author>(.*)</author>");

  private static final Pattern DATE_PATTERN = Pattern.compile("<date>(.*)T(.*)\\.(.*)Z</date>");

  private boolean insideCommitSection = false;
  private boolean insideMergedSection = false;

  private SimpleDateFormat dateFormat;

  private List<BlameLine> lines = new ArrayList<BlameLine>();

  private final String filename;

  public SvnBlameConsumer(String filename) {
    this.filename = filename;
    dateFormat = new SimpleDateFormat(SVN_TIMESTAMP_PATTERN);
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
  }

  private int lineNumber = 0;

  private String committerRevision;
  private String committer;
  private Date committerDate;
  private String authorRevision;
  private String author;
  private Date authorDate;

  @Override
  public void consumeLine(String line) {
    Matcher matcher;
    if ((matcher = LINE_PATTERN.matcher(line)).find()) {
      String lineNumberStr = matcher.group(1);
      lineNumber = Integer.parseInt(lineNumberStr);
      insideCommitSection = false;
      insideMergedSection = false;
    } else if (line.contains("<commit") && !insideMergedSection) {
      insideCommitSection = true;
    } else if (line.contains("<merged")) {
      insideMergedSection = true;
      insideCommitSection = false;
    } else if ((matcher = REVISION_PATTERN.matcher(line)).find()) {
      if (insideCommitSection) {
        committerRevision = matcher.group(1);
      } else if (insideMergedSection) {
        authorRevision = matcher.group(1);
      }
    } else if ((matcher = AUTHOR_PATTERN.matcher(line)).find()) {
      if (insideCommitSection) {
        committer = matcher.group(1);
      } else if (insideMergedSection) {
        author = matcher.group(1);
      }
    } else if ((matcher = DATE_PATTERN.matcher(line)).find()) {
      String date = matcher.group(1);
      String time = matcher.group(2);
      Date dateTime = parseDateTime(date + " " + time);
      if (insideCommitSection) {
        committerDate = dateTime;
      } else if (insideMergedSection) {
        authorDate = dateTime;
      }
    } else if (line.contains("</entry>")) {
      if (authorRevision != null) {
        lines.add(new BlameLine().revision(authorRevision).author(author).date(authorDate));
      } else if (committerRevision != null) {
        lines.add(new BlameLine().revision(committerRevision).author(committer).date(committerDate));
      } else {
        throw new IllegalStateException("Unable to blame file " + filename + ". No blame info at line " + lineNumber + ". Is file commited?");
      }
      insideCommitSection = false;
      insideMergedSection = false;
      author = null;
      committer = null;
      committerRevision = null;
      authorRevision = null;
    }
  }

  @CheckForNull
  protected Date parseDateTime(String dateTimeStr) {
    try {
      return dateFormat.parse(dateTimeStr);
    } catch (ParseException e) {
      LOG.error("skip ParseException: " + e.getMessage() + " during parsing date " + dateTimeStr, e);
      return null;
    }
  }

  public List<BlameLine> getLines() {
    return lines;
  }
}
TOP

Related Classes of org.sonar.plugins.scm.svn.SvnBlameConsumer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.