Weitere Schritte zur Ueberarbeitung und Lokalisierung des Forums. Reiterliste der Hauptsicht angepasst.

git-svn-id: https://svn.libreccm.org/ccm/trunk@539 8810af33-2d31-482b-a856-94f89814c4df
master
pb 2010-09-22 19:00:55 +00:00
parent 43d3f73c30
commit 1d86f7e869
22 changed files with 359 additions and 165 deletions

View File

@ -32,6 +32,7 @@ object type Forum extends Application {
Boolean [1..1] isModerated = forum_forums.is_moderated;
Boolean [1..1] isNoticeboard = forum_forums.is_noticeboard;
component Group [0..1] adminGroup =
join forum_forums.admin_group_id to groups.group_id;
component Group [0..1] moderationGroup =
@ -45,6 +46,7 @@ object type Forum extends Application {
component ForumSubscription[0..n] subscriptions =
join forum_forums.forum_id to forum_subscriptions.forum_id;
component Category[1..1] category =
join forum_forums.category_id to cat_categories.category_id;

View File

@ -4,7 +4,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://rhea.redhat.com/schemas/waf/xml-renderer-rules xml-renderer-rules.xsd">
<xrd:context name="com.arsdigita.forum.ui.ThreadList">
<xrd:context name="com.arsdigita.forum.ui.ThreadsList">
<xrd:adapter objectType="com.arsdigita.messaging.Thread">
<xrd:formatter property="/object/id"

View File

@ -49,7 +49,7 @@ import com.arsdigita.util.Assert;
import com.arsdigita.web.Application;
/**
* The Forum class represents a discussion forum.
* Main domain class of a forum application representing a discussion forum.
*
* XXX: Forum knows about <i>threads</i> which groups a set of posts to the same
* subject, and <i>topics</i> which group a set of threads about the same general
@ -66,11 +66,17 @@ import com.arsdigita.web.Application;
public class Forum extends Application {
public static final String THREAD_SUBSCRIPTION_GROUPS_NAME =
/** Private logger instance for debugging purpose */
private static final Logger s_log = Logger.getLogger(Forum.class);
public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.forum.Forum";
public static final String PACKAGE_TYPE = "forum";
public static final String THREAD_SUBSCRIPTION_GROUPS_NAME =
"Thread Subscription Groups";
private static final ForumConfig s_config = new ForumConfig();
static {
s_config.load();
}
@ -80,12 +86,6 @@ public class Forum extends Application {
}
private static final Logger s_log = Logger.getLogger(Forum.class);
public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.forum.Forum";
public static final String PACKAGE_TYPE = "forum";
//////
//Forum specific privileges
/////
@ -102,7 +102,11 @@ public class Forum extends Application {
// returned for non public posts. This means there is no longer
// any need for a separate forum_read privilege, though it
// does no harm. Now removed
// public static final String FORUM_READ_PRIVILEGE = "forum_read";
//
// pb: Reactivated READ privilege in order to provide forums for different
// groups of users for their internal use and to provide private forums
// for logged in users only (no public read access).
public static final String FORUM_READ_PRIVILEGE = "forum_read";
///////
// pdl forum attribute/association names
@ -111,24 +115,29 @@ public class Forum extends Application {
private static final String SUBSCRIPTIONS = "subscriptions";
private static final String MODERATION = "isModerated";
private static final String NOTICEBOARD = "isNoticeboard";
private static final String ADMIN_GROUP = "adminGroup";
private static final String MODERATION_GROUP = "moderationGroup";
private static final String THREAD_CREATE_GROUP = "threadCreateGroup";
private static final String THREAD_RESPONDER_GROUP = "threadRespondGroup";
private static final String READ_GROUP = "readGroup";
private static final String CATEGORY = "category";
private static final String EXPIRE_AFTER = "expireAfter";
private static final String LIFECYCLE_DEFINITION = "lifecycleDefinition";
// additional attributes added chris.gilbert@westsussex.gov.uk
private static final String ALLOW_FILE_ATTACHMENTS =
"fileAttachmentsAllowed";
private static final String ALLOW_FILE_ATTACHMENTS = "fileAttachmentsAllowed";
private static final String ALLOW_IMAGE_UPLOADS = "imageUploadsAllowed";
private static final String AUTOSUBSCRIBE_THREAD_STARTER =
"autoSubscribeThreadStarter";
"autoSubscribeThreadStarter";
private static final String INTRODUCTION = "introduction";
private static final String NO_CATEGORY_POSTS = "noCategoryPostsAllowed";
private static final String ANONYMOUS_POSTS = "anonymousPostsAllowed";
/**
*
* @param data
*/
public Forum(DataObject data) {
super(data);
}
@ -226,7 +235,10 @@ public class Forum extends Application {
return category;
}
private void createGroups() {
/**
*
*/
private void createGroups() {
Group administrators = new Group();
administrators.setName(getTitle() + " Administrators");
setAssociation(ADMIN_GROUP, administrators);
@ -864,8 +876,8 @@ public class Forum extends Application {
group));
}
/**
* method required for upgrade - normally groups are set during forum creation and so
* creation and so there is no need to invoke a setter
* method required for upgrade - normally groups are set during forum
* creation and so creation and so there is no need to invoke a setter
* @author cgyg9330
*
*/

View File

@ -46,9 +46,11 @@ import org.apache.log4j.Logger;
*/
public final class ForumContext {
/** Private logger instance for debugging purpose */
private static final Logger s_log = Logger.getLogger(ForumContext.class);
private static final RequestLocal s_context = new RequestLocal() {
@Override
public Object initialValue(PageState state) {
return new ForumContext();
}
@ -63,7 +65,11 @@ public final class ForumContext {
private boolean m_canAdminister;
private boolean m_canModerate;
/**
* Default Constructor
*/
ForumContext() {
m_forum = (Forum)Kernel.getContext().getResource();
Assert.exists(m_forum, Forum.class);
@ -135,23 +141,43 @@ public final class ForumContext {
}
/**
*
* @return
*/
public boolean canEdit() {
return m_canEdit;
}
/**
*
* @return
*/
public boolean canAdminister() {
return m_canAdminister;
}
/**
*
* @return
*/
public boolean canModerate() {
return m_canModerate;
}
/**
*
* @return
*/
public BigDecimal getCategorySelection() {
return m_categorySelection;
}
/**
*
* @param categorySelection
*/
public void setCategorySelection(BigDecimal categorySelection) {
m_categorySelection = categorySelection;
}

View File

@ -36,7 +36,9 @@ import com.arsdigita.xml.Element;
/**
* Implementation of com.arsdigita.forum.PageBuilder that creates a
* basic forum page with read access check
* basic forum page with read access check.
* Controls forum.ui classes to generate the xml and display the desired
* elements (here esp. ForumUserCompactView).
*
* @author chris.gilbert@westsussex.gov.uk
*/
@ -116,6 +118,6 @@ public class ForumPageBuilder implements PageBuilder, Constants {
context.setCategorySelection(
(BigDecimal) event.getPageState().getValue(m_categorySelection));
}
}
}
}

View File

@ -43,8 +43,14 @@ import org.apache.log4j.Logger;
public class ForumServlet extends BebopApplicationServlet
implements Constants {
/** Private logger instance for debugging purpose */
private static final Logger s_log = Logger.getLogger(ForumServlet.class);
/**
*
* @throws ServletException
*/
@Override
public void init() throws ServletException {
super.init();
s_log.debug("creating forum page");

View File

@ -27,46 +27,66 @@ 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.ThreadComponent;
import com.arsdigita.forum.ui.DiscussionThreadSimpleView;
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
* thread page with read access check
*
* Implementation of com.arsdigita.forum.PageBuilder that creates a basic thread page with read access check
* @author chris.gilbert@westsussex.gov.uk
*/
public class ThreadPageBuilder implements PageBuilder, Constants {
/* (non-Javadoc)
* @see com.arsdigita.forum.PageBuilder#buildPage(com.arsdigita.bebop.parameters.ParameterModel)
* @see com.arsdigita.forum.PageBuilder#buildPage(
* com.arsdigita.bebop.parameters.ParameterModel)
*/
public Page buildPage() {
Page threadPage = PageFactory.buildPage(Constants.FORUM_XML_PREFIX, "Threads", "forumThreadPage");
/**
*
* @return
*/
public Page buildPage() {
Page threadPage = PageFactory.buildPage(Constants.FORUM_XML_PREFIX,
"Threads", "forumThreadPage");
//Output the title in an easy to find place
threadPage.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());
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());
}
});
threadPage.add(new ThreadComponent());
//
threadPage.add(new DiscussionThreadSimpleView());
// Register the thread id parameter as a global state parameter.
BigDecimalParameter threadID = new BigDecimalParameter(THREAD_PARAM);
threadPage.addGlobalStateParam(threadID);
threadPage.addRequestListener(new ApplicationAuthenticationListener(PrivilegeDescriptor.READ));
threadPage.addRequestListener(
new ApplicationAuthenticationListener(PrivilegeDescriptor.READ));
threadPage.addRequestListener
(new ThreadPageRequestListener(threadID));
return threadPage;
}
private static class ThreadPageRequestListener implements RequestListener {
/**
*
*/
private static class ThreadPageRequestListener implements RequestListener {
private BigDecimalParameter m_threadID;
public ThreadPageRequestListener(BigDecimalParameter threadID) {

View File

@ -1,20 +1,18 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>com.arsdigita.bboard</title>
<title>com.arsdigita.forum</title>
</head>
<body>
<p>
<b><font color="red">Experimental</font></b>
The bboard package provides
discussion forums in which users can post and reply to messages.
Additionally, users may register for notifications of new posts to
the system.
The forum package provides discussion forums in which users can post and
reply to messages. Additionally, users may register for notifications of
new posts to the system.
</p>
<p>
<i>Forum.java</i> is the main domain class.
</p>
</body>
</html>

View File

@ -21,7 +21,7 @@ package com.arsdigita.forum.portlet;
import com.arsdigita.forum.Forum;
import com.arsdigita.forum.ThreadCollection;
import com.arsdigita.forum.ui.Constants;
import com.arsdigita.forum.ui.ThreadList;
import com.arsdigita.forum.ui.ThreadsList;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.domain.DomainObjectXMLRenderer;
import com.arsdigita.bebop.portal.AbstractPortletRenderer;

View File

@ -21,7 +21,7 @@ package com.arsdigita.forum.portlet;
import com.arsdigita.forum.Forum;
import com.arsdigita.forum.ThreadCollection;
import com.arsdigita.forum.ui.Constants;
import com.arsdigita.forum.ui.ThreadList;
import com.arsdigita.forum.ui.ThreadsList;
import com.arsdigita.domain.DomainObjectXMLRenderer;
import com.arsdigita.bebop.portal.AbstractPortletRenderer;
import com.arsdigita.bebop.PageState;
@ -122,7 +122,7 @@ class RecentPostingsPortletRenderer
xr.setWrapAttributes(true);
xr.setWrapObjects(false);
xr.walk(thread, ThreadList.class.getName());
xr.walk(thread, ThreadsList.class.getName());
}
}

View File

@ -57,19 +57,21 @@ 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.
* Child panel of DiscussionThreadSimpleVew. Provides for the given thread (usually
* selected from the list of threads created by ThreadsPanel) a list of its posts
* along with a reply link and additionally links to edit, delete, etc (according
* to given authorisation) for each listed post.
*
* Curently used by ThreadComponent to create the actual list of threads and by
* So it creates the actual list of threads for DiscussionThreadSimpleVew and by
* MessageView.
*/
public class ThreadDisplay extends SimpleComponent implements Constants {
public class DiscussionPostsList extends SimpleComponent implements Constants {
private static final Logger s_log =
Logger.getLogger(ThreadDisplay.class);
Logger.getLogger(DiscussionPostsList.class);
private IntegerParameter m_pageNumber =
new IntegerParameter(PAGINATOR_PARAM);
new IntegerParameter(PAGINATOR_PARAM);
private int m_pageSize = Forum.getConfig().getThreadPageSize();
private static final String ACTION_EDIT = "edit";
@ -78,22 +80,37 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
private static final String ACTION_APPROVE = "approve";
private static final String ACTION_REJECT = "reject";
private ThreadComponent m_threadComponent;
private DiscussionThreadSimpleView m_threadMessagesPanel;
private ACSObjectSelectionModel m_post;
public ThreadDisplay(ACSObjectSelectionModel post,
ThreadComponent threadComponent) {
m_threadComponent = threadComponent;
/**
* Defaultg Constructor
*
* @param post
* @param threadMessagesPanel
*/
public DiscussionPostsList(ACSObjectSelectionModel post,
DiscussionThreadSimpleView threadMessagesPanel) {
m_threadMessagesPanel = threadMessagesPanel;
m_post = post;
}
/**
*
* @param p
*/
public void register(Page p) {
super.register(p);
p.addGlobalStateParam(m_pageNumber);
}
/**
*
* @param state
* @throws ServletException
*/
public void respond(PageState state)
throws ServletException {
super.respond(state);
@ -109,7 +126,7 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
if (ACTION_EDIT.equals(key)) {
m_post.setSelectedObject(state, post);
m_threadComponent.makeEditFormVisible(state);
m_threadMessagesPanel.makeEditFormVisible(state);
} else if (ACTION_DELETE.equals(key)) {
Assert.isTrue(ctx.canAdminister(), "can administer forums");
@ -150,14 +167,14 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
}
} else if (ACTION_REPLY.equals(key)) {
m_post.setSelectedObject(state, post);
m_threadComponent.makeReplyFormVisible(state);
m_threadMessagesPanel.makeReplyFormVisible(state);
} else if (ACTION_APPROVE.equals(key)) {
post.setStatus(Post.APPROVED);
post.save();
post.sendNotifications(null);
} else if (ACTION_REJECT.equals(key)) {
m_post.setSelectedObject(state, post);
m_threadComponent.makeRejectFormVisible(state);
m_threadMessagesPanel.makeRejectFormVisible(state);
}
state.clearControlEvent();
@ -168,6 +185,11 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
}
}
/**
*
* @param state
* @return
*/
private DomainCollection getMessages(PageState state) {
ForumContext context = ForumContext.getContext(state);
@ -208,15 +230,23 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
return new DomainCollection(messages);
}
/**
*
* @param state
* @param parent
*/
@Override
public void generateXML(PageState state,
Element parent) {
Element content = parent.newChildElement(FORUM_XML_PREFIX + ":threadDisplay",
Element content = parent.newChildElement(FORUM_XML_PREFIX +
":threadDisplay",
FORUM_XML_NS);
exportAttributes(content);
Forum forum = ForumContext.getContext(state).getForum();
content.addAttribute("forumTitle", forum.getTitle());
content.addAttribute("noticeboard", (new Boolean(forum.isNoticeboard())).toString());
content.addAttribute("noticeboard", (new Boolean(forum.isNoticeboard())).
toString());
DomainCollection messages = getMessages(state);
Integer page = (Integer)state.getValue(m_pageNumber);
@ -261,11 +291,17 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
xr.setWrapAttributes(true);
xr.setWrapObjects(false);
xr.walk(message, ThreadDisplay.class.getName());
xr.walk(message, DiscussionPostsList.class.getName());
}
}
/**
*
* @param state
* @param parent
* @param post
*/
protected void generateActionXML(PageState state,
Element parent,
Post post) {
@ -301,9 +337,12 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
makeURL(state, ACTION_EDIT, post));
}
PermissionDescriptor canRespond = new PermissionDescriptor(PrivilegeDescriptor.get(Forum.RESPOND_TO_THREAD_PRIVILEGE), Kernel.getContext().getResource(), party);
PermissionDescriptor canRespond = new PermissionDescriptor(
PrivilegeDescriptor.get(Forum.RESPOND_TO_THREAD_PRIVILEGE),
Kernel.getContext().getResource(), party);
if (!ctx.getForum().isNoticeboard() && PermissionService.checkPermission(canRespond)) {
if (!ctx.getForum().isNoticeboard() && PermissionService.
checkPermission(canRespond)) {
parent.addAttribute("replyURL",
makeURL(state, ACTION_REPLY, post));
}
@ -332,7 +371,8 @@ public class ThreadDisplay 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());

View File

@ -47,55 +47,73 @@ import com.arsdigita.messaging.MessageThread;
import org.apache.log4j.Logger;
/**
* Display for looking at a single thread and posting new messages and
* replying to it. Contains MessagesComponent, EditPostForm, and
* ReplyToPostForm
* A Bebop component which provides the dynamic parts of the UI for looking at
* a single thread of the forum and posting new messages as well as replying to it.
* (The invoking class forum.ThreadPageBuilder creates the static parts as the
* title of the forum and the forum introcuction text).
*
* The dynamic part of the discussion page contains three components:
* a MessageList, a ThreadEdit component, and a ThreadReply component.
*
* Contains MessagesComponent, EditPostForm, and ReplyToPostForm
* @see com.arsdigita.forum.ui.MessagesComponent
* @see com.arsdigita.forum.ui.EditPostForm
* @see com.arsdigita.forum.ui.ReplyToPostForm
*/
public class ThreadComponent extends ModalContainer implements Constants {
public class DiscussionThreadSimpleView extends ModalContainer implements Constants {
/** Private logger instance for debugging purpose. */
private static final Logger s_log
= Logger.getLogger(DiscussionThreadSimpleView.class);
// References to sub-components for event access.
private Container m_threadView;
/** The message list component */
private Container m_threadMessagesPanel;
/** The post component for a root mesage */
private PostForm m_rootForm;
/** The post component for a reply mesage */
private PostForm m_replyForm;
/** A message component for moderators */
private Form m_rejectForm;
private static final Logger s_log
= Logger.getLogger(ThreadComponent.class);
/** */
private ACSObjectSelectionModel m_postModel;
/**
* The forum page contains three components: a MessageList,
* Default Constructor creates the component of the discussio view.
* The discussion page contains three components: a MessageList,
* a ThreadEdit component, and a ThreadReply component.
* Creates the component.
*
*/
public ThreadComponent() {
public DiscussionThreadSimpleView() {
// Create a modal container: shows only one containee at a time.
m_postModel = new ACSObjectSelectionModel("post");
initComponents();
}
/**
* Internal helper method for constructor
* Add the thread components to the modal container and maintain
* references for event manipulation purposes.
*/
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");
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");
m_replyForm = new ReplyToPostForm(m_postModel);
s_log.debug("creating reject form");
m_rejectForm = new RejectionForm(m_postModel);
addForm(m_rootForm);
addForm(m_replyForm);
addForm(m_rejectForm);
m_threadView = new SimpleContainer();
Container linksPanel = new SimpleContainer(FORUM_XML_PREFIX + ":threadOptions",
m_threadMessagesPanel = new SimpleContainer();
Container linksPanel = new SimpleContainer(FORUM_XML_PREFIX +
":threadOptions",
Constants.FORUM_XML_NS);
// Offer links to return to index or control alerts.
@ -110,16 +128,16 @@ public class ThreadComponent extends ModalContainer implements Constants {
linksPanel.add(subLinks);
// Add the panel to the view.
m_threadView.add(linksPanel);
m_threadView.add(new ThreadDisplay(m_postModel, this));
add(m_threadView);
m_threadMessagesPanel.add(linksPanel);
m_threadMessagesPanel.add(new DiscussionPostsList(m_postModel, this));
add(m_threadMessagesPanel);
// The thread view is the default component.
setDefaultComponent(m_threadView);
// The threadMessagesPanel is the default component.
setDefaultComponent(m_threadMessagesPanel);
}
public void makeListViewVisible(PageState state) {
setVisibleComponent(state, m_threadView);
setVisibleComponent(state, m_threadMessagesPanel);
}
public void makeEditFormVisible(PageState state) {
@ -208,6 +226,7 @@ public class ThreadComponent extends ModalContainer implements Constants {
private Component createThreadUnsubscribeLink() {
ActionLink unsubscribeLink = new ActionLink(
new Label(Text.gz("forum.ui.thread.unsubscribe"))) {
@Override
public boolean isVisible(PageState s) {
Party party = Kernel.getContext().getParty();

View File

@ -32,7 +32,7 @@ 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=Achtung: Deaktivieren der Modereation \u00e4ndert den Status von ausstehenden Nachrichten auf akzeptiert!
forum.ui.moderate.warning=Achtung: Deaktivieren der Moderation \u00e4ndert den Status von ausstehenden Nachrichten auf akzeptiert!
forum.ui.noticeboard.label=Noticeboard functionality (Antworten deaktiviert)
forum.ui.noticeboard.switch.on=Turn on (disable replying)

View File

@ -33,6 +33,7 @@ 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.globalization.GlobalizedMessage;
import com.arsdigita.kernel.Kernel;
import com.arsdigita.kernel.Party;
import com.arsdigita.kernel.permissions.PermissionDescriptor;
@ -71,7 +72,8 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
public static final String MODE_ALERTS = "alerts";
/** Denominator of the 'moderation handling' forum mode */
public static final String MODE_MODERATION = "moderation";
/** Denominator of the 'permission administration' forum mode (administrators only) */
/** 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";
@ -167,6 +169,8 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
PermissionDescriptor forumAdmin =
new PermissionDescriptor(PrivilegeDescriptor.ADMIN, forum, party);
PermissionService.assertPermission(forumAdmin);
if (MODE_TOPICS.equals(mode)) {
if (Forum.getConfig().topicCreationByAdminOnly()) {
if (party == null) {
@ -200,6 +204,7 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
PermissionService.assertPermission(forumAdmin);
setVisibleComponent(state, m_setupView);
} else if (MODE_THREADS.equals(mode)) {
PermissionService.assertPermission(forumAdmin);
setVisibleComponent(state, m_threadsView);
}
}
@ -221,6 +226,7 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
"noticeboard",
(new Boolean(forum.isNoticeboard())).toString());
// If visitor not logged in, set user (=party) to publicUser
Party party = Kernel.getContext().getParty();
if (party == null) {
party = Kernel.getPublicUser();
@ -246,27 +252,34 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
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);
// currently thread panel is always shown. If read access should be
// bound to logged in users, additional logic is required here.
generateModeXML(state, content, MODE_THREADS,
Text.gz("forum.ui.modeThreads"));
// topics panel is always shoen as well if not restricted to admins.
if (!Forum.getConfig().topicCreationByAdminOnly()) {
generateModeXML(state, content, MODE_TOPICS);
generateModeXML(state, content, MODE_TOPICS,
Text.gz("forum.ui.modeTopics"));
}
// alerts panel is always shown as well, no private read access avail.
generateModeXML(state, content, MODE_ALERTS);
generateModeXML(state, content, MODE_ALERTS,
Text.gz("forum.ui.modeAlerts"));
// admin section
if (PermissionService.checkPermission(permission)) {
generateModeXML(state, content, MODE_MODERATION);
generateModeXML(state, content, MODE_MODERATION,
Text.gz("forum.ui.modeAlerts"));
if (Forum.getConfig().showNewTabs()) {
generateModeXML(state, content, MODE_SETUP);
generateModeXML(state, content, MODE_PERMISSIONS);
generateModeXML(state, content, MODE_SETUP,
Text.gz("forum.ui.modeSetup"));
generateModeXML(state, content, MODE_PERMISSIONS,
Text.gz("forum.ui.modePermissions"));
}
// 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);
generateModeXML(state, content, MODE_TOPICS,
Text.gz("forum.ui.modeTopics"));
}
}
}
@ -280,14 +293,17 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
* @param parent
* @param mode forum mode (threadspanel, topicspanel, alertpanel, ...) to
* create entry for
* @deprecated use generateModeXML(PageState, Element, String,
* GlobalizedMessage) instead
*/
protected void generateModeXML(PageState state,
Element parent,
String mode) {
generateModeXML(state, parent, mode, null);
/*
String current = (String)state.getValue(m_mode);
if (current == null) {
current = MODE_THREADS;
current = MODE_THREADS; // used as default mode
}
Element content =
@ -297,20 +313,6 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
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",
@ -321,7 +323,60 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
content.addAttribute("selected",
current.equals(mode) ? "1" : "0");
state.clearControlEvent();
*/
}
/**
* Generates a forum mode selection entry (usually a tab).
*
*
* @param state
* @param parent
* @param mode forum mode (threadspanel, topicspanel, alertpanel, ...) to
* create entry for
* @param label to denominate the mode
*/
protected void generateModeXML(PageState state,
Element parent,
String mode,
GlobalizedMessage label ) {
String current = (String)state.getValue(m_mode);
if (current == null) {
current = MODE_THREADS; // used as default mode
}
Element content =
parent.newChildElement(FORUM_XML_PREFIX + ":forumMode", FORUM_XML_NS);
state.setControlEvent(this, "mode", mode);
content.addAttribute("mode",
mode);
// add link to switch to 'mode'
try {
content.addAttribute("url",
state.stateAsURL());
} catch (IOException ex) {
throw new UncheckedWrapperException("cannot create url", ex);
}
// add localized mode label
// if-else should be removed when deprecated method above is removed!
if (label == null) {
content.addAttribute("label",
"UNAVAILABLE");
} else {
content.addAttribute("label",
(String)label.localize());
}
// add if current mode is actually selected
content.addAttribute("selected",
current.equals(mode) ? "1" : "0");
state.clearControlEvent();
}
}

View File

@ -48,6 +48,7 @@ class MessageView extends SimpleComponent implements Constants {
m_post = post;
}
@Override
public void register(Page page) {
super.register(page);
if (m_postModel != null) {
@ -56,6 +57,7 @@ class MessageView extends SimpleComponent implements Constants {
}
}
@Override
public void generateXML(PageState state,
Element parent) {
Message post = m_post;
@ -78,7 +80,7 @@ class MessageView extends SimpleComponent implements Constants {
xr.setWrapAttributes(true);
xr.setWrapObjects(false);
xr.walk(post, ThreadDisplay.class.getName());
xr.walk(post, DiscussionPostsList.class.getName());
}
}

View File

@ -25,8 +25,9 @@ import com.arsdigita.persistence.metadata.Property;
public class MessageXMLFormatter
extends SimpleDomainObjectXMLFormatter {
extends SimpleDomainObjectXMLFormatter {
@Override
public Object format(DomainObject obj,
String path,
Property prop,
@ -39,6 +40,7 @@ public class MessageXMLFormatter
return super.format(obj, path, prop, value);
}
@Override
public boolean isEmpty() {
return false;
}

View File

@ -50,7 +50,7 @@ import java.math.BigDecimal;
* A paginator is added to handle a high number of threads.
*
*/
public class ThreadList extends SimpleComponent implements Constants {
public class ThreadsList extends SimpleComponent implements Constants {
/** */
private IntegerParameter m_pageNumber =
@ -81,9 +81,8 @@ public class ThreadList extends SimpleComponent implements Constants {
categoryID = null;
}
ThreadCollection threads = forum.getThreads(
categoryID,
Kernel.getContext().getParty());
ThreadCollection threads = forum.getThreads(categoryID,
Kernel.getContext().getParty());
return threads;
}
@ -95,6 +94,7 @@ public class ThreadList extends SimpleComponent implements Constants {
*/
public void generateXML(PageState state,
Element parent) {
// Begin of thread list, XSL constructs (and localizes) the list title bar
Element content = parent.newChildElement(FORUM_XML_PREFIX +
":threadList", FORUM_XML_NS);
@ -130,11 +130,14 @@ public class ThreadList extends SimpleComponent implements Constants {
new Integer((int)end+1));
}
while (threads.next()) {
while (threads.next()) { // step through ThreadCollections
MessageThread thread = threads.getMessageThread();
Element threadEl = content.newChildElement(FORUM_XML_PREFIX +
":thread", FORUM_XML_NS);
// create link to a JSP which provide a List of messages for the
// thread, i.e. this first message and all its followup messages
ParameterMap map = new ParameterMap();
map.setParameter(THREAD_PARAM, thread.getID());
URL url = URL.there((Application)Kernel.getContext().getResource(),
@ -147,7 +150,7 @@ public class ThreadList extends SimpleComponent implements Constants {
xr.setWrapAttributes(true);
xr.setWrapObjects(false);
xr.walk(thread, ThreadList.class.getName());
xr.walk(thread, ThreadsList.class.getName());
}
}

View File

@ -69,7 +69,7 @@ public class ThreadsPanel extends SimpleContainer
private ModalContainer m_mode;
/** Bebop Component, list of threads along with some othere elements, will
* be one child of ModalContainer */
private Component m_threadsComponent;
private Component m_threadsListing;
/** Bebop Component, add new post to a thread form. Will be another child of
* ModalContainer */
private PostForm m_postComponent;
@ -90,13 +90,13 @@ public class ThreadsPanel extends SimpleContainer
m_mode = new ModalContainer();
add(m_mode);
m_threadsComponent = createThreadsComponent();
m_postComponent = createPostComponent();
m_threadsListing = createThreadsListing();
m_postComponent = createNewThreadForm();
m_mode.add(m_threadsComponent);
m_mode.add(m_threadsListing);
m_mode.add(m_postComponent);
m_mode.setDefaultComponent(m_threadsComponent);
m_mode.setDefaultComponent(m_threadsListing);
}
@ -123,7 +123,7 @@ public class ThreadsPanel extends SimpleContainer
m_postComponent.setContext(s, PostForm.NEW_CONTEXT);
m_mode.setVisibleComponent(s, m_postComponent);
} else {
m_mode.setVisibleComponent(s, m_threadsComponent);
m_mode.setVisibleComponent(s, m_threadsListing);
}
}
});
@ -135,7 +135,7 @@ public class ThreadsPanel extends SimpleContainer
* with author, # of responses, etc. Filtered for approved
* messages if the forum is moderated.
*/
private Component createThreadsComponent() {
private Component createThreadsListing() {
Container forums = new SimpleContainer();
@ -166,8 +166,8 @@ public class ThreadsPanel extends SimpleContainer
TopicSelector topics = new TopicSelector();
forums.add(topics);
ThreadList threads
= new ThreadList();
ThreadsList threads
= new ThreadsList();
forums.add(threads);
@ -175,10 +175,14 @@ public class ThreadsPanel extends SimpleContainer
}
/**
* Provides a Form to create a new Thread. It is accomplished by constructing
* a RootPostForm to create a new post which contains a subject line and
* a selection box for a topic the new thread should be associated to.
*
* @return
* @return a form to create the first post of a new thread which implicitly
* creates a new thread.
*/
private PostForm createPostComponent() {
private PostForm createNewThreadForm() {
PostForm editForm = new RootPostForm();
editForm.addCompletionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {

View File

@ -44,7 +44,7 @@ import java.util.Iterator;
* uses category in the usual CMS way, esp. navigation categories.
*
*/
public class TopicList extends SimpleComponent implements Constants {
public class TopicsList extends SimpleComponent implements Constants {
/** List of properties a topic may have. */
private final static Set s_catProps;

View File

@ -138,7 +138,7 @@ public class TopicsPanel extends SimpleContainer
topicslist.add(linksPanel);
// create and add topics list
topicslist.add(new TopicList()); // separate class
topicslist.add(new TopicsList()); // separate class
return topicslist;
}

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<!-- module ccm-forum - servlet declarations BEGIN -->
<servlet>

View File

@ -4,11 +4,11 @@
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<!-- IMPORT DEFINITIONS ccm-ldn-shortcuts installed as separate web application
<!-- IMPORT DEFINITIONS ccm-forum installed as separate web application
<xsl:import href="../../../../ROOT/packages/bebop/xsl/bebop.xsl"/>
<xsl:import href="../../../../ROOT/packages/ui/xsl/ui.xsl"/>
-->
<!-- IMPORT DEFINITIONS ccm-ldn-shortcuts installed into the main CCM webapp
<!-- IMPORT DEFINITIONS ccm-forum installed into the main CCM webapp
-->
<xsl:import href="../../../packages/bebop/xsl/bebop.xsl"/>
<xsl:import href="../../../packages/ui/xsl/ui.xsl"/>