com.tysanclan.site.projectewok.pages.ForumThreadPage.java Source code

Java tutorial

Introduction

Here is the source code for com.tysanclan.site.projectewok.pages.ForumThreadPage.java

Source

/**
 * Tysan Clan Website
 * Copyright (C) 2008-2013 Jeroen Steenbeeke and Ties van de Ven
 *
 * This program 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 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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, see <http://www.gnu.org/licenses/>.
 */
package com.tysanclan.site.projectewok.pages;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.List;

import javax.annotation.Nullable;
import javax.servlet.http.HttpServletResponse;

import org.apache.wicket.RestartResponseAtInterceptPageException;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.image.ContextImage;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.request.http.flow.AbortWithHttpErrorCodeException;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.spring.injection.annot.SpringBean;

import com.jeroensteenbeeke.hyperion.data.ModelMaker;
import com.tysanclan.rest.api.data.Rank;
import com.tysanclan.site.projectewok.TysanPage;
import com.tysanclan.site.projectewok.TysanSession;
import com.tysanclan.site.projectewok.beans.ForumService;
import com.tysanclan.site.projectewok.beans.MembershipService;
import com.tysanclan.site.projectewok.components.AutoForumLink;
import com.tysanclan.site.projectewok.components.AutoThreadLink;
import com.tysanclan.site.projectewok.components.ForumDataProvider;
import com.tysanclan.site.projectewok.components.ForumEventPanel;
import com.tysanclan.site.projectewok.components.ForumThreadModeratorPanel;
import com.tysanclan.site.projectewok.components.PostPanel;
import com.tysanclan.site.projectewok.components.TrialPanel;
import com.tysanclan.site.projectewok.entities.Event;
import com.tysanclan.site.projectewok.entities.Forum;
import com.tysanclan.site.projectewok.entities.ForumPost;
import com.tysanclan.site.projectewok.entities.ForumThread;
import com.tysanclan.site.projectewok.entities.Game;
import com.tysanclan.site.projectewok.entities.JoinApplication;
import com.tysanclan.site.projectewok.entities.JoinVerdict;
import com.tysanclan.site.projectewok.entities.Realm;
import com.tysanclan.site.projectewok.entities.Trial;
import com.tysanclan.site.projectewok.entities.User;
import com.tysanclan.site.projectewok.entities.UserGameRealm;
import com.tysanclan.site.projectewok.entities.dao.EventDAO;
import com.tysanclan.site.projectewok.entities.dao.ForumPostDAO;
import com.tysanclan.site.projectewok.entities.dao.ForumThreadDAO;
import com.tysanclan.site.projectewok.entities.dao.JoinApplicationDAO;
import com.tysanclan.site.projectewok.entities.dao.TrialDAO;
import com.tysanclan.site.projectewok.pages.forum.ReplyPage;
import com.tysanclan.site.projectewok.util.DateUtil;
import com.tysanclan.site.projectewok.util.MemberUtil;

/**
 * @author Jeroen Steenbeeke
 */
public class ForumThreadPage extends TysanPage {

    public static class ForumThreadPageParams {
        private final long threadId;

        private final int pageNumber;

        public ForumThreadPageParams(Long threadId, Integer pageNumber) {
            this.threadId = threadId;
            this.pageNumber = pageNumber;
        }

        public long getThreadId() {
            return threadId;
        }

        public int getPageNumber() {
            return pageNumber;
        }

    }

    private static final long serialVersionUID = 1L;

    @SpringBean
    private ForumThreadDAO dao;

    @SpringBean
    private EventDAO eventDAO;

    @SpringBean
    private ForumService forumService;

    @SpringBean
    private JoinApplicationDAO joinApplicationDAO;

    @SpringBean
    private TrialDAO trialDAO;

    private IModel<ForumThread> threadModel;

    @SpringBean
    private ForumPostDAO forumPostDAO;

    public ForumThreadPage(PageParameters params) {
        super("");

        ForumThreadPageParams parameters;

        try {
            parameters = requiredLong("threadid").requiredInt("pageid").forParameters(params)
                    .toClass(ForumThreadPageParams.class);
        } catch (PageParameterExtractorException e) {
            throw new AbortWithHttpErrorCodeException(HttpServletResponse.SC_NOT_FOUND);
        }

        ForumThread t = dao.get(parameters.getThreadId());

        if (t == null) {
            throw new RestartResponseAtInterceptPageException(AccessDeniedPage.class);
        }

        initComponents(t, parameters.getPageNumber(), getUser() == null);
    }

    public ForumThreadPage(final long threadId, int pageId, final boolean publicView) {
        super("");

        initComponents(dao.load(threadId), pageId, publicView);
    }

    /**
     * @return the dao
     */
    public ForumThreadDAO getDao() {
        return dao;
    }

