DefaultForumService.java
/*
* Copyright (C) 2000 - 2024 Silverpeas
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* As a special exception to the terms and conditions of version 3.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* Open Source Software ("FLOSS") applications as described in Silverpeas's
* FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* "https://www.silverpeas.org/legal/floss_exception.html"
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.silverpeas.components.forums.service;
import org.silverpeas.components.forums.ForumsContentManager;
import org.silverpeas.components.forums.model.Forum;
import org.silverpeas.components.forums.model.ForumDetail;
import org.silverpeas.components.forums.model.ForumPK;
import org.silverpeas.components.forums.model.ForumPath;
import org.silverpeas.components.forums.model.Message;
import org.silverpeas.components.forums.model.MessagePK;
import org.silverpeas.components.forums.model.MessagePath;
import org.silverpeas.components.forums.model.Moderator;
import org.silverpeas.components.forums.subscription.ForumMessageSubscription;
import org.silverpeas.components.forums.subscription.ForumMessageSubscriptionResource;
import org.silverpeas.components.forums.subscription.ForumSubscription;
import org.silverpeas.components.forums.subscription.ForumSubscriptionResource;
import org.silverpeas.core.ResourceReference;
import org.silverpeas.core.annotation.Service;
import org.silverpeas.core.contribution.attachment.AttachmentServiceProvider;
import org.silverpeas.core.contribution.attachment.model.SimpleDocument;
import org.silverpeas.core.contribution.content.wysiwyg.service.WysiwygController;
import org.silverpeas.core.contribution.contentcontainer.content.ContentManagerException;
import org.silverpeas.core.contribution.rating.model.ContributionRatingPK;
import org.silverpeas.core.contribution.rating.service.RatingService;
import org.silverpeas.core.index.indexing.model.FullIndexEntry;
import org.silverpeas.core.index.indexing.model.IndexEngineProxy;
import org.silverpeas.core.index.indexing.model.IndexEntryKey;
import org.silverpeas.core.node.model.NodeDetail;
import org.silverpeas.core.node.model.NodePK;
import org.silverpeas.core.node.service.NodeService;
import org.silverpeas.core.persistence.jdbc.DBUtil;
import org.silverpeas.core.subscription.SubscriptionService;
import org.silverpeas.core.subscription.SubscriptionServiceProvider;
import org.silverpeas.core.subscription.service.ComponentSubscriptionResource;
import org.silverpeas.core.subscription.service.ResourceSubscriptionProvider;
import org.silverpeas.core.subscription.util.SubscriptionSubscriberList;
import org.silverpeas.core.tagcloud.dao.TagCloudPK;
import org.silverpeas.core.tagcloud.model.TagCloud;
import org.silverpeas.core.tagcloud.model.TagCloudUtil;
import org.silverpeas.core.tagcloud.service.TagCloudService;
import org.silverpeas.core.util.StringUtil;
import javax.inject.Inject;
import javax.transaction.Transactional;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import static org.silverpeas.core.i18n.I18NHelper.DEFAULT_LANGUAGE;
/**
* Forums service layer which manage forums application
*/
@Service
@Transactional(Transactional.TxType.SUPPORTS)
public class DefaultForumService implements ForumService {
private static final String RESOURCE_TYPE = "Forum";
@Inject
private TagCloudService tagcloud;
@Inject
private RatingService notation;
@Inject
private NodeService node;
@Inject
private ForumsContentManager forumsContentManager;
@Override
public Collection<ForumDetail> getForums(Collection<ForumPK> forumPKs) {
try (Connection con = openConnection()) {
return ForumsDAO.selectByForumPKs(con, forumPKs);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public Forum getForum(ForumPK forumPK) {
try (Connection con = openConnection()) {
return ForumsDAO.getForum(con, forumPK);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public ForumPath getForumPath(final ForumPK forumPK) {
final List<Forum> path = new ArrayList<>();
try (Connection con = openConnection()) {
Forum currentForum = ForumsDAO.getForum(con, forumPK);
if (currentForum != null) {
path.add(currentForum);
while (currentForum != null && !currentForum.isRoot()) {
currentForum = ForumsDAO.getForum(con,
new ForumPK(forumPK.getInstanceId(), currentForum.getParentIdAsString()));
if (currentForum != null) {
path.add(currentForum);
}
}
}
return new ForumPath(path);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Gets all forums of an instanceId that have not parent forum.
* @param instanceId
* @return
*/
@Override
public Collection<Forum> getForumRootList(final String instanceId) {
Collection<String> forumRootIds = getForumSonsIds(new ForumPK(instanceId, "0"));
Collection<Forum> forumRoots = new ArrayList<>();
for (String forumRootId : forumRootIds) {
forumRoots.add(getForum(new ForumPK(instanceId, forumRootId)));
}
return forumRoots;
}
@Override
public Collection<Forum> getForumsList(Collection<ForumPK> forumPKs) {
try (Connection con = openConnection()) {
return ForumsDAO.getForumsByKeys(con, forumPKs);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public Collection<Message> getThreadsList(Collection<MessagePK> messagePKs) {
try (Connection con = openConnection()) {
return ForumsDAO.getThreadsByKeys(con, messagePKs);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public String getForumName(int forumId) {
try (Connection con = openConnection()) {
return ForumsDAO.getForumName(con, forumId);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public void deleteAll(final String instanceId) {
try (Connection con = openConnection()) {
ForumsDAO.deleteAllForums(con, instanceId);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public boolean isForumActive(int forumId) {
try (Connection con = openConnection()) {
return ForumsDAO.isForumActive(con, forumId);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public int getForumParentId(int forumId) {
try (Connection con = openConnection()) {
return ForumsDAO.getForumParentId(con, forumId);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public String getForumInstanceId(int forumId) {
try (Connection con = openConnection()) {
return ForumsDAO.getForumInstanceId(con, forumId);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
public String getForumCreatorId(int forumId) {
try (Connection con = openConnection()) {
return ForumsDAO.getForumCreatorId(con, forumId);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* @param forumPK
* @return
*/
@Override
public List<Forum> getForums(ForumPK forumPK) {
try (Connection con = openConnection()) {
return ForumsDAO.getForumsList(con, forumPK);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public ForumDetail getForumDetail(ForumPK forumPK) {
try (Connection con = openConnection()) {
return ForumsDAO.getForumDetail(con, forumPK);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public List<Forum> getForumsByCategory(ForumPK forumPK, String categoryId) {
try (Connection con = openConnection()) {
return ForumsDAO.getForumsListByCategory(con, forumPK, categoryId);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* @param forumPK
* @return
*/
@Override
public List<String> getForumSonsIds(ForumPK forumPK) {
try (Connection con = openConnection()) {
return ForumsDAO.getForumSonsIds(con, forumPK);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Verrouille recursivement l'arborescence d'un forum en ecriture a partir de sa primary key
* @param forumPK la primary key du forum
* @param level le niveau de verrouillage
*/
@Override
public void lockForum(ForumPK forumPK, int level) {
List<String> sonsIds = getForumSonsIds(forumPK);
for (String sonsId : sonsIds) {
lockForum(new ForumPK(forumPK.getComponentName(), sonsId), level);
}
try (Connection con = openConnection()) {
ForumsDAO.lockForum(con, forumPK, level);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Deverrouille recursivement un forum en ecriture a partir de sa primary key
* @param forumPK la primary key du forum
* @param level le niveau de verrouillage
* @return int le code d'erreur
*/
@Override
public int unlockForum(ForumPK forumPK, int level) {
List<String> sonsIds = getForumSonsIds(forumPK);
for (String sonsId : sonsIds) {
unlockForum(new ForumPK(forumPK.getComponentName(), sonsId), level);
}
try (Connection con = openConnection()) {
return ForumsDAO.unlockForum(con, forumPK, level);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Supprime un forum et tous ses sous-forums a partir de sa primary key
* @param forumPK la primary key du forum
*/
@Transactional(Transactional.TxType.REQUIRED)
@Override
public void deleteForum(ForumPK forumPK) {
List<String> sonsIds = getForumSonsIds(forumPK);
for (String sonsId : sonsIds) {
deleteForum(new ForumPK(forumPK.getComponentName(), sonsId));
}
try (Connection con = openConnection()) {
// Deleting subscriptions
getSubscribeService().unsubscribeByResource(ForumSubscriptionResource.from(forumPK));
// Recuperation des ids de messages
List<String> messagesIds = getMessagesIds(forumPK);
// Suppression du forum et de ses messages
ForumsDAO.deleteForum(con, forumPK);
// Suppression de l'index du forum dans le moteur de recherches
deleteIndex(forumPK);
// Suppression de l'index de chaque message dans le moteur de recherches
for (String messagesId : messagesIds) {
deleteMessage(new MessagePK(forumPK.getComponentName(), messagesId));
}
forumsContentManager.deleteSilverContent(con, forumPK);
deleteTagCloud(forumPK);
deleteNotation(forumPK);
} catch (ContentManagerException | SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Cree un nouveau forum dans la datasource
* @param forumPK la primary key
* @param forumName nom du forum
* @param forumDescription description du forum
* @param forumCreator l'id du createur du forum
* @param forumParent l'id du forum parent
* @param categoryId l'id de la categorie
* @param keywords
* @return String l'id du nouveau forum
* @author frageade
*/
@Transactional(Transactional.TxType.REQUIRED)
@Override
public int createForum(ForumPK forumPK, String forumName, String forumDescription,
String forumCreator, int forumParent, String categoryId, String keywords) {
try (Connection con = openConnection()) {
int forumId = ForumsDAO
.createForum(con, forumPK, forumName, forumDescription, forumCreator, forumParent,
categoryId);
forumPK.setId(String.valueOf(forumId));
createIndex(forumPK);
forumsContentManager.createSilverContent(con, forumPK, forumCreator);
createTagCloud(forumPK, keywords);
return forumId;
} catch (ContentManagerException | SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Met a jour les informations sur un forum dans la datasource
* @param forumPK la primary key du forum
* @param forumName nom du forum
* @param forumDescription description du forum
* @param forumParent l'id du forum parent
* @param categoryId l'id de la catégorie
* @param keywords the keywords associated to this forum.
*/
@Override
public void updateForum(ForumPK forumPK, String forumName, String forumDescription,
int forumParent, String categoryId, String keywords) {
updateForum(forumPK, forumName, forumDescription, forumParent, categoryId, keywords, true);
}
private void updateForum(ForumPK forumPK, String forumName, String forumDescription,
int forumParent, String categoryId, String keywords, boolean updateTagCloud) {
try (Connection con = openConnection()) {
ForumsDAO.updateForum(con, forumPK, forumName, forumDescription, forumParent, categoryId);
deleteIndex(forumPK);
createIndex(forumPK);
if (updateTagCloud) {
updateTagCloud(forumPK, keywords);
}
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* @param forumPK
* @return
*/
private List<Message> getMessagesList(ForumPK forumPK) {
try (Connection con = openConnection()) {
return ForumsDAO.getMessagesList(con, forumPK);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public Collection<Message> getMessages(ForumPK forumPK) {
List<Message> messages = getMessagesList(forumPK);
String componentId = forumPK.getInstanceId();
for (Message message : messages) {
message.setText(getWysiwygContent(componentId, String.valueOf(message.getId())));
}
return messages;
}
private List<String> getSubjectsIds(ForumPK forumPK) {
try (Connection con = openConnection()) {
return ForumsDAO.getSubjectsIds(con, forumPK);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
private List<String> getMessagesIds(ForumPK forumPK, int messageParentId) {
try (Connection con = openConnection()) {
return ForumsDAO.getMessagesIds(con, forumPK, messageParentId);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
private List<String> getMessagesIds(ForumPK forumPK) {
return getMessagesIds(forumPK, -1);
}
@Override
public int getNbMessages(int forumId, String type, String status) {
try (Connection con = openConnection()) {
return ForumsDAO.getNbMessages(con, forumId, type, status);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public int getAuthorNbMessages(String userId, String status) {
try (Connection con = openConnection()) {
return ForumsDAO.getAuthorNbMessages(con, userId, status);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public int getNbResponses(int forumId, int messageId, String status) {
try (Connection con = openConnection()) {
return ForumsDAO.getNbResponses(con, forumId, messageId, status);
} catch (Exception e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Retourne le dernier message d'un forum
* @param forumPK la primary key du forum
* @param status
* @return the last message in a forum with the specified status.
* @author sfariello
*/
@Override
public Message getLastMessage(ForumPK forumPK, String status) {
try (Connection con = openConnection()) {
return ForumsDAO.getLastMessage(con, forumPK, status);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public Collection getLastMessageRSS(String instanceId, int nbReturned) {
int countdown = nbReturned;
// retourne les nbReturned messages des forums de l'instance instanceId
Collection messages = new ArrayList();
try (Connection con = openConnection()) {
// récupère la liste des id des messages
Collection<String> allMessagesIds = ForumsDAO.getLastMessageRSS(con, instanceId);
Iterator<String> it = allMessagesIds.iterator();
// prendre que les nbReturned derniers
while (it.hasNext() && countdown != 0) {
String messageId = it.next();
MessagePK messagePK = new MessagePK(instanceId, messageId);
messages.add(getMessageInfos(messagePK));
countdown--;
}
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
return messages;
}
@Override
public Message getLastMessage(ForumPK forumPK, int messageParentId, String status) {
try {
// liste de tous les messages de la discussion
List<String> messagesIds = getMessagesIds(forumPK, messageParentId);
// ajouter la "racine" du message dans la liste de ses réponses
messagesIds.add(String.valueOf(messageParentId));
// récupération de la date du dernier message du forum
return getLastMessage(forumPK, messagesIds, status);
} catch (Exception e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public Message getLastMessage(ForumPK forumPK, List<String> messageParentIds, String status) {
try (Connection con = openConnection()) {
return ForumsDAO.getLastMessage(con, forumPK, messageParentIds, status);
} catch (Exception e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Retourne vrai s'il y a des messages non lus sur ce forum depuis la dernière visite
* @param userId l'id de l'utilisateur
* @param forumPK l'id du forum
* @param status le status (validé, en attente, ...)
* @return
*/
@Override
public boolean isNewMessageByForum(String userId, ForumPK forumPK, String status) {
// liste de tous les sujets du forum
List<String> messagesIds = getSubjectsIds(forumPK);
int messageParentId;
for (String messagesId : messagesIds) {
// pour ce message on recherche la date de la dernière visite
messageParentId = Integer.parseInt(messagesId);
if (isNewMessage(userId, forumPK, messageParentId, status)) {
return true;
}
}
return false;
}
@Override
public boolean isNewMessage(String userId, ForumPK forumPK, int messageParentId, String status) {
try (Connection con = openConnection()) {
// liste de tous les messages de la discussion
List<String> messagesIds = getMessagesIds(forumPK, messageParentId);
// ajouter la "racine" du message dans la liste de ses réponses
messagesIds.add(String.valueOf(messageParentId));
// récupération de la date du dernier message du forum
Message message = getLastMessage(forumPK, messagesIds, status);
// date du dernier message de la discussion
Date dateLastMessageBySubject = (message != null ? message.getDate() : null);
// recherche sur tous les messages de la date de visite la plus ancienne
// date de la dernière visite pour un message
Date dateLastVisit = ForumsDAO.getLastVisit(con, userId, messagesIds);
if (dateLastMessageBySubject == null || dateLastVisit == null ||
dateLastVisit.before(dateLastMessageBySubject)) {
// la date de dernière visite de ce message est antérieure à la date du
// dernier message, il y a donc des réponses non lues pour ce message
return true;
}
} catch (Exception e) {
throw new ForumsRuntimeException(e);
}
return false;
}
/**
* enregistre la date de la dernière visite d'un utilisateur sur un forum
* @param messageId l'id du message
* @param userId l'id de l'utilisateur
* @author sfariello
*/
@Override
public void setLastVisit(String userId, int messageId) {
try (Connection con = openConnection()) {
ForumsDAO.addLastVisit(con, userId, messageId);
} catch (Exception e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Recupere les infos d'un message
* @param messagePK la primary key du message
* @return Vector la liste des champs du message
* @author frageade
* @since 04 Octobre 2000
*/
private List getMessageInfos(MessagePK messagePK) {
try (Connection con = openConnection()) {
return ForumsDAO.getMessageInfos(con, messagePK);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public Message getMessage(MessagePK messagePK) {
try (Connection con = openConnection()) {
Message message = ForumsDAO.getMessage(con, messagePK);
if (message != null) {
message.setText(getWysiwygContent(messagePK.getInstanceId(), messagePK.getId()));
}
return message;
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public MessagePath getMessagePath(final MessagePK messagePK) {
final List<Message> path = new ArrayList<>();
Message currentMessage = getMessage(messagePK);
if (currentMessage != null) {
path.add(currentMessage);
while (currentMessage != null && !currentMessage.isSubject()) {
currentMessage = getMessage(
new MessagePK(messagePK.getInstanceId(), currentMessage.getParentIdAsString()));
if (currentMessage != null) {
path.add(currentMessage);
}
}
}
final Message subject = path.iterator().next();
return new MessagePath(
getForumPath(new ForumPK(subject.getInstanceId(), subject.getForumIdAsString())), path);
}
@Override
public String getMessageTitle(int messageId) {
try (Connection con = openConnection()) {
return ForumsDAO.getMessageTitle(con, messageId);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public int getMessageParentId(int messageId) {
try (Connection con = openConnection()) {
return ForumsDAO.getMessageParentId(con, messageId);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Create new forum message
* @param messagePK message primary key identifier
* @param title message title
* @param authorId message author identifier
* @param creationDate creation date
* @param forumId forum identifier
* @param parentId parent message identifier
* @param content message content
* @param keywords the message keywords
* @param status the message status
* @return new message identifier
*/
@Transactional(Transactional.TxType.REQUIRED)
@Override
public int createMessage(MessagePK messagePK, String title, String authorId, Date creationDate,
int forumId, int parentId, String content, String keywords, String status) {
try (Connection con = openConnection()) {
int messageId =
ForumsDAO.createMessage(con, title, authorId, creationDate, forumId, parentId, status);
messagePK.setId(String.valueOf(messageId));
createTagCloud(messagePK, keywords);
createWysiwyg(messagePK, content, authorId);
createIndex(messagePK);
return messageId;
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Transactional(Transactional.TxType.REQUIRED)
@Override
public void updateMessage(MessagePK messagePK, String title, String message, String userId,
String status) {
try (Connection con = openConnection()) {
deleteIndex(messagePK);
ForumsDAO.updateMessage(con, messagePK, title, status);
updateWysiwyg(messagePK, message, userId);
createIndex(messagePK);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public void updateMessageKeywords(MessagePK messagePK, String keywords) {
try {
updateTagCloud(messagePK, keywords);
} catch (Exception e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Supprime un message et tous ses sous-messages a partir de sa primary key
* @param messagePK la primary key du message
* @author frageade
* @since 04 Octobre 2000
*/
@Transactional(Transactional.TxType.REQUIRED)
@Override
public void deleteMessage(MessagePK messagePK) {
try (Connection con = openConnection()) {
Collection<String> messageChildren = ForumsDAO.getMessageSons(con, messagePK);
if (!messageChildren.isEmpty()) {
for (String child : messageChildren) {
deleteMessage(new MessagePK(messagePK.getComponentName(), child));
}
}
// Deleting subscriptions
getSubscribeService().unsubscribeByResource(ForumMessageSubscriptionResource.from(messagePK));
ForumsDAO.deleteMessage(con, messagePK);
deleteIndex(messagePK);
deleteTagCloud(messagePK);
deleteNotation(messagePK);
deleteAllAttachments(messagePK);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* @param userId
* @param forumPK
* @return
*/
@Override
public boolean isModerator(String userId, ForumPK forumPK) {
if (!("0".equals(forumPK.getId()))) {
try (Connection con = openConnection()) {
return ForumsDAO.isModerator(con, forumPK, userId);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
return false;
}
/**
* @param forumPK
* @param userId
*/
@Override
public void addModerator(ForumPK forumPK, String userId) {
try (Connection con = openConnection()) {
ForumsDAO.addModerator(con, forumPK, userId);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* @param forumPK
* @param userId
*/
@Override
public void removeModerator(ForumPK forumPK, String userId) {
try (Connection con = openConnection()) {
ForumsDAO.removeModerator(con, forumPK, userId);
} catch (Exception e) {
throw new ForumsRuntimeException(e);
}
}
/**
* @param forumPK
*/
@Override
public void removeAllModerators(ForumPK forumPK) {
try (Connection con = openConnection()) {
ForumsDAO.removeAllModerators(con, forumPK);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public List<Moderator> getModerators(int forumId) {
try (Connection con = openConnection()) {
List<Moderator> moderators = ForumsDAO.getModerators(con, forumId);
int parentId = getForumParentId(forumId);
while (parentId > 0) {
for (Moderator moderatorByInheritance : ForumsDAO.getModerators(con, parentId)) {
moderatorByInheritance.setByInheritance(true);
moderators.add(moderatorByInheritance);
}
parentId = getForumParentId(parentId);
}
return moderators;
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* @param messagePK
* @param forumPK
*/
@Transactional(Transactional.TxType.REQUIRED)
@Override
public void moveMessage(MessagePK messagePK, ForumPK forumPK) {
try (Connection con = openConnection()) {
Collection<String> children = ForumsDAO.getMessageSons(con, messagePK);
if (!children.isEmpty()) {
for (String childId : children) {
moveMessage(new MessagePK(messagePK.getComponentName(), childId), forumPK);
}
}
ForumsDAO.moveMessage(con, messagePK, forumPK);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Liste tous les sous-messages d'un message
* @param messagePK la primary key du message pere
* @return Vector liste des ids fils
* @author frageade
*/
public Collection<String> getMessageSons(MessagePK messagePK) {
try (Connection con = openConnection()) {
return ForumsDAO.getMessageSons(con, messagePK);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Liste tous les sous-messages d'un message récursivement
* @param messagePK la primary key du message pere
* @return Vector liste des ids fils
* @author frageade
*/
public Collection<String> getAllMessageSons(MessagePK messagePK) {
try (Connection con = openConnection()) {
return ForumsDAO.getAllMessageSons(con, messagePK);
} catch (SQLException e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Subscribe the given user to the given forum message.
* @param messagePK
* @param userId
*/
@Transactional(Transactional.TxType.REQUIRED)
@Override
public void subscribeMessage(MessagePK messagePK, String userId) {
getSubscribeService().subscribe(new ForumMessageSubscription(userId, messagePK));
}
/**
* Unsubscribe the given user to the given forum message.
* @param messagePK
* @param userId
*/
@Transactional(Transactional.TxType.REQUIRED)
@Override
public void unsubscribeMessage(MessagePK messagePK, String userId) {
getSubscribeService().unsubscribe(new ForumMessageSubscription(userId, messagePK));
}
/**
* Subscribe the given user to the given forum.
* @param forumPK
* @param userId
*/
@Transactional(Transactional.TxType.REQUIRED)
@Override
public void subscribeForum(final ForumPK forumPK, final String userId) {
getSubscribeService().subscribe(new ForumSubscription(userId, forumPK));
}
/**
* Unsubscribe the given user to the given forum.
* @param forumPK
* @param userId
*/
@Transactional(Transactional.TxType.REQUIRED)
@Override
public void unsubscribeForum(final ForumPK forumPK, final String userId) {
getSubscribeService().unsubscribe(new ForumSubscription(userId, forumPK));
}
/**
* Gets the list of subscribers related to the given forum message primary key.
* @param messagePK
* @return
*/
@Override
public SubscriptionSubscriberList listAllSubscribers(MessagePK messagePK) {
return ResourceSubscriptionProvider
.getSubscribersOfSubscriptionResource(ForumMessageSubscriptionResource.from(messagePK));
}
/**
* Gets the list of subscribers related to the given forum primary key.
* @param forumPK
* @return
*/
@Override
public SubscriptionSubscriberList listAllSubscribers(final ForumPK forumPK) {
return ResourceSubscriptionProvider
.getSubscribersOfSubscriptionResource(ForumSubscriptionResource.from(forumPK));
}
/**
* Gets the list of subscribers to the given component instance identifier.
* This kind of subscribers come from WEB-Service subscriptions (/services/subscribe/{instanceId})
* @param instanceId
* @return
*/
@Override
public SubscriptionSubscriberList listAllSubscribers(final String instanceId) {
return ResourceSubscriptionProvider.getSubscribersOfComponent(instanceId);
}
/**
* Indicates if the given user has subscribed to the given forum message identifier.
* @param messagePK
* @param userId
* @return
*/
@Override
public boolean isSubscriber(MessagePK messagePK, String userId) {
return getSubscribeService()
.isUserSubscribedToResource(userId, ForumMessageSubscriptionResource.from(messagePK));
}
/**
* Indicates if the given user is subscribed by inheritance to the given forum message
* identifier.
* @param messagePK
* @param userId
* @return
*/
@Override
public boolean isSubscriberByInheritance(final MessagePK messagePK, final String userId) {
return !isSubscriber(messagePK, userId) && ResourceSubscriptionProvider
.getSubscribersOfSubscriptionResource(ForumMessageSubscriptionResource.from(messagePK))
.getAllUserIds().contains(userId);
}
/**
* Indicates if the given user has subscribed to the given forum identifier.
* @param forumPK
* @param userId
* @return
*/
@Override
public boolean isSubscriber(final ForumPK forumPK, final String userId) {
return getSubscribeService()
.isUserSubscribedToResource(userId, ForumSubscriptionResource.from(forumPK));
}
/**
* Indicates if the given user is subscribed by inheritance to the given forum identifier.
* @param forumPK
* @param userId
* @return
*/
@Override
public boolean isSubscriberByInheritance(final ForumPK forumPK, final String userId) {
return !isSubscriber(forumPK, userId) && ResourceSubscriptionProvider
.getSubscribersOfSubscriptionResource(ForumSubscriptionResource.from(forumPK))
.getAllUserIds().contains(userId);
}
/**
* Indicates if the given user has subscribed to the given component instance identifier.
* @param instanceId
* @param userId
* @return
*/
@Override
public boolean isSubscriber(final String instanceId, final String userId) {
return getSubscribeService()
.isUserSubscribedToResource(userId, ComponentSubscriptionResource.from(instanceId));
}
/**
* Method declaration
* @param messagePK
*
*/
@Override
public void createIndex(MessagePK messagePK) {
if (messagePK != null) {
Message message = getMessage(messagePK);
String componentId = messagePK.getComponentName();
String messageId = messagePK.getId();
FullIndexEntry indexEntry = new FullIndexEntry(componentId, "Message", messageId);
indexEntry.setTitle(message.getTitle());
indexEntry.setCreationDate(message.getDate());
indexEntry.setCreationUser(message.getAuthor());
WysiwygController.addToIndex(indexEntry, new ResourceReference(messagePK), DEFAULT_LANGUAGE);
IndexEngineProxy.addIndexEntry(indexEntry);
}
}
/**
* @param messagePK
*/
private void deleteIndex(MessagePK messagePK) {
IndexEngineProxy.removeIndexEntry(
new IndexEntryKey(messagePK.getComponentName(), "Message", messagePK.getId()));
}
/**
* @param forumPK
*/
@Override
public void createIndex(ForumPK forumPK) {
if (forumPK != null) {
Forum forum = getForum(forumPK);
FullIndexEntry indexEntry =
new FullIndexEntry(forumPK.getComponentName(), RESOURCE_TYPE, forumPK.
getId());
indexEntry.setTitle(forum.getName());
indexEntry.setPreview(forum.getDescription());
IndexEngineProxy.addIndexEntry(indexEntry);
}
}
/**
* @param forumPK
*/
private void deleteIndex(ForumPK forumPK) {
IndexEngineProxy.removeIndexEntry(
new IndexEntryKey(forumPK.getComponentName(), RESOURCE_TYPE, forumPK.
getId()));
}
/**
* Open connection
* @return the connection
*/
protected Connection openConnection() {
try {
return DBUtil.openConnection();
} catch (SQLException ue) {
throw new ForumsRuntimeException(ue);
}
}
@Override
public int getSilverObjectId(ForumPK forumPK) {
int silverObjectId = -1;
try {
int forumId = Integer.parseInt(forumPK.getId());
String instanceId = forumPK.getComponentName();
if (instanceId == null || instanceId.length() == 0) {
instanceId = getForumInstanceId(forumId);
forumPK.setComponentName(instanceId);
}
silverObjectId = forumsContentManager.getSilverContentId(forumPK.getId(), instanceId);
if (silverObjectId == -1) {
String creatorId = getForumCreatorId(forumId);
silverObjectId = forumsContentManager.createSilverContent(null, forumPK, creatorId);
}
} catch (Exception e) {
throw new ForumsRuntimeException(e);
}
return silverObjectId;
}
@Transactional(Transactional.TxType.REQUIRED)
@Override
public String createCategory(NodeDetail category) {
try {
NodePK nodePK = node.createNode(category, new NodeDetail());
return nodePK.getId();
} catch (Exception e) {
throw new ForumsRuntimeException(e);
}
}
@Transactional(Transactional.TxType.REQUIRED)
@Override
public void updateCategory(NodeDetail category) {
node.setDetail(category);
}
@Transactional(Transactional.TxType.REQUIRED)
@Override
public void deleteCategory(String categoryId, String instanceId) {
try {
// pour cette categorie, rechercher les forums et mettre '0' dans la categorie
List<Forum> forums = getForumsByCategory(new ForumPK(instanceId, null), categoryId);
for (Forum forum : forums) {
ForumPK forumPK = new ForumPK(instanceId, forum.getIdAsString());
updateForum(forumPK, forum.getName(), forum.getDescription(), forum.getParentId(), null,
null, false);
}
// suppression de la categorie
NodePK nodePk = new NodePK(categoryId, instanceId);
node.removeNode(nodePk);
} catch (Exception e) {
throw new ForumsRuntimeException(e);
}
}
@Override
public NodeDetail getCategory(NodePK pk) {
return node.getDetail(pk);
}
@Override
public Collection<NodeDetail> getAllCategories(String instanceId) {
return node.getChildrenDetails(new NodePK(NodePK.ROOT_NODE_ID, instanceId));
}
@Override
public Collection<Message> getLastThreads(ForumPK forumPK, int count) {
return getLastThreads(forumPK, count, false);
}
@Override
public Collection<Message> getNotAnsweredLastThreads(ForumPK forumPK, int count) {
return getLastThreads(forumPK, count, true);
}
private Collection<Message> getLastThreads(ForumPK forumPK, int count, boolean notAnswered) {
try (Connection con = openConnection()) {
ForumPK[] forumPKs;
if ("0".equals(forumPK.getId())) {
// Derniers threads des forums du composant.
List<String> forumsIds = ForumsDAO.getForumsIds(con, forumPK);
int forumsCount = forumsIds.size();
forumPKs = new ForumPK[forumsCount];
String componentId = forumPK.getComponentName();
for (int i = 0; i < forumsCount; i++) {
forumPKs[i] = new ForumPK(componentId, forumsIds.get(i));
}
} else {
// Derniers threads du forum.
forumPKs = new ForumPK[]{forumPK};
}
if (notAnswered) {
// Threads non répondus.
return ForumsDAO.getNotAnsweredLastThreads(con, forumPKs, count);
} else {
// Tous les threads.
return ForumsDAO.getLastThreads(con, forumPKs, count);
}
} catch (Exception e) {
throw new ForumsRuntimeException(e);
}
}
/**
* Create the tagclouds corresponding to the forum detail.
* @param forumPK theprimary key of the forum.
* @
*/
private void createTagCloud(ForumPK forumPK, String keywords) {
TagCloud tagCloud =
new TagCloud(forumPK.getComponentName(), forumPK.getId(), TagCloud.TYPE_FORUM);
createTagCloud(tagCloud, keywords);
}
private void createTagCloud(MessagePK messagePK, String keywords) {
TagCloud tagCloud =
new TagCloud(messagePK.getComponentName(), messagePK.getId(), TagCloud.TYPE_MESSAGE);
createTagCloud(tagCloud, keywords);
}
private void createTagCloud(TagCloud tags, String keywords) {
if (keywords != null) {
String[] words = StringUtil.split(keywords, ' ');
List<String> tagList = new ArrayList<>(words.length);
for (String tag : words) {
String tagKey = TagCloudUtil.getTag(tag);
if (!tagList.contains(tagKey)) {
tags.setTag(tagKey);
tags.setLabel(tag.toLowerCase());
tagcloud.createTagCloud(tags);
tagList.add(tagKey);
}
}
}
}
/**
* Delete the tagclouds corresponding to the publication key.
* @param forumPK The primary key of the forum.
*/
private void deleteTagCloud(ForumPK forumPK) {
tagcloud.deleteTagCloud(new TagCloudPK(forumPK.getId(), forumPK.getComponentName()),
TagCloud.TYPE_FORUM);
}
private void deleteTagCloud(MessagePK messagePK) {
tagcloud.deleteTagCloud(new TagCloudPK(messagePK.getId(), messagePK.getComponentName()),
TagCloud.TYPE_MESSAGE);
}
/**
* Update the tagclouds corresponding to the publication detail.
* @param forumPK the primary key of the forum.
*/
private void updateTagCloud(ForumPK forumPK, String keywords) {
deleteTagCloud(forumPK);
createTagCloud(forumPK, keywords);
}
private void updateTagCloud(MessagePK messagePK, String keywords) {
deleteTagCloud(messagePK);
createTagCloud(messagePK, keywords);
}
@Override
public String getForumTags(ForumPK forumPK) {
Collection<TagCloud> tagClouds = tagcloud
.getTagCloudsByElement(forumPK.getComponentName(), forumPK.getId(), TagCloud.TYPE_FORUM);
return getTags(tagClouds);
}
@Override
public String getMessageTags(MessagePK messagePK) {
Collection<TagCloud> tagClouds = tagcloud
.getTagCloudsByElement(messagePK.getComponentName(), messagePK.getId(),
TagCloud.TYPE_MESSAGE);
return getTags(tagClouds);
}
private String getTags(Collection<TagCloud> tagClouds) {
StringBuilder sb = new StringBuilder();
for (TagCloud tag : tagClouds) {
if (sb.length() > 0) {
sb.append(' ');
}
sb.append(tag.getLabel());
}
return sb.toString();
}
private void deleteNotation(ForumPK forumPK) {
notation.deleteRating(
new ContributionRatingPK(forumPK.getId(), forumPK.getComponentName(), RESOURCE_TYPE));
}
private void deleteNotation(MessagePK messagePK) {
notation.deleteRating(
new ContributionRatingPK(messagePK.getId(), messagePK.getComponentName(), "ForumMessage"));
}
protected String getWysiwygContent(String componentId, String messageId) {
String text = "";
if (WysiwygController.haveGotWysiwyg(componentId, messageId, DEFAULT_LANGUAGE)) {
text = WysiwygController.load(componentId, messageId, DEFAULT_LANGUAGE);
}
return text;
}
private void createWysiwyg(MessagePK messagePK, String text, String userId) {
WysiwygController.createUnindexedFileAndAttachment(text, new ResourceReference(messagePK),
userId, DEFAULT_LANGUAGE);
}
private void updateWysiwyg(MessagePK messagePK, String text, String userId) {
String componentId = messagePK.getComponentName();
String messageId = messagePK.getId();
if (WysiwygController.haveGotWysiwyg(componentId, messageId, DEFAULT_LANGUAGE)) {
WysiwygController
.updateFileAndAttachment(text, componentId, messageId, userId, DEFAULT_LANGUAGE);
} else {
WysiwygController.createUnindexedFileAndAttachment(text, new ResourceReference(messagePK),
userId, DEFAULT_LANGUAGE);
}
}
private void deleteAllAttachments(MessagePK messagePK) {
ResourceReference foreignKey = new ResourceReference(messagePK);
List<SimpleDocument> documents = AttachmentServiceProvider.getAttachmentService()
.listAllDocumentsByForeignKey(foreignKey, null);
for (SimpleDocument doc : documents) {
AttachmentServiceProvider.getAttachmentService().deleteAttachment(doc);
}
}
/**
* Gets instance of centralized subscription services.
* @return
*/
protected SubscriptionService getSubscribeService() {
return SubscriptionServiceProvider.getSubscribeService();
}
}