From cf586f9cd06cf1408425f681cd410a53b9bd434a Mon Sep 17 00:00:00 2001 From: pb Date: Mon, 13 Sep 2010 10:33:25 +0000 Subject: [PATCH] Erster Teil einer Ueberarbeitung des Forums: Dokumentation hinzugefuegt, Benennungen systematisiert, Lokalisierung im Java code ergaenzt. git-svn-id: https://svn.libreccm.org/ccm/trunk@531 8810af33-2d31-482b-a856-94f89814c4df --- ccm-forum/src/com/arsdigita/forum/Forum.java | 23 +- .../com/arsdigita/forum/ForumPageBuilder.java | 105 ++++-- .../com/arsdigita/forum/ForumPageFactory.java | 12 +- .../src/com/arsdigita/forum/ForumServlet.java | 16 +- ccm-forum/src/com/arsdigita/forum/Loader.java | 32 +- .../src/com/arsdigita/forum/PageBuilder.java | 2 +- .../com/arsdigita/forum/ui/CategoryView.java | 101 ------ .../arsdigita/forum/ui/CategoryWidget.java | 16 +- ...m.java => EditPostForm.java.nolongerInUse} | 0 .../arsdigita/forum/ui/ForumAlertsView.java | 21 +- .../forum/ui/ForumResources.properties | 79 ++-- .../forum/ui/ForumResources_de.properties | 67 ++-- .../forum/ui/ForumResources_fr.properties | 57 +-- ...mponent.java => ForumUserCompactView.java} | 342 +++++++++++------- .../src/com/arsdigita/forum/ui/PostForm.java | 4 +- .../com/arsdigita/forum/ui/RootPostForm.java | 18 +- .../src/com/arsdigita/forum/ui/Text.java | 4 + .../arsdigita/forum/ui/ThreadComponent.java | 56 +-- .../com/arsdigita/forum/ui/ThreadDisplay.java | 7 + .../com/arsdigita/forum/ui/ThreadList.java | 39 +- .../{ForumUserView.java => ThreadsPanel.java} | 159 +++++--- ...CategoryAddForm.java => TopicAddForm.java} | 95 ++--- .../src/com/arsdigita/forum/ui/TopicList.java | 46 ++- .../com/arsdigita/forum/ui/TopicSelector.java | 18 +- .../com/arsdigita/forum/ui/TopicsPanel.java | 162 +++++++++ 25 files changed, 926 insertions(+), 555 deletions(-) delete mode 100755 ccm-forum/src/com/arsdigita/forum/ui/CategoryView.java rename ccm-forum/src/com/arsdigita/forum/ui/{EditPostForm.java => EditPostForm.java.nolongerInUse} (100%) rename ccm-forum/src/com/arsdigita/forum/ui/{ForumComponent.java => ForumUserCompactView.java} (51%) rename ccm-forum/src/com/arsdigita/forum/ui/{ForumUserView.java => ThreadsPanel.java} (51%) rename ccm-forum/src/com/arsdigita/forum/ui/{CategoryAddForm.java => TopicAddForm.java} (58%) create mode 100755 ccm-forum/src/com/arsdigita/forum/ui/TopicsPanel.java diff --git a/ccm-forum/src/com/arsdigita/forum/Forum.java b/ccm-forum/src/com/arsdigita/forum/Forum.java index 9b8260b12..34e4b8de8 100755 --- a/ccm-forum/src/com/arsdigita/forum/Forum.java +++ b/ccm-forum/src/com/arsdigita/forum/Forum.java @@ -51,6 +51,13 @@ import com.arsdigita.web.Application; /** * The Forum class represents a discussion forum. * + * XXX: Forum knows about threads which groups a set of posts to the same + * subject, and topics which group a set of threads about the same general + * theme. Currently Forum uses catgegory as synonym for topic, which may be + * misleading in some contexts, because there is forum-categorized which + * uses category in the usual CMS way, esp. navigation categories. Should be + * cleaned up in the future. + * * @author Kevin Scaldeferri (kevin@arsdigita.com) * @author chrisg23 * @version $Revision: 1.7 $ @@ -62,7 +69,7 @@ public class Forum extends Application { public static final String THREAD_SUBSCRIPTION_GROUPS_NAME = "Thread Subscription Groups"; - private static ForumConfig s_config = new ForumConfig(); + private static final ForumConfig s_config = new ForumConfig(); static { s_config.load(); @@ -151,7 +158,6 @@ public class Forum extends Application { * Also sets default values for other forum settings. These can be * amended under the setup tab in the ui */ - public static Forum create(String urlName, String title, Application parent, boolean moderated) { s_log.debug("creating forum " + title); @@ -182,7 +188,6 @@ public class Forum extends Application { * @return the Root Category for this forum, or creates a new one * does not have a root category, and returns it. */ - public Category getRootCategory() { DataObject category = (DataObject) get(CATEGORY); if (category == null) { @@ -237,7 +242,8 @@ public class Forum extends Application { // NPE when trying to retrieve sender's email address, thus stopping any // further message processing. // Actually, the only hack involved is making the email address unique. - String email = "forum-moderator-" + getID() + "-" + moderators.getID() + "@" + s_config.getReplyHostName(); + String email = "forum-moderator-" + getID() + "-" + + moderators.getID() + "@" + s_config.getReplyHostName(); moderators.setPrimaryEmail(new EmailAddress(email)); // chris.gilbert@westsussex.gov.uk create additional groups for privilege @@ -272,6 +278,7 @@ public class Forum extends Application { } + @Override public void initialize() { super.initialize(); @@ -290,11 +297,13 @@ public class Forum extends Application { private boolean m_wasNew; + @Override protected void beforeSave() { m_wasNew = isNew(); super.beforeSave(); } + @Override protected void afterSave() { if (m_wasNew) { PermissionService.setContext(getRootCategory(), this); @@ -462,7 +471,6 @@ public class Forum extends Application { FilterFactory factory = posts.getFilterFactory(); Filter pending = factory.equals(Post.STATUS, Post.PENDING); Filter reapprove = factory.equals(Post.STATUS, Post.REAPPROVE); - ; posts.addFilter(factory.or().addFilter(pending).addFilter(reapprove)); @@ -471,7 +479,7 @@ public class Forum extends Application { /** * gets all suppressed messages - allows moderators to see which messages - * heve been rejectedrequire their attention + * heve been rejected / require their attention * @return */ public DataAssociation getSuppressedPosts() { @@ -963,8 +971,9 @@ public class Forum extends Application { * * @return path name to the applications servlet/JSP */ + @Override public String getServletPath() { - // sufficient it installed into its own web appl. context (ccm-forum) + // sufficient if installed into its own web appl. context (ccm-forum) // return "/main"; return "/forum-main/main"; } diff --git a/ccm-forum/src/com/arsdigita/forum/ForumPageBuilder.java b/ccm-forum/src/com/arsdigita/forum/ForumPageBuilder.java index be3e334d5..efd3ca2a1 100644 --- a/ccm-forum/src/com/arsdigita/forum/ForumPageBuilder.java +++ b/ccm-forum/src/com/arsdigita/forum/ForumPageBuilder.java @@ -27,62 +27,95 @@ import com.arsdigita.bebop.SimpleComponent; import com.arsdigita.bebop.event.RequestEvent; import com.arsdigita.bebop.event.RequestListener; import com.arsdigita.bebop.parameters.BigDecimalParameter; -import com.arsdigita.bebop.parameters.ParameterModel; +// import com.arsdigita.bebop.parameters.ParameterModel; import com.arsdigita.forum.ui.Constants; -import com.arsdigita.forum.ui.ForumComponent; +import com.arsdigita.forum.ui.ForumUserCompactView; import com.arsdigita.kernel.permissions.PrivilegeDescriptor; import com.arsdigita.toolbox.ui.ApplicationAuthenticationListener; import com.arsdigita.xml.Element; /** - * @author chris.gilbert@westsussex.gov.uk + * Implementation of com.arsdigita.forum.PageBuilder that creates a + * basic forum page with read access check * - * Implementation of com.arsdigita.forum.PageBuilder that creates a basic forum page with read access check + * @author chris.gilbert@westsussex.gov.uk */ public class ForumPageBuilder implements PageBuilder, Constants { + /** + * + * @return + */ public Page buildPage() { - Page page = PageFactory.buildPage(Constants.FORUM_XML_PREFIX, "Forum", "forumPage"); - //Output the title in an easy to find place - page.add(new SimpleComponent(){ - public void generateXML(PageState state, Element parent) { - Element nameElement = parent.newChildElement(Constants.FORUM_XML_PREFIX + ":name", Constants.FORUM_XML_NS); - nameElement.setText(ForumContext.getContext(state).getForum().getTitle()); - Element introductionElement = parent.newChildElement(Constants.FORUM_XML_PREFIX + ":introduction", Constants.FORUM_XML_NS); - introductionElement.setText(ForumContext.getContext(state).getForum().getIntroduction()); - } - }); - ForumComponent forumComp = getForumComponent(); - page.add(forumComp); - BigDecimalParameter topic = new BigDecimalParameter(TOPIC_PARAM); - page.addGlobalStateParam(topic); - page.addRequestListener(new ApplicationAuthenticationListener(PrivilegeDescriptor.READ)); - page.addRequestListener(new ForumPageRequestListener(topic, forumComp)); - return page; + + Page page = PageFactory.buildPage(Constants.FORUM_XML_PREFIX, + "Forum", + "forumPage"); + + //Output the title in an easy to find place + page.add(new SimpleComponent(){ + public void generateXML(PageState state, Element parent) { + Element nameElement = parent.newChildElement( + Constants.FORUM_XML_PREFIX + + ":name", + Constants.FORUM_XML_NS); + nameElement.setText( + ForumContext.getContext(state).getForum().getTitle()); + Element introductionElement = parent.newChildElement( + Constants.FORUM_XML_PREFIX + + ":introduction", + Constants.FORUM_XML_NS); + introductionElement.setText( + ForumContext.getContext(state).getForum().getIntroduction()); + } + }); + + ForumUserCompactView forumComp = getForumComponent(); + page.add(forumComp); + BigDecimalParameter topic = new BigDecimalParameter(TOPIC_PARAM); + page.addGlobalStateParam(topic); + page.addRequestListener( + new ApplicationAuthenticationListener(PrivilegeDescriptor.READ)); + page.addRequestListener(new ForumPageRequestListener(topic, forumComp)); + return page; } - - - protected ForumComponent getForumComponent() { - return new ForumComponent(); + + + /** + * + * @return + */ + protected ForumUserCompactView getForumComponent() { + return new ForumUserCompactView(); } + /** + * Internal class + */ private static class ForumPageRequestListener implements RequestListener { - private BigDecimalParameter m_categorySelection; - private ForumComponent m_forumComp; - public ForumPageRequestListener(BigDecimalParameter topicSelection, ForumComponent forumComp) { - m_categorySelection = topicSelection; - m_forumComp = forumComp; - } + private BigDecimalParameter m_categorySelection; + private ForumUserCompactView m_forumComp; - public void pageRequested(RequestEvent event) { + /** + * Default Constructor + * @param topicSelection + * @param forumComp + */ + public ForumPageRequestListener(BigDecimalParameter topicSelection, + ForumUserCompactView forumComp) { + m_categorySelection = topicSelection; + m_forumComp = forumComp; + } - PageState state = event.getPageState(); - ForumContext context = ForumContext.getContext(state); + public void pageRequested(RequestEvent event) { - context.setCategorySelection - ((BigDecimal) event.getPageState().getValue(m_categorySelection)); + PageState state = event.getPageState(); + ForumContext context = ForumContext.getContext(state); + + context.setCategorySelection( + (BigDecimal) event.getPageState().getValue(m_categorySelection)); } } } diff --git a/ccm-forum/src/com/arsdigita/forum/ForumPageFactory.java b/ccm-forum/src/com/arsdigita/forum/ForumPageFactory.java index 3f7ce915c..25d60d77d 100644 --- a/ccm-forum/src/com/arsdigita/forum/ForumPageFactory.java +++ b/ccm-forum/src/com/arsdigita/forum/ForumPageFactory.java @@ -23,15 +23,15 @@ import java.util.Iterator; import java.util.Map; import com.arsdigita.bebop.Page; -import com.arsdigita.bebop.parameters.ParameterModel; +// import com.arsdigita.bebop.parameters.ParameterModel; import com.arsdigita.util.Assert; /** - * @author chris.gilbert@westsussex.gov.uk - * * Factory class that enables projects to provide their own page creators. * A reason for doing this is that a particular forum project may wish to * include components on the page that introduce dependencies on other projects + * + * @author chris.gilbert@westsussex.gov.uk */ public class ForumPageFactory { @@ -46,8 +46,10 @@ public class ForumPageFactory { pageBuilders.put(FORUM_PAGE, new ForumPageBuilder()); } - public static Page getPage(String pageType) { - Assert.isTrue(pageBuilders.containsKey(pageType), "Requested page type (" + pageType + ") does not have a builder registered" ); + public static Page getPage(String pageType) { + Assert.isTrue(pageBuilders.containsKey(pageType), + "Requested page type (" + pageType + + ") does not have a builder registered" ); PageBuilder builder = (PageBuilder)pageBuilders.get(pageType); Page page = builder.buildPage(); page.lock(); diff --git a/ccm-forum/src/com/arsdigita/forum/ForumServlet.java b/ccm-forum/src/com/arsdigita/forum/ForumServlet.java index 6d18913df..2fc9fdc6a 100755 --- a/ccm-forum/src/com/arsdigita/forum/ForumServlet.java +++ b/ccm-forum/src/com/arsdigita/forum/ForumServlet.java @@ -18,24 +18,26 @@ */ package com.arsdigita.forum; -import java.util.Iterator; -// unused import -//import java.util.Map; - -import com.arsdigita.forum.ui.Constants; import com.arsdigita.bebop.Page; import com.arsdigita.bebop.page.BebopApplicationServlet; // unused import // import com.arsdigita.bebop.parameters.BigDecimalParameter; +import com.arsdigita.forum.ui.Constants; + +import java.util.Iterator; +// unused import +//import java.util.Map; import javax.servlet.ServletException; import org.apache.log4j.Logger; /** + * * @author Justin Ross <jross@redhat.com> * - * Updated chris.gilbert@westsussex.gov.uk to make use of PageFactory and to enable - * disablement of client/middleware caching + * @author Chris Gilbert (chris.gilbert@westsussex.gov.uk) updated to make use of + * PageFactory and to enable disablement of client/middleware + * caching * @version $Id: ForumServlet.java 1628 2007-09-17 08:10:40Z chrisg23 $ */ public class ForumServlet extends BebopApplicationServlet diff --git a/ccm-forum/src/com/arsdigita/forum/Loader.java b/ccm-forum/src/com/arsdigita/forum/Loader.java index 4cc502de6..5f81d1019 100755 --- a/ccm-forum/src/com/arsdigita/forum/Loader.java +++ b/ccm-forum/src/com/arsdigita/forum/Loader.java @@ -52,6 +52,7 @@ import org.apache.log4j.Logger; */ public class Loader extends PackageLoader { + /** Private logger instance for debugging purpose. */ private static final Logger s_log = Logger.getLogger(Loader.class); public void run(final ScriptContext ctx) { @@ -140,22 +141,23 @@ public class Loader extends PackageLoader { } public static void setupPrivileges() { - PrivilegeDescriptor.createPrivilege( - Forum.FORUM_MODERATION_PRIVILEGE); - PrivilegeDescriptor.createPrivilege( - Forum.CREATE_THREAD_PRIVILEGE); - PrivilegeDescriptor.createPrivilege( - Forum.RESPOND_TO_THREAD_PRIVILEGE); - PrivilegeDescriptor.addChildPrivilege( - Forum.FORUM_MODERATION_PRIVILEGE, - Forum.CREATE_THREAD_PRIVILEGE); - PrivilegeDescriptor.addChildPrivilege( - Forum.CREATE_THREAD_PRIVILEGE, - Forum.RESPOND_TO_THREAD_PRIVILEGE); - PrivilegeDescriptor.addChildPrivilege( - Forum.RESPOND_TO_THREAD_PRIVILEGE, - PrivilegeDescriptor.READ.getName()); + PrivilegeDescriptor.createPrivilege( + Forum.FORUM_MODERATION_PRIVILEGE); + PrivilegeDescriptor.createPrivilege( + Forum.CREATE_THREAD_PRIVILEGE); + PrivilegeDescriptor.createPrivilege( + Forum.RESPOND_TO_THREAD_PRIVILEGE); + + PrivilegeDescriptor.addChildPrivilege( + Forum.FORUM_MODERATION_PRIVILEGE, + Forum.CREATE_THREAD_PRIVILEGE); + PrivilegeDescriptor.addChildPrivilege( + Forum.CREATE_THREAD_PRIVILEGE, + Forum.RESPOND_TO_THREAD_PRIVILEGE); + PrivilegeDescriptor.addChildPrivilege( + Forum.RESPOND_TO_THREAD_PRIVILEGE, + PrivilegeDescriptor.READ.getName()); diff --git a/ccm-forum/src/com/arsdigita/forum/PageBuilder.java b/ccm-forum/src/com/arsdigita/forum/PageBuilder.java index e0ba02e8d..bd1d3aa67 100644 --- a/ccm-forum/src/com/arsdigita/forum/PageBuilder.java +++ b/ccm-forum/src/com/arsdigita/forum/PageBuilder.java @@ -19,7 +19,7 @@ package com.arsdigita.forum; import com.arsdigita.bebop.Page; -import com.arsdigita.bebop.parameters.ParameterModel; +// import com.arsdigita.bebop.parameters.ParameterModel; /** * @author chris.gilbert@westsussex.gov.uk diff --git a/ccm-forum/src/com/arsdigita/forum/ui/CategoryView.java b/ccm-forum/src/com/arsdigita/forum/ui/CategoryView.java deleted file mode 100755 index b11040ceb..000000000 --- a/ccm-forum/src/com/arsdigita/forum/ui/CategoryView.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -package com.arsdigita.forum.ui; - -import com.arsdigita.bebop.Component; -import com.arsdigita.bebop.Container; -import com.arsdigita.bebop.Form; -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.ModalContainer; -import com.arsdigita.bebop.Page; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.SimpleContainer; -import com.arsdigita.bebop.ToggleLink; -import com.arsdigita.bebop.event.ActionEvent; -import com.arsdigita.bebop.event.ActionListener; - -import org.apache.log4j.Logger; - - -public class CategoryView extends SimpleContainer - implements ActionListener { - - private static Logger s_log = Logger.getLogger(CategoryView.class); - - private ModalContainer m_mode; - private Component m_categories; - private Component m_addForm; - private ToggleLink m_addCategoryLink; - - public CategoryView() { - m_mode = new ModalContainer(); - add(m_mode); - - m_categories = createCategoryView(); - m_addForm = createAddCategoryForm(); - - m_mode.add(m_categories); - m_mode.add(m_addForm); - - m_mode.setDefaultComponent(m_categories); - } - - public void register(Page p) { - super.register(p); - p.addActionListener(this); - } - - public void actionPerformed(ActionEvent e) { - PageState s = e.getPageState(); - - if (m_addCategoryLink.isSelected(s)) { - m_mode.setVisibleComponent(s, m_addForm); - } else { - m_mode.setVisibleComponent(s, m_categories); - } - } - - private Container createCategoryView() { - - Container categories = new SimpleContainer(); - - Container linksPanel = new SimpleContainer(Constants.FORUM_XML_PREFIX + ":topicOptions", - Constants.FORUM_XML_NS); - m_addCategoryLink = new ToggleLink(new Label(Text.gz("forum.ui.newTopic"))); - m_addCategoryLink.setClassAttr("actionLink"); - linksPanel.add(m_addCategoryLink); - - categories.add(linksPanel); - categories.add(new TopicList()); - - return categories; - } - - private Component createAddCategoryForm() { - Form addForm = new CategoryAddForm(); - addForm.addCompletionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - PageState s = e.getPageState(); - m_addCategoryLink.setSelected(s, false); - m_mode.setVisibleComponent(s, m_categories); - } - }); - return addForm; - } -} diff --git a/ccm-forum/src/com/arsdigita/forum/ui/CategoryWidget.java b/ccm-forum/src/com/arsdigita/forum/ui/CategoryWidget.java index 180a6de12..5a0770be3 100755 --- a/ccm-forum/src/com/arsdigita/forum/ui/CategoryWidget.java +++ b/ccm-forum/src/com/arsdigita/forum/ui/CategoryWidget.java @@ -40,9 +40,8 @@ import java.util.TooManyListenersException; * @author ron@arsdigita.com * @author sarah@arsdigita.com * - * @version $Id: CategoryWidget.java 1628 2007-09-17 08:10:40Z chrisg23 $ + * @version $Id: CategoryWidget.java 1628 2007-09-17 08:10:40Z chrisg23 $ */ - public class CategoryWidget extends SingleSelect implements Constants { public CategoryWidget(ParameterModel categoryParameter) { @@ -53,13 +52,14 @@ public class CategoryWidget extends SingleSelect implements Constants { public void prepare(PrintEvent e) { PageState s = e.getPageState(); final Forum forum = getForum(s); - SingleSelect target = (SingleSelect) e.getTarget(); - + SingleSelect target = (SingleSelect) e.getTarget(); + // Get categories for this forum - if (forum.noCategoryPostsAllowed()) { - target.addOption(new Option(TOPIC_NONE.toString(), - new Label(Text.gz("forum.ui.topic.none")))); - } + if (forum.noCategoryPostsAllowed()) { + target.addOption(new Option( + TOPIC_NONE.toString(), + new Label(Text.gz("forum.ui.topic.none")))); + } final Category root = forum.getRootCategory(); if (root != null) { addCategories(root, target); diff --git a/ccm-forum/src/com/arsdigita/forum/ui/EditPostForm.java b/ccm-forum/src/com/arsdigita/forum/ui/EditPostForm.java.nolongerInUse similarity index 100% rename from ccm-forum/src/com/arsdigita/forum/ui/EditPostForm.java rename to ccm-forum/src/com/arsdigita/forum/ui/EditPostForm.java.nolongerInUse diff --git a/ccm-forum/src/com/arsdigita/forum/ui/ForumAlertsView.java b/ccm-forum/src/com/arsdigita/forum/ui/ForumAlertsView.java index ec4f31c57..17b072a42 100755 --- a/ccm-forum/src/com/arsdigita/forum/ui/ForumAlertsView.java +++ b/ccm-forum/src/com/arsdigita/forum/ui/ForumAlertsView.java @@ -51,24 +51,31 @@ import java.math.BigDecimal; import org.apache.log4j.Logger; +/** + * + * + */ class ForumAlertsView extends SimpleContainer implements Constants { private static final Logger s_log = Logger.getLogger (ForumAlertsView.class); + /** + * Standard Constructor + */ ForumAlertsView() { add(forumAlertsSegment()); add(threadAlertsSegment()); } private Component forumAlertsSegment() { - SimpleContainer seg = new SimpleContainer(FORUM_XML_PREFIX + ":forumAlerts", + SimpleContainer seg = new SimpleContainer(FORUM_XML_PREFIX + ":forumAlerts", FORUM_XML_NS); seg.add(forumAlertsForm()); return seg; } private Component threadAlertsSegment() { - SimpleContainer seg = new SimpleContainer(FORUM_XML_PREFIX + ":threadAlerts", + SimpleContainer seg = new SimpleContainer(FORUM_XML_PREFIX + ":threadAlerts", FORUM_XML_NS); seg.add(threadAlertsForm()); return seg; @@ -78,19 +85,19 @@ class ForumAlertsView extends SimpleContainer implements Constants { Form alertsForm = new Form("instantAlerts", new ColumnPanel(2)); final RadioGroup instant = new RadioGroup("instant"); - instant.addOption(new Option("Yes")); - instant.addOption(new Option("No")); + instant.addOption(new Option(Text.gzAsStr("forum.ui.yes"))); + instant.addOption(new Option(Text.gzAsStr("forum.ui.no"))); alertsForm.add(new Label(Text.gz("forum.ui.receive_instant_alerts"))); alertsForm.add(instant); final RadioGroup daily = new RadioGroup("daily"); - daily.addOption(new Option("Yes")); - daily.addOption(new Option("No")); + daily.addOption(new Option(Text.gzAsStr("forum.ui.yes"))); + daily.addOption(new Option(Text.gzAsStr("forum.ui.no"))); alertsForm.add(new Label(Text.gz("forum.ui.receive_daily_summary"))); alertsForm.add(daily); alertsForm.add(new Label("")); - alertsForm.add(new Submit("Save")); + alertsForm.add(new Submit(Text.gz("forum.ui.save"))); alertsForm.addInitListener(new FormInitListener() { public void init(FormSectionEvent e) { diff --git a/ccm-forum/src/com/arsdigita/forum/ui/ForumResources.properties b/ccm-forum/src/com/arsdigita/forum/ui/ForumResources.properties index 0b5caadc4..1300ee29a 100755 --- a/ccm-forum/src/com/arsdigita/forum/ui/ForumResources.properties +++ b/ccm-forum/src/com/arsdigita/forum/ui/ForumResources.properties @@ -1,18 +1,31 @@ -forum.ui.name=Name -forum.ui.description=Description -forum.ui.cancel=Cancel +forum.ui.delete=Delete -forum.ui.newTopic=New topic -forum.ui.topic.none=None +forum.ui.noSubscriptions=You are not subscribed to any threads forum.ui.receive_instant_alerts=Receive instant alerts forum.ui.receive_daily_summary=Receive daily summary -forum.ui.noSubscriptions=You are not subscribed to any threads -forum.ui.delete=Delete -forum.ui.newPost=New thread -forum.ui.threads.viewAll=View all threads + +forum.ui.modeAlerts=Alerts +forum.ui.modeThreads=Threads +forum.ui.modeTopics=Topics +forum.ui.modeModeration=Moderation +forum.ui.modeSetup=Setup +forum.ui.modePermissions=Permissions + +forum.ui.cancel=Cancel +forum.ui.save=Save +forum.ui.yes=Yes +forum.ui.no=No + +forum.ui.thread.newPost=Start New thread forum.ui.thread.subscribe=Subscribe to thread forum.ui.thread.unsubscribe=Unsubscribe to thread -forum.ui.topic.save=Create Topic +forum.ui.thread.viewAll=View all threads + +forum.ui.topic.description=Description +forum.ui.topic.name=Name +forum.ui.topic.newTopic=New topic +forum.ui.topic.none=None +forum.ui.topic.save=Create Topic forum.ui.moderate.label=Moderation: forum.ui.moderate.switch.on=Turn on @@ -28,26 +41,26 @@ forum.ui.noticeboard.status.on=On (replying disabled) forum.ui.noticeboard.status.off=Off (replying enabled) forum.ui.noticeboard.expiry_after=Expires after (in days) forum.ui.noticeboard.change_expiry=Update - -forum.ui.settings.moderated=Moderated -forum.ui.settings.noticeboard=Noticeboard (Disable Replying) -forum.ui.settings.allowFiles=Allow File Attachments -forum.ui.settings.allowImages=Allow images in posts -forum.ui.settings.autosubscribe=Automatically subscribe thread starters -forum.ui.settings.noCategoryPosts=Allow posts with no topic -forum.ui.settings.anonymousPosts=Allow anonymous posts -forum.ui.settings.save=Save Changes -forum.ui.settings.introduction=Introduction -forum.ui.settings.title=Forum Title - -forum.ui.validation.subject_null=Please enter a subject -forum.ui.validation.body_null=Please enter a message -forum.ui.validation.body_too_long=Your message is too long, only 4000 characters can be stored -forum.ui.validation.image_file_null=Please use the browse button above to find an image to add -forum.ui.validation.image_description_null=Please enter a description for the image (This will be displayed to users who cannot see the image) -forum.ui.validation.image_description_too_long=Your description is too long, only 4000 characters can be stored -forum.ui.validation.file_null=Please use the browse button above to find a file to add -forum.ui.validation.file_description_too_long=Your description is too long, only 4000 characters can be stored -forum.ui.validation.image_not_uploaded=To add the specified image, use the Add Image button before leaving this page. If you don't want to add the image, click Next or Previous. -forum.ui.validation.file_not_uploaded=To add the specified file, use the Add File button before leaving this page. If you don't want to add the file, click Next or Previous. -forum.ui.validation.introduction_too_long=Your introduction is too long, only 4000 characters can be stored + +forum.ui.settings.moderated=Moderated +forum.ui.settings.noticeboard=Noticeboard (Disable Replying) +forum.ui.settings.allowFiles=Allow File Attachments +forum.ui.settings.allowImages=Allow images in posts +forum.ui.settings.autosubscribe=Automatically subscribe thread starters +forum.ui.settings.noCategoryPosts=Allow posts with no topic +forum.ui.settings.anonymousPosts=Allow anonymous posts +forum.ui.settings.save=Save Changes +forum.ui.settings.introduction=Introduction +forum.ui.settings.title=Forum Title + +forum.ui.validation.subject_null=Please enter a subject +forum.ui.validation.body_null=Please enter a message +forum.ui.validation.body_too_long=Your message is too long, only 4000 characters can be stored +forum.ui.validation.image_file_null=Please use the browse button above to find an image to add +forum.ui.validation.image_description_null=Please enter a description for the image (This will be displayed to users who cannot see the image) +forum.ui.validation.image_description_too_long=Your description is too long, only 4000 characters can be stored +forum.ui.validation.file_null=Please use the browse button above to find a file to add +forum.ui.validation.file_description_too_long=Your description is too long, only 4000 characters can be stored +forum.ui.validation.image_not_uploaded=To add the specified image, use the Add Image button before leaving this page. If you don't want to add the image, click Next or Previous. +forum.ui.validation.file_not_uploaded=To add the specified file, use the Add File button before leaving this page. If you don't want to add the file, click Next or Previous. +forum.ui.validation.introduction_too_long=Your introduction is too long, only 4000 characters can be stored diff --git a/ccm-forum/src/com/arsdigita/forum/ui/ForumResources_de.properties b/ccm-forum/src/com/arsdigita/forum/ui/ForumResources_de.properties index 56b54608c..ee40b69b0 100644 --- a/ccm-forum/src/com/arsdigita/forum/ui/ForumResources_de.properties +++ b/ccm-forum/src/com/arsdigita/forum/ui/ForumResources_de.properties @@ -1,27 +1,40 @@ -forum.ui.name=Name -forum.ui.description=Beschreibung -forum.ui.cancel=Abbrechen +forum.ui.delete=L\u00f6schen -forum.ui.newTopic=Neues Thema -forum.ui.topic.none=Nichts -forum.ui.receive_instant_alerts=Sofortige Benachrichtigung -forum.ui.receive_daily_summary=T\u00E4gliche Zusammenfassung forum.ui.noSubscriptions=You are not subscribed to any threads -forum.ui.delete=L\u00F6schen -forum.ui.newPost=New thread -forum.ui.threads.viewAll=View all threads -forum.ui.thread.subscribe=Subscribe to thread -forum.ui.thread.unsubscribe=Unsubscribe to thread -forum.ui.topic.save=Neues Thema erstellen +forum.ui.receive_instant_alerts=Sofortige Benachrichtigung +forum.ui.receive_daily_summary=T\u00e4gliche Zusammenfassung + +forum.ui.modeAlerts=Benachrichtigung +forum.ui.modeThreads=Themen +forum.ui.modeTopics=Themenbereiche +forum.ui.modeModeration=Moderation +forum.ui.modeSetup=Einstellungen +forum.ui.modePermissions=Berechtigungen + +forum.ui.cancel=Abbrechen +forum.ui.save=Speichern +forum.ui.yes=Ja +forum.ui.no=Nein + +forum.ui.thread.newPost=Neues Diskussionsthema er\u00f6ffnen +forum.ui.thread.subscribe=Thema abonnieren +forum.ui.thread.unsubscribe=Thema stornieren +forum.ui.thread.viewAll=Alle Themen + +forum.ui.topic.description=Beschreibung +forum.ui.topic.name=Name +forum.ui.topic.newTopic=Neues Thema +forum.ui.topic.none=Nichts +forum.ui.topic.save=Themenbereich erstellen forum.ui.moderate.label=Moderation: forum.ui.moderate.switch.on=Einschalten forum.ui.moderate.switch.off=Ausschalten forum.ui.moderate.status.on=Aktiv forum.ui.moderate.status.off=Inaktiv -forum.ui.moderate.warning=NB. Turning moderation off will change pending posts to approved status +forum.ui.moderate.warning=Achtung: Deaktivieren der Modereation \u00e4ndert den Status von ausstehenden Nachrichten auf akzeptiert! -forum.ui.noticeboard.label=Noticeboard functionality (disable replying) +forum.ui.noticeboard.label=Noticeboard functionality (Antworten deaktiviert) forum.ui.noticeboard.switch.on=Turn on (disable replying) forum.ui.noticeboard.switch.off=Turn off (enable replying) forum.ui.noticeboard.status.on=An (replying disabled) @@ -29,25 +42,25 @@ forum.ui.noticeboard.status.off=Aus (replying enabled) forum.ui.noticeboard.expiry_after=Expires after (in days) forum.ui.noticeboard.change_expiry=Update -forum.ui.settings.moderated=Moderated -forum.ui.settings.noticeboard=Noticeboard (Disable Replying) -forum.ui.settings.allowFiles=Dateianh\u00E4nge zulassen +forum.ui.settings.moderated=Moderiert +forum.ui.settings.noticeboard=Noticeboard (Keine Antworten m\u00f6glich) +forum.ui.settings.allowFiles=Dateianh\u00e4nge zulassen forum.ui.settings.allowImages=Bilder in Posts zulassen forum.ui.settings.autosubscribe=Automatically subscribe thread starters forum.ui.settings.noCategoryPosts=Allow posts with no topic forum.ui.settings.anonymousPosts=Allow anonymous posts -forum.ui.settings.save=\u00C4nderungen sichern -forum.ui.settings.introduction=Einf\u00FChrung +forum.ui.settings.save=\u00c4nderungen sichern +forum.ui.settings.introduction=Einf\u00fchrung forum.ui.settings.title=Forum Titel forum.ui.validation.subject_null=Betreff eingeben forum.ui.validation.body_null=Nachricht verfassen -forum.ui.validation.body_too_long=Your message is too long, only 4000 characters can be stored -forum.ui.validation.image_file_null=Please use the browse button above to find an image to add -forum.ui.validation.image_description_null=Please enter a description for the image (This will be displayed to users who cannot see the image) -forum.ui.validation.image_description_too_long=Your description is too long, only 4000 characters can be stored -forum.ui.validation.file_null=Please use the browse button above to find a file to add -forum.ui.validation.file_description_too_long=Your description is too long, only 4000 characters can be stored +forum.ui.validation.body_too_long=Die Nachricht is zu lang, maximal 4000 Zeichen sind zugelassen. +forum.ui.validation.image_file_null=Bitte den Button Durchsuchen benutzen, um ein Bild anzuf\u00fcgen +forum.ui.validation.image_description_null=Bitte eine kurze Bildbeschreibung eingeben (f\u00fcr Benutzer, die das Bild nicht anschauen k\u00f6nnen.) +forum.ui.validation.image_description_too_long=Die Beschreibung is zu lang, maximal 4000 Zeichen sind zugelassen. +forum.ui.validation.file_null=Bitte den Button Durchsuchen benutzen, um eine Datei anzuf\u00fcgen +forum.ui.validation.file_description_too_long=Die Beschreibung is zu lang, maximal 4000 Zeichen sind zugelassen. forum.ui.validation.image_not_uploaded=To add the specified image, use the Add Image button before leaving this page. If you don't want to add the image, click Next or Previous. forum.ui.validation.file_not_uploaded=To add the specified file, use the Add File button before leaving this page. If you don't want to add the file, click Next or Previous. -forum.ui.validation.introduction_too_long=Your introduction is too long, only 4000 characters can be stored +forum.ui.validation.introduction_too_long=Die Einf\u00fchrung ist zu lang, maximal 4000 Zeichen sind zugelassen. diff --git a/ccm-forum/src/com/arsdigita/forum/ui/ForumResources_fr.properties b/ccm-forum/src/com/arsdigita/forum/ui/ForumResources_fr.properties index 0b5caadc4..aab789fc5 100644 --- a/ccm-forum/src/com/arsdigita/forum/ui/ForumResources_fr.properties +++ b/ccm-forum/src/com/arsdigita/forum/ui/ForumResources_fr.properties @@ -1,6 +1,6 @@ forum.ui.name=Name forum.ui.description=Description -forum.ui.cancel=Cancel +forum.ui.cancel=Cancel forum.ui.newTopic=New topic forum.ui.topic.none=None @@ -12,7 +12,7 @@ forum.ui.newPost=New thread forum.ui.threads.viewAll=View all threads forum.ui.thread.subscribe=Subscribe to thread forum.ui.thread.unsubscribe=Unsubscribe to thread -forum.ui.topic.save=Create Topic +forum.ui.topic.save=Create Topic forum.ui.moderate.label=Moderation: forum.ui.moderate.switch.on=Turn on @@ -28,26 +28,33 @@ forum.ui.noticeboard.status.on=On (replying disabled) forum.ui.noticeboard.status.off=Off (replying enabled) forum.ui.noticeboard.expiry_after=Expires after (in days) forum.ui.noticeboard.change_expiry=Update - -forum.ui.settings.moderated=Moderated -forum.ui.settings.noticeboard=Noticeboard (Disable Replying) -forum.ui.settings.allowFiles=Allow File Attachments -forum.ui.settings.allowImages=Allow images in posts -forum.ui.settings.autosubscribe=Automatically subscribe thread starters -forum.ui.settings.noCategoryPosts=Allow posts with no topic -forum.ui.settings.anonymousPosts=Allow anonymous posts -forum.ui.settings.save=Save Changes -forum.ui.settings.introduction=Introduction -forum.ui.settings.title=Forum Title - -forum.ui.validation.subject_null=Please enter a subject -forum.ui.validation.body_null=Please enter a message -forum.ui.validation.body_too_long=Your message is too long, only 4000 characters can be stored -forum.ui.validation.image_file_null=Please use the browse button above to find an image to add -forum.ui.validation.image_description_null=Please enter a description for the image (This will be displayed to users who cannot see the image) -forum.ui.validation.image_description_too_long=Your description is too long, only 4000 characters can be stored -forum.ui.validation.file_null=Please use the browse button above to find a file to add -forum.ui.validation.file_description_too_long=Your description is too long, only 4000 characters can be stored -forum.ui.validation.image_not_uploaded=To add the specified image, use the Add Image button before leaving this page. If you don't want to add the image, click Next or Previous. -forum.ui.validation.file_not_uploaded=To add the specified file, use the Add File button before leaving this page. If you don't want to add the file, click Next or Previous. -forum.ui.validation.introduction_too_long=Your introduction is too long, only 4000 characters can be stored + +forum.ui.settings.moderated=Moderated +forum.ui.settings.noticeboard=Noticeboard (Disable Replying) +forum.ui.settings.allowFiles=Allow File Attachments +forum.ui.settings.allowImages=Allow images in posts +forum.ui.settings.autosubscribe=Automatically subscribe thread starters +forum.ui.settings.noCategoryPosts=Allow posts with no topic +forum.ui.settings.anonymousPosts=Allow anonymous posts +forum.ui.settings.save=Save Changes +forum.ui.settings.introduction=Introduction +forum.ui.settings.title=Forum Title + +forum.ui.validation.subject_null=Please enter a subject +forum.ui.validation.body_null=Please enter a message +forum.ui.validation.body_too_long=Your message is too long, only 4000 characters can be stored +forum.ui.validation.image_file_null=Please use the browse button above to find an image to add +forum.ui.validation.image_description_null=Please enter a description for the image (This will be displayed to users who cannot see the image) +forum.ui.validation.image_description_too_long=Your description is too long, only 4000 characters can be stored +forum.ui.validation.file_null=Please use the browse button above to find a file to add +forum.ui.validation.file_description_too_long=Your description is too long, only 4000 characters can be stored +forum.ui.validation.image_not_uploaded=To add the specified image, use the Add Image button before leaving this page. If you don't want to add the image, click Next or Previous. +forum.ui.validation.file_not_uploaded=To add the specified file, use the Add File button before leaving this page. If you don't want to add the file, click Next or Previous. +forum.ui.validation.introduction_too_long=Your introduction is too long, only 4000 characters can be stored +forum.ui.yes=Yes +forum.ui.no=No +forum.ui.save=Save +forum.ui.alerts=Alerts +forum.ui.threads=Threads +forum.ui.topics=Topics +forum.ui.thread.viewAll=View all threads diff --git a/ccm-forum/src/com/arsdigita/forum/ui/ForumComponent.java b/ccm-forum/src/com/arsdigita/forum/ui/ForumUserCompactView.java similarity index 51% rename from ccm-forum/src/com/arsdigita/forum/ui/ForumComponent.java rename to ccm-forum/src/com/arsdigita/forum/ui/ForumUserCompactView.java index c67fae953..c5800d958 100755 --- a/ccm-forum/src/com/arsdigita/forum/ui/ForumComponent.java +++ b/ccm-forum/src/com/arsdigita/forum/ui/ForumUserCompactView.java @@ -18,120 +18,165 @@ */ package com.arsdigita.forum.ui; -import java.io.IOException; - -import javax.servlet.ServletException; - -import org.apache.log4j.Logger; - +import java.io.IOException; + +import javax.servlet.ServletException; + +import org.apache.log4j.Logger; + import com.arsdigita.bebop.ModalContainer; -import com.arsdigita.bebop.Page; -import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.Page; +import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.parameters.StringParameter; -import com.arsdigita.forum.Forum; -import com.arsdigita.forum.ForumContext; -import com.arsdigita.forum.ui.admin.ModerationView; -import com.arsdigita.forum.ui.admin.PermissionsView; -import com.arsdigita.forum.ui.admin.SetupView; +import com.arsdigita.forum.Forum; +import com.arsdigita.forum.ForumContext; +import com.arsdigita.forum.ui.admin.ModerationView; +import com.arsdigita.forum.ui.admin.PermissionsView; +import com.arsdigita.forum.ui.admin.SetupView; import com.arsdigita.kernel.Kernel; import com.arsdigita.kernel.Party; -import com.arsdigita.kernel.permissions.PermissionDescriptor; +import com.arsdigita.kernel.permissions.PermissionDescriptor; import com.arsdigita.kernel.permissions.PermissionService; import com.arsdigita.kernel.permissions.PrivilegeDescriptor; -import com.arsdigita.kernel.security.UserContext; +import com.arsdigita.kernel.security.UserContext; import com.arsdigita.util.UncheckedWrapperException; -import com.arsdigita.xml.Element; +import com.arsdigita.xml.Element; /** - * The Bebop Page which provides the complete UI for the bboard application + * A Bebop Page which provides the complete UI for the forum application in a + * CCM specific compact style. Using this style the different components + * (view modes or forum modes) as the threads lists, the list of topics or the + * alerts management panel etc. are presented onto one page in a condensed form. + * + * Main task is to provide a mode selection facility (by default styled + * as a tabulator bar) and to switch to a page component based on the active + * selection (by default displayed beyond the mode selection facility). * * @author Kevin Scaldeferri (kevin@arsdigita.com) - * - * @version $Revision: 1.3 $ $Author: chrisg23 $ $Date: 2006/03/09 13:48:15 $ + * @author Chris Gilbert (chrisg23) + * @version $Revision: 1.3 $ $Author: chrisg23 $ $Date: 2006/03/09 13:48:15 $ */ -public class ForumComponent extends ModalContainer implements Constants { +public class ForumUserCompactView extends ModalContainer implements Constants { - private static Logger s_log = Logger.getLogger(ForumComponent.class); + /** Private logger instance for debugging purpose. */ + private static Logger s_log = Logger.getLogger(ForumUserCompactView.class); + // Denotes the 6 panels of the user interface, also used as marker to store + // and select the active panel + /** Denotation of the 'threads' forum mode */ public static final String MODE_THREADS = "threads"; + /** Denominator of the 'topics' forum mode */ public static final String MODE_TOPICS = "topics"; + /** Denominator of the 'alerts handling' forum mode */ public static final String MODE_ALERTS = "alerts"; + /** Denominator of the 'moderation handling' forum mode */ public static final String MODE_MODERATION = "moderation"; - public static final String MODE_PERMISSIONS = "permissions"; - public static final String MODE_SETUP = "setup"; - + /** Denominator of the 'permission administration' forum mode (administrators only) */ + public static final String MODE_PERMISSIONS = "permissions"; + /** Denominator of the 'configuration' forum mode (administrators only)*/ + public static final String MODE_SETUP = "setup"; + /** Holds the current active mode */ private StringParameter m_mode; - /** - * Constructs the bboard use interface - */ - private SetupView m_setupView; - private ModerationView m_moderationView; + /** Object containing the threads panel (main working panel for users) */ + private ThreadsPanel m_threadsView; + /** Object containing the topics panel */ + private TopicsPanel m_topicsView; + /** Object containing the alerts management panel */ private ForumAlertsView m_alertsView; - private CategoryView m_topicView; - private ForumUserView m_userView; - private PermissionsView m_permissionsView; + /** Object containing the moderation panel */ + private ModerationView m_moderationView; + /** Object containing the setup panel */ + private SetupView m_setupView; + /** Object containing the permission management panel*/ + private PermissionsView m_permissionsView; - public ForumComponent() { - super(FORUM_XML_PREFIX + ":forum", FORUM_XML_NS); + /** + * Default Constructor. Initializes the forum user interface elements. + */ + public ForumUserCompactView() { + + // determine namespace + super(FORUM_XML_PREFIX + ":forum", FORUM_XML_NS); m_mode = new StringParameter("mode"); - m_setupView = new SetupView(); - m_moderationView = new ModerationView(); + // setup panels which make up the forum + m_threadsView = new ThreadsPanel(); + m_topicsView = new TopicsPanel(); m_alertsView = new ForumAlertsView(); - m_topicView = new CategoryView(); - m_userView = new ForumUserView(); - m_permissionsView = new PermissionsView(); + // administration section + m_moderationView = new ModerationView(); + m_setupView = new SetupView(); + m_permissionsView = new PermissionsView(); - add(m_setupView); - add(m_moderationView); + add(m_threadsView); + add(m_topicsView); add(m_alertsView); - add(m_topicView); - add(m_userView); - add(m_permissionsView); + // administration section + add(m_moderationView); + add(m_setupView); + add(m_permissionsView); - setDefaultComponent(m_userView); + setDefaultComponent(m_threadsView); } + /** + * + * @param p + */ public void register(Page p) { - super.register(p); + super.register(p); p.addGlobalStateParam(m_mode); } - public void respond(PageState state) - throws ServletException { - + /** + * + * @param state + * @throws ServletException + */ + public void respond(PageState state) throws ServletException { + super.respond(state); - Party party = Kernel.getContext().getParty(); - Forum forum = ForumContext.getContext(state).getForum(); - + Party party = Kernel.getContext().getParty(); + Forum forum = ForumContext.getContext(state).getForum(); + String mode = (String)state.getControlEventValue(); state.setValue(m_mode, mode); - - setVisible(state, party, forum, mode); - } - - protected void setVisible( - PageState state, - Party party, - Forum forum, - String mode) { - PermissionDescriptor forumAdmin = - new PermissionDescriptor(PrivilegeDescriptor.ADMIN, forum, party); - + + setVisible(state, party, forum, mode); + } + + /** + * Checks for the given forum mode (parameter value) whether its prerequisites + * are given (currently permission, but additional properties may be added here). + * If positive the panel is set visible, otherwise a login screen is + * presented. + * + * + * @param state + * @param party currently logged in user (or null if none) + * @param forum the forum instance to handle + * @param mode forum mode to check visibility for + */ + protected void setVisible( PageState state, Party party, + Forum forum, String mode) { + + PermissionDescriptor forumAdmin = + new PermissionDescriptor(PrivilegeDescriptor.ADMIN, forum, party); + if (MODE_TOPICS.equals(mode)) { - if (Forum.getConfig().topicCreationByAdminOnly()) { - if (party == null) { - UserContext.redirectToLoginPage(state.getRequest()); - } - PermissionService.assertPermission(forumAdmin); - } - setVisibleComponent(state, m_topicView); + if (Forum.getConfig().topicCreationByAdminOnly()) { + if (party == null) { + UserContext.redirectToLoginPage(state.getRequest()); + } + PermissionService.assertPermission(forumAdmin); + } + setVisibleComponent(state, m_topicsView); } else if (MODE_ALERTS.equals(mode)) { - if (party == null) { + if (party == null) { UserContext.redirectToLoginPage(state.getRequest()); } setVisibleComponent(state, m_alertsView); @@ -139,85 +184,134 @@ public class ForumComponent extends ModalContainer implements Constants { if (party == null) { UserContext.redirectToLoginPage(state.getRequest()); } - PermissionService.assertPermission(forumAdmin); + PermissionService.assertPermission(forumAdmin); setVisibleComponent(state, m_moderationView); - } else if (MODE_PERMISSIONS.equals(mode)) { - if (party == null) { - UserContext.redirectToLoginPage(state.getRequest()); - } - PermissionService.assertPermission(forumAdmin); - - setVisibleComponent(state, m_permissionsView); - } else if (MODE_SETUP.equals(mode)) { - if (party == null) { - UserContext.redirectToLoginPage(state.getRequest()); - } - PermissionService.assertPermission(forumAdmin); - setVisibleComponent(state, m_setupView); - } else if (MODE_THREADS.equals(mode)) { - setVisibleComponent(state, m_userView); + } else if (MODE_PERMISSIONS.equals(mode)) { + if (party == null) { + UserContext.redirectToLoginPage(state.getRequest()); + } + PermissionService.assertPermission(forumAdmin); + + setVisibleComponent(state, m_permissionsView); + } else if (MODE_SETUP.equals(mode)) { + if (party == null) { + UserContext.redirectToLoginPage(state.getRequest()); + } + PermissionService.assertPermission(forumAdmin); + setVisibleComponent(state, m_setupView); + } else if (MODE_THREADS.equals(mode)) { + setVisibleComponent(state, m_threadsView); } } - public void generateXML(PageState state, - Element parent) { + /** + * Generate the page XML. + * Overwrites SimpleContainer standard method + * + * @param state + * @param parent + */ + @Override + public void generateXML(PageState state, Element parent) { + Element content = generateParent(parent); Forum forum = ForumContext.getContext(state).getForum(); content.addAttribute("title", forum.getTitle()); - content.addAttribute( - "noticeboard", - (new Boolean(forum.isNoticeboard())).toString()); + content.addAttribute( + "noticeboard", + (new Boolean(forum.isNoticeboard())).toString()); Party party = Kernel.getContext().getParty(); - if (party == null) { - party = Kernel.getPublicUser(); - } - - generateModes(state, content, party, forum); - generateChildrenXML(state, content); - } - - protected void generateModes( - PageState state, - Element content, - Party party, - Forum forum) { - PermissionDescriptor permission = - new PermissionDescriptor(PrivilegeDescriptor.ADMIN, forum, party); - - generateModeXML(state, content, MODE_THREADS); - if (!Forum.getConfig().topicCreationByAdminOnly()) { - generateModeXML(state, content, MODE_TOPICS); - } - generateModeXML(state, content, MODE_ALERTS); + if (party == null) { + party = Kernel.getPublicUser(); + } - if (PermissionService.checkPermission(permission)) { - generateModeXML(state, content, MODE_MODERATION); - if (Forum.getConfig().showNewTabs()) { - generateModeXML(state, content, MODE_SETUP); - generateModeXML(state, content, MODE_PERMISSIONS); - } - if (Forum.getConfig().topicCreationByAdminOnly()) { - generateModeXML(state, content, MODE_TOPICS); + // generate tab bar for panel (mode) selection + generateModes(state, content, party, forum); + // generate + generateChildrenXML(state, content); + } + + /** + * Initializes the mode selection facility (usually a tab bar) + * + * @param state + * @param content + * @param party + * @param forum + */ + protected void generateModes(PageState state, Element content, + Party party, Forum forum) { + + PermissionDescriptor permission = + new PermissionDescriptor(PrivilegeDescriptor.ADMIN, forum, party); + + // currently thread panel is alwasy shown. If read access should be + // bound to logged in users, additional logic is frequired here. + generateModeXML(state, content, MODE_THREADS); + // topics panel is always shoen as well if not restricted to admins. + if (!Forum.getConfig().topicCreationByAdminOnly()) { + generateModeXML(state, content, MODE_TOPICS); + } + // alerts panel is always shown as well, no private read access avail. + generateModeXML(state, content, MODE_ALERTS); + + // admin section + if (PermissionService.checkPermission(permission)) { + generateModeXML(state, content, MODE_MODERATION); + if (Forum.getConfig().showNewTabs()) { + generateModeXML(state, content, MODE_SETUP); + generateModeXML(state, content, MODE_PERMISSIONS); + } + // In case topic creation is bound to admin (and therefore not + // created above) we must create xml here. + if (Forum.getConfig().topicCreationByAdminOnly()) { + generateModeXML(state, content, MODE_TOPICS); } } } + /** + * Generates a forum mode selection entry (usually a tab). + * + * Currently the mode string is used to create the label in xsl file. + * + * @param state + * @param parent + * @param mode forum mode (threadspanel, topicspanel, alertpanel, ...) to + * create entry for + */ protected void generateModeXML(PageState state, Element parent, String mode) { + String current = (String)state.getValue(m_mode); if (current == null) { current = MODE_THREADS; } - Element content = - parent.newChildElement(FORUM_XML_PREFIX + ":forumMode", FORUM_XML_NS); + Element content = + parent.newChildElement(FORUM_XML_PREFIX + ":forumMode", FORUM_XML_NS); state.setControlEvent(this, "mode", mode); content.addAttribute("mode", mode); + // add localized label here + // content.addAttribute("label", + if (MODE_THREADS.equals(mode)) + content.addAttribute("label",Text.gzAsStr("forum.ui.modeThreads")); + else if(MODE_TOPICS.equals(mode)) + content.addAttribute("label",Text.gzAsStr("forum.ui.modeTopics")); + else if(MODE_ALERTS.equals(mode)) + content.addAttribute("label",Text.gzAsStr("forum.ui.modeAlerts")); + else if(MODE_MODERATION.equals(mode)) + content.addAttribute("label",Text.gzAsStr("forum.ui.modeModeration")); + else if(MODE_SETUP.equals(mode)) + content.addAttribute("label",Text.gzAsStr("forum.ui.modeSetup")); + else if(MODE_PERMISSIONS.equals(mode)) + content.addAttribute("label",Text.gzAsStr("forum.ui.modePermissions")); + try { content.addAttribute("url", state.stateAsURL()); diff --git a/ccm-forum/src/com/arsdigita/forum/ui/PostForm.java b/ccm-forum/src/com/arsdigita/forum/ui/PostForm.java index 3099bd3b5..99c242af7 100755 --- a/ccm-forum/src/com/arsdigita/forum/ui/PostForm.java +++ b/ccm-forum/src/com/arsdigita/forum/ui/PostForm.java @@ -48,8 +48,8 @@ import com.arsdigita.xml.Element; * differently in final processing (final meaning on the last step * of the wizard) by overriding the processWidgets method. * - * They all share the remainder of the steps (currently add files, add images and preview) - * and processing relating to shared behaviour + * They all share the remainder of the steps (currently add files, add images + * and preview) and processing relating to shared behaviour * * @author Jon Orris (jorris@arsdigita.com) * @author rewritten by Chris Gilbert diff --git a/ccm-forum/src/com/arsdigita/forum/ui/RootPostForm.java b/ccm-forum/src/com/arsdigita/forum/ui/RootPostForm.java index e32d30901..4b1ca31cb 100644 --- a/ccm-forum/src/com/arsdigita/forum/ui/RootPostForm.java +++ b/ccm-forum/src/com/arsdigita/forum/ui/RootPostForm.java @@ -18,22 +18,22 @@ */ package com.arsdigita.forum.ui; -import com.arsdigita.bebop.Container; +// import com.arsdigita.bebop.Container; import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.parameters.BigDecimalParameter; -import com.arsdigita.categorization.Category; +// import com.arsdigita.bebop.parameters.BigDecimalParameter; +// import com.arsdigita.categorization.Category; import com.arsdigita.forum.ForumContext; import com.arsdigita.forum.Post; -import com.arsdigita.forum.Forum; -import com.arsdigita.forum.ThreadSubscription; +// import com.arsdigita.forum.Forum; +// import com.arsdigita.forum.ThreadSubscription; import com.arsdigita.kernel.Kernel; import com.arsdigita.kernel.Party; -import com.arsdigita.kernel.User; +// import com.arsdigita.kernel.User; import com.arsdigita.kernel.ui.ACSObjectSelectionModel; -import com.arsdigita.web.RedirectSignal; -import com.arsdigita.web.URL; +// import com.arsdigita.web.RedirectSignal; +// import com.arsdigita.web.URL; -import java.math.BigDecimal; +// import java.math.BigDecimal; import org.apache.log4j.Logger; diff --git a/ccm-forum/src/com/arsdigita/forum/ui/Text.java b/ccm-forum/src/com/arsdigita/forum/ui/Text.java index 7607f07d6..2d757bf27 100755 --- a/ccm-forum/src/com/arsdigita/forum/ui/Text.java +++ b/ccm-forum/src/com/arsdigita/forum/ui/Text.java @@ -34,6 +34,10 @@ public class Text { return new GlobalizedMessage(key, BUNDLE_NAME); } + public static String gzAsStr(String key) { + return (String) new GlobalizedMessage(key, BUNDLE_NAME).localize(); + } + public static GlobalizedMessage gz(String key, Object[] args) { return new GlobalizedMessage(key, BUNDLE_NAME, args); } diff --git a/ccm-forum/src/com/arsdigita/forum/ui/ThreadComponent.java b/ccm-forum/src/com/arsdigita/forum/ui/ThreadComponent.java index e17b12321..7ef80b08b 100755 --- a/ccm-forum/src/com/arsdigita/forum/ui/ThreadComponent.java +++ b/ccm-forum/src/com/arsdigita/forum/ui/ThreadComponent.java @@ -19,7 +19,7 @@ package com.arsdigita.forum.ui; import com.arsdigita.forum.ForumContext; -import com.arsdigita.forum.Post; +import com.arsdigita.forum.Post; import com.arsdigita.forum.ThreadSubscription; import com.arsdigita.forum.ui.admin.RejectionForm; @@ -60,8 +60,8 @@ public class ThreadComponent extends ModalContainer implements Constants { // References to sub-components for event access. private Container m_threadView; - private PostForm m_rootForm; - private PostForm m_replyForm; + private PostForm m_rootForm; + private PostForm m_replyForm; private Form m_rejectForm; private static final Logger s_log @@ -84,22 +84,22 @@ public class ThreadComponent extends ModalContainer implements Constants { private void initComponents() { // Add the thread components to the modal container and maintain // references for event manipulation purposes. - s_log.debug("creating edit post form"); - m_rootForm = new RootPostForm(m_postModel); + s_log.debug("creating edit post form"); + m_rootForm = new RootPostForm(m_postModel); m_replyForm = new ReplyToPostForm(m_postModel); - s_log.debug("creating reply to post form"); - s_log.debug("creating reject form"); + s_log.debug("creating reply to post form"); + s_log.debug("creating reject form"); m_rejectForm = new RejectionForm(m_postModel); - addForm(m_rootForm); + addForm(m_rootForm); addForm(m_replyForm); addForm(m_rejectForm); m_threadView = new SimpleContainer(); - Container linksPanel = new SimpleContainer(FORUM_XML_PREFIX + ":threadOptions", + Container linksPanel = new SimpleContainer(FORUM_XML_PREFIX + ":threadOptions", Constants.FORUM_XML_NS); // Offer links to return to index or control alerts. - Link returnLink = new Link(new Label(Text.gz("forum.ui.threads.viewAll")), + Link returnLink = new Link(new Label(Text.gz("forum.ui.thread.viewAll")), "index.jsp"); returnLink.setClassAttr("actionLink"); linksPanel.add(returnLink); @@ -123,21 +123,21 @@ public class ThreadComponent extends ModalContainer implements Constants { } public void makeEditFormVisible(PageState state) { - s_log.debug("making edit form visible"); - Post post = (Post)m_postModel.getSelectedObject(state); - if (post.getRoot() == null) { - m_rootForm.setContext(state, ReplyToPostForm.EDIT_CONTEXT); - setVisibleComponent(state, m_rootForm); - } else { - m_replyForm.setContext(state, ReplyToPostForm.EDIT_CONTEXT); - setVisibleComponent(state, m_replyForm); - } - + s_log.debug("making edit form visible"); + Post post = (Post)m_postModel.getSelectedObject(state); + if (post.getRoot() == null) { + m_rootForm.setContext(state, ReplyToPostForm.EDIT_CONTEXT); + setVisibleComponent(state, m_rootForm); + } else { + m_replyForm.setContext(state, ReplyToPostForm.EDIT_CONTEXT); + setVisibleComponent(state, m_replyForm); + } + } public void makeReplyFormVisible(PageState state) { - s_log.debug("making reply form visible"); - m_replyForm.setContext(state, PostForm.REPLY_CONTEXT); + s_log.debug("making reply form visible"); + m_replyForm.setContext(state, PostForm.REPLY_CONTEXT); setVisibleComponent(state, m_replyForm); } @@ -149,14 +149,14 @@ public class ThreadComponent extends ModalContainer implements Constants { * Creates the component for viewing a thread. */ - private final void addForm(final Form form) { + private final void addForm(final Form form) { add(form); form.addCompletionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { s_log.debug("FORM ACTION COMPLETED"); - PageState ps = e.getPageState(); - // ps.reset(form); - makeListViewVisible(ps); + PageState ps = e.getPageState(); + // ps.reset(form); + makeListViewVisible(ps); } }); @@ -164,8 +164,8 @@ public class ThreadComponent extends ModalContainer implements Constants { public void cancel(FormSectionEvent e) { s_log.debug("fire cancel listener"); PageState ps = e.getPageState(); - // ps.reset(form); - makeListViewVisible(ps); + // ps.reset(form); + makeListViewVisible(ps); } }); } diff --git a/ccm-forum/src/com/arsdigita/forum/ui/ThreadDisplay.java b/ccm-forum/src/com/arsdigita/forum/ui/ThreadDisplay.java index 4f12d3539..87d98608e 100755 --- a/ccm-forum/src/com/arsdigita/forum/ui/ThreadDisplay.java +++ b/ccm-forum/src/com/arsdigita/forum/ui/ThreadDisplay.java @@ -56,6 +56,13 @@ import com.arsdigita.web.Web; import com.arsdigita.xml.Element; import com.arsdigita.xml.XML; +/** + * Provides List of posts for a thread with links to edit, delete, etc + * according to authorisation. + * + * Curently used by ThreadComponent to create the actual list of threads and by + * MessageView. + */ public class ThreadDisplay extends SimpleComponent implements Constants { private static final Logger s_log = diff --git a/ccm-forum/src/com/arsdigita/forum/ui/ThreadList.java b/ccm-forum/src/com/arsdigita/forum/ui/ThreadList.java index ba09573e8..ecb4fc983 100755 --- a/ccm-forum/src/com/arsdigita/forum/ui/ThreadList.java +++ b/ccm-forum/src/com/arsdigita/forum/ui/ThreadList.java @@ -44,11 +44,18 @@ import com.arsdigita.forum.ThreadCollection; import java.math.BigDecimal; +/** + * Creates a list of existing threads as a GUI component. Currently invoked + * by ThreadsPanel only. + * A paginator is added to handle a high number of threads. + * + */ public class ThreadList extends SimpleComponent implements Constants { + /** */ private IntegerParameter m_pageNumber = new IntegerParameter(PAGINATOR_PARAM); - + /** Default max number of threads (rows) per page */ private int m_pageSize = 15; public void register(Page p) { @@ -57,7 +64,13 @@ public class ThreadList extends SimpleComponent implements Constants { p.addGlobalStateParam(m_pageNumber); } + /** + * + * @param state + * @return + */ private ThreadCollection getThreads(PageState state) { + ForumContext context = ForumContext.getContext(state); Party party = Kernel.getContext().getParty(); Forum forum = context.getForum(); @@ -75,9 +88,15 @@ public class ThreadList extends SimpleComponent implements Constants { return threads; } + /** + * Create the xml for this component. + * @param state + * @param parent + */ public void generateXML(PageState state, Element parent) { - Element content = parent.newChildElement(FORUM_XML_PREFIX + ":threadList", FORUM_XML_NS); + Element content = parent.newChildElement(FORUM_XML_PREFIX + + ":threadList", FORUM_XML_NS); ThreadCollection threads = getThreads(state); @@ -113,7 +132,8 @@ public class ThreadList extends SimpleComponent implements Constants { while (threads.next()) { MessageThread thread = threads.getMessageThread(); - Element threadEl = content.newChildElement(FORUM_XML_PREFIX + ":thread", FORUM_XML_NS); + Element threadEl = content.newChildElement(FORUM_XML_PREFIX + + ":thread", FORUM_XML_NS); ParameterMap map = new ParameterMap(); map.setParameter(THREAD_PARAM, thread.getID()); @@ -132,6 +152,16 @@ public class ThreadList extends SimpleComponent implements Constants { } + /** + * Create the paginators xml + * @param parent + * @param pageNumber + * @param pageCount + * @param pageSize + * @param begin + * @param end + * @param objectCount + */ protected void generatePaginatorXML(Element parent, int pageNumber, int pageCount, @@ -139,7 +169,8 @@ public class ThreadList extends SimpleComponent implements Constants { long begin, long end, long objectCount) { - Element paginator = parent.newChildElement(FORUM_XML_PREFIX + ":paginator", FORUM_XML_NS); + Element paginator = parent.newChildElement(FORUM_XML_PREFIX + + ":paginator", FORUM_XML_NS); URL here = Web.getContext().getRequestURL(); ParameterMap params = new ParameterMap(here.getParameterMap()); diff --git a/ccm-forum/src/com/arsdigita/forum/ui/ForumUserView.java b/ccm-forum/src/com/arsdigita/forum/ui/ThreadsPanel.java similarity index 51% rename from ccm-forum/src/com/arsdigita/forum/ui/ForumUserView.java rename to ccm-forum/src/com/arsdigita/forum/ui/ThreadsPanel.java index cd8972c3f..c30ec102e 100755 --- a/ccm-forum/src/com/arsdigita/forum/ui/ForumUserView.java +++ b/ccm-forum/src/com/arsdigita/forum/ui/ThreadsPanel.java @@ -20,7 +20,7 @@ package com.arsdigita.forum.ui; import com.arsdigita.bebop.Component; import com.arsdigita.bebop.Container; -import com.arsdigita.bebop.Form; +// import com.arsdigita.bebop.Form; import com.arsdigita.bebop.ModalContainer; import com.arsdigita.bebop.Label; import com.arsdigita.bebop.Page; @@ -30,51 +30,82 @@ import com.arsdigita.bebop.ToggleLink; import com.arsdigita.bebop.event.ActionEvent; import com.arsdigita.bebop.event.ActionListener; import com.arsdigita.bebop.parameters.StringParameter; -import com.arsdigita.forum.Forum; +import com.arsdigita.forum.Forum; import com.arsdigita.forum.ForumContext; -import com.arsdigita.kernel.Party; -import com.arsdigita.kernel.permissions.PermissionDescriptor; -import com.arsdigita.kernel.permissions.PermissionService; -import com.arsdigita.kernel.permissions.PrivilegeDescriptor; -import com.arsdigita.toolbox.ui.SecurityContainer; +import com.arsdigita.kernel.Party; +import com.arsdigita.kernel.permissions.PermissionDescriptor; +import com.arsdigita.kernel.permissions.PermissionService; +import com.arsdigita.kernel.permissions.PrivilegeDescriptor; +import com.arsdigita.toolbox.ui.SecurityContainer; import org.apache.log4j.Logger; /** - * A reusable Bebop component to display the user view on a Forum + * A reusable Bebop component to display and maintain threads in a given forum + * instance. Currently used as a page component in ForumUserCompactView but may + * be used (in future) by other styles of forum display or even standalone as + * part of other pages as well. In any case it is the main user view and + * working area of a forum. + * + * It consists of two (sub) components which provide + * (a) a list of existing threads including author, number of replies and date + * of last post for each, and a link to create a new thread. (By createing + * a new root post, i.e. including specifying a subject line). + * (b) an add new post form including an editable subject line to make up a new + * thread. * * @author Kevin Scaldeferri (kevin@arsdigita.com) - * - * @version $Revision: 1.8 $ $Author: chrisg23 $ $DateTime: 2004/08/17 23:26:27 $ + * @version $Revision: 1.8 $ $Author: chrisg23 $ $DateTime: 2004/08/17 23:26:27 $ + * @version $Id: */ -public class ForumUserView extends SimpleContainer - implements Constants { +public class ThreadsPanel extends SimpleContainer + implements Constants { - private static Logger s_log = Logger.getLogger(ForumUserView.class); + /** Private logger instance for debugging purpose. */ + private static Logger s_log = Logger.getLogger(ThreadsPanel.class); - private Component m_forumView; - private PostForm m_forumPost; + /** Modal container for components, only one of its children can be visibal */ private ModalContainer m_mode; - - private ToggleLink m_newTopicLink; + /** Bebop Component, list of threads along with some othere elements, will + * be one child of ModalContainer */ + private Component m_threadsComponent; + /** Bebop Component, add new post to a thread form. Will be another child of + * ModalContainer */ + private PostForm m_postComponent; + /** Reusable Bebop component. Link providing access to new thread form */ + private ToggleLink m_newThreadLink; + /** Switch from threadsComponent to forum post NOCH ÜBERPRÜFEN! */ private StringParameter m_newPostParam; - public ForumUserView() { + /** + * Default Constructor creates the containing components. + * + * The threads panel contains two components: a threads List and a New Post + * input form. + */ + public ThreadsPanel() { + + // Create a modal container: shows only one component at a time. m_mode = new ModalContainer(); add(m_mode); - m_forumView = createForumView(); - m_forumPost = createForumPost(); + m_threadsComponent = createThreadsComponent(); + m_postComponent = createPostComponent(); - m_mode.add(m_forumView); - m_mode.add(m_forumPost); + m_mode.add(m_threadsComponent); + m_mode.add(m_postComponent); - m_mode.setDefaultComponent(m_forumView); + m_mode.setDefaultComponent(m_threadsComponent); } + /** + * + * @param p + */ public void register(Page p) { + super.register(p); // XXX new post param /* @@ -83,24 +114,19 @@ public class ForumUserView extends SimpleContainer p.addGlobalStateParam(m_newPostParam); */ p.addActionListener( new ActionListener() { - public void actionPerformed(ActionEvent e) { - s_log.debug("create link pressed"); - PageState s = e.getPageState(); - /* - if ("t".equals((String)s.getValue(m_newPostParam))) { - m_newTopicLink.setSelected(s, true); - s.setValue(m_newPostParam, null); - } - */ + public void actionPerformed(ActionEvent e) { + s_log.debug("create link pressed"); - if (m_newTopicLink.isSelected(s)) { - m_forumPost.setContext(s, PostForm.NEW_CONTEXT); - m_mode.setVisibleComponent(s, m_forumPost); - } else { - m_mode.setVisibleComponent(s, m_forumView); - } + PageState s = e.getPageState(); + // switch between modes (components to display) + if (m_newThreadLink.isSelected(s)) { + m_postComponent.setContext(s, PostForm.NEW_CONTEXT); + m_mode.setVisibleComponent(s, m_postComponent); + } else { + m_mode.setVisibleComponent(s, m_threadsComponent); } - }); + } + }); } @@ -109,29 +135,34 @@ public class ForumUserView extends SimpleContainer * with author, # of responses, etc. Filtered for approved * messages if the forum is moderated. */ + private Component createThreadsComponent() { - private Component createForumView() { Container forums = new SimpleContainer(); Container forumOptions = new SimpleContainer( - FORUM_XML_PREFIX + ":forumOptions", Constants.FORUM_XML_NS); - m_newTopicLink = new ToggleLink(new Label(Text.gz("forum.ui.newPost"))); - m_newTopicLink.setClassAttr("actionLink"); - // chris.gilbert@westsussex.gov.uk - security container added - SecurityContainer sc = new SecurityContainer(m_newTopicLink) { - - protected boolean canAccess(Party party, PageState state) { - Forum forum = ForumContext.getContext(state).getForum(); - PermissionDescriptor createThread = new PermissionDescriptor(PrivilegeDescriptor.get(Forum.CREATE_THREAD_PRIVILEGE), forum, party); - return PermissionService.checkPermission(createThread); - - } - }; - - forumOptions.add(sc); + FORUM_XML_PREFIX + ":forumOptions", Constants.FORUM_XML_NS); + // XXX APLAWS standard theme currently (2010-09) does not use the label! + m_newThreadLink = new ToggleLink(new Label(Text.gz("forum.ui.thread.newPost"))); + m_newThreadLink.setClassAttr("actionLink"); + + // chris.gilbert@westsussex.gov.uk - security container added + SecurityContainer sc = new SecurityContainer(m_newThreadLink) { + + protected boolean canAccess(Party party, PageState state) { + Forum forum = ForumContext.getContext(state).getForum(); + PermissionDescriptor createThread = new PermissionDescriptor( + PrivilegeDescriptor.get(Forum.CREATE_THREAD_PRIVILEGE), + forum, + party); + return PermissionService.checkPermission(createThread); + + } + }; + + forumOptions.add(sc); forums.add(forumOptions); - // list of categories + // list of topics (if one or more actually available) TopicSelector topics = new TopicSelector(); forums.add(topics); @@ -143,11 +174,15 @@ public class ForumUserView extends SimpleContainer return forums; } - private PostForm createForumPost() { - PostForm editForm = new RootPostForm(); + /** + * + * @return + */ + private PostForm createPostComponent() { + PostForm editForm = new RootPostForm(); editForm.addCompletionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - ForumUserView.this + ThreadsPanel.this .editPageStateCleanup(e.getPageState()); } }); @@ -155,8 +190,12 @@ public class ForumUserView extends SimpleContainer return editForm; } + /** + * + * @param state + */ private void editPageStateCleanup(PageState state) { - m_newTopicLink.setSelected(state, false); + m_newThreadLink.setSelected(state, false); ForumContext.getContext(state).setCategorySelection (Constants.TOPIC_ANY); } diff --git a/ccm-forum/src/com/arsdigita/forum/ui/CategoryAddForm.java b/ccm-forum/src/com/arsdigita/forum/ui/TopicAddForm.java similarity index 58% rename from ccm-forum/src/com/arsdigita/forum/ui/CategoryAddForm.java rename to ccm-forum/src/com/arsdigita/forum/ui/TopicAddForm.java index bd5b88886..b8b689071 100755 --- a/ccm-forum/src/com/arsdigita/forum/ui/CategoryAddForm.java +++ b/ccm-forum/src/com/arsdigita/forum/ui/TopicAddForm.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved. + * Copyright (C) 2006-2007 Chris Gilbert (Westsussex) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -24,7 +25,7 @@ import com.arsdigita.bebop.FormData; import com.arsdigita.bebop.FormProcessException; import com.arsdigita.bebop.Label; import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.SaveCancelSection; +// import com.arsdigita.bebop.SaveCancelSection; import com.arsdigita.bebop.event.FormInitListener; import com.arsdigita.bebop.event.FormProcessListener; import com.arsdigita.bebop.event.FormSectionEvent; @@ -43,36 +44,40 @@ import org.apache.log4j.Logger; /** - * Experimental - * class to create form to add categories and map them to the forum - * parent category. temporary hack for testing purposes + * Class to create a form for adding new topics. + * + * A created topic is mapped to the forum parent category. * * @author Sarah Barwig * @author rewritten by Chris Gilbert - * @version $Revision: 1.2 $ $Author: chrisg23 $ $DateTime: 2004/08/17 23:26:27 $ - * @version $Id: CategoryAddForm.java 1628 2007-09-17 08:10:40Z chrisg23 $ + * @version $Id: TopicAddForm.java 1628 2007-09-17 08:10:40Z chrisg23 $ */ -public class CategoryAddForm extends Form { +public class TopicAddForm extends Form { + /** Private logger instance for debugging purpose. */ private static final Logger s_log = Logger.getLogger - (CategoryAddForm.class); + (TopicAddForm.class); + /** Input field for name of new topic*/ private TextField m_name; + /** Input field for (short) description of new topic */ private TextArea m_description; /** - * Builds a form to add a category. + * Default Constructor builds a form to add a category. + * */ - public CategoryAddForm() { + public TopicAddForm() { + super("categoryAdd"); - setRedirecting(true); + setRedirecting(true); // clear form and redirect back - add(new Label(Text.gz("forum.ui.name"))); + add(new Label(Text.gz("forum.ui.topic.name"))); m_name = new TextField("name"); m_name.addValidationListener(new NotNullValidationListener()); add(m_name); - add(new Label(Text.gz("forum.ui.description"))); + add(new Label(Text.gz("forum.ui.topic.description"))); m_description = new TextArea("description"); m_description.setRows(5); m_description.setCols(60); @@ -83,52 +88,52 @@ public class CategoryAddForm extends Form { // Would have used a saveCancel section but this would make existing // stylesheets for legacy forums miss the buttons Submit submit = new Submit(Text.gz("forum.ui.topic.save")); - final Submit cancel = new Submit(Text.gz("forum.ui.cancel")); + final Submit cancel = new Submit(Text.gz("forum.ui.cancel")); add(submit); add(cancel); - addSubmissionListener(new FormSubmissionListener(){ - public void submitted(FormSectionEvent e) throws FormProcessException { - PageState state = e.getPageState(); - if (cancel.isSelected(state)){ - fireCompletionEvent(state); - throw new FormProcessException("cancelled"); - } - } - }); - - + addSubmissionListener(new FormSubmissionListener(){ + public void submitted(FormSectionEvent e) + throws FormProcessException { + PageState state = e.getPageState(); + if (cancel.isSelected(state)){ + fireCompletionEvent(state); + throw new FormProcessException("cancelled"); + } + } + }); + /* - * Listener to process form data. Just adds the categories, then + * Listener to process form data. Just adds the topic, then * adds mappings. */ addProcessListener (new FormProcessListener() { - public void process( FormSectionEvent e ) { - PageState state = e.getPageState(); - - Forum forum = ForumContext.getContext(state).getForum(); + public void process( FormSectionEvent e ) { + PageState state = e.getPageState(); - String name = (String)m_name.getValue(state); - String description = (String)m_description.getValue(state); + Forum forum = ForumContext.getContext(state).getForum(); - Category topic = new Category(); - topic.setName(name); - topic.setDescription(description); - topic.save(); + String name = (String)m_name.getValue(state); + String description = (String)m_description.getValue(state); - Category parent = forum.getRootCategory(); - parent.addChild(topic); - parent.save(); - topic.setDefaultParentCategory(parent); - topic.save(); + Category topic = new Category(); + topic.setName(name); + topic.setDescription(description); + topic.save(); - fireCompletionEvent(state); - } - }); + Category parent = forum.getRootCategory(); + parent.addChild(topic); + parent.save(); + topic.setDefaultParentCategory(parent); + topic.save(); + + fireCompletionEvent(state); + } + }); /* - * Generates the object id for the new category + * Generates the object id for the new topic (category) */ addInitListener (new FormInitListener() { diff --git a/ccm-forum/src/com/arsdigita/forum/ui/TopicList.java b/ccm-forum/src/com/arsdigita/forum/ui/TopicList.java index 6027d0680..06df61d38 100755 --- a/ccm-forum/src/com/arsdigita/forum/ui/TopicList.java +++ b/ccm-forum/src/com/arsdigita/forum/ui/TopicList.java @@ -20,11 +20,8 @@ package com.arsdigita.forum.ui; import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.SimpleComponent; - import com.arsdigita.persistence.DataQuery; - import com.arsdigita.web.URL; - import com.arsdigita.xml.Element; import com.arsdigita.xml.XML; @@ -36,20 +33,41 @@ import java.util.HashSet; import java.util.Iterator; +/** + * Creates a list of defined (available) topics as a GUI component. Currently + * invoked by TopicsPanel only. + * + * XXX: Forum knows about threads which groups a set of posts to the same + * subject, and topics which group a set of threads about the same general + * theme. Currently Forum uses catgegory as synonym for topic, which may be + * misleading in some contexts, because there is forum-categorized which + * uses category in the usual CMS way, esp. navigation categories. + * + */ public class TopicList extends SimpleComponent implements Constants { - private static Set s_catProps; + /** List of properties a topic may have. */ + private final static Set s_catProps; static { s_catProps = new HashSet(); s_catProps.add("id"); - s_catProps.add("latestPost"); - s_catProps.add("numThreads"); s_catProps.add("name"); + s_catProps.add("numThreads"); + s_catProps.add("latestPost"); } + /** + * + * @param state + * @param parent + */ + @Override public void generateXML(PageState state, Element parent) { - Element content = parent.newChildElement(FORUM_XML_PREFIX + ":topicList", + + // Header of list is constructed in xsl, no globalization here + // Globalization has currently to be done in theme. + Element content = parent.newChildElement(FORUM_XML_PREFIX + ":topicList", FORUM_XML_NS); exportAttributes(content); @@ -57,13 +75,17 @@ public class TopicList extends SimpleComponent implements Constants { content.addAttribute("baseURL", url.toString()); content.addAttribute("param", TOPIC_PARAM); + // Get handle to current forum instance Forum forum = ForumContext.getContext(state).getForum(); + // Get categories for the forum instance DataQuery categories = forum.getCategories(); + // Generate xml for the retrieved topics (categories) generateQueryXML(content, categories); DataQuery unCategory = forum.getUnCategory(); while (unCategory.next()) { - Element noTopic = content.newChildElement(FORUM_XML_PREFIX + ":noTopicSummary", + Element noTopic = content.newChildElement(FORUM_XML_PREFIX + + ":noTopicSummary", FORUM_XML_NS); Element id = noTopic.newChildElement("id"); @@ -78,10 +100,16 @@ public class TopicList extends SimpleComponent implements Constants { } + /** + * + * @param parent + * @param query + */ public void generateQueryXML(Element parent, DataQuery query) { while (query.next()) { - Element content = parent.newChildElement(FORUM_XML_PREFIX + ":topicSummary", + Element content = parent.newChildElement(FORUM_XML_PREFIX + + ":topicSummary", FORUM_XML_NS); Iterator keys = s_catProps.iterator(); diff --git a/ccm-forum/src/com/arsdigita/forum/ui/TopicSelector.java b/ccm-forum/src/com/arsdigita/forum/ui/TopicSelector.java index a6f829bc3..b80d2311c 100755 --- a/ccm-forum/src/com/arsdigita/forum/ui/TopicSelector.java +++ b/ccm-forum/src/com/arsdigita/forum/ui/TopicSelector.java @@ -36,11 +36,24 @@ import com.arsdigita.categorization.Category; import java.math.BigDecimal; +/** + * Helper Class which generates the XML for a topic selection box. + * Used with ThreadsPanel to filter the threads listing by a topic. + * + * XXX: Forum knows about threads which groups a set of posts to the same + * subject, and topics which group a set of threads about the same general + * theme. Currently Forum uses catgegory as synonym for topic, which may be + * misleading in some contexts, because there is forum-categorized which + * uses category in the usual CMS way, esp. navigation categories. + * + */ public class TopicSelector extends SimpleComponent implements Constants { + @Override public void generateXML(PageState state, Element parent) { - Element content = parent.newChildElement(FORUM_XML_PREFIX + ":topicSelector", + Element content = parent.newChildElement(FORUM_XML_PREFIX + + ":topicSelector", FORUM_XML_NS); URL url = URL.request(state.getRequest(), null); @@ -60,7 +73,8 @@ public class TopicSelector extends SimpleComponent implements Constants { while (cursor.next()) { Category c = new Category(cursor.getDataObject()); - Element topicEl = content.newChildElement(FORUM_XML_PREFIX + ":topic", FORUM_XML_NS); + Element topicEl = content.newChildElement(FORUM_XML_PREFIX + + ":topic", FORUM_XML_NS); DomainObjectXMLRenderer xr = new DomainObjectXMLRenderer(topicEl); xr.setWrapRoot(false); xr.setWrapAttributes(true); diff --git a/ccm-forum/src/com/arsdigita/forum/ui/TopicsPanel.java b/ccm-forum/src/com/arsdigita/forum/ui/TopicsPanel.java new file mode 100755 index 000000000..d39327431 --- /dev/null +++ b/ccm-forum/src/com/arsdigita/forum/ui/TopicsPanel.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.forum.ui; + +import com.arsdigita.bebop.Component; +import com.arsdigita.bebop.Container; +import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.ModalContainer; +import com.arsdigita.bebop.Page; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.SimpleContainer; +import com.arsdigita.bebop.ToggleLink; +import com.arsdigita.bebop.event.ActionEvent; +import com.arsdigita.bebop.event.ActionListener; + +import org.apache.log4j.Logger; + + +/** + * Reusable Bebop UI component (container) to display and maintain topics a given + * forum instance is dealing with. It consists of two (sub) components + * which provide + * (a) a list of existing topics including number of assoziated threads and date + * of last post for each topic, and a link to create a new topic. + * (b) an add new topic form to add a new topic. + * + * Used eg. by ForumUserCompactView as a component (sub-panel) to maintain + * topics. May be used (in future) by other styles of forum display or even + * standalone as part of other pages. + * + * XXX: Forum knows about threads which groups a set of posts to the same + * subject, and topics which group a set of threads about the same general + * theme. Currently Forum uses catgegory as synonym for topic, which may be + * misleading in some contexts, because there is forum-categorized which + * uses category in the usual CMS way, esp. navigation categories. We use topic + * here where possible. + */ +public class TopicsPanel extends SimpleContainer + implements ActionListener { + + /** Private logger instance for debugging purpose. */ + private static Logger s_log = Logger.getLogger(TopicsPanel.class); + + /** Modal container for components, only one of its children can be visibal */ + private ModalContainer m_mode; + /** Bebop Component, list of topics. Will be one child of ModalContainer */ + private Component m_topicslist; + /** Bebop Component, add new topic form. Will be another child of + * ModalContainer */ + private Component m_addTopicForm; + /** Link providing access to new topic form from topic list */ + private ToggleLink m_addNewTopicLink; + + + /** + * Default Constructor creates the containing components. + * + * The topic panel contains two components: a Topics List and a Add New Topic + * input form. + * + */ + public TopicsPanel() { + + // Create a modal container: shows only one component at a time. + m_mode = new ModalContainer(); + add(m_mode); + + // References to sub-components for event access. + m_topicslist = createTopicsList(); + m_addTopicForm = createAddTopicForm(); + + m_mode.add(m_topicslist); + m_mode.add(m_addTopicForm); + + m_mode.setDefaultComponent(m_topicslist); + } + + /** + * + * @param p + */ + public void register(Page p) { + super.register(p); + p.addActionListener(this); + } + + /** + * Switch between the two available components, only one may be visible at + * a time. + * + * @param e action event. + */ + public void actionPerformed(ActionEvent e) { + PageState s = e.getPageState(); + + if (m_addNewTopicLink.isSelected(s)) { + m_mode.setVisibleComponent(s, m_addTopicForm); + } else { + m_mode.setVisibleComponent(s, m_topicslist); + } + } + + /** + * Creates the component TopicsList. It consists of a link to add a new + * topic and a list of currently defined (available) topics. + * @return + */ + private Container createTopicsList() { + + Container topicslist = new SimpleContainer(); + + // Create the Add Topic Link. + Container linksPanel = new SimpleContainer( + Constants.FORUM_XML_PREFIX + ":topicOptions", + Constants.FORUM_XML_NS); + m_addNewTopicLink = new ToggleLink( + new Label(Text.gz("forum.ui.topic.newTopic"))); + m_addNewTopicLink.setClassAttr("actionLink"); + linksPanel.add(m_addNewTopicLink); + // add to component + topicslist.add(linksPanel); + + // create and add topics list + topicslist.add(new TopicList()); // separate class + + return topicslist; + } + + /** + * Creates the component AddTopicForm. It consists of a name field and a + * description field. + * @return + */ + private Component createAddTopicForm() { + Form addForm = new TopicAddForm(); //separate class of package + addForm.addCompletionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PageState s = e.getPageState(); + m_addNewTopicLink.setSelected(s, false); + m_mode.setVisibleComponent(s, m_topicslist); + } + }); + return addForm; + } +}