Package com.gitblit.utils

Source Code of com.gitblit.utils.MetricUtils

/*
* Copyright 2011 gitblit.com.
*
* Licensed 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.
*/
package com.gitblit.utils;

import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitblit.models.Metric;
import com.gitblit.models.RefModel;

/**
* Utility class for collecting metrics on a branch, tag, or other ref within
* the repository.
*
* @author James Moger
*
*/
public class MetricUtils {

  private static final Logger LOGGER = LoggerFactory.getLogger(MetricUtils.class);

  /**
   * Log an error message and exception.
   *
   * @param t
   * @param repository
   *            if repository is not null it MUST be the {0} parameter in the
   *            pattern.
   * @param pattern
   * @param objects
   */
  private static void error(Throwable t, Repository repository, String pattern, Object... objects) {
    List<Object> parameters = new ArrayList<Object>();
    if (objects != null && objects.length > 0) {
      for (Object o : objects) {
        parameters.add(o);
      }
    }
    if (repository != null) {
      parameters.add(0, repository.getDirectory().getAbsolutePath());
    }
    LOGGER.error(MessageFormat.format(pattern, parameters.toArray()), t);
  }

  /**
   * Returns the list of metrics for the specified commit reference, branch,
   * or tag within the repository. If includeTotal is true, the total of all
   * the metrics will be included as the first element in the returned list.
   *
   * If the dateformat is unspecified an attempt is made to determine an
   * appropriate date format by determining the time difference between the
   * first commit on the branch and the most recent commit. This assumes that
   * the commits are linear.
   *
   * @param repository
   * @param objectId
   *            if null or empty, HEAD is assumed.
   * @param includeTotal
   * @param dateFormat
   * @param timezone
   * @return list of metrics
   */
  public static List<Metric> getDateMetrics(Repository repository, String objectId,
      boolean includeTotal, String dateFormat, TimeZone timezone) {
    Metric total = new Metric("TOTAL");
    final Map<String, Metric> metricMap = new HashMap<String, Metric>();

    if (JGitUtils.hasCommits(repository)) {
      final List<RefModel> tags = JGitUtils.getTags(repository, true, -1);
      final Map<ObjectId, RefModel> tagMap = new HashMap<ObjectId, RefModel>();
      for (RefModel tag : tags) {
        tagMap.put(tag.getReferencedObjectId(), tag);
      }
      RevWalk revWalk = null;
      try {
        // resolve branch
        ObjectId branchObject;
        if (StringUtils.isEmpty(objectId)) {
          branchObject = JGitUtils.getDefaultBranch(repository);
        } else {
          branchObject = repository.resolve(objectId);
        }

        revWalk = new RevWalk(repository);
        RevCommit lastCommit = revWalk.parseCommit(branchObject);
        revWalk.markStart(lastCommit);

        DateFormat df;
        if (StringUtils.isEmpty(dateFormat)) {
          // dynamically determine date format
          RevCommit firstCommit = JGitUtils.getFirstCommit(repository,
              branchObject.getName());
          int diffDays = (lastCommit.getCommitTime() - firstCommit.getCommitTime())
              / (60 * 60 * 24);
          total.duration = diffDays;
          if (diffDays <= 365) {
            // Days
            df = new SimpleDateFormat("yyyy-MM-dd");
          } else {
            // Months
            df = new SimpleDateFormat("yyyy-MM");
          }
        } else {
          // use specified date format
          df = new SimpleDateFormat(dateFormat);
        }
        df.setTimeZone(timezone);

        Iterable<RevCommit> revlog = revWalk;
        for (RevCommit rev : revlog) {
          Date d = JGitUtils.getCommitDate(rev);
          String p = df.format(d);
          if (!metricMap.containsKey(p)) {
            metricMap.put(p, new Metric(p));
          }
          Metric m = metricMap.get(p);
          m.count++;
          total.count++;
          if (tagMap.containsKey(rev.getId())) {
            m.tag++;
            total.tag++;
          }
        }
      } catch (Throwable t) {
        error(t, repository, "{0} failed to mine log history for date metrics of {1}",
            objectId);
      } finally {
        if (revWalk != null) {
          revWalk.dispose();
        }
      }
    }
    List<String> keys = new ArrayList<String>(metricMap.keySet());
    Collections.sort(keys);
    List<Metric> metrics = new ArrayList<Metric>();
    for (String key : keys) {
      metrics.add(metricMap.get(key));
    }
    if (includeTotal) {
      metrics.add(0, total);
    }
    return metrics;
  }

  /**
   * Returns a list of author metrics for the specified repository.
   *
   * @param repository
   * @param objectId
   *            if null or empty, HEAD is assumed.
   * @param byEmailAddress
   *            group metrics by author email address otherwise by author name
   * @return list of metrics
   */
  public static List<Metric> getAuthorMetrics(Repository repository, String objectId,
      boolean byEmailAddress) {
    final Map<String, Metric> metricMap = new HashMap<String, Metric>();
    if (JGitUtils.hasCommits(repository)) {
      try {
        RevWalk walk = new RevWalk(repository);
        // resolve branch
        ObjectId branchObject;
        if (StringUtils.isEmpty(objectId)) {
          branchObject = JGitUtils.getDefaultBranch(repository);
        } else {
          branchObject = repository.resolve(objectId);
        }
        RevCommit lastCommit = walk.parseCommit(branchObject);
        walk.markStart(lastCommit);

        Iterable<RevCommit> revlog = walk;
        for (RevCommit rev : revlog) {
          String p;
          if (byEmailAddress) {
            p = rev.getAuthorIdent().getEmailAddress().toLowerCase();
            if (StringUtils.isEmpty(p)) {
              p = rev.getAuthorIdent().getName().toLowerCase();
            }
          } else {
            p = rev.getAuthorIdent().getName().toLowerCase();
            if (StringUtils.isEmpty(p)) {
              p = rev.getAuthorIdent().getEmailAddress().toLowerCase();
            }
          }
          p = p.replace('\n',' ').replace('\r'' ').trim();
          if (!metricMap.containsKey(p)) {
            metricMap.put(p, new Metric(p));
          }
          Metric m = metricMap.get(p);
          m.count++;
        }
      } catch (Throwable t) {
        error(t, repository, "{0} failed to mine log history for author metrics of {1}",
            objectId);
      }
    }
    List<String> keys = new ArrayList<String>(metricMap.keySet());
    Collections.sort(keys);
    List<Metric> metrics = new ArrayList<Metric>();
    for (String key : keys) {
      metrics.add(metricMap.get(key));
    }
    return metrics;
  }
}
TOP

Related Classes of com.gitblit.utils.MetricUtils

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.