Package models

Source Code of models.AbstractPosting

/**
* 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.ResourceType;
import models.resource.Resource;
import models.resource.ResourceConvertible;

import org.joda.time.Duration;
import play.data.format.Formats;
import play.data.validation.Constraints;
import play.db.ebean.*;
import utils.JodaDateUtil;

import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@MappedSuperclass
abstract public class AbstractPosting extends Model implements ResourceConvertible {
    public static final int FIRST_PAGE_NUMBER = 0;
    public static final int NUMBER_OF_ONE_MORE_COMMENTS = 1;

    private static final long serialVersionUID = 1L;

    @Id
    public Long id;

    @Constraints.Required
    @Size(max=255)
    public String title;

    @Lob
    public String body;

    @Constraints.Required
    @Formats.DateTime(pattern = "YYYY/MM/DD/hh/mm/ss")
    public Date createdDate;

    @Constraints.Required
    @Formats.DateTime(pattern = "YYYY/MM/DD/hh/mm/ss")
    public Date updatedDate;

    public Long authorId;
    public String authorLoginId;
    public String authorName;

    @Transient
    public User author;

    @ManyToOne
    public Project project;

    protected Long number;

    // This field is only for ordering. This field should be persistent because
    // Ebean does NOT sort entities by transient field.
    public int numOfComments;

    abstract public int computeNumOfComments();

    public AbstractPosting() {
        this.createdDate = JodaDateUtil.now();
        this.updatedDate = JodaDateUtil.now();
    }

    /**
     * @see models.Issue#increaseNumber()
     * @see models.Posting#increaseNumber()
     */
    protected abstract Long increaseNumber();

    protected abstract void fixLastNumber();

    public Long getNumber() {
        return number;
    }

    public void setNumber(Long number) {
        this.number = number;
    }

    /**
     * @see #increaseNumber()
     * @see #computeNumOfComments()
     */
    @Transactional
    public void save() {
        if (number == null) {
            number = increaseNumber();
        }
        numOfComments = computeNumOfComments();

        try {
            super.save();
            updateMention();
        } catch (PersistenceException e) {
            Long oldNumber = number;
            fixLastNumber();
            number = increaseNumber();
            // What causes this PersistenceException?
            if (!oldNumber.equals(number)) {
                // caused by invalid number.
                play.Logger.warn(String.format("%s/%s: Invalid last number %d is fixed to %d",
                        asResource().getProject(), asResource().getType(), oldNumber, number));
                super.save();
            } else {
                // caused by the other reason.
                throw e;
            }
        }
    }

    @Transactional
    public void update() {
        numOfComments = computeNumOfComments();
        super.update();
        updateMention();
    }

    /**
     * use EBean save functionality directly
     * to prevent occurring select table lock
     */
    public void directSave(){
        updateMention();
        super.save();
    }

    public void updateNumber() {
        number = increaseNumber();
        super.update();
    }

    public static <T> T findByNumber(Finder<Long, T> finder, Project project, Long number) {
        return finder.where().eq("project.id", project.id).eq("number", number).findUnique();
    }

    public Duration ago() {
        return JodaDateUtil.ago(this.createdDate);
    }

    public Resource asResource(final ResourceType type) {
        return new Resource() {
            @Override
            public String getId() {
                return id.toString();
            }

            @Override
            public Project getProject() {
                return project;
            }

            @Override
            public ResourceType getType() {
                return type;
            }

            @Override
            public Long getAuthorId() {
                return authorId;
            }
        };
    }

    @Transient
    public void setAuthor(User user) {
        authorId = user.id;
        authorLoginId = user.loginId;
        authorName = user.name;
    }

    @Transient
    public User getAuthor() {
        return User.findByLoginId(authorLoginId);
    }

    abstract public List<? extends Comment> getComments();

    public void delete() {
        for (Comment comment: getComments()) {
            comment.delete();
        }
        Attachment.deleteAll(asResource());
        NotificationEvent.deleteBy(this.asResource());
        super.delete();
    }

    public void updateProperties() {
        // default implementation for convenience
    }

    /**
     * @see {@link #getWatchers()}
     * @see <a href="https://github.com/nforge/yobi/blob/master/docs/technical/watch.md>watch.md</a>
     */
    @Transient
    public Set<User> getWatchers() {
        return getWatchers(new HashSet<User>());
    }

    /**
     * @see {@link #getWatchers()}
     * @see <a href="https://github.com/nforge/yobi/blob/master/docs/technical/watch.md>watch.md</a>
     */
    @Transient
    public Set<User> getWatchers(Set<User> baseWatchers) {
        Set<User> actualWatchers = new HashSet<>();

        actualWatchers.addAll(baseWatchers);

        actualWatchers.add(getAuthor());
        for (Comment c : getComments()) {
            User user = User.find.byId(c.authorId);
            if (user != null) {
                actualWatchers.add(user);
            }
        }

        return Watch.findActualWatchers(actualWatchers, asResource());
    }

    protected void updateMention() {
        if (this.body != null) {
            Mention.add(this.asResource(), NotificationEvent.getMentionedUsers(this.body));
        }
    }

    public abstract void checkLabels() throws IssueLabel.IssueLabelException;
}
TOP

Related Classes of models.AbstractPosting

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.