/* * TopicBean.java * * This work is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, * or (at your option) any later version. * * This work 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * Copyright (c) 2004-2007 Per Cederberg. All rights reserved. */ package org.liquidsite.app.template; import java.util.ArrayList; import org.liquidsite.core.content.Content; import org.liquidsite.core.content.ContentException; import org.liquidsite.core.content.ContentSecurityException; import org.liquidsite.core.content.ContentSelector; import org.liquidsite.core.content.ContentTopic; import org.liquidsite.core.text.PlainFormatter; import org.liquidsite.util.log.Log; /** * A topic template bean. This class is used to access topics from * the template data model. * * @author Per Cederberg, <per at percederberg dot net> * @version 1.0 */ public class TopicBean extends ContentBean { /** * The class logger. */ private static final Log LOG = new Log(TopicBean.class); /** * The first post in the forum. This variable is set upon the * first request. */ private PostBean first = null; /** * The last post in the forum. This variable is set upon the first * request. */ private PostBean last = null; /** * Creates a new empty topic template bean. */ TopicBean() { this(null, null); } /** * Creates a new topic template bean based on the request * environment topic. * * @param context the bean context */ TopicBean(BeanContext context) { this(context, context.getRequest().getEnvironment().getTopic()); } /** * Creates a new topic template bean. * * @param context the bean context * @param topic the content topic, or null */ TopicBean(BeanContext context, ContentTopic topic) { super(context, topic); } /** * Returns the topic subject. * * @return the topic subject, or * an empty string if the topic doesn't exist */ public String getSubject() { return PlainFormatter.formatHtml(getSubjectSource()); } /** * Returns the unprocessed topic subject. * * @return the unprocessed topic subject, or * an empty string if the topic doesn't exist */ public String getSubjectSource() { if (getContent() != null) { return ((ContentTopic) getContent()).getSubject(); } return ""; } /** * Returns the topic locked flag. * * @return the topic locked flag, or * true if the topic doesn't exist */ public boolean getLocked() { if (getContent() != null) { return ((ContentTopic) getContent()).isLocked(); } return true; } /** * Returns the first post in this topic. The posts are ordered in * creation date order. * * @return the first post in this topic, or * an empty post if the topic doesn't exist */ public PostBean getFirst() { ContentSelector selector; if (first == null) { if (getContent() != null) { try { selector = createPostSelector(); selector.sortById(true); selector.limitResults(0, 1); first = createPost(selector); } catch (ContentException e) { LOG.error(e.getMessage()); } } if (first == null) { first = new PostBean(); } } return first; } /** * Returns the last post in this topic. The posts are ordered in * creation date order. * * @return the last post in this topic, or * an empty post if the topic doesn't exist */ public PostBean getLast() { ContentSelector selector; if (last == null) { if (getContent() != null) { try { selector = createPostSelector(); selector.sortById(false); selector.limitResults(0, 1); last = createPost(selector); } catch (ContentException e) { LOG.error(e.getMessage()); } } if (last == null) { last = new PostBean(); } } return last; } /** * Returns the number of posts in this topic. * * @return the number of posts in this topic */ public int getPostCount() { if (getContent() != null) { try { return getContext().countContent(createPostSelector()); } catch (ContentException e) { LOG.error(e.getMessage()); } } return 0; } /** * Returns a specified post in this topic. The post content * identifier must be specified. * * @param id the post content identifier * * @return the post found (as a post bean), or * an empty post if not found */ public PostBean findPost(int id) { Content content; if (getContent() != null) { try { content = getContext().findContent(id); if (content != null) { return (PostBean) getContext().createContentBean(content); } } catch (ContentException e) { LOG.error(e.getMessage()); } catch (ContentSecurityException e) { LOG.warning(e.getMessage()); } } return new PostBean(); } /** * Returns all posts in this topic. At most the specified number * of posts will be returned. The posts will be ordered by * creation date. * * @param offset the number of post to skip * @param count the maximum number of posts * * @return a list of the posts found (as post beans) */ public ArrayList findPosts(int offset, int count) { ArrayList results = new ArrayList(); ContentSelector selector; Content[] content; if (getContent() != null) { try { selector = createPostSelector(); selector.sortById(true); selector.limitResults(offset, count); content = getContext().findContent(selector); for (int i = 0; i < content.length; i++) { results.add(getContext().createContentBean(content[i])); } } catch (ContentException e) { LOG.error(e.getMessage()); } } return results; } /** * Creates a content selector for finding all posts in this topic. * * @return a content post selector * * @throws ContentException if the database couldn't be accessed * properly */ private ContentSelector createPostSelector() throws ContentException { ContentSelector selector; selector = new ContentSelector(getContent().getDomain()); selector.requireParent(getContent()); selector.requireCategory(Content.POST_CATEGORY); return selector; } /** * Returns the first content post matching the specified selector. * * @param selector the content selector to use * * @return the post bean for the found post, or * null if no matching posts were found * * @throws ContentException if the database couldn't be accessed * properly */ private PostBean createPost(ContentSelector selector) throws ContentException { Content[] content; content = getContext().findContent(selector); if (content.length > 0) { return (PostBean) getContext().createContentBean(content[0]); } else { return null; } } }