Verschiedene Formatierungen und Dokumentationsergänzungen.

git-svn-id: https://svn.libreccm.org/ccm/trunk@542 8810af33-2d31-482b-a856-94f89814c4df
master
pb 2010-09-26 23:27:08 +00:00
parent 5424b1ea64
commit 1804c32331
10 changed files with 518 additions and 456 deletions

View File

@ -115,7 +115,10 @@ public class PrivilegeDescriptor {
priv.set("privilege", name); priv.set("privilege", name);
priv.save(); priv.save();
addChildPrivilege(ADMIN_NAME, name); addChildPrivilege(ADMIN_NAME, name);
PrivilegeDescriptor desc = new PrivilegeDescriptor(name); // Constructor PrivilegeDescriptor is deprecated and should be
// replace the class method get(name)
// PrivilegeDescriptor desc = new PrivilegeDescriptor(name);
PrivilegeDescriptor desc = get(name);
put(desc); put(desc);
return desc; return desc;
} }
@ -145,7 +148,6 @@ public class PrivilegeDescriptor {
} }
/** /**
*
* Given a privilege name, returns a privilege descriptor or null * Given a privilege name, returns a privilege descriptor or null
* if the privilege does not exist on the system. * if the privilege does not exist on the system.
* *
@ -159,19 +161,17 @@ public class PrivilegeDescriptor {
} }
/** /**
*
* Returns a collection of privilege descriptors for every privilege in * Returns a collection of privilege descriptors for every privilege in
* the system. * the system.
* @return a collection of privilege descriptors.
*
* @see #get(String) * @see #get(String)
*
* @return a collection of privilege descriptors.
*/ */
public static Collection getAll() { public static Collection getAll() {
return s_privs.values(); return s_privs.values();
} }
/** /**
*
* Deletes the privilege described by this from the system. * Deletes the privilege described by this from the system.
* *
* @exception PersistenceException when there is a persistence * @exception PersistenceException when there is a persistence
@ -185,9 +185,9 @@ public class PrivilegeDescriptor {
OID oid = new OID("com.arsdigita.kernel.permissions.Privilege", OID oid = new OID("com.arsdigita.kernel.permissions.Privilege",
m_name); m_name);
DataObject priv = SessionManager.getSession() DataObject priv = SessionManager.getSession().retrieve(oid);
.retrieve(oid);
priv.delete(); priv.delete();
s_privs.remove(m_name); s_privs.remove(m_name);
} }
@ -201,14 +201,11 @@ public class PrivilegeDescriptor {
} }
/** /**
* <br>
*
* Returns the display name for the privilege, or just the * Returns the display name for the privilege, or just the
* privilege name if no display name is defined. * privilege name if no display name is defined.
* *
* @return the display name * @return the display name
*/ */
public String getDisplayName() { public String getDisplayName() {
if (m_displayName != null) { if (m_displayName != null) {
return m_displayName; return m_displayName;
@ -261,8 +258,8 @@ public class PrivilegeDescriptor {
* Create a new privilege descriptor for use with PermissionDescriptor * Create a new privilege descriptor for use with PermissionDescriptor
* and PermissionService. * and PermissionService.
* *
* @deprecated see #get
* @param name The name of the privilege. * @param name The name of the privilege.
* @deprecated see #get
**/ **/
public PrivilegeDescriptor(String name) { public PrivilegeDescriptor(String name) {
m_name = name; m_name = name;
@ -281,9 +278,8 @@ public class PrivilegeDescriptor {
} }
/** /**
* * Puts a privilege descriptor into the internal cache that is used by
* Puts a privilege descriptor into the internal cache that is * the get method. The put method supports extendibility by allowing
* used by the get method. The put method supports extendibility by allowing
* subclasses to be returned by the get method. * subclasses to be returned by the get method.
*/ */
protected static void put(PrivilegeDescriptor privDesc) { protected static void put(PrivilegeDescriptor privDesc) {
@ -291,7 +287,6 @@ public class PrivilegeDescriptor {
} }
/** /**
*
* Returns the list of privilege names that imply this privilege. * Returns the list of privilege names that imply this privilege.
* @return a collection of the privilege names that imply this privilege. * @return a collection of the privilege names that imply this privilege.
*/ */
@ -349,5 +344,4 @@ public class PrivilegeDescriptor {
privs.close(); privs.close();
} }
} }

View File

@ -85,6 +85,13 @@ public class Application extends Resource {
return BASE_DATA_OBJECT_TYPE; return BASE_DATA_OBJECT_TYPE;
} }
/**
* Creates a new Application instance encapsulating the given data object.
* @see com.arsdigita.persistence.Session#retrieve(String)
*
* @param dataObject The data object to encapsulate in the Forum instance
* (new domain object).
*/
protected Application(DataObject dataObject) { protected Application(DataObject dataObject) {
super(dataObject); super(dataObject);
} }

View File

@ -51,6 +51,9 @@ import com.arsdigita.web.Application;
/** /**
* Main domain class of a forum application representing a discussion forum. * Main domain class of a forum application representing a discussion forum.
* *
* It manages creation of new forum instances and provides getters and setters
* for instance specific configuration options.
*
* 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
* theme. Currently Forum uses <i>catgegory</i> as synonym for topic, which may be * theme. Currently Forum uses <i>catgegory</i> as synonym for topic, which may be
@ -63,7 +66,6 @@ import com.arsdigita.web.Application;
* @version $Revision: 1.7 $ * @version $Revision: 1.7 $
* @version $Id: Forum.java 1628 2007-09-17 08:10:40Z chrisg23 $ * @version $Id: Forum.java 1628 2007-09-17 08:10:40Z chrisg23 $
*/ */
public class Forum extends Application { public class Forum extends Application {
/** Private logger instance for debugging purpose */ /** Private logger instance for debugging purpose */
@ -86,12 +88,12 @@ public class Forum extends Application {
} }
////// //////
//Forum specific privileges //Forum specific privileges
///// /////
public static final String FORUM_MODERATION_PRIVILEGE = "forum_moderation"; public static final String FORUM_MODERATION_PRIVILEGE = "forum_moderation";
public static final String CREATE_THREAD_PRIVILEGE = "forum_create_thread"; public static final String CREATE_THREAD_PRIVILEGE = "forum_create_thread";
public static final String RESPOND_TO_THREAD_PRIVILEGE = "forum_respond"; public static final String RESPOND_TO_THREAD_PRIVILEGE = "forum_respond";
// separate read privilege required because all public users // separate read privilege required because all public users
// have READ on homepage, which is parent of forum, hence // have READ on homepage, which is parent of forum, hence
// everyone inherits READ cg // everyone inherits READ cg
@ -106,50 +108,77 @@ public class Forum extends Application {
// pb: Reactivated READ privilege in order to provide forums for different // pb: Reactivated READ privilege in order to provide forums for different
// groups of users for their internal use and to provide private forums // groups of users for their internal use and to provide private forums
// for logged in users only (no public read access). // for logged in users only (no public read access).
public static final String FORUM_READ_PRIVILEGE = "forum_read"; public static final String FORUM_READ_PRIVILEGE = "forum_read";
/////// ///////
// pdl forum attribute/association names // pdl forum attribute/association names
/////// ///////
private static final String POSTS = "posts"; private static final String POSTS = "posts";
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 = "fileAttachmentsAllowed"; private static final String ALLOW_FILE_ATTACHMENTS = "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";
/** /**
* Creates a new Forum instance encapsulating the given data object.
* @see com.arsdigita.persistence.Session#retrieve(String)
* *
* @param data * @param data The data object to encapsulate in the Forum instance
* (new domain object).
*/ */
public Forum(DataObject data) { public Forum(DataObject data) {
super(data); super(data);
} }
/**
* The contained <code>DataObject</code> is retrieved from the
* persistent storage mechanism with an OID specified by <i>oid</i>.
*
* @param oid The <code>OID</code> for the retrieved
* <code>DataObject</code>.
*
* @exception DataObjectNotFoundException Thrown if we cannot
* retrieve a data object for the specified OID
*/
public Forum(OID oid) throws DataObjectNotFoundException { public Forum(OID oid) throws DataObjectNotFoundException {
super(oid); super(oid);
} }
/**
* Retrieves a Forum instance (its contained DataObject) based on its
* internal id which is used to search for the OID.
*
* @param id
* @throws DataObjectNotFoundException
*/
public Forum(BigDecimal id) throws DataObjectNotFoundException { public Forum(BigDecimal id) throws DataObjectNotFoundException {
super(new OID(BASE_DATA_OBJECT_TYPE, id)); super(new OID(BASE_DATA_OBJECT_TYPE, id));
} }
/**
*
* @param urlName of the forum to be created
* @param title of forum to be created
* @param parent object of forum to be created
* @return
*/
public static Forum create(String urlName, String title, public static Forum create(String urlName, String title,
Application parent) { Application parent) {
return create(urlName, title, parent, false); return create(urlName, title, parent, false);
@ -159,28 +188,30 @@ public class Forum extends Application {
* This method should be used to create a new Forum object everywhere * This method should be used to create a new Forum object everywhere
* except in the constructor of a subclass of Forum. * except in the constructor of a subclass of Forum.
* This will by default create a new Category which will be the root * This will by default create a new Category which will be the root
* category for the Forum in the event that the Forum should be * category for the Forum in the event that the Forum should be categorized.
* categorized. *
* This also sets up instant and daily subscriptions on the Forum. * This also sets up instant and daily subscriptions on the Forum.
* The default for moderation is false. * The default for moderation is false.
* *
* Also sets default values for other forum settings. These can be * Also sets default values for other forum settings. These can be
* amended under the setup tab in the ui * amended under the setup tab in the ui
*/ */
public static Forum create(String urlName, String title, public static Forum create(String urlName, String title,
Application parent, boolean moderated) { Application parent, boolean moderated) {
s_log.debug("creating forum " + title); s_log.debug("creating forum " + title);
Forum forum = (Forum) Application.createApplication
(BASE_DATA_OBJECT_TYPE, urlName, title, parent, true); Forum forum = (Forum) Application.createApplication(BASE_DATA_OBJECT_TYPE,
urlName,
title, parent, true);
forum.setModerated(moderated); forum.setModerated(moderated);
// default settings ensure legacy forum users do not // default settings ensure legacy forum users do not
// see any change chris.gilbert@westsussex.gov.uk // see any change chris.gilbert@westsussex.gov.uk
forum.setAllowFileAttachments(false); forum.setAllowFileAttachments(false);
forum.setAllowImageUploads(false); forum.setAllowImageUploads(false);
forum.setAutoSubscribeThreadCreator(false); forum.setAutoSubscribeThreadCreator(false);
forum.setNoCategoryPostsAllowed(true); forum.setNoCategoryPostsAllowed(true);
forum.setAnonymousPostsAllowed(false); forum.setAnonymousPostsAllowed(false);
return forum; return forum;
} }
@ -208,22 +239,20 @@ public class Forum extends Application {
} }
/** /**
* Set introduction * Set introduction
*/ */
public void setIntroduction(String introduction) { public void setIntroduction(String introduction) {
set(INTRODUCTION, introduction); set(INTRODUCTION, introduction);
} }
/** /**
* @return introduction * @return introduction
*/ */
public String getIntroduction() {
return (String) get(INTRODUCTION);
}
public String getIntroduction() { /**
return (String) get(INTRODUCTION);
}
/**
* creates a Root Category for the forum. * creates a Root Category for the forum.
*/ */
private Category createRootCategory() { private Category createRootCategory() {
@ -235,13 +264,14 @@ public class Forum extends Application {
return category; return category;
} }
/** /**
* *
*/ */
private void createGroups() { private void createGroups() {
Group administrators = new Group();
administrators.setName(getTitle() + " Administrators"); Group administrators = new Group();
setAssociation(ADMIN_GROUP, administrators); administrators.setName(getTitle() + " Administrators");
setAssociation(ADMIN_GROUP, administrators);
Group moderators = new Group(); Group moderators = new Group();
moderators.setName(getTitle() + " Moderators"); moderators.setName(getTitle() + " Moderators");
@ -258,35 +288,34 @@ public class Forum extends Application {
moderators.getID() + "@" + s_config.getReplyHostName(); moderators.getID() + "@" + s_config.getReplyHostName();
moderators.setPrimaryEmail(new EmailAddress(email)); moderators.setPrimaryEmail(new EmailAddress(email));
// chris.gilbert@westsussex.gov.uk create additional groups for privilege // chris.gilbert@westsussex.gov.uk create additional groups for privilege
// assignment - could have assigned privileges directly without having associated // assignment - could have assigned privileges directly without having
// groups, but this reduces rows in the (already enormous) dnm_permissions // associated groups, but this reduces rows in the (already enormous)
// table // dnm_permissions table
Group threadCreators = new Group(); Group threadCreators = new Group();
threadCreators.setName(getTitle() + " Thread Creators"); threadCreators.setName(getTitle() + " Thread Creators");
setAssociation(THREAD_CREATE_GROUP, threadCreators); setAssociation(THREAD_CREATE_GROUP, threadCreators);
Group threadResponders = new Group(); Group threadResponders = new Group();
threadResponders.setName(getTitle() + " Thread Responders"); threadResponders.setName(getTitle() + " Thread Responders");
setAssociation(THREAD_RESPONDER_GROUP, threadResponders); setAssociation(THREAD_RESPONDER_GROUP, threadResponders);
Group forumReaders = new Group(); Group forumReaders = new Group();
forumReaders.setName(getTitle() + " Readers"); forumReaders.setName(getTitle() + " Readers");
setAssociation(READ_GROUP, forumReaders); setAssociation(READ_GROUP, forumReaders);
Group container = getGroup();
container.addSubgroup(administrators);
container.addSubgroup(moderators);
container.addSubgroup(threadCreators);
container.addSubgroup(threadResponders);
container.addSubgroup(forumReaders);
Group threadSubscriptions = new Group();
threadSubscriptions.setName(THREAD_SUBSCRIPTION_GROUPS_NAME);
container.addSubgroup(threadSubscriptions);
container.save();
Group container = getGroup(); // Application.getGroup(): get group
// associated with this application
container.addSubgroup(administrators);
container.addSubgroup(moderators);
container.addSubgroup(threadCreators);
container.addSubgroup(threadResponders);
container.addSubgroup(forumReaders);
Group threadSubscriptions = new Group();
threadSubscriptions.setName(THREAD_SUBSCRIPTION_GROUPS_NAME);
container.addSubgroup(threadSubscriptions);
container.save();
} }
@ -297,11 +326,11 @@ public class Forum extends Application {
if (isNew()) { if (isNew()) {
setModerated(false); setModerated(false);
setNoticeboard(false); setNoticeboard(false);
setAllowFileAttachments(false); setAllowFileAttachments(false);
setAllowImageUploads(false); setAllowImageUploads(false);
setAutoSubscribeThreadCreator(false); setAutoSubscribeThreadCreator(false);
setNoCategoryPostsAllowed(true); setNoCategoryPostsAllowed(true);
setAnonymousPostsAllowed(false); setAnonymousPostsAllowed(false);
createRootCategory(); createRootCategory();
} }
@ -315,76 +344,85 @@ public class Forum extends Application {
super.beforeSave(); super.beforeSave();
} }
/**
*
*/
@Override @Override
protected void afterSave() { protected void afterSave() {
if (m_wasNew) { if (m_wasNew) {
PermissionService.setContext(getRootCategory(), this); PermissionService.setContext(getRootCategory(), this);
createGroups(); createGroups();
if (getAdminGroup() != null) { if (getAdminGroup() != null) {
PermissionService.grantPermission( PermissionService.grantPermission( new PermissionDescriptor(
new PermissionDescriptor( PrivilegeDescriptor.ADMIN,
PrivilegeDescriptor.ADMIN, this,
this, getAdminGroup()));
getAdminGroup())); s_log.debug("Current user : "
s_log.debug( + Kernel.getContext().getParty().getPrimaryEmail()
"Current user : " + " class is "
+ Kernel.getContext().getParty().getPrimaryEmail() + Kernel.getContext().getParty().getClass());
+ " class is "
+ Kernel.getContext().getParty().getClass()); //
// // chris.gilbert@westsussex.gov.uk Original plan was that
// chris.gilbert@westsussex.gov.uk Original plan was that creator of forum // creator of forum is administrator by default,
// is administrator by default, but party from Kernel at this point in code is // but party from Kernel at this point in code is
// acs-system-party - creation must happen in a KernelExcersion somewhere // acs-system-party - creation must happen in a KernelExcersion
// though I can't immediately see where. // somewhere though I can't immediately see where.
// as a consequence, code below justs causes a classcast exception, // As a consequence, code below justs causes a classcast exception,
// //
// revisit, but in meantime, only site admin can administer new forum // revisit, but in meantime, only site admin can administer new forum
// until forum admin permissions set in UI // until forum admin permissions set in UI
// //
// User creator = (User) Kernel.getContext().getParty(); // User creator = (User) Kernel.getContext().getParty();
// can't be null but let's be supercautious // can't be null but let's be supercautious
// if (creator != null) { // if (creator != null) {
// getAdminGroup().addMember(creator); // getAdminGroup().addMember(creator);
// } // }
/// //
} }
if (getModerationGroup() != null ) { if (getModerationGroup() != null ) {
PermissionService.grantPermission( PermissionService.grantPermission(
new PermissionDescriptor( new PermissionDescriptor(
PrivilegeDescriptor.get(FORUM_MODERATION_PRIVILEGE), PrivilegeDescriptor.get(
this, FORUM_MODERATION_PRIVILEGE),
getModerationGroup())); this,
} getModerationGroup()));
if (getThreadCreateGroup() != null) {
PermissionService.grantPermission(
new PermissionDescriptor(
PrivilegeDescriptor.get(CREATE_THREAD_PRIVILEGE),
this,
getThreadCreateGroup()));
// chris.gilbert@westsussex.gov.uk
// wouldn't do this normally, but this enables legacy implementations
// to use new version without any side effects
// public can view forum by default and see create thread link - existing
// code forces login if link is selected
getThreadCreateGroup().addMember(Kernel.getPublicUser());
}
if (getThreadResponderGroup() != null) {
PermissionService.grantPermission(
new PermissionDescriptor(
PrivilegeDescriptor.get(RESPOND_TO_THREAD_PRIVILEGE),
this,
getThreadResponderGroup()));
}
if (getReadGroup() != null) {
PermissionService.grantPermission(
new PermissionDescriptor(
PrivilegeDescriptor.READ,
this,
getReadGroup()));
} }
if (getThreadCreateGroup() != null) {
PermissionService.grantPermission(
new PermissionDescriptor(
PrivilegeDescriptor.get(
CREATE_THREAD_PRIVILEGE),
this,
getThreadCreateGroup()));
// chris.gilbert@westsussex.gov.uk
// wouldn't do this normally, but this enables legacy implementations
// to use new version without any side effects
// public can view forum by default and see create thread link - existing
// code forces login if link is selected
getThreadCreateGroup().addMember(Kernel.getPublicUser());
}
if (getThreadResponderGroup() != null) {
PermissionService.grantPermission(
new PermissionDescriptor(
PrivilegeDescriptor.get(
RESPOND_TO_THREAD_PRIVILEGE),
this,
getThreadResponderGroup()));
}
if (getReadGroup() != null) {
PermissionService.grantPermission(
new PermissionDescriptor(
PrivilegeDescriptor.READ,
this,
getReadGroup()));
}
KernelExcursion excursion = new KernelExcursion() { KernelExcursion excursion = new KernelExcursion() {
protected void excurse() { protected void excurse() {
setParty(Kernel.getSystemParty()); setParty(Kernel.getSystemParty());
@ -402,9 +440,9 @@ public class Forum extends Application {
// } // }
} }
}; };
excursion.run(); excursion.run();
} } //if mWasNew
DataCollection subs = null; DataCollection subs = null;
try { try {
@ -420,16 +458,15 @@ public class Forum extends Application {
} }
// chris.gilbert@westsussex.gov.uk line removed. // chris.gilbert@westsussex.gov.uk line removed.
// afterSave in Application sets permission // afterSave in Application sets permission
// context of forum to parent app (portal homepage) // context of forum to parent app (portal homepage)
// don't want to inherit permissions of portal, // don't want to inherit permissions of portal,
// as public users have 'READ' privilege on this // as public users have 'READ' privilege on this
// and so get shown postings in search results. // and so get shown postings in search results.
// // super.afterSave();
//
// super.afterSave(); } //Method afterSave()
}
protected String getBaseDataObjectType() { protected String getBaseDataObjectType() {
return BASE_DATA_OBJECT_TYPE; return BASE_DATA_OBJECT_TYPE;
@ -472,37 +509,37 @@ public class Forum extends Application {
} }
/** /**
* gets all pending messages and messages for reapproval - allows * gets all pending messages and messages for reapproval - allows
* moderators to see which messages require their attention * moderators to see which messages require their attention
* @return * @return
*/ */
public DataAssociation getPendingPosts() { public DataAssociation getPendingPosts() {
// doesn't use getPosts in view of the warning that it // doesn't use getPosts in view of the warning that it
// may disappear // may disappear
DataAssociation posts = (DataAssociation) get(POSTS); DataAssociation posts = (DataAssociation) get(POSTS);
FilterFactory factory = posts.getFilterFactory(); FilterFactory factory = posts.getFilterFactory();
Filter pending = factory.equals(Post.STATUS, Post.PENDING); Filter pending = factory.equals(Post.STATUS, Post.PENDING);
Filter reapprove = factory.equals(Post.STATUS, Post.REAPPROVE); Filter reapprove = factory.equals(Post.STATUS, Post.REAPPROVE);
posts.addFilter(factory.or().addFilter(pending).addFilter(reapprove)); posts.addFilter(factory.or().addFilter(pending).addFilter(reapprove));
return posts; return posts;
} }
/** /**
* gets all suppressed messages - allows moderators to see which messages * gets all suppressed messages - allows moderators to see which messages
* heve been rejected / require their attention * heve been rejected / require their attention
* @return * @return
*/ */
public DataAssociation getSuppressedPosts() { public DataAssociation getSuppressedPosts() {
// doesn't use getPosts in view of the warning that it // doesn't use getPosts in view of the warning that it
// may disappear // may disappear
DataAssociation posts = (DataAssociation) get(POSTS); DataAssociation posts = (DataAssociation) get(POSTS);
posts.addEqualsFilter(Post.STATUS, Post.SUPPRESSED); posts.addEqualsFilter(Post.STATUS, Post.SUPPRESSED);
return posts; return posts;
} }
/** /**
* Gets a ThreadCollection of the threads in this forum. I.e. the * Gets a ThreadCollection of the threads in this forum. I.e. the
* top-level posts which are not replies to any other post. * top-level posts which are not replies to any other post.
*/ */
@ -743,12 +780,13 @@ public class Forum extends Application {
return Boolean.TRUE.equals(get(NOTICEBOARD)); return Boolean.TRUE.equals(get(NOTICEBOARD));
} }
/** Returns the administrator group. Null if it doesn't exist */ /** Returns the administrator group. Null if it doesn't exist */
public Group getAdminGroup() { public Group getAdminGroup() {
DataObject dObj = (DataObject) get(ADMIN_GROUP); DataObject dObj = (DataObject) get(ADMIN_GROUP);
Assert.exists(dObj, DataObject.class); Assert.exists(dObj, DataObject.class);
return (Group) DomainObjectFactory.newInstance(dObj); return (Group) DomainObjectFactory.newInstance(dObj);
} }
/** Returns the moderator group. Null if it doesn't exist */ /** Returns the moderator group. Null if it doesn't exist */
public Group getModerationGroup() { public Group getModerationGroup() {
DataObject dObj = (DataObject) get( MODERATION_GROUP ); DataObject dObj = (DataObject) get( MODERATION_GROUP );
@ -756,26 +794,26 @@ public class Forum extends Application {
return (Group)DomainObjectFactory.newInstance(dObj); return (Group)DomainObjectFactory.newInstance(dObj);
} }
/** Returns the thread create group. Null if it doesn't exist */ /** Returns the thread create group. Null if it doesn't exist */
public Group getThreadCreateGroup() { public Group getThreadCreateGroup() {
DataObject dObj = (DataObject) get(THREAD_CREATE_GROUP); DataObject dObj = (DataObject) get(THREAD_CREATE_GROUP);
Assert.exists(dObj, DataObject.class); Assert.exists(dObj, DataObject.class);
return (Group) DomainObjectFactory.newInstance(dObj); return (Group) DomainObjectFactory.newInstance(dObj);
} }
/** Returns the thread reply group. Null if it doesn't exist */ /** Returns the thread reply group. Null if it doesn't exist */
public Group getThreadResponderGroup() { public Group getThreadResponderGroup() {
DataObject dObj = (DataObject) get(THREAD_RESPONDER_GROUP); DataObject dObj = (DataObject) get(THREAD_RESPONDER_GROUP);
Assert.exists(dObj, DataObject.class); Assert.exists(dObj, DataObject.class);
return (Group) DomainObjectFactory.newInstance(dObj); return (Group) DomainObjectFactory.newInstance(dObj);
} }
/** Returns the read group. Null if it doesn't exist */ /** Returns the read group. Null if it doesn't exist */
public Group getReadGroup() { public Group getReadGroup() {
DataObject dObj = (DataObject) get(READ_GROUP); DataObject dObj = (DataObject) get(READ_GROUP);
Assert.exists(dObj, DataObject.class); Assert.exists(dObj, DataObject.class);
return (Group) DomainObjectFactory.newInstance(dObj); return (Group) DomainObjectFactory.newInstance(dObj);
} }
public void setExpireAfter(int value) { public void setExpireAfter(int value) {
set(EXPIRE_AFTER, new BigDecimal(value)); set(EXPIRE_AFTER, new BigDecimal(value));
@ -800,20 +838,14 @@ public class Forum extends Application {
// have the same expiration policy. // have the same expiration policy.
DataAssociationCursor posts = getPosts().cursor(); DataAssociationCursor posts = getPosts().cursor();
while (posts.next()) { while (posts.next()) {
Post post = Post post = (Post) DomainObjectFactory.newInstance(posts.getDataObject());
(Post) DomainObjectFactory.newInstance(posts.getDataObject()); if (post.getThread().getRootMessage().getID()
if (post .equals(post.getID())) {
.getThread() s_log.debug("Resetting expiration lifecycle for " + post.getOID());
.getRootMessage() post.setLifecycle(newLife);
.getID() }
.equals(post.getID())) {
s_log.debug(
"Resetting expiration lifecycle for " + post.getOID());
post.setLifecycle(newLife);
} }
} }
}
public int getExpireAfter() { public int getExpireAfter() {
BigDecimal expire = (BigDecimal) get(EXPIRE_AFTER); BigDecimal expire = (BigDecimal) get(EXPIRE_AFTER);
@ -836,66 +868,70 @@ public class Forum extends Application {
set(LIFECYCLE_DEFINITION, life); set(LIFECYCLE_DEFINITION, life);
} }
/** /**
* method required for upgrade - normally groups are set during * method required for upgrade - normally groups are set during
* forum creation and so there is no need to invoke a setter * forum creation and so there is no need to invoke a setter
* @author cgyg9330 * @author cgyg9330
* *
*/ */
public void setAdminGroup(Group group) { public void setAdminGroup(Group group) {
setAssociation(ADMIN_GROUP, group); setAssociation(ADMIN_GROUP, group);
PermissionService.grantPermission( PermissionService.grantPermission(
new PermissionDescriptor(PrivilegeDescriptor.ADMIN, this, group)); new PermissionDescriptor(PrivilegeDescriptor.ADMIN, this, group));
} }
/**
* method required for upgrade - normally groups are set during /**
* forum creation and so there is no need to invoke a setter * method required for upgrade - normally groups are set during
* @author cgyg9330 * forum creation and so there is no need to invoke a setter
* * @author cgyg9330
*/ *
public void setThreadCreatorGroup(Group group) { */
setAssociation(THREAD_CREATE_GROUP, group); public void setThreadCreatorGroup(Group group) {
PermissionService.grantPermission( setAssociation(THREAD_CREATE_GROUP, group);
new PermissionDescriptor( PermissionService.grantPermission(
new PermissionDescriptor(
PrivilegeDescriptor.get(CREATE_THREAD_PRIVILEGE), PrivilegeDescriptor.get(CREATE_THREAD_PRIVILEGE),
this, this,
group)); group));
} }
/**
* method required for upgrade - normally groups are set during forum
* creation and so there is no need to invoke a setter
* @author cgyg9330
*
*/
public void setThreadResponderGroup(Group group) {
setAssociation(THREAD_RESPONDER_GROUP, group);
PermissionService.grantPermission(
new PermissionDescriptor(
PrivilegeDescriptor.get(RESPOND_TO_THREAD_PRIVILEGE),
this,
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
* @author cgyg9330
*
*/
public void setReaderGroup(Group group) {
setAssociation(READ_GROUP, group);
PermissionService.grantPermission(
new PermissionDescriptor(PrivilegeDescriptor.READ, this, group));
}
/** /**
* @return * method required for upgrade - normally groups are set during forum
*/ * creation and so there is no need to invoke a setter
public boolean allowFileAttachments() { * @author cgyg9330
return ((Boolean) get(ALLOW_FILE_ATTACHMENTS)).booleanValue(); *
} */
public boolean allowImageUploads() { public void setThreadResponderGroup(Group group) {
return ((Boolean) get(ALLOW_IMAGE_UPLOADS)).booleanValue(); setAssociation(THREAD_RESPONDER_GROUP, group);
} PermissionService.grantPermission(
new PermissionDescriptor(
PrivilegeDescriptor.get(RESPOND_TO_THREAD_PRIVILEGE),
this,
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
* @author cgyg9330
*
*/
public void setReaderGroup(Group group) {
setAssociation(READ_GROUP, group);
PermissionService.grantPermission(
new PermissionDescriptor(
PrivilegeDescriptor.READ, this, group));
}
/**
* @return
*/
public boolean allowFileAttachments() {
return ((Boolean) get(ALLOW_FILE_ATTACHMENTS)).booleanValue();
}
public boolean allowImageUploads() {
return ((Boolean) get(ALLOW_IMAGE_UPLOADS)).booleanValue();
}
public boolean autoSubscribeThreadStarter() { public boolean autoSubscribeThreadStarter() {
return ((Boolean) get(AUTOSUBSCRIBE_THREAD_STARTER)).booleanValue(); return ((Boolean) get(AUTOSUBSCRIBE_THREAD_STARTER)).booleanValue();
@ -922,33 +958,39 @@ public class Forum extends Application {
set(NO_CATEGORY_POSTS, new Boolean(allow)); set(NO_CATEGORY_POSTS, new Boolean(allow));
} }
public void setAnonymousPostsAllowed(boolean allow) { public void setAnonymousPostsAllowed(boolean allow) {
set(ANONYMOUS_POSTS, new Boolean(allow)); set(ANONYMOUS_POSTS, new Boolean(allow));
} }
public void setTitle (String title) { public void setTitle (String title) {
String oldTitle = getTitle(); String oldTitle = getTitle();
super.setTitle(title); super.setTitle(title);
if (!oldTitle.equals(title)) { if (!oldTitle.equals(title)) {
// 1. rename permission groups // 1. rename permission groups
getAdminGroup().setName(title + " Administrators"); getAdminGroup().setName(title + " Administrators");
getModerationGroup().setName(title + " Moderators"); getModerationGroup().setName(title + " Moderators");
getThreadCreateGroup().setName(title + " Thread Creators"); getThreadCreateGroup().setName(title + " Thread Creators");
getThreadResponderGroup().setName(title + " Thread Responders"); getThreadResponderGroup().setName(title + " Thread Responders");
getReadGroup().setName(title + " Readers"); getReadGroup().setName(title + " Readers");
DataCollection subscriptions = getSubscriptions();
while (subscriptions.next()) {
ForumSubscription subscription = (ForumSubscription)DomainObjectFactory.newInstance(subscriptions.getDataObject());
subscription.getGroup().setName(subscription.getGroupName(this));
}
ThreadCollection threads = getThreads();
while (threads.next()) {
ThreadSubscription threadSub = ThreadSubscription.getThreadSubscription(threads.getMessageThread());
threadSub.getGroup().setName(threadSub.getSubscriptionGroupName(this));
} DataCollection subscriptions = getSubscriptions();
while (subscriptions.next()) {
ForumSubscription
subscription = (ForumSubscription)DomainObjectFactory.
newInstance(subscriptions.getDataObject());
subscription.getGroup().setName(subscription.getGroupName(this));
}
} ThreadCollection threads = getThreads();
while (threads.next()) {
ThreadSubscription threadSub = ThreadSubscription.
getThreadSubscription(
threads.getMessageThread());
threadSub.getGroup().setName(threadSub.getSubscriptionGroupName(this));
}
}
} }

View File

@ -77,6 +77,11 @@ public class ForumPageBuilder implements PageBuilder, Constants {
page.add(forumComp); page.add(forumComp);
BigDecimalParameter topic = new BigDecimalParameter(TOPIC_PARAM); BigDecimalParameter topic = new BigDecimalParameter(TOPIC_PARAM);
page.addGlobalStateParam(topic); page.addGlobalStateParam(topic);
// adds primitive READ descriptor, should be FORUM_READ instead in order
// to allow forum specific READ access and forums not accessible to
// the public, not logged-in user.
// PrivilegeDescriptor.get(RESPOND_TO_THREAD_PRIVILEGE)
// PrivilegeDescriptor.get(FORUM_READ_PRIVILEGE)
page.addRequestListener( page.addRequestListener(
new ApplicationAuthenticationListener(PrivilegeDescriptor.READ)); new ApplicationAuthenticationListener(PrivilegeDescriptor.READ));
page.addRequestListener(new ForumPageRequestListener(topic, forumComp)); page.addRequestListener(new ForumPageRequestListener(topic, forumComp));

View File

@ -111,7 +111,7 @@ public class Initializer extends CompoundInitializer {
} }
}); });
e.getFactory().registerInstantiator( // OOPS: inbox commented out in e.getFactory().registerInstantiator( // OOPS: inbox commented out in
"com.arsdigita.forum.Inbox", // Forum loader! "com.arsdigita.forum.Inbox", // Forum loader! see Inbox.pdl
new ACSObjectInstantiator() { new ACSObjectInstantiator() {
public DomainObject doNewInstance(DataObject dataObject) { public DomainObject doNewInstance(DataObject dataObject) {
return new Forum(dataObject); return new Forum(dataObject);

View File

@ -62,7 +62,7 @@ public class Loader extends PackageLoader {
setupPrivileges(); setupPrivileges();
setupForumAppType(); setupForumAppType();
//setupInboxAppType(); //setupInboxAppType(); //TODO: why it is commented out?
setupRecentPostingsPortletType(); setupRecentPostingsPortletType();
setupMyForumsPortletType(); setupMyForumsPortletType();
setupDigestUser(); setupDigestUser();
@ -87,7 +87,7 @@ public class Loader extends PackageLoader {
/** /**
* * TODO: What is it for? Execution is currently commented out.
* @return * @return
*/ */
private static ApplicationType setupInboxAppType() { private static ApplicationType setupInboxAppType() {
@ -136,11 +136,11 @@ public class Loader extends PackageLoader {
// Email address corresponding to the digest sender, as // Email address corresponding to the digest sender, as
// specified in the configuration file. // specified in the configuration file.
String email = Forum.getConfig().getDigestUserEmail(); String email = Forum.getConfig().getDigestUserEmail();
UserCollection users = User.retrieveAll(); UserCollection users = User.retrieveAll();
users.addEqualsFilter("primaryEmail", email); users.addEqualsFilter("primaryEmail", email);
if (users.next()) { if (users.next()) {
s_log.debug("user exists"); s_log.debug("user exists");
} else { } else {
s_log.debug("Creating a user with the email " + email); s_log.debug("Creating a user with the email " + email);
User user = new User(); User user = new User();
user.setPrimaryEmail(new EmailAddress(email)); user.setPrimaryEmail(new EmailAddress(email));
@ -148,9 +148,8 @@ public class Loader extends PackageLoader {
user.getPersonName().setFamilyName("Digest Sender"); user.getPersonName().setFamilyName("Digest Sender");
// Fixes a NPE in Loader of ccm-forum if screen_names are being used // Fixes a NPE in Loader of ccm-forum if screen_names are being used
user.setScreenName("Forum"); user.setScreenName("Forum");
users.close(); users.close();
} }
} }
@ -165,7 +164,7 @@ public class Loader extends PackageLoader {
Forum.CREATE_THREAD_PRIVILEGE); Forum.CREATE_THREAD_PRIVILEGE);
PrivilegeDescriptor.createPrivilege( PrivilegeDescriptor.createPrivilege(
Forum.RESPOND_TO_THREAD_PRIVILEGE); Forum.RESPOND_TO_THREAD_PRIVILEGE);
// Establich privilege hierarchie, eg. moderation includes createThread
PrivilegeDescriptor.addChildPrivilege( PrivilegeDescriptor.addChildPrivilege(
Forum.FORUM_MODERATION_PRIVILEGE, Forum.FORUM_MODERATION_PRIVILEGE,
Forum.CREATE_THREAD_PRIVILEGE); Forum.CREATE_THREAD_PRIVILEGE);
@ -174,7 +173,7 @@ public class Loader extends PackageLoader {
Forum.RESPOND_TO_THREAD_PRIVILEGE); Forum.RESPOND_TO_THREAD_PRIVILEGE);
PrivilegeDescriptor.addChildPrivilege( PrivilegeDescriptor.addChildPrivilege(
Forum.RESPOND_TO_THREAD_PRIVILEGE, Forum.RESPOND_TO_THREAD_PRIVILEGE,
PrivilegeDescriptor.READ.getName()); PrivilegeDescriptor.READ.getName()); // general read privilege
} }
} }

View File

@ -81,9 +81,9 @@ import com.arsdigita.util.Assert;
* <li> Submitter edits already approved message (notify admin) * <li> Submitter edits already approved message (notify admin)
* status changes to 'reapprove'</li> * status changes to 'reapprove'</li>
* *
* <li> -> Admin moderates, change state to 'approve', * <li> -> Admin moderates, change state to 'approve','supressed', or
*'supressed', or 'rejected' depending on whether they want to hide * 'rejected' depending on whether they want to hide the entire
*the entire thread or just the content of the message.</li> * thread or just the content of the message.</li>
* *
* <li> -> APPROVED new version of message goes live</li> * <li> -> APPROVED new version of message goes live</li>
* *
@ -113,7 +113,6 @@ import com.arsdigita.util.Assert;
* @author Kevin Scaldeferri (kevin@arsdigita.com) * @author Kevin Scaldeferri (kevin@arsdigita.com)
* @author Nobuko Asakai (nasakai@redhat.com) * @author Nobuko Asakai (nasakai@redhat.com)
*/ */
public class Post extends ThreadedMessage { public class Post extends ThreadedMessage {
private static final Logger s_log = Logger.getLogger(Post.class); private static final Logger s_log = Logger.getLogger(Post.class);
@ -125,15 +124,15 @@ public class Post extends ThreadedMessage {
* message */ * message */
public static final String MODERATOR = "moderator"; public static final String MODERATOR = "moderator";
/** /**
* 0..n association with PostImageAttachments * 0..n association with PostImageAttachments
*/ */
public static final String IMAGE_ATTACHMENTS = "images"; public static final String IMAGE_ATTACHMENTS = "images";
/** /**
* 0..n association with PostFileAttachments * 0..n association with PostFileAttachments
*/ */
public static final String FILE_ATTACHMENTS = "files"; public static final String FILE_ATTACHMENTS = "files";
/** The status strings */ /** The status strings */
public static final String PENDING = "pending"; public static final String PENDING = "pending";
@ -148,14 +147,13 @@ public class Post extends ThreadedMessage {
private Party m_moderator; private Party m_moderator;
// referred to afterSave method // referred to afterSave method
private boolean m_wasNew; private boolean m_wasNew;
/* /*
* The base DomainObject is Post which extends ThreadedMessage. In * The base DomainObject is Post which extends ThreadedMessage. In
* other words, all bboard messages are ThreadedMessages. * other words, all bboard messages are ThreadedMessages.
*/ */
public static final String BASE_DATA_OBJECT_TYPE = public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.forum.Post"; "com.arsdigita.forum.Post";
@ -180,25 +178,29 @@ public class Post extends ThreadedMessage {
} }
/** /**
* Creates a new Posting in a forum. The post is * Creates a new Posting in a forum. The post is
* not yet in a fit state to be saved as it needs * not yet in a fit state to be saved as it needs
* it's status to be set, and the subject and message * it's status to be set, and the subject and message
* *
* @param forum the owner forum * @param forum the owner forum
*/ */
public static Post create(Forum forum) { public static Post create(Forum forum) {
Post post = new Post(); Post post = new Post();
post.setForum(forum); post.setForum(forum);
return post; return post;
} }
/**
*
* @return
*/
protected String getBaseDataObjectType() { protected String getBaseDataObjectType() {
return BASE_DATA_OBJECT_TYPE; return BASE_DATA_OBJECT_TYPE;
} }
/** /**
* overridden version of method in ThreadedMessage * overridden version of method in ThreadedMessage
* used to create a reply to an existing post * used to create a reply to an existing post
*/ */
public ThreadedMessage newInstance() { public ThreadedMessage newInstance() {
return create(getForum()); return create(getForum());
@ -209,7 +211,7 @@ public class Post extends ThreadedMessage {
* before saving. * before saving.
*/ */
protected void beforeSave() { protected void beforeSave() {
m_wasNew = isNew(); m_wasNew = isNew();
Forum forum = getForum(); Forum forum = getForum();
Assert.exists(forum, Forum.class); Assert.exists(forum, Forum.class);
@ -224,12 +226,11 @@ public class Post extends ThreadedMessage {
} }
/** /**
* set permission contexts for this post to the root post, and for the root * set permission contexts for this post to the root post, and for the root
* post to the forum. Additionally create a lifecycle if required for a new * post to the forum. Additionally create a lifecycle if required for a new
* root post * root post
*/ */
protected void afterSave() { protected void afterSave() {
super.afterSave(); super.afterSave();
Forum forum = getForum(); Forum forum = getForum();
@ -238,40 +239,40 @@ public class Post extends ThreadedMessage {
s_log.info("Setting context for " + getOID() + " to " + root.getOID()); s_log.info("Setting context for " + getOID() + " to " + root.getOID());
PermissionService.setContext(this, root); PermissionService.setContext(this, root);
s_log.info( s_log.info( "Setting context for " + root.getOID() + " to " +
"Setting context for " + root.getOID() + " to " + forum.getOID());
forum.getOID());
PermissionService.setContext(root, forum); PermissionService.setContext(root, forum);
// originally this was created in beforeSave, but this was when only noticeboard // originally this was created in beforeSave, but this was when only
// (reply disabled) forums could have a lifecycle. Now that all forums may // noticeboard (reply disabled) forums could have a lifecycle. Now that
// have a lifecycle on root posts, the method needs to be here in order // all forums may have a lifecycle on root posts, the method needs to be
// for persistence to work when users are replying to posts chris.gilbert@westsussex.gov.uk // here in order for persistence to work when users are replying to
// posts (chris.gilbert@westsussex.gov.uk)
if (m_wasNew) { if (m_wasNew) {
if (getRoot() == null && forum.getExpireAfter() > 0) { if (getRoot() == null && forum.getExpireAfter() > 0) {
s_log.info("Creating expiration lifecycle for " + getOID()); s_log.info("Creating expiration lifecycle for " + getOID());
setLifecycle(forum.getLifecycleDefinition()); setLifecycle(forum.getLifecycleDefinition());
} }
} }
m_wasNew = false; m_wasNew = false;
DataAssociationCursor files = getFiles(); DataAssociationCursor files = getFiles();
// allow attached files to be returned in search results // allow attached files to be returned in search results
// by setting their status as live // by setting their status as live
while (files.next()) { while (files.next()) {
PostFileAttachment file = PostFileAttachment file =
(PostFileAttachment) DomainObjectFactory.newInstance( (PostFileAttachment) DomainObjectFactory.newInstance(
files.getDataObject()); files.getDataObject());
if (getStatus().equals(APPROVED)) { if (getStatus().equals(APPROVED)) {
file.setLive(); file.setLive();
} else { } else {
file.setDraft(); file.setDraft();
} }
} }
} } // Method afterSave()
/** /**
* Sends out the notifications for any subscriptions to the forum * Sends out the notifications for any subscriptions to the forum
@ -322,7 +323,8 @@ public class Post extends ThreadedMessage {
subscriptions.getDataObject()); subscriptions.getDataObject());
s_log.debug("notification to " + subscription.getOID()); s_log.debug("notification to " + subscription.getOID());
subscription.sendNotification(Post.this, Forum.getConfig().deleteNotifications()); subscription.sendNotification(Post.this, Forum.getConfig()
.deleteNotifications());
} }
s_log.debug("Sending thread level subsriptions"); s_log.debug("Sending thread level subsriptions");
@ -493,13 +495,13 @@ public class Post extends ThreadedMessage {
* on the forum is not cached. * on the forum is not cached.
*/ */
public boolean canEdit(Party party) { public boolean canEdit(Party party) {
Party author = getFrom(); Party author = getFrom(); //determin sender / author of message
// cg added - for anonymous posts, don't allow editing, else everyone could edit everyone else's posts // cg added - for anonymous posts, don't allow editing, else everyone
return ( // could edit everyone else's posts
!author.equals(Kernel.getPublicUser()) return ( !author.equals(Kernel.getPublicUser())
&& Forum.getConfig().canAuthorEditPosts() && Forum.getConfig().canAuthorEditPosts()
&& author.equals(party)) && author.equals(party) )
|| getForum().canEdit(party); || getForum().canEdit(party);
} }
public void setStatus(String status) { public void setStatus(String status) {

View File

@ -42,46 +42,50 @@ import com.arsdigita.xml.Element;
*/ */
public class ThreadPageBuilder implements PageBuilder, Constants { public class ThreadPageBuilder implements PageBuilder, Constants {
/* (non-Javadoc) /* (non-Javadoc)
* @see com.arsdigita.forum.PageBuilder#buildPage( * @see com.arsdigita.forum.PageBuilder#buildPage(
* com.arsdigita.bebop.parameters.ParameterModel) * com.arsdigita.bebop.parameters.ParameterModel)
*/ */
/** /**
* *
* @return * @return
*/ */
public Page buildPage() { public Page buildPage() {
Page threadPage = PageFactory.buildPage(Constants.FORUM_XML_PREFIX,
Page threadPage = PageFactory.buildPage(Constants.FORUM_XML_PREFIX,
"Threads", "forumThreadPage"); "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) {
Element nameElement = parent.newChildElement( public void generateXML(PageState state, Element parent) {
Element nameElement = parent.newChildElement(
Constants.FORUM_XML_PREFIX + ":name", Constants.FORUM_XML_PREFIX + ":name",
Constants.FORUM_XML_NS); Constants.FORUM_XML_NS);
nameElement.setText(ForumContext.getContext(state).getForum(). nameElement.setText(ForumContext.getContext(state)
getTitle()); .getForum().getTitle());
Element introductionElement = parent.newChildElement(
Element introductionElement = parent.newChildElement(
Constants.FORUM_XML_PREFIX + Constants.FORUM_XML_PREFIX +
":introduction", ":introduction",
Constants.FORUM_XML_NS); Constants.FORUM_XML_NS);
introductionElement.setText(ForumContext.getContext(state). introductionElement.setText(ForumContext.getContext(state).
getForum(). getForum().
getIntroduction()); getIntroduction());
} }
}); });
// //
threadPage.add(new DiscussionThreadSimpleView()); 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 // Register the thread id parameter as a global state parameter.
(new ThreadPageRequestListener(threadID)); BigDecimalParameter threadID = new BigDecimalParameter(THREAD_PARAM);
return threadPage; threadPage.addGlobalStateParam(threadID);
} // Basic PrivilegeDescriptor.READ allows general read access to the public
// Should be FORUM_READ instead!
threadPage.addRequestListener(
new ApplicationAuthenticationListener(PrivilegeDescriptor.READ));
threadPage.addRequestListener(new ThreadPageRequestListener(threadID));
return threadPage;
}
/** /**
* *

View File

@ -6,10 +6,19 @@
<body> <body>
<p> <p>
The forum package provides discussion forums in which users can post and The forum package provides electronic bulletin board where users can post and
reply to messages. Additionally, users may register for notifications of reply to messages. It is highly integrated with ccm systems user and permission
new posts to the system. administration as well as search feature. More than one instance of a forum is
supported, each with its own set f configuration. There exists a enhancement
package forum-categorized which allows a forum to be integrated into navigation
system.
</p> </p>
<p>Several features and funcionality may be configured (some system wide, most of
them on a per forum base), among others:</p>
<ul>
<li>Reply functionality may be disabled so it is just a noticeboard.</li>
<li>Users may register for notifications of new posts to the system</li>
</ul>
<p> <p>
<i>Forum.java</i> is the main domain class. <i>Forum.java</i> is the main domain class.
</p> </p>

View File

@ -89,9 +89,9 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
/** Object containing the moderation panel */ /** Object containing the moderation panel */
private ModerationView m_moderationView; private ModerationView m_moderationView;
/** Object containing the setup panel */ /** Object containing the setup panel */
private SetupView m_setupView; private SetupView m_setupView;
/** Object containing the permission management panel*/ /** Object containing the permission management panel*/
private PermissionsView m_permissionsView; private PermissionsView m_permissionsView;
/** /**
* Default Constructor. Initializes the forum user interface elements. * Default Constructor. Initializes the forum user interface elements.
@ -99,26 +99,26 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
public ForumUserCompactView() { public ForumUserCompactView() {
// determine namespace // determine namespace
super(FORUM_XML_PREFIX + ":forum", FORUM_XML_NS); super(FORUM_XML_PREFIX + ":forum", FORUM_XML_NS);
m_mode = new StringParameter("mode"); m_mode = new StringParameter("mode");
// setup panels which make up the forum // setup panels which make up the forum
m_threadsView = new ThreadsPanel(); m_threadsView = new ThreadsPanel();
m_topicsView = new TopicsPanel(); m_topicsView = new TopicsPanel();
m_alertsView = new ForumAlertsView(); m_alertsView = new ForumAlertsView();
// administration section // administration section
m_moderationView = new ModerationView(); m_moderationView = new ModerationView();
m_setupView = new SetupView(); m_setupView = new SetupView();
m_permissionsView = new PermissionsView(); m_permissionsView = new PermissionsView();
add(m_threadsView); add(m_threadsView);
add(m_topicsView); add(m_topicsView);
add(m_alertsView); add(m_alertsView);
// administration section // administration section
add(m_moderationView); add(m_moderationView);
add(m_setupView); add(m_setupView);
add(m_permissionsView); add(m_permissionsView);
setDefaultComponent(m_threadsView); setDefaultComponent(m_threadsView);
} }
@ -142,16 +142,16 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
super.respond(state); super.respond(state);
Party party = Kernel.getContext().getParty(); Party party = Kernel.getContext().getParty();
Forum forum = ForumContext.getContext(state).getForum(); Forum forum = ForumContext.getContext(state).getForum();
String mode = (String)state.getControlEventValue(); String mode = (String)state.getControlEventValue();
state.setValue(m_mode, mode); state.setValue(m_mode, mode);
setVisible(state, party, forum, mode); setVisible(state, party, forum, mode);
} }
/** /**
* Checks for the given forum mode (parameter value) whether its prerequisites * Checks for the given forum mode (parameter value) whether its prerequisites
* are given (currently permission, but additional properties may be added here). * are given (currently permission, but additional properties may be added here).
* If positive the panel is set visible, otherwise a login screen is * If positive the panel is set visible, otherwise a login screen is
@ -166,18 +166,18 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
protected void setVisible( PageState state, Party party, protected void setVisible( PageState state, Party party,
Forum forum, String mode) { Forum forum, String mode) {
PermissionDescriptor forumAdmin = PermissionDescriptor forumAdmin =
new PermissionDescriptor(PrivilegeDescriptor.ADMIN, forum, party); new PermissionDescriptor(PrivilegeDescriptor.ADMIN, forum, party);
PermissionService.assertPermission(forumAdmin); 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) {
UserContext.redirectToLoginPage(state.getRequest()); UserContext.redirectToLoginPage(state.getRequest());
} }
PermissionService.assertPermission(forumAdmin); PermissionService.assertPermission(forumAdmin);
} }
setVisibleComponent(state, m_topicsView); setVisibleComponent(state, m_topicsView);
} else if (MODE_ALERTS.equals(mode)) { } else if (MODE_ALERTS.equals(mode)) {
if (party == null) { if (party == null) {
@ -188,22 +188,22 @@ public class ForumUserCompactView extends ModalContainer implements Constants {
if (party == null) { if (party == null) {
UserContext.redirectToLoginPage(state.getRequest()); UserContext.redirectToLoginPage(state.getRequest());
} }
PermissionService.assertPermission(forumAdmin); PermissionService.assertPermission(forumAdmin);
setVisibleComponent(state, m_moderationView); setVisibleComponent(state, m_moderationView);
} else if (MODE_PERMISSIONS.equals(mode)) { } else if (MODE_PERMISSIONS.equals(mode)) {
if (party == null) { if (party == null) {
UserContext.redirectToLoginPage(state.getRequest()); UserContext.redirectToLoginPage(state.getRequest());
} }
PermissionService.assertPermission(forumAdmin); PermissionService.assertPermission(forumAdmin);
setVisibleComponent(state, m_permissionsView); setVisibleComponent(state, m_permissionsView);
} else if (MODE_SETUP.equals(mode)) { } else if (MODE_SETUP.equals(mode)) {
if (party == null) { if (party == null) {
UserContext.redirectToLoginPage(state.getRequest()); UserContext.redirectToLoginPage(state.getRequest());
} }
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); PermissionService.assertPermission(forumAdmin);
setVisibleComponent(state, m_threadsView); setVisibleComponent(state, m_threadsView);
} }