/**
* Copyright (C) 2011 JTalks.org Team
* This library 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 2.1 of the License, or (at your option) any later version.
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.jtalks.jcommune.model.entity;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import ch.lambdaj.Lambda;
import org.apache.commons.lang.Validate;
/**
* Forum branch that contains topics related to branch theme.
*
* @author Vitaliy Kravchenko
* @author Kirill Afonin
* @author Max Malakhov
* @author masyan
* @author Anuar_Nurmakanov
*/
public class Branch extends org.jtalks.common.model.entity.Branch
implements SubscriptionAwareEntity {
public static final int BRANCH_NAME_MAX_LENGTH = 80;
public static final int BRANCH_DESCRIPTION_MAX_LENGTH = 255;
public static final String URL_SUFFIX = "/branches/";
private List<Topic> topics = new ArrayList<>();
private Set<JCUser> subscribers = new HashSet<>();
private Integer topicsCount;
private Integer postsCount;
private boolean unreadPosts;
private Post lastPost;
/**
* For Hibernate use only
*/
protected Branch() {
}
/**
* Creates the Branch instance with required fields.
*
* @param name unique branch name
* @param description branch description
*/
public Branch(String name, String description) {
super(name, description);
}
/**
* Returns the next topic for the topic given.
* This method is sorting aware, i. e. all the sorting applied
* in topic selection query will be taken into account.
*
* @param topic a topic to found the next one for
* @return next topic or null, if the argument is the last topic in the branch
*/
public Topic getNextTopic(Topic topic) {
int index = this.getTopicIndexInList(topic);
if (index == topics.size() - 1) {
return null;
}
else {
return topics.get(index + 1);
}
}
/**
* Returns the previous topic for the topic given.
* This method is sorting aware, i. e. all the sorting applied
* in topic selection query will be be taken into account.
*
* @param topic a topic to found predecessor for
* @return previous topic or null, if the argument is the first topic in the branch
*/
public Topic getPreviousTopic(Topic topic) {
int index = this.getTopicIndexInList(topic);
if (index == 0) {
return null;
}
else {
return topics.get(index - 1);
}
}
/**
* Gets topic index in the branch or throws an exception if there is no such
* a topic in the branch
*
* @param topic topic to find index for
* @return index of the topic branch's collection
*/
private int getTopicIndexInList(Topic topic) {
int index = topics.indexOf(topic);
Validate.isTrue(index != -1, "There is no such topic in the branch");
return index;
}
/**
* @return list of topics
*/
public List<Topic> getTopics() {
return topics;
}
/**
* @param topics list of topics
*/
protected void setTopics(List<Topic> topics) {
this.topics = topics;
}
/**
* Add topic to branch.
*
* @param topic topic
*/
public void addTopic(Topic topic) {
topic.setBranch(this);
this.topics.add(topic);
}
/**
* Delete topic from branch.
*
* @param topic topic
*/
public void deleteTopic(Topic topic) {
this.topics.remove(topic);
}
/**
* @return count topics in branch
*/
public int getTopicCount() {
if (topicsCount == null) {
return topics.size();
}
return topicsCount;
}
/**
* Returns a sum of all topic's post count for that branch.
* <p/>
* Value is computed only for the first time (if not set explicitly before),
* so it may not take into account the posts added later
*
* @return sum of post count for all the topics in this branch
*/
public int getPostCount() {
if (postsCount == null) {
postsCount = Lambda.sumFrom(topics, Topic.class).getPostCount();
}
return postsCount;
}
/**
* {@inheritDoc}
*/
@Override
public Set<JCUser> getSubscribers() {
return subscribers;
}
/**
* {@inheritDoc}
*/
public void setSubscribers(Set<JCUser> subscribers) {
this.subscribers = subscribers;
}
/**
* {@inheritDoc}
*
* <p>
* The target URL has the next format http://{forum root}/branches/{id}
*/
@Override
public String getUrlSuffix() {
return URL_SUFFIX + getId();
}
/**
* {@inheritDoc}
*/
@Override
public <T extends SubscriptionAwareEntity> String getUnsubscribeLinkForSubscribersOf(Class<T> clazz) {
if (Branch.class.isAssignableFrom(clazz)) {
return String.format("/branches/%s/unsubscribe", getId());
}
return null;
}
/**
* Set count of topics in this branch.
*
* @param topicsCount count of posts in this branch
*/
public void setTopicsCount(Integer topicsCount) {
this.topicsCount = topicsCount;
}
/**
* Set count of posts in this branch.
*
* @param postsCount count of posts in this branch
*/
public void setPostsCount(Integer postsCount) {
this.postsCount = postsCount;
}
/**
* Returns state of unread posts in branch to user
*
* @return state of unread posts
*/
public boolean isUnreadPosts() {
return this.unreadPosts;
}
/**
* Set state of unread posts in branch to user
*
* @param unreadPosts actual state of unread posts
*/
public void setUnreadPosts(boolean unreadPosts) {
this.unreadPosts = unreadPosts;
}
/**
* Get last post in this branch.
*
* @return last post in this branch
*/
public Post getLastPost() {
return lastPost;
}
/**
* Set last post in this branch.
*
*/
public void setLastPost(Post lastPost) {
this.lastPost = lastPost;
}
/**
* Checks whether a sent post is the last in the branch.
*
* @param checkedPost checked post
* @return {@code true} if sent post is the last in the branch,
* otherwise {@code false}
*/
public boolean isLastPost(Post checkedPost) {
Validate.notNull(checkedPost);
return checkedPost.equals(lastPost);
}
/**
* Clear the last post in the branch.
*/
public void clearLastPost() {
this.lastPost = null;
}
}