    protected void initComponents(ForumThread thread, final int pageId, final boolean publicView) {
        TysanSession sess = TysanSession.get();

        Forum forum = thread.getForum();

        if (!forumService.canView(getUser(), forum)) {
            throw new RestartResponseAtInterceptPageException(AccessDeniedPage.class);
        }

        boolean memberLoggedIn = sess != null;

        setPageTitle(thread.getTitle());
        threadModel = ModelMaker.wrap(thread);

        initJoinComponents(thread, pageId);

        Link<ForumThread> replyLink = new Link<ForumThread>("replylink") {
            private static final long serialVersionUID = 1L;

            /**
             * @see org.apache.wicket.markup.html.link.Link#onClick()
             */
            @Override
            public void onClick() {
                setResponsePage(new ReplyPage(threadModel.getObject(), pageId));

            }
        };

        WebMarkupContainer branchnote = new WebMarkupContainer("branchnote");
        if (thread.getBranchFrom() != null) {
            branchnote.add(new AutoThreadLink("source", thread.getBranchFrom()));
        } else {
            branchnote.add(new WebMarkupContainer("source"));
        }
        add(branchnote);
        branchnote.setVisible(thread.getBranchFrom() != null);

        ForumThreadModeratorPanel modPanel = new ForumThreadModeratorPanel("moderatorToolbox", thread);

        User currentUser = getUser();
        boolean moderator = forumService.isModerator(currentUser, thread.getForum());

        modPanel.setVisible(moderator);

        add(modPanel);

        add(replyLink);

        long parentPageIndex = determineParentPageIndex(thread);

        add(new AutoForumLink("returnlink", thread.getForum(), "Return to forum", parentPageIndex));
        add(new AutoForumLink("returnlink2", thread.getForum(), "Return to forum", parentPageIndex));

        Event event = eventDAO.getEventByThread(thread);
        if (event == null) {
            add(new WebMarkupContainer("event").setVisible(false));
        } else {
            add(new ForumEventPanel("event", event, getUser()));
        }

        Trial trial = trialDAO.getTrialByThread(thread);
        if (trial == null) {
            add(new WebMarkupContainer("trial").setVisible(false));
        } else {
            add(new TrialPanel("trial", trial, getUser()));
        }

        DataView<ForumPost> postView = new DataView<ForumPost>("posts",
                ForumDataProvider.of(thread, forumPostDAO)) {
            private static final long serialVersionUID = 1L;

            @Override
            protected void populateItem(Item<ForumPost> item) {
                final ForumPost fp = item.getModelObject();

                item.add(new PostPanel("postpanel", fp));
            }

        };

        postView.setItemsPerPage(ForumThread.POSTS_PER_PAGE);
        postView.setCurrentPage(pageId - 1);

        add(postView);

        add(new PagingNavigator("topnavigation", postView));
        add(new PagingNavigator("bottomnavigation", postView));

        replyLink.setVisible(memberLoggedIn && !thread.isLocked()
                && forumService.canReply(getUser(), thread.getForum()) && mayReplyToTrial(trial, getUser()));

    }

    private boolean mayReplyToTrial(Trial trial, User user) {
        if (trial != null) {
            return user.getRank() == Rank.TRUTHSAYER || trial.getAccused().equals(user);

        }

        return true;
    }

    public ForumThread getThread() {
        return threadModel.getObject();
    }

    private void initJoinComponents(ForumThread thread, long pageId) {
        JoinApplication app = joinApplicationDAO.getJoinApplicationByThread(thread);

        addSenatorBox(app);

        addMentorBox(app);

        addStatusBox(app);

    }

    private void addStatusBox(JoinApplication app) {
        WebMarkupContainer joinMessages = new WebMarkupContainer("joinMessages");

        joinMessages.add(new Label("mentor",
                app != null ? app.getMentor() != null
                        ? "<b>" + app.getMentor().getUsername()
                                + "</b> has volunteered to be this candidate member's Mentor"
                        : "This candidate member has no mentor" : "").setEscapeModelStrings(false));

        int infavor = 0, total = 0;

        Calendar calendar = DateUtil.getCalendarInstance();

        if (app != null) {
            for (JoinVerdict verdict : app.getVerdicts()) {
                if (verdict.isInFavor()) {
                    infavor++;
                }
                total++;
            }
            calendar.setTime(app.getStartDate());
            calendar.add(Calendar.DAY_OF_YEAR, 3);

            if (app.getPrimaryGame() != null && app.getPrimaryRealm() != null) {
                joinMessages.add(new Label("realms", app.getApplicant().getUsername() + " primarily plays "
                        + app.getPrimaryGame().getName() + " on " + app.getPrimaryRealm().getName()));
            } else {
                joinMessages.add(new WebMarkupContainer("realms").setVisible(false));
            }
        } else {
            joinMessages.add(new WebMarkupContainer("realms").setVisible(false));
        }

        joinMessages.add(new Label("expirationTime",
                DateUtil.getTimezoneFormattedString(calendar.getTime(),
                        getUser() != null ? getUser().getTimezone() : DateUtil.NEW_YORK.getID()))
                                .setVisible(app != null));

        int against = total - infavor;

        joinMessages.add(new Label("senatestatus", new Model<String>(
                String.format("%d Senators voted in favor, %d voted against", infavor, against))));

        joinMessages.setVisible(app != null);

        add(joinMessages);
    }

