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] isModerated = forum_forums.is_moderated;
Boolean [1..1] isNoticeboard = forum_forums.is_noticeboard; Boolean [1..1] isNoticeboard = forum_forums.is_noticeboard;
component Group [0..1] adminGroup = component Group [0..1] adminGroup =
join forum_forums.admin_group_id to groups.group_id; join forum_forums.admin_group_id to groups.group_id;
component Group [0..1] moderationGroup = component Group [0..1] moderationGroup =
@ -45,6 +46,7 @@ object type Forum extends Application {
component ForumSubscription[0..n] subscriptions = component ForumSubscription[0..n] subscriptions =
join forum_forums.forum_id to forum_subscriptions.forum_id; join forum_forums.forum_id to forum_subscriptions.forum_id;
component Category[1..1] category = component Category[1..1] category =
join forum_forums.category_id to cat_categories.category_id; 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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://rhea.redhat.com/schemas/waf/xml-renderer-rules xml-renderer-rules.xsd"> 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:adapter objectType="com.arsdigita.messaging.Thread">
<xrd:formatter property="/object/id" <xrd:formatter property="/object/id"

View File

@ -49,7 +49,7 @@ import com.arsdigita.util.Assert;
import com.arsdigita.web.Application; 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 * 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 * 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 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"; "Thread Subscription Groups";
private static final ForumConfig s_config = new ForumConfig(); private static final ForumConfig s_config = new ForumConfig();
static { static {
s_config.load(); 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 //Forum specific privileges
///// /////
@ -102,7 +102,11 @@ public class Forum extends Application {
// returned for non public posts. This means there is no longer // returned for non public posts. This means there is no longer
// any need for a separate forum_read privilege, though it // any need for a separate forum_read privilege, though it
// does no harm. Now removed // 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 // pdl forum attribute/association names
@ -111,24 +115,29 @@ public class Forum extends Application {
private static final String SUBSCRIPTIONS = "subscriptions"; private static final String SUBSCRIPTIONS = "subscriptions";
private static final String MODERATION = "isModerated"; private static final String MODERATION = "isModerated";
private static final String NOTICEBOARD = "isNoticeboard"; private static final String NOTICEBOARD = "isNoticeboard";
private static final String ADMIN_GROUP = "adminGroup"; private static final String ADMIN_GROUP = "adminGroup";
private static final String MODERATION_GROUP = "moderationGroup"; private static final String MODERATION_GROUP = "moderationGroup";
private static final String THREAD_CREATE_GROUP = "threadCreateGroup"; private static final String THREAD_CREATE_GROUP = "threadCreateGroup";
private static final String THREAD_RESPONDER_GROUP = "threadRespondGroup"; private static final String THREAD_RESPONDER_GROUP = "threadRespondGroup";
private static final String READ_GROUP = "readGroup"; private static final String READ_GROUP = "readGroup";
private static final String CATEGORY = "category"; private static final String CATEGORY = "category";
private static final String EXPIRE_AFTER = "expireAfter"; private static final String EXPIRE_AFTER = "expireAfter";
private static final String LIFECYCLE_DEFINITION = "lifecycleDefinition"; private static final String LIFECYCLE_DEFINITION = "lifecycleDefinition";
// additional attributes added chris.gilbert@westsussex.gov.uk // additional attributes added chris.gilbert@westsussex.gov.uk
private static final String ALLOW_FILE_ATTACHMENTS = private static final String ALLOW_FILE_ATTACHMENTS = "fileAttachmentsAllowed";
"fileAttachmentsAllowed";
private static final String ALLOW_IMAGE_UPLOADS = "imageUploadsAllowed"; private static final String ALLOW_IMAGE_UPLOADS = "imageUploadsAllowed";
private static final String AUTOSUBSCRIBE_THREAD_STARTER = private static final String AUTOSUBSCRIBE_THREAD_STARTER =
"autoSubscribeThreadStarter"; "autoSubscribeThreadStarter";
private static final String INTRODUCTION = "introduction"; private static final String INTRODUCTION = "introduction";
private static final String NO_CATEGORY_POSTS = "noCategoryPostsAllowed"; private static final String NO_CATEGORY_POSTS = "noCategoryPostsAllowed";
private static final String ANONYMOUS_POSTS = "anonymousPostsAllowed"; private static final String ANONYMOUS_POSTS = "anonymousPostsAllowed";
/**
*
* @param data
*/
public Forum(DataObject data) { public Forum(DataObject data) {
super(data); super(data);
} }
@ -226,7 +235,10 @@ public class Forum extends Application {
return category; return category;
} }
private void createGroups() { /**
*
*/
private void createGroups() {
Group administrators = new Group(); Group administrators = new Group();
administrators.setName(getTitle() + " Administrators"); administrators.setName(getTitle() + " Administrators");
setAssociation(ADMIN_GROUP, administrators); setAssociation(ADMIN_GROUP, administrators);
@ -864,8 +876,8 @@ public class Forum extends Application {
group)); group));
} }
/** /**
* method required for upgrade - normally groups are set during forum creation and so * method required for upgrade - normally groups are set during forum
* creation and so there is no need to invoke a setter * creation and so creation and so there is no need to invoke a setter
* @author cgyg9330 * @author cgyg9330
* *
*/ */

View File

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

View File

@ -36,7 +36,9 @@ import com.arsdigita.xml.Element;
/** /**
* Implementation of com.arsdigita.forum.PageBuilder that creates a * 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 * @author chris.gilbert@westsussex.gov.uk
*/ */
@ -116,6 +118,6 @@ public class ForumPageBuilder implements PageBuilder, Constants {
context.setCategorySelection( context.setCategorySelection(
(BigDecimal) event.getPageState().getValue(m_categorySelection)); (BigDecimal) event.getPageState().getValue(m_categorySelection));
} }
} }
} }

