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

View File

@ -85,6 +85,13 @@ public class Application extends Resource {
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) {
super(dataObject);
}

View File

@ -51,6 +51,9 @@ import com.arsdigita.web.Application;
/**
* 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
* 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
@ -63,7 +66,6 @@ import com.arsdigita.web.Application;
* @version $Revision: 1.7 $
* @version $Id: Forum.java 1628 2007-09-17 08:10:40Z chrisg23 $
*/
public class Forum extends Application {
/** Private logger instance for debugging purpose */
@ -86,12 +88,12 @@ public class Forum extends Application {
}
//////
//Forum specific privileges
/////
public static final String FORUM_MODERATION_PRIVILEGE = "forum_moderation";
public static final String CREATE_THREAD_PRIVILEGE = "forum_create_thread";
public static final String RESPOND_TO_THREAD_PRIVILEGE = "forum_respond";
//////
//Forum specific privileges
/////
public static final String FORUM_MODERATION_PRIVILEGE = "forum_moderation";
public static final String CREATE_THREAD_PRIVILEGE = "forum_create_thread";
public static final String RESPOND_TO_THREAD_PRIVILEGE = "forum_respond";
// separate read privilege required because all public users
// have READ on homepage, which is parent of forum, hence
// everyone inherits READ cg
@ -106,50 +108,77 @@ public class Forum extends Application {
// 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";
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 SUBSCRIPTIONS = "subscriptions";
private static final String MODERATION = "isModerated";
private static final String NOTICEBOARD = "isNoticeboard";
private static final String ADMIN_GROUP = "adminGroup";
private static final String ADMIN_GROUP = "adminGroup";
private static final String MODERATION_GROUP = "moderationGroup";
private static final String THREAD_CREATE_GROUP = "threadCreateGroup";
private static final String THREAD_RESPONDER_GROUP = "threadRespondGroup";
private static final String READ_GROUP = "readGroup";
private static final String THREAD_CREATE_GROUP = "threadCreateGroup";
private static final String THREAD_RESPONDER_GROUP = "threadRespondGroup";
private static final String READ_GROUP = "readGroup";
private static final String CATEGORY = "category";
private static final String EXPIRE_AFTER = "expireAfter";
private static final String LIFECYCLE_DEFINITION = "lifecycleDefinition";
// additional attributes added chris.gilbert@westsussex.gov.uk
private static final String ALLOW_FILE_ATTACHMENTS = "fileAttachmentsAllowed";
private static final String ALLOW_IMAGE_UPLOADS = "imageUploadsAllowed";
private static final String AUTOSUBSCRIBE_THREAD_STARTER =
// additional attributes added chris.gilbert@westsussex.gov.uk
private static final String ALLOW_FILE_ATTACHMENTS = "fileAttachmentsAllowed";
private static final String ALLOW_IMAGE_UPLOADS = "imageUploadsAllowed";
private static final String AUTOSUBSCRIBE_THREAD_STARTER =
"autoSubscribeThreadStarter";
private static final String INTRODUCTION = "introduction";
private static final String NO_CATEGORY_POSTS = "noCategoryPostsAllowed";
private static final String ANONYMOUS_POSTS = "anonymousPostsAllowed";
private static final String INTRODUCTION = "introduction";
private static final String NO_CATEGORY_POSTS = "noCategoryPostsAllowed";
private static final String ANONYMOUS_POSTS = "anonymousPostsAllowed";
/**
*
* @param data
/**
* Creates a new Forum instance encapsulating the given data object.
* @see com.arsdigita.persistence.Session#retrieve(String)
*
* @param data The data object to encapsulate in the Forum instance
* (new domain object).
*/
public Forum(DataObject 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 {
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 {
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,
Application parent) {
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
* except in the constructor of a subclass of Forum.
* 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
* categorized.
* category for the Forum in the event that the Forum should be categorized.
*
* This also sets up instant and daily subscriptions on the Forum.
* The default for moderation is false.
*
* Also sets default values for other forum settings. These can be
* amended under the setup tab in the ui
* The default for moderation is false.
*
* Also sets default values for other forum settings. These can be
* amended under the setup tab in the ui
*/
public static Forum create(String urlName, String title,
Application parent, boolean moderated) {
s_log.debug("creating forum " + title);
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);
// default settings ensure legacy forum users do not
// see any change chris.gilbert@westsussex.gov.uk
forum.setAllowFileAttachments(false);
forum.setAllowImageUploads(false);
forum.setAutoSubscribeThreadCreator(false);
forum.setNoCategoryPostsAllowed(true);
forum.setAnonymousPostsAllowed(false);
// default settings ensure legacy forum users do not
// see any change chris.gilbert@westsussex.gov.uk
forum.setAllowFileAttachments(false);
forum.setAllowImageUploads(false);
forum.setAutoSubscribeThreadCreator(false);
forum.setNoCategoryPostsAllowed(true);
forum.setAnonymousPostsAllowed(false);
return forum;
}
@ -208,22 +239,20 @@ public class Forum extends Application {
}
/**
* Set introduction
*/
public void setIntroduction(String introduction) {
set(INTRODUCTION, introduction);
}
* Set introduction
*/
public void setIntroduction(String 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.
*/
private Category createRootCategory() {
@ -235,13 +264,14 @@ public class Forum extends Application {
return category;
}
/**
/**
*
*/
private void createGroups() {
Group administrators = new Group();
administrators.setName(getTitle() + " Administrators");
setAssociation(ADMIN_GROUP, administrators);
Group administrators = new Group();
administrators.setName(getTitle() + " Administrators");
setAssociation(ADMIN_GROUP, administrators);
Group moderators = new Group();
moderators.setName(getTitle() + " Moderators");
@ -258,35 +288,34 @@ public class Forum extends Application {
moderators.getID() + "@" + s_config.getReplyHostName();
moderators.setPrimaryEmail(new EmailAddress(email));
// chris.gilbert@westsussex.gov.uk create additional groups for privilege
// assignment - could have assigned privileges directly without having associated
// groups, but this reduces rows in the (already enormous) dnm_permissions
// table
Group threadCreators = new Group();
threadCreators.setName(getTitle() + " Thread Creators");
setAssociation(THREAD_CREATE_GROUP, threadCreators);
// chris.gilbert@westsussex.gov.uk create additional groups for privilege
// assignment - could have assigned privileges directly without having
// associated groups, but this reduces rows in the (already enormous)
// dnm_permissions table
Group threadCreators = new Group();
threadCreators.setName(getTitle() + " Thread Creators");
setAssociation(THREAD_CREATE_GROUP, threadCreators);
Group threadResponders = new Group();
threadResponders.setName(getTitle() + " Thread Responders");
setAssociation(THREAD_RESPONDER_GROUP, threadResponders);
Group threadResponders = new Group();
threadResponders.setName(getTitle() + " Thread Responders");
setAssociation(THREAD_RESPONDER_GROUP, threadResponders);
Group forumReaders = new Group();
forumReaders.setName(getTitle() + " Readers");
setAssociation(READ_GROUP, forumReaders);
Group forumReaders = new Group();
forumReaders.setName(getTitle() + " Readers");
setAssociation(READ_GROUP, forumReaders);
Group container = getGroup();
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();
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()) {
setModerated(false);
setNoticeboard(false);
setAllowFileAttachments(false);
setAllowImageUploads(false);
setAutoSubscribeThreadCreator(false);
setNoCategoryPostsAllowed(true);
setAnonymousPostsAllowed(false);
setAllowFileAttachments(false);
setAllowImageUploads(false);
setAutoSubscribeThreadCreator(false);
setNoCategoryPostsAllowed(true);
setAnonymousPostsAllowed(false);
createRootCategory();
}
@ -315,76 +344,85 @@ public class Forum extends Application {
super.beforeSave();
}
/**
*
*/
@Override
protected void afterSave() {
if (m_wasNew) {
PermissionService.setContext(getRootCategory(), this);
createGroups();
if (getAdminGroup() != null) {
PermissionService.grantPermission(
new PermissionDescriptor(
PrivilegeDescriptor.ADMIN,
this,
getAdminGroup()));
s_log.debug(
"Current user : "
+ Kernel.getContext().getParty().getPrimaryEmail()
+ " class is "
+ Kernel.getContext().getParty().getClass());
//
// chris.gilbert@westsussex.gov.uk Original plan was that creator of forum
// is administrator by default, but party from Kernel at this point in code is
// acs-system-party - creation must happen in a KernelExcersion somewhere
// though I can't immediately see where.
// as a consequence, code below justs causes a classcast exception,
//
// revisit, but in meantime, only site admin can administer new forum
// until forum admin permissions set in UI
//
// User creator = (User) Kernel.getContext().getParty();
// can't be null but let's be supercautious
// if (creator != null) {
// getAdminGroup().addMember(creator);
// }
///
}
createGroups();
if (getAdminGroup() != null) {
PermissionService.grantPermission( new PermissionDescriptor(
PrivilegeDescriptor.ADMIN,
this,
getAdminGroup()));
s_log.debug("Current user : "
+ Kernel.getContext().getParty().getPrimaryEmail()
+ " class is "
+ Kernel.getContext().getParty().getClass());
//
// chris.gilbert@westsussex.gov.uk Original plan was that
// creator of forum is administrator by default,
// but party from Kernel at this point in code is
// acs-system-party - creation must happen in a KernelExcersion
// somewhere though I can't immediately see where.
// As a consequence, code below justs causes a classcast exception,
//
// revisit, but in meantime, only site admin can administer new forum
// until forum admin permissions set in UI
//
// User creator = (User) Kernel.getContext().getParty();
// can't be null but let's be supercautious
// if (creator != null) {
// getAdminGroup().addMember(creator);
// }
//
}
if (getModerationGroup() != null ) {
PermissionService.grantPermission(
new PermissionDescriptor(
PrivilegeDescriptor.get(FORUM_MODERATION_PRIVILEGE),
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()));
new PermissionDescriptor(
PrivilegeDescriptor.get(
FORUM_MODERATION_PRIVILEGE),
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()));
}
KernelExcursion excursion = new KernelExcursion() {
protected void excurse() {
setParty(Kernel.getSystemParty());
@ -402,9 +440,9 @@ public class Forum extends Application {
// }
}
};
};
excursion.run();
}
} //if mWasNew
DataCollection subs = null;
try {
@ -420,16 +458,15 @@ public class Forum extends Application {
}
// chris.gilbert@westsussex.gov.uk line removed.
// afterSave in Application sets permission
// context of forum to parent app (portal homepage)
// don't want to inherit permissions of portal,
// as public users have 'READ' privilege on this
// and so get shown postings in search results.
//
//
// super.afterSave();
}
// chris.gilbert@westsussex.gov.uk line removed.
// afterSave in Application sets permission
// context of forum to parent app (portal homepage)
// don't want to inherit permissions of portal,
// as public users have 'READ' privilege on this
// and so get shown postings in search results.
// super.afterSave();
} //Method afterSave()
protected String getBaseDataObjectType() {
return BASE_DATA_OBJECT_TYPE;
@ -472,37 +509,37 @@ public class Forum extends Application {
}
/**
* gets all pending messages and messages for reapproval - allows
* moderators to see which messages require their attention
* @return
*/
public DataAssociation getPendingPosts() {
// doesn't use getPosts in view of the warning that it
// may disappear
DataAssociation posts = (DataAssociation) get(POSTS);
FilterFactory factory = posts.getFilterFactory();
Filter pending = factory.equals(Post.STATUS, Post.PENDING);
Filter reapprove = factory.equals(Post.STATUS, Post.REAPPROVE);
* gets all pending messages and messages for reapproval - allows
* moderators to see which messages require their attention
* @return
*/
public DataAssociation getPendingPosts() {
// doesn't use getPosts in view of the warning that it
// may disappear
DataAssociation posts = (DataAssociation) get(POSTS);
FilterFactory factory = posts.getFilterFactory();
Filter pending = factory.equals(Post.STATUS, Post.PENDING);
Filter reapprove = factory.equals(Post.STATUS, Post.REAPPROVE);
posts.addFilter(factory.or().addFilter(pending).addFilter(reapprove));
posts.addFilter(factory.or().addFilter(pending).addFilter(reapprove));
return posts;
}
return posts;
}
/**
* gets all suppressed messages - allows moderators to see which messages
* heve been rejected / require their attention
* @return
*/
public DataAssociation getSuppressedPosts() {
/**
* gets all suppressed messages - allows moderators to see which messages
* heve been rejected / require their attention
* @return
*/
public DataAssociation getSuppressedPosts() {
// doesn't use getPosts in view of the warning that it
// may disappear
DataAssociation posts = (DataAssociation) get(POSTS);
posts.addEqualsFilter(Post.STATUS, Post.SUPPRESSED);
return posts;
}
}
/**
/**
* Gets a ThreadCollection of the threads in this forum. I.e. the
* 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));
}
/** Returns the administrator group. Null if it doesn't exist */
public Group getAdminGroup() {
DataObject dObj = (DataObject) get(ADMIN_GROUP);
Assert.exists(dObj, DataObject.class);
return (Group) DomainObjectFactory.newInstance(dObj);
/** Returns the administrator group. Null if it doesn't exist */
public Group getAdminGroup() {
DataObject dObj = (DataObject) get(ADMIN_GROUP);
Assert.exists(dObj, DataObject.class);
return (Group) DomainObjectFactory.newInstance(dObj);
}
/** Returns the moderator group. Null if it doesn't exist */
public Group getModerationGroup() {
DataObject dObj = (DataObject) get( MODERATION_GROUP );
@ -756,26 +794,26 @@ public class Forum extends Application {
return (Group)DomainObjectFactory.newInstance(dObj);
}
/** Returns the thread create group. Null if it doesn't exist */
public Group getThreadCreateGroup() {
DataObject dObj = (DataObject) get(THREAD_CREATE_GROUP);
Assert.exists(dObj, DataObject.class);
return (Group) DomainObjectFactory.newInstance(dObj);
}
/** Returns the thread create group. Null if it doesn't exist */
public Group getThreadCreateGroup() {
DataObject dObj = (DataObject) get(THREAD_CREATE_GROUP);
Assert.exists(dObj, DataObject.class);
return (Group) DomainObjectFactory.newInstance(dObj);
}
/** Returns the thread reply group. Null if it doesn't exist */
public Group getThreadResponderGroup() {
DataObject dObj = (DataObject) get(THREAD_RESPONDER_GROUP);
Assert.exists(dObj, DataObject.class);
return (Group) DomainObjectFactory.newInstance(dObj);
}
/** Returns the thread reply group. Null if it doesn't exist */
public Group getThreadResponderGroup() {
DataObject dObj = (DataObject) get(THREAD_RESPONDER_GROUP);
Assert.exists(dObj, DataObject.class);
return (Group) DomainObjectFactory.newInstance(dObj);
}
/** Returns the read group. Null if it doesn't exist */
public Group getReadGroup() {
DataObject dObj = (DataObject) get(READ_GROUP);
Assert.exists(dObj, DataObject.class);
return (Group) DomainObjectFactory.newInstance(dObj);
}
/** Returns the read group. Null if it doesn't exist */
public Group getReadGroup() {
DataObject dObj = (DataObject) get(READ_GROUP);
Assert.exists(dObj, DataObject.class);
return (Group) DomainObjectFactory.newInstance(dObj);
}
public void setExpireAfter(int value) {
set(EXPIRE_AFTER, new BigDecimal(value));
@ -800,20 +838,14 @@ public class Forum extends Application {
// have the same expiration policy.
DataAssociationCursor posts = getPosts().cursor();
while (posts.next()) {
Post post =
(Post) DomainObjectFactory.newInstance(posts.getDataObject());
if (post
.getThread()
.getRootMessage()
.getID()
.equals(post.getID())) {
s_log.debug(
"Resetting expiration lifecycle for " + post.getOID());
post.setLifecycle(newLife);
Post post = (Post) DomainObjectFactory.newInstance(posts.getDataObject());
if (post.getThread().getRootMessage().getID()
.equals(post.getID())) {
s_log.debug("Resetting expiration lifecycle for " + post.getOID());
post.setLifecycle(newLife);
}
}
}
}
public int getExpireAfter() {
BigDecimal expire = (BigDecimal) get(EXPIRE_AFTER);
@ -836,66 +868,70 @@ public class Forum extends Application {
set(LIFECYCLE_DEFINITION, life);
}
/**
* 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 setAdminGroup(Group group) {
setAssociation(ADMIN_GROUP, group);
PermissionService.grantPermission(
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
* @author cgyg9330
*
*/
public void setThreadCreatorGroup(Group group) {
setAssociation(THREAD_CREATE_GROUP, group);
PermissionService.grantPermission(
new PermissionDescriptor(
/**
* 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 setAdminGroup(Group group) {
setAssociation(ADMIN_GROUP, group);
PermissionService.grantPermission(
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
* @author cgyg9330
*
*/
public void setThreadCreatorGroup(Group group) {
setAssociation(THREAD_CREATE_GROUP, group);
PermissionService.grantPermission(
new PermissionDescriptor(
PrivilegeDescriptor.get(CREATE_THREAD_PRIVILEGE),
this,
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
*/
public boolean allowFileAttachments() {
return ((Boolean) get(ALLOW_FILE_ATTACHMENTS)).booleanValue();
}
public boolean allowImageUploads() {
return ((Boolean) get(ALLOW_IMAGE_UPLOADS)).booleanValue();
}
/**
* 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
*/
public boolean allowFileAttachments() {
return ((Boolean) get(ALLOW_FILE_ATTACHMENTS)).booleanValue();
}
public boolean allowImageUploads() {
return ((Boolean) get(ALLOW_IMAGE_UPLOADS)).booleanValue();
}
public boolean autoSubscribeThreadStarter() {
return ((Boolean) get(AUTOSUBSCRIBE_THREAD_STARTER)).booleanValue();
@ -922,33 +958,39 @@ public class Forum extends Application {
set(NO_CATEGORY_POSTS, new Boolean(allow));
}
public void setAnonymousPostsAllowed(boolean allow) {
set(ANONYMOUS_POSTS, new Boolean(allow));
}
public void setAnonymousPostsAllowed(boolean allow) {
set(ANONYMOUS_POSTS, new Boolean(allow));
}
public void setTitle (String title) {
String oldTitle = getTitle();
super.setTitle(title);
if (!oldTitle.equals(title)) {
// 1. rename permission groups
getAdminGroup().setName(title + " Administrators");
getModerationGroup().setName(title + " Moderators");
getThreadCreateGroup().setName(title + " Thread Creators");
getThreadResponderGroup().setName(title + " Thread Responders");
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));
public void setTitle (String title) {
String oldTitle = getTitle();
super.setTitle(title);
if (!oldTitle.equals(title)) {
// 1. rename permission groups
getAdminGroup().setName(title + " Administrators");
getModerationGroup().setName(title + " Moderators");
getThreadCreateGroup().setName(title + " Thread Creators");
getThreadResponderGroup().setName(title + " Thread Responders");
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));
}
}
}
}
}

View File

@ -77,6 +77,11 @@ public class ForumPageBuilder implements PageBuilder, Constants {
page.add(forumComp);
BigDecimalParameter topic = new BigDecimalParameter(TOPIC_PARAM);
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(
new ApplicationAuthenticationListener(PrivilegeDescriptor.READ));
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
"com.arsdigita.forum.Inbox", // Forum loader!
"com.arsdigita.forum.Inbox", // Forum loader! see Inbox.pdl
new ACSObjectInstantiator() {
public DomainObject doNewInstance(DataObject dataObject) {
return new Forum(dataObject);

View File

@ -62,7 +62,7 @@ public class Loader extends PackageLoader {
setupPrivileges();
setupForumAppType();
//setupInboxAppType();
//setupInboxAppType(); //TODO: why it is commented out?
setupRecentPostingsPortletType();
setupMyForumsPortletType();
setupDigestUser();
@ -87,7 +87,7 @@ public class Loader extends PackageLoader {
/**
*
* TODO: What is it for? Execution is currently commented out.
* @return
*/
private static ApplicationType setupInboxAppType() {
@ -136,11 +136,11 @@ public class Loader extends PackageLoader {
// Email address corresponding to the digest sender, as
// specified in the configuration file.
String email = Forum.getConfig().getDigestUserEmail();
UserCollection users = User.retrieveAll();
users.addEqualsFilter("primaryEmail", email);
if (users.next()) {
s_log.debug("user exists");
} else {
UserCollection users = User.retrieveAll();
users.addEqualsFilter("primaryEmail", email);
if (users.next()) {
s_log.debug("user exists");
} else {
s_log.debug("Creating a user with the email " + email);
User user = new User();
user.setPrimaryEmail(new EmailAddress(email));
@ -148,10 +148,9 @@ public class Loader extends PackageLoader {
user.getPersonName().setFamilyName("Digest Sender");
// Fixes a NPE in Loader of ccm-forum if screen_names are being used
user.setScreenName("Forum");
users.close();
}
users.close();
}
}
/**
@ -165,7 +164,7 @@ public class Loader extends PackageLoader {
Forum.CREATE_THREAD_PRIVILEGE);
PrivilegeDescriptor.createPrivilege(
Forum.RESPOND_TO_THREAD_PRIVILEGE);
// Establich privilege hierarchie, eg. moderation includes createThread
PrivilegeDescriptor.addChildPrivilege(
Forum.FORUM_MODERATION_PRIVILEGE,
Forum.CREATE_THREAD_PRIVILEGE);
@ -174,7 +173,7 @@ public class Loader extends PackageLoader {
Forum.RESPOND_TO_THREAD_PRIVILEGE);
PrivilegeDescriptor.addChildPrivilege(
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)
* status changes to 'reapprove'</li>
*
* <li> -> Admin moderates, change state to 'approve',
*'supressed', or 'rejected' depending on whether they want to hide
*the entire thread or just the content of the message.</li>
* <li> -> Admin moderates, change state to 'approve','supressed', or
* 'rejected' depending on whether they want to hide the entire
* thread or just the content of the message.</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 Nobuko Asakai (nasakai@redhat.com)
*/
public class Post extends ThreadedMessage {
private static final Logger s_log = Logger.getLogger(Post.class);
@ -125,15 +124,15 @@ public class Post extends ThreadedMessage {
* message */
public static final String MODERATOR = "moderator";
/**
* 0..n association with PostImageAttachments
*/
public static final String IMAGE_ATTACHMENTS = "images";
/**
* 0..n association with PostImageAttachments
*/
public static final String IMAGE_ATTACHMENTS = "images";
/**
* 0..n association with PostFileAttachments
*/
public static final String FILE_ATTACHMENTS = "files";
/**
* 0..n association with PostFileAttachments
*/
public static final String FILE_ATTACHMENTS = "files";
/** The status strings */
public static final String PENDING = "pending";
@ -148,14 +147,13 @@ public class Post extends ThreadedMessage {
private Party m_moderator;
// referred to afterSave method
private boolean m_wasNew;
// referred to afterSave method
private boolean m_wasNew;
/*
* The base DomainObject is Post which extends ThreadedMessage. In
* other words, all bboard messages are ThreadedMessages.
*/
public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.forum.Post";
@ -180,25 +178,29 @@ public class Post extends ThreadedMessage {
}
/**
* Creates a new Posting in a forum. The post is
* not yet in a fit state to be saved as it needs
* it's status to be set, and the subject and message
*
* Creates a new Posting in a forum. The post is
* not yet in a fit state to be saved as it needs
* it's status to be set, and the subject and message
*
* @param forum the owner forum
*/
public static Post create(Forum forum) {
Post post = new Post();
post.setForum(forum);
post.setForum(forum);
return post;
}
/**
*
* @return
*/
protected String getBaseDataObjectType() {
return BASE_DATA_OBJECT_TYPE;
}
/**
* overridden version of method in ThreadedMessage
* used to create a reply to an existing post
* overridden version of method in ThreadedMessage
* used to create a reply to an existing post
*/
public ThreadedMessage newInstance() {
return create(getForum());
@ -209,7 +211,7 @@ public class Post extends ThreadedMessage {
* before saving.
*/
protected void beforeSave() {
m_wasNew = isNew();
m_wasNew = isNew();
Forum forum = getForum();
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
* post to the forum. Additionally create a lifecycle if required for a new
* root post
*/
/**
* 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
* root post
*/
protected void afterSave() {
super.afterSave();
Forum forum = getForum();
@ -238,40 +239,40 @@ public class Post extends ThreadedMessage {
s_log.info("Setting context for " + getOID() + " to " + root.getOID());
PermissionService.setContext(this, root);
s_log.info(
"Setting context for " + root.getOID() + " to " +
forum.getOID());
s_log.info( "Setting context for " + root.getOID() + " to " +
forum.getOID());
PermissionService.setContext(root, forum);
// originally this was created in beforeSave, but this was when only noticeboard
// (reply disabled) forums could have a lifecycle. Now that all forums may
// have a lifecycle on root posts, the method needs to be here in order
// for persistence to work when users are replying to posts chris.gilbert@westsussex.gov.uk
// originally this was created in beforeSave, but this was when only
// noticeboard (reply disabled) forums could have a lifecycle. Now that
// all forums may have a lifecycle on root posts, the method needs to be
// here in order for persistence to work when users are replying to
// posts (chris.gilbert@westsussex.gov.uk)
if (m_wasNew) {
if (getRoot() == null && forum.getExpireAfter() > 0) {
s_log.info("Creating expiration lifecycle for " + getOID());
setLifecycle(forum.getLifecycleDefinition());
}
}
m_wasNew = false;
if (m_wasNew) {
if (getRoot() == null && forum.getExpireAfter() > 0) {
s_log.info("Creating expiration lifecycle for " + getOID());
setLifecycle(forum.getLifecycleDefinition());
}
}
m_wasNew = false;
DataAssociationCursor files = getFiles();
DataAssociationCursor files = getFiles();
// allow attached files to be returned in search results
// by setting their status as live
while (files.next()) {
PostFileAttachment file =
(PostFileAttachment) DomainObjectFactory.newInstance(
files.getDataObject());
if (getStatus().equals(APPROVED)) {
file.setLive();
} else {
file.setDraft();
}
// allow attached files to be returned in search results
// by setting their status as live
while (files.next()) {
PostFileAttachment file =
(PostFileAttachment) DomainObjectFactory.newInstance(
files.getDataObject());
if (getStatus().equals(APPROVED)) {
file.setLive();
} else {
file.setDraft();
}
}
}
}
} // Method afterSave()
/**
* Sends out the notifications for any subscriptions to the forum
@ -322,7 +323,8 @@ public class Post extends ThreadedMessage {
subscriptions.getDataObject());
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");
@ -493,13 +495,13 @@ public class Post extends ThreadedMessage {
* on the forum is not cached.
*/
public boolean canEdit(Party party) {
Party author = getFrom();
// cg added - for anonymous posts, don't allow editing, else everyone could edit everyone else's posts
return (
!author.equals(Kernel.getPublicUser())
&& Forum.getConfig().canAuthorEditPosts()
&& author.equals(party))
|| getForum().canEdit(party);
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
return ( !author.equals(Kernel.getPublicUser())
&& Forum.getConfig().canAuthorEditPosts()
&& author.equals(party) )
|| getForum().canEdit(party);
}
public void setStatus(String status) {

View File

@ -42,46 +42,50 @@ import com.arsdigita.xml.Element;
*/
public class ThreadPageBuilder implements PageBuilder, Constants {
/* (non-Javadoc)
* @see com.arsdigita.forum.PageBuilder#buildPage(
/* (non-Javadoc)
* @see com.arsdigita.forum.PageBuilder#buildPage(
* com.arsdigita.bebop.parameters.ParameterModel)
*/
/**
*/
/**
*
* @return
*/
public Page buildPage() {
Page threadPage = PageFactory.buildPage(Constants.FORUM_XML_PREFIX,
Page threadPage = PageFactory.buildPage(Constants.FORUM_XML_PREFIX,
"Threads", "forumThreadPage");
//Output the title in an easy to find place
threadPage.add(new SimpleComponent(){
public void generateXML(PageState state, Element parent) {
Element nameElement = parent.newChildElement(
//Output the title in an easy to find place
threadPage.add(new SimpleComponent(){
public void generateXML(PageState state, Element parent) {
Element nameElement = parent.newChildElement(
Constants.FORUM_XML_PREFIX + ":name",
Constants.FORUM_XML_NS);
nameElement.setText(ForumContext.getContext(state).getForum().
getTitle());
Element introductionElement = parent.newChildElement(
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).
introductionElement.setText(ForumContext.getContext(state).
getForum().
getIntroduction());
}
});
}
});
//
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(
threadPage.add(new DiscussionThreadSimpleView());
// Register the thread id parameter as a global state parameter.
BigDecimalParameter threadID = new BigDecimalParameter(THREAD_PARAM);
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;
}
threadPage.addRequestListener(new ThreadPageRequestListener(threadID));
return threadPage;
}
/**
*

View File

@ -6,10 +6,19 @@
<body>
<p>
The forum package provides discussion forums in which users can post and
reply to messages. Additionally, users may register for notifications of
new posts to the system.
The forum package provides electronic bulletin board where users can post and
reply to messages. It is highly integrated with ccm systems user and permission
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>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>
<i>Forum.java</i> is the main domain class.
</p>

View File

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