    private void addMentorBox(JoinApplication app) {
        WebMarkupContainer mentorBox = new WebMarkupContainer("mentorApplication");

        boolean realmInCommon = false;
        final boolean activated = app != null ? app.getApplicant().getActivations().isEmpty() : false;

        if (app != null && getUser() != null) {
            Game game = app.getPrimaryGame();
            Realm realm = app.getPrimaryRealm();

            if (game != null && realm != null) {
                for (UserGameRealm ugr : getUser().getPlayedGames()) {
                    if (ugr.getGame().equals(game) && ugr.getRealm().equals(realm)) {
                        realmInCommon = true;
                    }
                }
            } else {
                realmInCommon = true;
                // If no realm supplied then anyone can mentor
            }
        }

        Link<JoinApplication> yesLink = new Link<JoinApplication>("clickYes", ModelMaker.wrap(app)) {
            private static final long serialVersionUID = 1L;

            @SpringBean
            private MembershipService service;

            @Override
            public void onClick() {
                User mentor = getUser();

                service.setMentor(getModelObject(), mentor);

                ForumThread thread = getModelObject().getJoinThread();

                setResponsePage(new ForumThreadPage(thread.getId(), 1, true));
            }

        };

        yesLink.add(new ContextImage("yes", new Model<String>("images/icons/tick.png")));
        yesLink.add(new Label("username", app != null ? app.getApplicant().getUsername() : "-"));
        yesLink.setVisible(realmInCommon && activated);
        mentorBox.add(yesLink);

        mentorBox.add(new Label("realmWarning",
                "You cannot be Mentor of this applicant, as you do not have a realm and game in common")
                        .setVisible(!realmInCommon));

        mentorBox.add(new Label("activationWarning",
                "You cannot volunteer to mentor for this applicant until his or her account is activated")
                        .setVisible(realmInCommon && !activated));

        mentorBox.setVisible(app != null && MemberUtil.canUserBeMentor(getUser()) && app.getMentor() == null);

        add(mentorBox);
    }

    private void addSenatorBox(@Nullable JoinApplication app) {
        boolean visible = getUser() != null && getUser().getRank() == Rank.SENATOR && app != null;

        WebMarkupContainer senatorBox = new WebMarkupContainer("senatorApproval");
        senatorBox.setVisible(visible);

        final boolean activated = visible ? app.getApplicant().getActivations().isEmpty() : false;

        Boolean inFavor = null;
        final String status;

        if (app != null) {
            for (JoinVerdict verdict : app.getVerdicts()) {
                if (verdict.getUser().equals(getUser())) {
                    inFavor = verdict.isInFavor();

                }

            }
        }

        if (activated) {
            if (inFavor != null) {
                if (inFavor.booleanValue()) {
                    status = "You have voted in favor of this candidate";
                } else {
                    status = "You have voted against this candidate";
                }
            } else {
                status = "You have not yet cast your vote";
            }

        } else {
            status = "You cannot vote until the applicant activates his account";
        }

        senatorBox.add(new Label("status", status));

        Link<JoinApplication> yesLink = new Link<JoinApplication>("clickYes", ModelMaker.wrap(app)) {
            private static final long serialVersionUID = 1L;

            @SpringBean
            private MembershipService service;

            @Override
            public void onClick() {
                JoinApplication _app = getModelObject();

                User user = getUser();

                service.setJoinApplicationVote(_app, user, true);

                ForumThread thread = getModelObject().getJoinThread();

                setResponsePage(new ForumThreadPage(thread.getId(), 1, true));
            }

        };

        yesLink.add(new ContextImage("yes", new Model<String>("images/icons/tick.png")));

        senatorBox.add(new WebMarkupContainer("question"));

        senatorBox.add(yesLink);

        Link<JoinApplication> noLink = new Link<JoinApplication>("clickNo", ModelMaker.wrap(app)) {
            private static final long serialVersionUID = 1L;

            @SpringBean
            private MembershipService service;

            @Override
            public void onClick() {
                JoinApplication _app = getModelObject();

                User user = getUser();

                service.setJoinApplicationVote(_app, user, false);

                ForumThread thread = getModelObject().getJoinThread();

                setResponsePage(new ForumThreadPage(thread.getId(), 1, true));
            }

        };

        noLink.add(new ContextImage("no", new Model<String>("images/icons/cross.png")));

        senatorBox.add(noLink);

        yesLink.setVisible(activated);
        noLink.setVisible(activated);

        add(senatorBox);
    }

    private long determineParentPageIndex(ForumThread thread) {

        List<ForumThread> allThreads = forumService.fiterAndSortThreads(getUser(), thread.getForum(),
                getUser() == null);

        int index = allThreads.indexOf(thread);
        int pos = 1 + new BigDecimal(index).divide(new BigDecimal(ForumThread.POSTS_PER_PAGE), RoundingMode.FLOOR)
                .intValue();
        return pos;
    }

    /**
     * @see org.apache.wicket.Page#onDetach()
     */
    @Override
    protected void onDetach() {
        super.onDetach();

        if (threadModel != null) {
            threadModel.detach();
        }
    }
}