View File

@ -43,8 +43,14 @@ import org.apache.log4j.Logger;
public class ForumServlet extends BebopApplicationServlet public class ForumServlet extends BebopApplicationServlet
implements Constants { implements Constants {
/** Private logger instance for debugging purpose */
private static final Logger s_log = Logger.getLogger(ForumServlet.class); private static final Logger s_log = Logger.getLogger(ForumServlet.class);
/**
*
* @throws ServletException
*/
@Override
public void init() throws ServletException { public void init() throws ServletException {
super.init(); super.init();
s_log.debug("creating forum page"); 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.RequestEvent;
import com.arsdigita.bebop.event.RequestListener; import com.arsdigita.bebop.event.RequestListener;
import com.arsdigita.bebop.parameters.BigDecimalParameter; 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.Constants;
import com.arsdigita.forum.ui.ThreadComponent; import com.arsdigita.forum.ui.DiscussionThreadSimpleView;
import com.arsdigita.kernel.permissions.PrivilegeDescriptor; import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
import com.arsdigita.toolbox.ui.ApplicationAuthenticationListener; import com.arsdigita.toolbox.ui.ApplicationAuthenticationListener;
import com.arsdigita.xml.Element; 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 { public class ThreadPageBuilder implements PageBuilder, Constants {
/* (non-Javadoc) /* (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 //Output the title in an easy to find place
threadPage.add(new SimpleComponent(){ threadPage.add(new SimpleComponent(){
public void generateXML(PageState state, Element parent) { public void generateXML(PageState state, Element parent) {
Element nameElement = parent.newChildElement(Constants.FORUM_XML_PREFIX + ":name", Constants.FORUM_XML_NS); Element nameElement = parent.newChildElement(
nameElement.setText(ForumContext.getContext(state).getForum().getTitle()); Constants.FORUM_XML_PREFIX + ":name",
Element introductionElement = parent.newChildElement(Constants.FORUM_XML_PREFIX + ":introduction", Constants.FORUM_XML_NS); Constants.FORUM_XML_NS);
introductionElement.setText(ForumContext.getContext(state).getForum().getIntroduction()); 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. // Register the thread id parameter as a global state parameter.
BigDecimalParameter threadID = new BigDecimalParameter(THREAD_PARAM); BigDecimalParameter threadID = new BigDecimalParameter(THREAD_PARAM);
threadPage.addGlobalStateParam(threadID); threadPage.addGlobalStateParam(threadID);
threadPage.addRequestListener(new ApplicationAuthenticationListener(PrivilegeDescriptor.READ)); threadPage.addRequestListener(
new ApplicationAuthenticationListener(PrivilegeDescriptor.READ));
threadPage.addRequestListener threadPage.addRequestListener
(new ThreadPageRequestListener(threadID)); (new ThreadPageRequestListener(threadID));
return threadPage; return threadPage;
} }
private static class ThreadPageRequestListener implements RequestListener { /**
*
*/
private static class ThreadPageRequestListener implements RequestListener {
private BigDecimalParameter m_threadID; private BigDecimalParameter m_threadID;
public ThreadPageRequestListener(BigDecimalParameter threadID) { public ThreadPageRequestListener(BigDecimalParameter threadID) {

View File

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

View File

@ -21,7 +21,7 @@ package com.arsdigita.forum.portlet;
import com.arsdigita.forum.Forum; import com.arsdigita.forum.Forum;
import com.arsdigita.forum.ThreadCollection; import com.arsdigita.forum.ThreadCollection;
import com.arsdigita.forum.ui.Constants; 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.DomainObjectFactory;
import com.arsdigita.domain.DomainObjectXMLRenderer; import com.arsdigita.domain.DomainObjectXMLRenderer;
import com.arsdigita.bebop.portal.AbstractPortletRenderer; 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.Forum;
import com.arsdigita.forum.ThreadCollection; import com.arsdigita.forum.ThreadCollection;
import com.arsdigita.forum.ui.Constants; 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.domain.DomainObjectXMLRenderer;
import com.arsdigita.bebop.portal.AbstractPortletRenderer; import com.arsdigita.bebop.portal.AbstractPortletRenderer;
import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PageState;
@ -122,7 +122,7 @@ class RecentPostingsPortletRenderer
xr.setWrapAttributes(true); xr.setWrapAttributes(true);
xr.setWrapObjects(false); 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; import com.arsdigita.xml.XML;
/** /**
* Provides List of posts for a thread with links to edit, delete, etc * Child panel of DiscussionThreadSimpleVew. Provides for the given thread (usually
* according to authorisation. * 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. * MessageView.
*/ */
public class ThreadDisplay extends SimpleComponent implements Constants { public class DiscussionPostsList extends SimpleComponent implements Constants {
private static final Logger s_log = private static final Logger s_log =
Logger.getLogger(ThreadDisplay.class); Logger.getLogger(DiscussionPostsList.class);
private IntegerParameter m_pageNumber = private IntegerParameter m_pageNumber =
new IntegerParameter(PAGINATOR_PARAM); new IntegerParameter(PAGINATOR_PARAM);
private int m_pageSize = Forum.getConfig().getThreadPageSize(); private int m_pageSize = Forum.getConfig().getThreadPageSize();
private static final String ACTION_EDIT = "edit"; 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_APPROVE = "approve";
private static final String ACTION_REJECT = "reject"; private static final String ACTION_REJECT = "reject";
private ThreadComponent m_threadComponent; private DiscussionThreadSimpleView m_threadMessagesPanel;
private ACSObjectSelectionModel m_post; private ACSObjectSelectionModel m_post;
public ThreadDisplay(ACSObjectSelectionModel post, /**
ThreadComponent threadComponent) { * Defaultg Constructor
m_threadComponent = threadComponent; *
* @param post
* @param threadMessagesPanel
*/
public DiscussionPostsList(ACSObjectSelectionModel post,
DiscussionThreadSimpleView threadMessagesPanel) {
m_threadMessagesPanel = threadMessagesPanel;
m_post = post; m_post = post;
} }
/**
*
* @param p
*/
public void register(Page p) { public void register(Page p) {
super.register(p); super.register(p);
p.addGlobalStateParam(m_pageNumber); p.addGlobalStateParam(m_pageNumber);
} }
/**
*
* @param state
* @throws ServletException
*/
public void respond(PageState state) public void respond(PageState state)
throws ServletException { throws ServletException {
super.respond(state); super.respond(state);
@ -109,7 +126,7 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
if (ACTION_EDIT.equals(key)) { if (ACTION_EDIT.equals(key)) {
m_post.setSelectedObject(state, post); m_post.setSelectedObject(state, post);
m_threadComponent.makeEditFormVisible(state); m_threadMessagesPanel.makeEditFormVisible(state);
} else if (ACTION_DELETE.equals(key)) { } else if (ACTION_DELETE.equals(key)) {
Assert.isTrue(ctx.canAdminister(), "can administer forums"); Assert.isTrue(ctx.canAdminister(), "can administer forums");
@ -150,14 +167,14 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
} }
} else if (ACTION_REPLY.equals(key)) { } else if (ACTION_REPLY.equals(key)) {
m_post.setSelectedObject(state, post); m_post.setSelectedObject(state, post);
m_threadComponent.makeReplyFormVisible(state); m_threadMessagesPanel.makeReplyFormVisible(state);
} else if (ACTION_APPROVE.equals(key)) { } else if (ACTION_APPROVE.equals(key)) {
post.setStatus(Post.APPROVED); post.setStatus(Post.APPROVED);
post.save(); post.save();
post.sendNotifications(null); post.sendNotifications(null);
} else if (ACTION_REJECT.equals(key)) { } else if (ACTION_REJECT.equals(key)) {
m_post.setSelectedObject(state, post); m_post.setSelectedObject(state, post);
m_threadComponent.makeRejectFormVisible(state); m_threadMessagesPanel.makeRejectFormVisible(state);
} }
state.clearControlEvent(); state.clearControlEvent();
@ -168,6 +185,11 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
} }
} }
/**
*
* @param state
* @return
*/
private DomainCollection getMessages(PageState state) { private DomainCollection getMessages(PageState state) {
ForumContext context = ForumContext.getContext(state); ForumContext context = ForumContext.getContext(state);
@ -208,15 +230,23 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
return new DomainCollection(messages); return new DomainCollection(messages);
} }
/**
*
* @param state
* @param parent
*/
@Override
public void generateXML(PageState state, public void generateXML(PageState state,
Element parent) { Element parent) {
Element content = parent.newChildElement(FORUM_XML_PREFIX + ":threadDisplay", Element content = parent.newChildElement(FORUM_XML_PREFIX +
":threadDisplay",
FORUM_XML_NS); FORUM_XML_NS);
exportAttributes(content); exportAttributes(content);
Forum forum = ForumContext.getContext(state).getForum(); Forum forum = ForumContext.getContext(state).getForum();
content.addAttribute("forumTitle", forum.getTitle()); 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); DomainCollection messages = getMessages(state);
Integer page = (Integer)state.getValue(m_pageNumber); Integer page = (Integer)state.getValue(m_pageNumber);
@ -261,11 +291,17 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
xr.setWrapAttributes(true); xr.setWrapAttributes(true);
xr.setWrapObjects(false); 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, protected void generateActionXML(PageState state,
Element parent, Element parent,
Post post) { Post post) {
@ -301,9 +337,12 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
makeURL(state, ACTION_EDIT, post)); 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", parent.addAttribute("replyURL",
makeURL(state, ACTION_REPLY, post)); makeURL(state, ACTION_REPLY, post));
} }
@ -332,7 +371,8 @@ public class ThreadDisplay extends SimpleComponent implements Constants {
long begin, long begin,
long end, long end,
long objectCount) { 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(); URL here = Web.getContext().getRequestURL();
ParameterMap params = new ParameterMap(here.getParameterMap()); ParameterMap params = new ParameterMap(here.getParameterMap());

View File

@ -47,55 +47,73 @@ import com.arsdigita.messaging.MessageThread;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
* Display for looking at a single thread and posting new messages and * A Bebop component which provides the dynamic parts of the UI for looking at
* replying to it. Contains MessagesComponent, EditPostForm, and * a single thread of the forum and posting new messages as well as replying to it.
* ReplyToPostForm * (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.MessagesComponent
* @see com.arsdigita.forum.ui.EditPostForm * @see com.arsdigita.forum.ui.EditPostForm
* @see com.arsdigita.forum.ui.ReplyToPostForm * @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. // References to sub-components for event access.
/** The message list component */
private Container m_threadView; private Container m_threadMessagesPanel;
/** The post component for a root mesage */
private PostForm m_rootForm; private PostForm m_rootForm;
/** The post component for a reply mesage */
private PostForm m_replyForm; private PostForm m_replyForm;
/** A message component for moderators */
private Form m_rejectForm; private Form m_rejectForm;
private static final Logger s_log /** */
= Logger.getLogger(ThreadComponent.class);
private ACSObjectSelectionModel m_postModel; 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. * 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. // Create a modal container: shows only one containee at a time.
m_postModel = new ACSObjectSelectionModel("post"); m_postModel = new ACSObjectSelectionModel("post");
initComponents(); initComponents();
} }
/**
* Internal helper method for constructor
* Add the thread components to the modal container and maintain
* references for event manipulation purposes.
*/
private void initComponents() { 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_rootForm = new RootPostForm(m_postModel);
m_replyForm = new ReplyToPostForm(m_postModel);
s_log.debug("creating reply to post form"); s_log.debug("creating reply to post form");
m_replyForm = new ReplyToPostForm(m_postModel);
s_log.debug("creating reject form"); s_log.debug("creating reject form");
m_rejectForm = new RejectionForm(m_postModel); m_rejectForm = new RejectionForm(m_postModel);
addForm(m_rootForm); addForm(m_rootForm);
addForm(m_replyForm); addForm(m_replyForm);
addForm(m_rejectForm); addForm(m_rejectForm);
m_threadView = new SimpleContainer(); m_threadMessagesPanel = new SimpleContainer();
Container linksPanel = new SimpleContainer(FORUM_XML_PREFIX + ":threadOptions", Container linksPanel = new SimpleContainer(FORUM_XML_PREFIX +
":threadOptions",
Constants.FORUM_XML_NS); Constants.FORUM_XML_NS);
// Offer links to return to index or control alerts. // Offer links to return to index or control alerts.
@ -110,16 +128,16 @@ public class ThreadComponent extends ModalContainer implements Constants {
linksPanel.add(subLinks); linksPanel.add(subLinks);
// Add the panel to the view. // Add the panel to the view.
m_threadView.add(linksPanel); m_threadMessagesPanel.add(linksPanel);
m_threadView.add(new ThreadDisplay(m_postModel, this)); m_threadMessagesPanel.add(new DiscussionPostsList(m_postModel, this));
add(m_threadView); add(m_threadMessagesPanel);
// The thread view is the default component. // The threadMessagesPanel is the default component.
setDefaultComponent(m_threadView); setDefaultComponent(m_threadMessagesPanel);
} }
public void makeListViewVisible(PageState state) { public void makeListViewVisible(PageState state) {
setVisibleComponent(state, m_threadView); setVisibleComponent(state, m_threadMessagesPanel);
} }
public void makeEditFormVisible(PageState state) { public void makeEditFormVisible(PageState state) {
@ -208,6 +226,7 @@ public class ThreadComponent extends ModalContainer implements Constants {
private Component createThreadUnsubscribeLink() { private Component createThreadUnsubscribeLink() {
ActionLink unsubscribeLink = new ActionLink( ActionLink unsubscribeLink = new ActionLink(
new Label(Text.gz("forum.ui.thread.unsubscribe"))) { new Label(Text.gz("forum.ui.thread.unsubscribe"))) {
@Override
public boolean isVisible(PageState s) { public boolean isVisible(PageState s) {
Party party = Kernel.getContext().getParty(); 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.switch.off=Ausschalten
forum.ui.moderate.status.on=Aktiv forum.ui.moderate.status.on=Aktiv
forum.ui.moderate.status.off=Inaktiv 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.label=Noticeboard functionality (Antworten deaktiviert)
forum.ui.noticeboard.switch.on=Turn on (disable replying) 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.ModerationView;
import com.arsdigita.forum.ui.admin.PermissionsView; import com.arsdigita.forum.ui.admin.PermissionsView;
import com.arsdigita.forum.ui.admin.SetupView; import com.arsdigita.forum.ui.admin.SetupView;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.Kernel; import com.arsdigita.kernel.Kernel;
import com.arsdigita.kernel.Party; import com.arsdigita.kernel.Party;
import com.arsdigita.kernel.permissions.PermissionDescriptor; import com.arsdigita.kernel.permissions.PermissionDescriptor;
@ -71,7 +72,8 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
public static final String MODE_ALERTS = "alerts"; public static final String MODE_ALERTS = "alerts";
/** Denominator of the 'moderation handling' forum mode */ /** Denominator of the 'moderation handling' forum mode */
public static final String MODE_MODERATION = "moderation"; 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"; public static final String MODE_PERMISSIONS = "permissions";
/** Denominator of the 'configuration' forum mode (administrators only)*/ /** Denominator of the 'configuration' forum mode (administrators only)*/
public static final String MODE_SETUP = "setup"; public static final String MODE_SETUP = "setup";
@ -167,6 +169,8 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
PermissionDescriptor forumAdmin = PermissionDescriptor forumAdmin =
new PermissionDescriptor(PrivilegeDescriptor.ADMIN, forum, party); new PermissionDescriptor(PrivilegeDescriptor.ADMIN, forum, party);
PermissionService.assertPermission(forumAdmin);
if (MODE_TOPICS.equals(mode)) { if (MODE_TOPICS.equals(mode)) {
if (Forum.getConfig().topicCreationByAdminOnly()) { if (Forum.getConfig().topicCreationByAdminOnly()) {
if (party == null) { if (party == null) {
@ -200,6 +204,7 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
PermissionService.assertPermission(forumAdmin); PermissionService.assertPermission(forumAdmin);
setVisibleComponent(state, m_setupView); setVisibleComponent(state, m_setupView);
} else if (MODE_THREADS.equals(mode)) { } else if (MODE_THREADS.equals(mode)) {
PermissionService.assertPermission(forumAdmin);
setVisibleComponent(state, m_threadsView); setVisibleComponent(state, m_threadsView);
} }
} }
@ -221,6 +226,7 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
"noticeboard", "noticeboard",
(new Boolean(forum.isNoticeboard())).toString()); (new Boolean(forum.isNoticeboard())).toString());
// If visitor not logged in, set user (=party) to publicUser
Party party = Kernel.getContext().getParty(); Party party = Kernel.getContext().getParty();
if (party == null) { if (party == null) {
party = Kernel.getPublicUser(); party = Kernel.getPublicUser();
@ -246,27 +252,34 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
PermissionDescriptor permission = PermissionDescriptor permission =
new PermissionDescriptor(PrivilegeDescriptor.ADMIN, forum, party); new PermissionDescriptor(PrivilegeDescriptor.ADMIN, forum, party);
// currently thread panel is alwasy shown. If read access should be // currently thread panel is always shown. If read access should be
// bound to logged in users, additional logic is frequired here. // bound to logged in users, additional logic is required here.
generateModeXML(state, content, MODE_THREADS); generateModeXML(state, content, MODE_THREADS,
Text.gz("forum.ui.modeThreads"));
// topics panel is always shoen as well if not restricted to admins. // topics panel is always shoen as well if not restricted to admins.
if (!Forum.getConfig().topicCreationByAdminOnly()) { 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. // 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 // admin section
if (PermissionService.checkPermission(permission)) { if (PermissionService.checkPermission(permission)) {
generateModeXML(state, content, MODE_MODERATION); generateModeXML(state, content, MODE_MODERATION,
Text.gz("forum.ui.modeAlerts"));
if (Forum.getConfig().showNewTabs()) { if (Forum.getConfig().showNewTabs()) {
generateModeXML(state, content, MODE_SETUP); generateModeXML(state, content, MODE_SETUP,
generateModeXML(state, content, MODE_PERMISSIONS); 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 // In case topic creation is bound to admin (and therefore not
// created above) we must create xml here. // created above) we must create xml here.
if (Forum.getConfig().topicCreationByAdminOnly()) { 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 parent
* @param mode forum mode (threadspanel, topicspanel, alertpanel, ...) to * @param mode forum mode (threadspanel, topicspanel, alertpanel, ...) to
* create entry for * create entry for
* @deprecated use generateModeXML(PageState, Element, String,
* GlobalizedMessage) instead
*/ */
protected void generateModeXML(PageState state, protected void generateModeXML(PageState state,
Element parent, Element parent,
String mode) { String mode) {
generateModeXML(state, parent, mode, null);
/*
String current = (String)state.getValue(m_mode); String current = (String)state.getValue(m_mode);
if (current == null) { if (current == null) {
current = MODE_THREADS; current = MODE_THREADS; // used as default mode
} }
Element content = Element content =
@ -297,20 +313,6 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
content.addAttribute("mode", content.addAttribute("mode",
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 { try {
content.addAttribute("url", content.addAttribute("url",
@ -321,7 +323,60 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
content.addAttribute("selected", content.addAttribute("selected",
current.equals(mode) ? "1" : "0"); current.equals(mode) ? "1" : "0");
state.clearControlEvent(); 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; m_post = post;
} }
@Override
public void register(Page page) { public void register(Page page) {
super.register(page); super.register(page);
if (m_postModel != null) { if (m_postModel != null) {
@ -56,6 +57,7 @@ class MessageView extends SimpleComponent implements Constants {
} }
} }
@Override
public void generateXML(PageState state, public void generateXML(PageState state,
Element parent) { Element parent) {
Message post = m_post; Message post = m_post;
@ -78,7 +80,7 @@ class MessageView extends SimpleComponent implements Constants {
xr.setWrapAttributes(true); xr.setWrapAttributes(true);
xr.setWrapObjects(false); 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 public class MessageXMLFormatter
extends SimpleDomainObjectXMLFormatter { extends SimpleDomainObjectXMLFormatter {
@Override
public Object format(DomainObject obj, public Object format(DomainObject obj,
String path, String path,
Property prop, Property prop,
@ -39,6 +40,7 @@ public class MessageXMLFormatter
return super.format(obj, path, prop, value); return super.format(obj, path, prop, value);
} }
@Override
public boolean isEmpty() { public boolean isEmpty() {
return false; return false;
} }

View File

@ -50,7 +50,7 @@ import java.math.BigDecimal;
* A paginator is added to handle a high number of threads. * 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 = private IntegerParameter m_pageNumber =
@ -81,9 +81,8 @@ public class ThreadList extends SimpleComponent implements Constants {
categoryID = null; categoryID = null;
} }
ThreadCollection threads = forum.getThreads( ThreadCollection threads = forum.getThreads(categoryID,
categoryID, Kernel.getContext().getParty());
Kernel.getContext().getParty());
return threads; return threads;
} }
@ -95,6 +94,7 @@ public class ThreadList extends SimpleComponent implements Constants {
*/ */
public void generateXML(PageState state, public void generateXML(PageState state,
Element parent) { Element parent) {
// Begin of thread list, XSL constructs (and localizes) the list title bar
Element content = parent.newChildElement(FORUM_XML_PREFIX + Element content = parent.newChildElement(FORUM_XML_PREFIX +
":threadList", FORUM_XML_NS); ":threadList", FORUM_XML_NS);
@ -130,11 +130,14 @@ public class ThreadList extends SimpleComponent implements Constants {
new Integer((int)end+1)); new Integer((int)end+1));
} }
while (threads.next()) { while (threads.next()) { // step through ThreadCollections
MessageThread thread = threads.getMessageThread(); MessageThread thread = threads.getMessageThread();
Element threadEl = content.newChildElement(FORUM_XML_PREFIX + Element threadEl = content.newChildElement(FORUM_XML_PREFIX +
":thread", FORUM_XML_NS); ":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(); ParameterMap map = new ParameterMap();
map.setParameter(THREAD_PARAM, thread.getID()); map.setParameter(THREAD_PARAM, thread.getID());
URL url = URL.there((Application)Kernel.getContext().getResource(), URL url = URL.there((Application)Kernel.getContext().getResource(),
@ -147,7 +150,7 @@ public class ThreadList extends SimpleComponent implements Constants {
xr.setWrapAttributes(true); xr.setWrapAttributes(true);
xr.setWrapObjects(false); 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; private ModalContainer m_mode;
/** Bebop Component, list of threads along with some othere elements, will /** Bebop Component, list of threads along with some othere elements, will
* be one child of ModalContainer */ * 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 /** Bebop Component, add new post to a thread form. Will be another child of
* ModalContainer */ * ModalContainer */
private PostForm m_postComponent; private PostForm m_postComponent;
@ -90,13 +90,13 @@ public class ThreadsPanel extends SimpleContainer
m_mode = new ModalContainer(); m_mode = new ModalContainer();
add(m_mode); add(m_mode);
m_threadsComponent = createThreadsComponent(); m_threadsListing = createThreadsListing();
m_postComponent = createPostComponent(); m_postComponent = createNewThreadForm();
m_mode.add(m_threadsComponent); m_mode.add(m_threadsListing);
m_mode.add(m_postComponent); 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_postComponent.setContext(s, PostForm.NEW_CONTEXT);
m_mode.setVisibleComponent(s, m_postComponent); m_mode.setVisibleComponent(s, m_postComponent);
} else { } 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 * with author, # of responses, etc. Filtered for approved
* messages if the forum is moderated. * messages if the forum is moderated.
*/ */
private Component createThreadsComponent() { private Component createThreadsListing() {
Container forums = new SimpleContainer(); Container forums = new SimpleContainer();
@ -166,8 +166,8 @@ public class ThreadsPanel extends SimpleContainer
TopicSelector topics = new TopicSelector(); TopicSelector topics = new TopicSelector();
forums.add(topics); forums.add(topics);
ThreadList threads ThreadsList threads
= new ThreadList(); = new ThreadsList();
forums.add(threads); 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(); PostForm editForm = new RootPostForm();
editForm.addCompletionListener(new ActionListener() { editForm.addCompletionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { 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. * 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. */ /** List of properties a topic may have. */
private final static Set s_catProps; private final static Set s_catProps;

View File

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

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-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 --> <!-- module ccm-forum - servlet declarations BEGIN -->
<servlet> <servlet>

View File

@ -4,11 +4,11 @@
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"> 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/bebop/xsl/bebop.xsl"/>
<xsl:import href="../../../../ROOT/packages/ui/xsl/ui.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/bebop/xsl/bebop.xsl"/>
<xsl:import href="../../../packages/ui/xsl/ui.xsl"/> <xsl:import href="../../../packages/ui/xsl/ui.xsl"/>