/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/msgcntr/trunk/messageforums-component-impl/src/java/org/sakaiproject/component/app/messageforums/AreaManagerImpl.java $
* $Id: AreaManagerImpl.java 9227 2006-05-15 15:02:42Z cwen@iupui.edu $
***********************************************************************************
*
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009 The Sakai Foundation
*
* Licensed under the Educational Community License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************************/
package org.sakaiproject.component.app.messageforums;
import java.sql.SQLException;
import java.util.Date;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.collection.PersistentSet;
import org.sakaiproject.api.app.messageforums.Area;
import org.sakaiproject.api.app.messageforums.AreaManager;
import org.sakaiproject.api.app.messageforums.BaseForum;
import org.sakaiproject.api.app.messageforums.DiscussionForum;
import org.sakaiproject.api.app.messageforums.DiscussionTopic;
import org.sakaiproject.api.app.messageforums.ForumScheduleNotification;
import org.sakaiproject.api.app.messageforums.MessageForumsForumManager;
import org.sakaiproject.api.app.messageforums.MessageForumsTypeManager;
import org.sakaiproject.api.app.messageforums.cover.ForumScheduleNotificationCover;
import org.sakaiproject.api.app.messageforums.cover.SynopticMsgcntrManagerCover;
import org.sakaiproject.component.api.ServerConfigurationService;
import org.sakaiproject.component.app.messageforums.dao.hibernate.AreaImpl;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.id.api.IdManager;
import org.sakaiproject.site.api.Site;
import org.sakaiproject.site.api.SiteService;
import org.sakaiproject.tool.api.Placement;
import org.sakaiproject.tool.api.SessionManager;
import org.sakaiproject.tool.cover.ToolManager;
import org.sakaiproject.util.ResourceLoader;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class AreaManagerImpl extends HibernateDaoSupport implements AreaManager {
private static final Log LOG = LogFactory.getLog(AreaManagerImpl.class);
private static final String QUERY_AREA_BY_CONTEXT_AND_TYPE_ID = "findAreaByContextIdAndTypeId";
private static final String QUERY_AREA_BY_TYPE = "findAreaByType";
// TODO: pull titles from bundle
private static final String MESSAGECENTER_BUNDLE = "org.sakaiproject.api.app.messagecenter.bundle.Messages";
private static final String MESSAGES_TITLE = "cdfm_message_pvtarea";
private static final String FORUMS_TITLE = "cdfm_discussion_forums";
private IdManager idManager;
private MessageForumsForumManager forumManager;
private SessionManager sessionManager;
private MessageForumsTypeManager typeManager;
private ServerConfigurationService serverConfigurationService;
private Boolean DEFAULT_AUTO_MARK_READ = false;
private SiteService siteService;
/**
* sakai.property for setting the default Messages tool option for sending a copy of a message
* to recipient email addresses. Options are {@link Area#EMAIL_COPY_NEVER}, {@link Area#EMAIL_COPY_OPTIONAL},
* and {@link Area#EMAIL_COPY_ALWAYS}
*/
private static final String DEFAULT_SEND_TO_EMAIL_PROP = "msgcntr.defaultSendToEmailSetting";
public void setServerConfigurationService(
ServerConfigurationService serverConfigurationService) {
this.serverConfigurationService = serverConfigurationService;
}
public void setSiteService(SiteService siteService) {
this.siteService = siteService;
}
public void init() {
LOG.info("init()");
DEFAULT_AUTO_MARK_READ = serverConfigurationService.getBoolean("msgcntr.forums.default.auto.mark.threads.read", false);
}
public MessageForumsTypeManager getTypeManager() {
return typeManager;
}
public void setTypeManager(MessageForumsTypeManager typeManager) {
this.typeManager = typeManager;
}
public void setSessionManager(SessionManager sessionManager) {
this.sessionManager = sessionManager;
}
public IdManager getIdManager() {
return idManager;
}
public SessionManager getSessionManager() {
return sessionManager;
}
public void setIdManager(IdManager idManager) {
this.idManager = idManager;
}
public void setForumManager(MessageForumsForumManager forumManager) {
this.forumManager = forumManager;
}
public Area getPrivateArea() {
return getPrivateArea(getContextId());
}
public Area getPrivateArea(String siteId){
Area area = getAreaByContextIdAndTypeId(siteId, typeManager.getPrivateMessageAreaType());
if (area == null) {
area = createArea(typeManager.getPrivateMessageAreaType(), siteId);
area.setContextId(siteId);
area.setName(getResourceBundleString(MESSAGES_TITLE));
area.setEnabled(Boolean.FALSE);
area.setHidden(Boolean.TRUE);
area.setLocked(Boolean.FALSE);
area.setModerated(Boolean.FALSE);
area.setPostFirst(Boolean.FALSE);
area.setAutoMarkThreadsRead(DEFAULT_AUTO_MARK_READ);
area.setSendToEmail(serverConfigurationService.getInt(DEFAULT_SEND_TO_EMAIL_PROP, Area.EMAIL_COPY_OPTIONAL));
saveArea(area);
}
return area;
}
public Area getDiscusionArea() {
return getDiscussionArea(this.getContextId());
}
public Area getDiscussionArea(String contextId) {
return getDiscussionArea(contextId, true);
}
public Area getDiscussionArea(String contextId, boolean createDefaultForum) {
LOG.debug("getDiscussionArea(" + contextId +")");
if (contextId == null) {
return getDiscusionArea();
}
Area area = this.getAreaByContextIdAndTypeId(contextId, typeManager.getDiscussionForumType());
if (area == null) {
LOG.info("setting up a new Discussion Area for " + contextId);
area = createArea(typeManager.getDiscussionForumType(), contextId);
area.setName(getResourceBundleString(FORUMS_TITLE));
area.setEnabled(Boolean.TRUE);
area.setHidden(Boolean.TRUE);
area.setLocked(Boolean.FALSE);
area.setModerated(Boolean.FALSE);
area.setPostFirst(Boolean.FALSE);
area.setAutoMarkThreadsRead(DEFAULT_AUTO_MARK_READ);
// this is a Messages tool option
area.setSendToEmail(serverConfigurationService.getInt(DEFAULT_SEND_TO_EMAIL_PROP, Area.EMAIL_COPY_OPTIONAL));
area.setAvailabilityRestricted(Boolean.FALSE);
saveArea(area);
//if set populate the default Forum and topic
if (createDefaultForum && serverConfigurationService.getBoolean("forums.setDefault.forum", true)) {
setAreaDefaultElements(area);
}
}
return area;
}
private void setAreaDefaultElements(Area area) {
LOG.info("setAreaDefaultElements(" + area.getId() + ")");
DiscussionForum forum = forumManager.createDiscussionForum();
forum.setArea(area);
String siteTitle = null;
try {
Site site = siteService.getSite(area.getContextId());
siteTitle = site.getTitle();
} catch (IdUnusedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//MSGCNTR-453
forum.setCreatedBy("admin");
forum.setTitle(getResourceBundleString("default_forum", new Object[]{(Object)siteTitle}));
forum.setDraft(false);
forum.setModerated(area.getModerated());
forum.setPostFirst(area.getPostFirst());
forumManager.saveDiscussionForum(forum);
DiscussionTopic topic = forumManager.createDiscussionForumTopic(forum);
topic.setTitle(getResourceBundleString("default_topic"));
//MSGCNTR-453
topic.setCreatedBy("admin");
forumManager.saveDiscussionForumTopic(topic, false);
}
public boolean isPrivateAreaEnabled() {
return getPrivateArea().getEnabled().booleanValue();
}
public Area createArea(String typeId, String contextParam) {
if (LOG.isDebugEnabled())
{
LOG.debug("createArea(" + typeId + "," + contextParam + ")");
}
Area area = new AreaImpl();
area.setUuid(getNextUuid());
area.setTypeUuid(typeId);
area.setCreated(new Date());
area.setCreatedBy(getCurrentUser());
/** compatibility with web services*/
if (contextParam == null){
String contextId = getContextId();
if (contextId == null){
throw new IllegalStateException("Cannot retrive current context");
}
area.setContextId(contextId);
}
else{
area.setContextId(contextParam);
}
LOG.debug("createArea executed with areaId: " + area.getUuid());
return area;
}
/**
* This method sets the modified user and date. It then checks all the open forums for a
* sort index of 0. (if a sort index on a forum is 0 then it is new). If there is a
* zero sort index then it increments all the sort indices by one so the new sort index
* becomes the first without having to rely on the creation date for the sorting.
*
* @param area Area to save
*/
public void saveArea(Area area) {
String currentUser = getCurrentUser();
saveArea( area, currentUser);
}
public void saveArea(Area area, String currentUser){
boolean isNew = area.getId() == null;
area.setModified(new Date());
area.setModifiedBy(currentUser);
boolean someForumHasZeroSortIndex = false;
// If the open forums were not loaded then there is no need to redo the sort index
// thus if it's a hibernate persistentset and initialized
if( area.getOpenForumsSet() != null &&
((area.getOpenForumsSet() instanceof PersistentSet &&
((PersistentSet)area.getOpenForumsSet()).wasInitialized()) || !(area.getOpenForumsSet() instanceof PersistentSet) )) {
for(Iterator i = area.getOpenForums().iterator(); i.hasNext(); ) {
BaseForum forum = (BaseForum)i.next();
if(forum.getSortIndex().intValue() == 0) {
someForumHasZeroSortIndex = true;
break;
}
}
if(someForumHasZeroSortIndex) {
for(Iterator i = area.getOpenForums().iterator(); i.hasNext(); ) {
BaseForum forum = (BaseForum)i.next();
forum.setSortIndex(Integer.valueOf(forum.getSortIndex().intValue() + 1));
}
}
}
// until we have a settings screen to allow the user to hide all forums,
// the area will always be available.
area.setAvailability(true);
getHibernateTemplate().saveOrUpdate(area);
LOG.debug("saveArea executed with areaId: " + area.getId());
}
public void deleteArea(Area area) {
getHibernateTemplate().delete(area);
LOG.debug("deleteArea executed with areaId: " + area.getId());
}
/**
* ContextId is present site id for now.
*/
private String getContextId() {
if (TestUtil.isRunningTests()) {
return "test-context";
}
Placement placement = ToolManager.getCurrentPlacement();
String presentSiteId = placement.getContext();
return presentSiteId;
}
public Area getAreaByContextIdAndTypeId(final String typeId) {
LOG.debug("getAreaByContextIdAndTypeId executing for current user: " + getCurrentUser());
return this.getAreaByContextIdAndTypeId(getContextId(), typeId);
}
public Area getAreaByContextIdAndTypeId(final String contextId, final String typeId) {
LOG.debug("getAreaByContextIdAndTypeId executing for current user: " + getCurrentUser());
HibernateCallback hcb = new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Query q = session.getNamedQuery(QUERY_AREA_BY_CONTEXT_AND_TYPE_ID);
q.setParameter("contextId", contextId, Hibernate.STRING);
q.setParameter("typeId", typeId, Hibernate.STRING);
return q.uniqueResult();
}
};
return (Area) getHibernateTemplate().execute(hcb);
}
public Area getAreaByType(final String typeId) {
final String currentUser = getCurrentUser();
LOG.debug("getAreaByType executing for current user: " + currentUser);
HibernateCallback hcb = new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Query q = session.getNamedQuery(QUERY_AREA_BY_TYPE);
q.setParameter("typeId", typeId, Hibernate.STRING);
return q.uniqueResult();
}
};
return (Area) getHibernateTemplate().execute(hcb);
}
// helpers
private String getNextUuid() {
return idManager.createUuid();
}
private String getCurrentUser() {
String user = sessionManager.getCurrentSessionUserId();
return (user == null) ? "test-user" : user;
}
private String getEventMessage(Object object) {
return "/MessageCenter/site/" + getContextId() + "/" + object.toString() + "/" + getCurrentUser();
//return "MessageCenter::" + getCurrentUser() + "::" + object.toString();
}
/**
* Gets Strings from Message Bundle (specifically for titles)
*
* @param key
* Message bundle key for String wanted
*
* @return
* String requested or "[missing key: key]" if not found
*/
public String getResourceBundleString(String key)
{
final ResourceLoader rb = new ResourceLoader(MESSAGECENTER_BUNDLE);
return rb.getString(key);
}
private String getResourceBundleString(String key, Object[] replacementValues)
{
final ResourceLoader rb = new ResourceLoader(MESSAGECENTER_BUNDLE);
return rb.getFormattedMessage(key, replacementValues);
}
}