Package net.sf.collabreview.other

Source Code of net.sf.collabreview.other.InternalCodeCampMails$MessageSender

/*
   Copyright 2012 Christian Prause and Fraunhofer FIT

   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 net.sf.collabreview.other;

import net.sf.collabreview.core.CollabReview;
import net.sf.collabreview.core.Lifecycle;
import net.sf.collabreview.core.Repository;
import net.sf.collabreview.core.configuration.ConfigurationData;
import net.sf.collabreview.core.mails.Mail;
import net.sf.collabreview.hooks.SetReviewHook;
import net.sf.collabreview.repository.Review;
import net.sf.collabreview.reputation.MetricDelta;
import net.sf.collabreview.reputation.ReputationMetric;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import java.util.*;

/**
* Send notification mails during the code camp...
*
* @author Christian Prause (prause)
* @date 2011-11-11 15:55
*/
public class InternalCodeCampMails implements Lifecycle {
  /**
   * Apache commons logging logger for class InternalCodeCampMails.
   */
  private static final Log logger = LogFactory.getLog(InternalCodeCampMails.class);

  /**
   * The CollabReview instance that this object belongs to.
   */
  private CollabReview collabReview = null;

  /**
   * The MessageSender TimerTask that is currently scheduled for execution, or null if no such task is scheduled.
   */
  private MessageSender mailSender = null;

  /**
   * How long to delay the message before it is sent by the mailSender task.
   */
  private long messageDelay = 300;

  /**
   * List of participants who are participating in the game and that should receive a mail.
   */
  private Set<String> participants = new HashSet<String>();

  /**
   * Who should receive the mail with the new technical debt scores (usually a mailing list?).
   * Needs to be configured in configuration.
   */
  private InternetAddress mailRecipient;

  /**
   * TimerTask responsible for sending the daily mails.
   */
  private class MessageSender extends TimerTask {
    /**
     * The review that caused this MessageSender to be scheduled for execution.
     */
    private Review review;

    private MessageSender(Review review) {
      this.review = review;
    }

    @Override
    public void run() {
      logger.info("Sending updated reputation scores in mail now...");
      try {
        sendMails();
      } catch (Exception e) {
        logger.error("Uncaught exception when sending daily mails", e);
      }
    }

    private void sendMails() {
      MetricDelta deltaDebt = (MetricDelta) collabReview.getReputationMetricManager().findReputationMetric("delta");
      assert deltaDebt != null;
      ReputationMetric quality = collabReview.getReputationMetricManager().findReputationMetric("qlybonqty");
      ReputationMetric technicalDebt = collabReview.getReputationMetricManager().findReputationMetric("techdebt");
      assert technicalDebt != null;
      Map<String, Float> scores = new TreeMap<String, Float>(quality.getAuthorScores());
      scores.keySet().retainAll(participants);
      logger.debug("Participant scores: " + scores);

      if (mailRecipient == null) {
        mailRecipient = collabReview.getMailManager().getAdministrator();
      }
      Mail listMail = collabReview.getMailManager().newMail("Javadoc reputation scores overview", mailRecipient.toString());
      assert review != null;
      String body = "Achtung liebe Entwickler,\n\n" +
          "es gibt eine kleine Änderung in der Berechnung der Punkte, weil mehrfach\n" +
          "darum gebeten wurde, doch auch Quantität mit einzubeziehen. Deshalb sind\n" +
          "die neuen Punkte jetzt inklusive einem Bonus von maximal 5 Punkten, der\n" +
          "sich anteilig an dem Beitrag des Entwicklers der am zweitmeisten beige-\n" +
          "tragen hat, bestimmt. Das heißt: hast du halb so viel wie derzeit Mark\n" +
          "beigetragen, dann ist dein Bonus 2,5.\n\n" +
          "Und jetzt weiter wie gehabt:\n" +
          "Eine Änderung wurde in das SourceForge repository übertragen und \n" +
          "anschließend auf Konformität zu den Java Coding Conventions überprüft.\n" +
          "Diese Mail informiert euch über eure aktuelle Code-Qualitäts-Reputation\n" +
          "nach dieser Änderung.\n\n" +
          "Die technische Schuld beträgt nun insgesamt " + toEuroString(technicalDebt.sum()) +
          " (Veränderung: " + toEuroString(deltaDebt.sum()) + ").\n\n" +
          getRankingTableString(scores, technicalDebt.getAuthorScores(), deltaDebt.getAuthorScores()) + "\n\n" +
          "Die Überprüfung einer der Dateien im Änderungssatz ergab (beispielhaft):\n" +
          " Datei:          " + review.getArtifactIdentifier().getName() + "\n" +
          " Bewertung:      " + review.getRating() + "\n" +
          " Bewertet durch: " + review.getAuthorName() + "\n" +
          " Erklärung:      " + review.getReviewText() + "\n\n";
      listMail.setBody(body);
      listMail.send();
      deltaDebt.setNewBaseline();
    }
  }

  private String toEuroString(Float value) {
    int integerValue = value != null ? Math.round(value / 100) : 0;
    if (integerValue == 0) {
      return "---";
    }
    return (integerValue > 0 ? "+" : "") + integerValue + "00EUR";
  }

  private String getRankingTableString(Map<String, Float> scores, Map<String, Float> technicalDebt, Map<String, Float> deltaDebts) {
    String table = "Javadoc Reputations-Rangliste:\n";
    int rank = 1;
    for (String otherParticipant : scores.keySet()) {
      table += String.format(" %2d. %s: %.2f Punkte, Technische Schuld: %s (Veränderung: %s)\n",
          rank, otherParticipant,
          scores.get(otherParticipant),
          toEuroString(technicalDebt.get(otherParticipant)),
          toEuroString(deltaDebts.get(otherParticipant))
      );
      rank++;
    }
    return table;
  }

  @Override
  public void start() {
    logger.debug("Registering SetReviewHook to enable sending of status mails");
    collabReview.getRepository().registerSetReviewHook(new SetReviewHook() {
      @Override
      public synchronized void reviewUpdated(Repository repository, Review oldReview, Review newReview) {
        logger.debug("Review updated, scheduling MessageSender to run in " + messageDelay / 1000 + "s");
        if (mailSender != null) {
          mailSender.cancel();
        }
        mailSender = new MessageSender(newReview);
        collabReview.getWorkerDaemon().schedule(mailSender, messageDelay);
      }

      @Override
      public int getPriority() {
        return PRIORITY_VERY_LOW;
      }
    });
  }

  @Override
  public void stop() {
    logger.info("Cancelling outstanding sending of mail");
    if (mailSender != null) {
      mailSender.cancel();
    }
  }

  @Override
  public void configure(CollabReview collabReview, ConfigurationData config) {
    this.collabReview = collabReview;
    assert this.collabReview != null;
    logger.debug("<participants/>: " + Arrays.toString(config.getValue("participants", "").split(";")));
    for (String participant : config.getValue("participants", "").split(";")) {
      participant = participant.trim();
      if ("".equals(participant)) {
        continue;
      }
      participants.add(participant);
    }
    if (config.getValue("messageDelay") != null) {
      messageDelay = Integer.parseInt(config.getValue("messageDelay")) * 1000l;
    }
    if (config.getValue("mailRecipient") != null) {
      try {
        mailRecipient = new InternetAddress(config.getValue("mailRecipient"));
      } catch (AddressException e) {
        logger.error("Not a valid email address: " + config.getValue("mailRecipient"));
      }
    }
  }
}
TOP

Related Classes of net.sf.collabreview.other.InternalCodeCampMails$MessageSender

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.