models.IssueEvent.java Source code

Java tutorial

Introduction

Here is the source code for models.IssueEvent.java

Source

/**
 * Yobi, Project Hosting SW
 *
 * Copyright 2013 NAVER Corp.
 * http://yobi.io
 *
 * @Author Yi EungJun
 *
 * 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 models;

import models.enumeration.EventType;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import play.Configuration;
import play.db.ebean.Model;

import javax.persistence.*;
import java.util.*;
import java.util.regex.Matcher;

@Entity
public class IssueEvent extends Model implements TimelineItem {
    private static final long serialVersionUID = 4029013291153199185L;

    @Id
    public Long id;

    public Date created;

    public String senderLoginId;
    public String senderEmail;

    @ManyToOne
    public Issue issue;

    @Enumerated(EnumType.STRING)
    public EventType eventType;

    public String oldValue;

    public String newValue;

    private static final int DRAFT_TIME_IN_MILLIS = Configuration.root()
            .getMilliseconds("application.issue-event.draft-time", 30 * 1000L).intValue();

    public static Finder<Long, IssueEvent> find = new Finder<>(Long.class, IssueEvent.class);

    /**
     * Adds {@code event}.
     *
     * If the last event is not older than {@link #DRAFT_TIME_IN_MILLIS}
     * miliseconds and the event is the same kind of event as the given one,
     * merge or delete both of the events if necessary to reduce hassle
     * notifications.
     *
     * Examples:
     *
     * - If an assignee was changed from A to B, then A to C, the two events
     *   are merged into the event of which assignee was changed from A to C.
     * - If an assignee was changed from A to B, then B to A, the two events
     *   will be deleted.
     *
     * Notes: This method originates from
     * {@link NotificationEvent#add(NotificationEvent)}
     *
     * @param event
     */
    public static void add(IssueEvent event) {
        Date draftDate = DateTime.now().minusMillis(DRAFT_TIME_IN_MILLIS).toDate();

        IssueEvent lastEvent = IssueEvent.find.where().eq("issue.id", event.issue.id).gt("created", draftDate)
                .orderBy("id desc").setMaxRows(1).findUnique();

        if (lastEvent != null) {
            if (lastEvent.eventType == event.eventType
                    && StringUtils.equals(event.senderLoginId, lastEvent.senderLoginId)) {
                // A -> B, B -> C ==> A -> C
                event.oldValue = lastEvent.oldValue;
                lastEvent.delete();

                // A -> B, B -> A ==> remove all of them
                if (StringUtils.equals(event.oldValue, event.newValue)) {
                    // No need to add this event because the event just cancels the last event
                    // which has just been deleted.
                    return;
                }
            }
        }

        event.save();
    }

    /**
     * Adds events based on the given {@code notiEvent}, {@code updatedIssue}
     * and {@code senderLoginId}.
     *
     * @param notiEvent
     * @param updatedIssue
     * @param senderLoginId
     * @see {@link #add(IssueEvent)}
     */
    public static void addFromNotificationEvent(NotificationEvent notiEvent, Issue updatedIssue,
            String senderLoginId) {
        IssueEvent event = new IssueEvent();
        event.created = notiEvent.created;
        event.senderLoginId = senderLoginId;
        event.issue = updatedIssue;
        event.eventType = notiEvent.eventType;
        event.oldValue = notiEvent.oldValue;
        event.newValue = notiEvent.newValue;
        add(event);
    }

    @Override
    public Date getDate() {
        return created;
    }

    public static Set<Issue> findReferredIssue(String message, Project project) {
        Matcher m = Issue.ISSUE_PATTERN.matcher(message);
        Set<Issue> referredIssues = new HashSet<>();

        while (m.find()) {
            String issueText = m.group();
            String issueNumber = issueText.substring(1); // removing the leading char #
            Issue issue = Issue.findByNumber(project, Long.parseLong(issueNumber));
            if (issue != null) {
                referredIssues.add(issue);
            }
        }

        return referredIssues;
    }
}