Java tutorial
/** * Copyright (C) 2000 - 2013 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: * "http://www.silverpeas.org/docs/core/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 <http://www.gnu.org/licenses/>. */ package com.stratelia.webactiv.kmelia.control.ejb; import com.silverpeas.comment.service.CommentService; import com.silverpeas.comment.service.CommentServiceFactory; import com.silverpeas.component.kmelia.KmeliaCopyDetail; import com.silverpeas.form.DataRecord; import com.silverpeas.form.FormException; import com.silverpeas.form.RecordSet; import com.silverpeas.form.RecordTemplate; import com.silverpeas.form.importExport.XMLField; import com.silverpeas.form.record.GenericRecordSet; import com.silverpeas.formTemplate.dao.ModelDAO; import com.silverpeas.kmelia.notification.KmeliaDefermentPublicationUserNotification; import com.silverpeas.kmelia.notification.KmeliaDocumentSubscriptionPublicationUserNotification; import com.silverpeas.kmelia.notification.KmeliaModificationPublicationUserNotification; import com.silverpeas.kmelia.notification.KmeliaNotifyPublicationUserNotification; import com.silverpeas.kmelia.notification.KmeliaPendingValidationPublicationUserNotification; import com.silverpeas.kmelia.notification.KmeliaSubscriptionPublicationUserNotification; import com.silverpeas.kmelia.notification.KmeliaSupervisorPublicationUserNotification; import com.silverpeas.kmelia.notification.KmeliaTopicUserNotification; import com.silverpeas.kmelia.notification.KmeliaValidationPublicationUserNotification; import com.silverpeas.notification.builder.helper.UserNotificationHelper; import com.silverpeas.pdc.PdcServiceFactory; import com.silverpeas.pdc.ejb.PdcBm; import com.silverpeas.pdc.model.PdcClassification; import com.silverpeas.pdc.service.PdcClassificationService; import com.silverpeas.pdcSubscription.util.PdcSubscriptionUtil; import com.silverpeas.publicationTemplate.PublicationTemplate; import com.silverpeas.publicationTemplate.PublicationTemplateException; import com.silverpeas.publicationTemplate.PublicationTemplateManager; import com.silverpeas.subscribe.Subscription; import com.silverpeas.subscribe.SubscriptionResource; import com.silverpeas.subscribe.SubscriptionService; import com.silverpeas.subscribe.SubscriptionServiceFactory; import com.silverpeas.subscribe.service.NodeSubscription; import com.silverpeas.subscribe.service.NodeSubscriptionResource; import com.silverpeas.subscribe.service.UserSubscriptionSubscriber; import com.silverpeas.thumbnail.ThumbnailException; import com.silverpeas.thumbnail.control.ThumbnailController; import com.silverpeas.thumbnail.model.ThumbnailDetail; import com.silverpeas.thumbnail.service.ThumbnailServiceFactory; import com.silverpeas.util.CollectionUtil; import com.silverpeas.util.FileUtil; import com.silverpeas.util.ForeignPK; import com.silverpeas.util.StringUtil; import com.silverpeas.util.i18n.I18NHelper; import com.stratelia.silverpeas.notificationManager.NotificationMetaData; import com.stratelia.silverpeas.notificationManager.constant.NotifAction; import com.stratelia.silverpeas.pdc.control.PdcBmImpl; import com.stratelia.silverpeas.pdc.model.ClassifyPosition; import com.stratelia.silverpeas.pdc.model.PdcException; import com.stratelia.silverpeas.silverpeasinitialize.CallBackManager; import com.stratelia.silverpeas.silvertrace.SilverTrace; import com.stratelia.webactiv.SilverpeasRole; import com.stratelia.webactiv.beans.admin.AdminController; import com.stratelia.webactiv.beans.admin.ObjectType; import com.stratelia.webactiv.beans.admin.ProfileInst; import com.stratelia.webactiv.beans.admin.UserDetail; import com.stratelia.webactiv.calendar.backbone.TodoBackboneAccess; import com.stratelia.webactiv.calendar.backbone.TodoDetail; import com.stratelia.webactiv.calendar.model.Attendee; import com.stratelia.webactiv.kmelia.KmeliaContentManager; import com.stratelia.webactiv.kmelia.KmeliaSecurity; import com.stratelia.webactiv.kmelia.PublicationImport; import com.stratelia.webactiv.kmelia.model.KmaxRuntimeException; import com.stratelia.webactiv.kmelia.model.KmeliaPublication; import com.stratelia.webactiv.kmelia.model.KmeliaRuntimeException; import com.stratelia.webactiv.kmelia.model.TopicComparator; import com.stratelia.webactiv.kmelia.model.TopicDetail; import com.stratelia.webactiv.util.ActionType; import com.stratelia.webactiv.util.DBUtil; import com.stratelia.webactiv.util.DateUtil; import com.stratelia.webactiv.util.FileRepositoryManager; import com.stratelia.webactiv.util.ResourceLocator; import com.stratelia.webactiv.util.annotation.Action; import com.stratelia.webactiv.util.annotation.SourcePK; import com.stratelia.webactiv.util.annotation.TargetPK; import com.stratelia.webactiv.util.coordinates.control.CoordinatesBm; import com.stratelia.webactiv.util.coordinates.model.Coordinate; import com.stratelia.webactiv.util.coordinates.model.CoordinatePK; import com.stratelia.webactiv.util.coordinates.model.CoordinatePoint; import com.stratelia.webactiv.util.node.control.NodeBm; import com.stratelia.webactiv.util.node.model.NodeDetail; import com.stratelia.webactiv.util.node.model.NodePK; import com.stratelia.webactiv.util.publication.control.PublicationBm; import com.stratelia.webactiv.util.publication.info.model.InfoDetail; import com.stratelia.webactiv.util.publication.info.model.InfoImageDetail; import com.stratelia.webactiv.util.publication.info.model.ModelDetail; import com.stratelia.webactiv.util.publication.info.model.ModelPK; import com.stratelia.webactiv.util.publication.model.Alias; import com.stratelia.webactiv.util.publication.model.CompletePublication; import com.stratelia.webactiv.util.publication.model.NodeTree; import com.stratelia.webactiv.util.publication.model.PublicationDetail; import com.stratelia.webactiv.util.publication.model.PublicationPK; import com.stratelia.webactiv.util.publication.model.ValidationStep; import com.stratelia.webactiv.util.statistic.control.StatisticBm; import com.stratelia.webactiv.util.statistic.model.HistoryObjectDetail; import org.apache.commons.io.FilenameUtils; import org.silverpeas.attachment.AttachmentException; import org.silverpeas.attachment.AttachmentServiceFactory; import org.silverpeas.attachment.model.DocumentType; import org.silverpeas.attachment.model.HistorisedDocument; import org.silverpeas.attachment.model.SimpleAttachment; import org.silverpeas.attachment.model.SimpleDocument; import org.silverpeas.attachment.model.SimpleDocumentPK; import org.silverpeas.component.kmelia.InstanceParameters; import org.silverpeas.component.kmelia.KmeliaPublicationHelper; import org.silverpeas.core.admin.OrganisationController; import org.silverpeas.process.annotation.SimulationActionProcess; import org.silverpeas.process.annotation.SimulationActionProcessAnnotationEJBInterceptor; import org.silverpeas.search.indexEngine.model.IndexManager; import org.silverpeas.wysiwyg.WysiwygException; import org.silverpeas.wysiwyg.control.WysiwygController; import javax.ejb.EJB; import javax.ejb.Stateless; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import javax.interceptor.Interceptors; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response.Status; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.rmi.RemoteException; import java.sql.Connection; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; import static com.silverpeas.util.StringUtil.*; import static com.stratelia.webactiv.util.JNDINames.SILVERPEAS_DATASOURCE; import static com.stratelia.webactiv.util.exception.SilverpeasRuntimeException.ERROR; import static org.silverpeas.attachment.AttachmentService.VERSION_MODE; import static org.silverpeas.core.admin.OrganisationControllerFactory.getOrganisationController; /** * This is the KMelia EJB-tier controller of the MVC. It is implemented as a session EJB. It * controls all the activities that happen in a client session. It also provides mechanisms to * access other session EJBs. * * @author Nicolas Eysseric */ @Stateless(name = "Kmelia", description = "Stateless session bean to manage Kmelia and Kmax.") @TransactionAttribute(TransactionAttributeType.SUPPORTS) public class KmeliaBmEJB implements KmeliaBm { private static final String MESSAGES_PATH = "org.silverpeas.kmelia.multilang.kmeliaBundle"; private static final String SETTINGS_PATH = "org.silverpeas.kmelia.settings.kmeliaSettings"; private static final ResourceLocator settings = new ResourceLocator(SETTINGS_PATH, ""); @EJB private NodeBm nodeBm; @EJB private PublicationBm publicationBm; @EJB private StatisticBm statisticBm; @EJB private PdcBm pdcBm; @EJB private CoordinatesBm coordinatesBm; private CommentService commentService = null; public KmeliaBmEJB() { } private int getNbPublicationsOnRoot(String componentId) { String parameterValue = getOrganisationController().getComponentParameterValue(componentId, "nbPubliOnRoot"); SilverTrace.info("kmelia", "KmeliaBmEJB.getNbPublicationsOnRoot()", "root.MSG_GEN_PARAM_VALUE", "parameterValue=" + parameterValue); if (isDefined(parameterValue)) { return Integer.parseInt(parameterValue); } else { if (KmeliaHelper.isToolbox(componentId)) { return 0; } // lecture du properties ResourceLocator theSettings = getComponentSettings(); return Integer.parseInt(theSettings.getString("HomeNbPublications")); } } private boolean isDraftModeUsed(String componentId) { return "yes".equals(getOrganisationController().getComponentParameterValue(componentId, "draft")); } public SubscriptionService getSubscribeBm() { return SubscriptionServiceFactory.getFactory().getSubscribeService(); } /** * Return a the detail of a topic * * @param pk the id of the topic * @param userId * @param isTreeStructureUsed * @param userProfile * @param isRightsOnTopicsUsed * @return */ @Override public TopicDetail goTo(NodePK pk, String userId, boolean isTreeStructureUsed, String userProfile, boolean isRightsOnTopicsUsed) { SilverTrace.info("kmelia", "KmeliaBmEJB.goTo()", "root.MSG_GEN_ENTER_METHOD"); Collection<NodeDetail> newPath = new ArrayList<NodeDetail>(); NodeDetail nodeDetail = null; // get the basic information (Header) of this topic SilverTrace.info("kmelia", "KmeliaBmEJB.goTo()", "root.MSG_GEN_PARAM_VALUE", "nodeBm.getDetail(pk) BEGIN"); try { nodeDetail = nodeBm.getDetail(pk); if (isRightsOnTopicsUsed) { OrganisationController orga = getOrganisationController(); if (nodeDetail.haveRights() && !orga.isObjectAvailable(nodeDetail.getRightsDependsOn(), ObjectType.NODE, pk.getInstanceId(), userId)) { nodeDetail.setUserRole("noRights"); } List<NodeDetail> availableChildren = getAllowedSubfolders(nodeDetail, userId); nodeDetail.setChildrenDetails(availableChildren); } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.goTo()", ERROR, "kmelia.EX_IMPOSSIBLE_DACCEDER_AU_THEME", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.goTo()", "root.MSG_GEN_PARAM_VALUE", "nodeBm.getDetail(pk) END"); // get publications List<KmeliaPublication> pubDetails = getPublicationsOfFolder(pk, userProfile, userId, isTreeStructureUsed, isRightsOnTopicsUsed); // get the path to this topic SilverTrace.info("kmelia", "KmeliaBmEJB.goTo()", "root.MSG_GEN_PARAM_VALUE", "GetPath BEGIN"); if (pk.isRoot()) { newPath.add(nodeDetail); } else { newPath = getPathFromAToZ(nodeDetail); } SilverTrace.info("kmelia", "KmeliaBmEJB.goTo()", "root.MSG_GEN_PARAM_VALUE", "GetPath END"); SilverTrace.info("kmelia", "KmeliaBmEJB.goTo()", "root.MSG_GEN_EXIT_METHOD"); // set the currentTopic and return it return new TopicDetail(newPath, nodeDetail, pubDetails); } @Override public List<KmeliaPublication> getPublicationsOfFolder(NodePK pk, String userProfile, String userId, boolean isTreeStructureUsed, boolean isRightsOnTopicsUsed) { Collection<PublicationDetail> pubDetails = null; // get the publications associated to this topic if (pk.isTrash()) { // Topic = Basket pubDetails = getPublicationsInBasket(pk, userProfile, userId); } else if (pk.isRoot()) { SilverTrace.info("kmelia", "KmeliaBmEJB.goTo()", "root.MSG_GEN_PARAM_VALUE", "publicationBm.getUnavailablePublicationsByPublisherId(pubPK, currentUser.getId()) BEGIN"); try { int nbPublisOnRoot = getNbPublicationsOnRoot(pk.getInstanceId()); if (nbPublisOnRoot == 0 || !isTreeStructureUsed || KmeliaHelper.isToolbox(pk.getInstanceId())) { pubDetails = publicationBm.getDetailsByFatherPK(pk, "P.pubUpdateDate desc", false); } else { return getLatestPublications(pk.getInstanceId(), nbPublisOnRoot, isRightsOnTopicsUsed, userId); } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getPublicationsOfFolder()", ERROR, "kmelia.EX_IMPOSSIBLE_DAVOIR_LES_DERNIERES_PUBLICATIONS", e); } } else { SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationsOfFolder()", "root.MSG_GEN_PARAM_VALUE", "publicationBm.getDetailsByFatherPK(pk) BEGIN"); try { // get the publication details linked to this topic pubDetails = publicationBm.getDetailsByFatherPK(pk, "P.pubUpdateDate DESC, P.pubId DESC", false); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getPublicationsOfFolder()", ERROR, "kmelia.EX_IMPOSSIBLE_DAVOIR_LA_LISTE_DES_PUBLICATIONS", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationsOfFolder()", "root.MSG_GEN_PARAM_VALUE", "publicationBm.getDetailsByFatherPK(pk) END"); } return pubDetails2userPubs(pubDetails); } @Override public List<KmeliaPublication> getLatestPublications(String instanceId, int nbPublisOnRoot, boolean isRightsOnTopicsUsed, String userId) { PublicationPK pubPK = new PublicationPK("unknown", instanceId); Collection<PublicationDetail> pubDetails = publicationBm .getDetailsByBeginDateDescAndStatusAndNotLinkedToFatherId(pubPK, PublicationDetail.VALID, nbPublisOnRoot, NodePK.BIN_NODE_ID); if (isRightsOnTopicsUsed) {// The list of publications must be filtered List<PublicationDetail> filteredList = new ArrayList<PublicationDetail>(); KmeliaSecurity security = new KmeliaSecurity(); for (PublicationDetail pubDetail : pubDetails) { if (security.isObjectAvailable(instanceId, userId, pubDetail.getPK().getId(), "Publication")) { filteredList.add(pubDetail); } } pubDetails.clear(); pubDetails.addAll(filteredList); } return pubDetails2userPubs(pubDetails); } @Override public List<NodeDetail> getAllowedSubfolders(NodeDetail folder, String userId) { OrganisationController orga = getOrganisationController(); NodePK pk = folder.getNodePK(); List<NodeDetail> children = (List<NodeDetail>) folder.getChildrenDetails(); List<NodeDetail> availableChildren = new ArrayList<NodeDetail>(); for (NodeDetail child : children) { NodePK childId = child.getNodePK(); if (childId.isTrash() || childId.isUnclassed() || !child.haveRights()) { availableChildren.add(child); } else { int rightsDependsOn = child.getRightsDependsOn(); boolean nodeAvailable = orga.isObjectAvailable(rightsDependsOn, ObjectType.NODE, pk.getInstanceId(), userId); if (nodeAvailable) { availableChildren.add(child); } else { // check if at least one descendant is available Iterator<NodeDetail> descendants = nodeBm.getDescendantDetails(child).iterator(); boolean childAllowed = false; while (!childAllowed && descendants.hasNext()) { NodeDetail descendant = descendants.next(); if (descendant.getRightsDependsOn() == rightsDependsOn) { // same rights of father (which is not available) so it is not available too } else { // different rights of father check if it is available if (orga.isObjectAvailable(descendant.getRightsDependsOn(), ObjectType.NODE, pk.getInstanceId(), userId)) { childAllowed = true; if (!availableChildren.contains(child)) { availableChildren.add(child); } } } } } } } return availableChildren; } private Collection<NodeDetail> getPathFromAToZ(NodeDetail nd) { Collection<NodeDetail> newPath = new ArrayList<NodeDetail>(); try { List<NodeDetail> pathInReverse = (List<NodeDetail>) nodeBm.getPath(nd.getNodePK()); // reverse the path from root to leaf for (int i = pathInReverse.size() - 1; i >= 0; i--) { newPath.add(pathInReverse.get(i)); } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getPathFromAToZ()", ERROR, "kmelia.EX_IMPOSSIBLE_DAVOIR_LE_CHEMIN_COURANT", e); } return newPath; } /** * Add a subtopic to a topic - If a subtopic of same name already exists a NodePK with id=-1 is * returned else the new topic NodePK * * @param fatherPK the topic Id of the future father * @param subTopic the NodeDetail of the new sub topic * @return If a subtopic of same name already exists a NodePK with id=-1 is returned else the new * topic NodePK * @see com.stratelia.webactiv.util.node.model.NodeDetail * @see com.stratelia.webactiv.util.node.model.NodePK */ @Override public NodePK addToTopic(NodePK fatherPK, NodeDetail subTopic) { SilverTrace.info("kmelia", "KmeliaBmEJB.addToTopic()", "root.MSG_GEN_ENTER_METHOD"); NodePK theNodePK = null; try { NodeDetail fatherDetail = nodeBm.getHeader(fatherPK); theNodePK = nodeBm.createNode(subTopic, fatherDetail); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.addToTopic()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_CREER_LE_THEME", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.addToTopic()", "root.MSG_GEN_EXIT_METHOD"); return theNodePK; } /** * Add a subtopic to currentTopic and alert users - If a subtopic of same name already exists a * NodePK with id=-1 is returned else the new topic NodePK * * @param fatherPK * @param subTopic the NodeDetail of the new sub topic * @param alertType Alert all users, only publishers or nobody of the topic creation alertType = * "All"|"Publisher"|"None" * @return If a subtopic of same name already exists a NodePK with id=-1 is returned else the new * topic NodePK */ @Override public NodePK addSubTopic(NodePK fatherPK, NodeDetail subTopic, String alertType) { SilverTrace.info("kmelia", "KmeliaBmEJB.addSubTopic()", "root.MSG_GEN_ENTER_METHOD"); // Construction de la date de cration (date courante) String creationDate = DateUtil.today2SQLDate(); subTopic.setCreationDate(creationDate); // Web visibility parameter. The topic is by default invisible. subTopic.setStatus("Invisible"); // add new topic to current topic NodePK pk = addToTopic(fatherPK, subTopic); SilverTrace.info("kmelia", "KmeliaBmEJB.addSubTopic()", "root.MSG_GEN_PARAM_VALUE", "pk = " + pk.toString()); // Creation alert if (!"-1".equals(pk.getId())) { topicCreationAlert(pk, fatherPK, alertType); } SilverTrace.info("kmelia", "KmeliaBmEJB.addSubTopic()", "root.MSG_GEN_EXIT_METHOD"); return pk; } private String displayPath(Collection<NodeDetail> path, int beforeAfter, String language) { StringBuilder pathString = new StringBuilder(); boolean first = true; List<NodeDetail> pathAsList = new ArrayList<NodeDetail>(path); Collections.reverse(pathAsList); // reverse path from root to node for (NodeDetail nodeInPath : pathAsList) { if (!first) { pathString.append(" > "); } first = false; pathString.append(nodeInPath.getName(language)); } return pathString.toString(); } /** * Alert all users, only publishers or nobody of the topic creation or update * * @param nodePK the NodePK of the new sub topic * @param fatherPK the NodePK of the parent topic * @param alertType alertType = "All"|"Publisher"|"None" * @see com.stratelia.webactiv.util.node.model.NodePK * @since 1.0 */ private void topicCreationAlert(final NodePK nodePK, final NodePK fatherPK, final String alertType) { SilverTrace.info("kmelia", "KmeliaBmEJB.topicCreationAlert()", "root.MSG_GEN_ENTER_METHOD"); UserNotificationHelper.buildAndSend(new KmeliaTopicUserNotification(nodePK, fatherPK, alertType)); SilverTrace.info("kmelia", "KmeliaBmEJB.topicCreationAlert()", "root.MSG_GEN_PARAM_VALUE", "AlertType alert = " + alertType); SilverTrace.info("kmelia", "KmeliaBmEJB.topicCreationAlert()", "root.MSG_GEN_EXIT_METHOD"); } /** * Update a subtopic to currentTopic and alert users - If a subtopic of same name already exists a * NodePK with id=-1 is returned else the new topic NodePK * * @param topic the NodeDetail of the updated sub topic * @param alertType Alert all users, only publishers or nobody of the topic creation alertType = * "All"|"Publisher"|"None" * @return If a subtopic of same name already exists a NodePK with id=-1 is returned else the new * topic NodePK * @see com.stratelia.webactiv.util.node.model.NodeDetail * @see com.stratelia.webactiv.util.node.model.NodePK * @since 1.0 */ @Override public NodePK updateTopic(NodeDetail topic, String alertType) { try { // Order of the node must be unchanged NodeDetail oldNode = nodeBm.getHeader(topic.getNodePK()); int order = oldNode.getOrder(); topic.setOrder(order); nodeBm.setDetail(topic); // manage operations relative to folder rights if (isRightsOnTopicsEnabled(topic.getNodePK().getInstanceId())) { if (oldNode.getRightsDependsOn() != topic.getRightsDependsOn()) { // rights dependency have changed if (!topic.haveRights()) { NodeDetail father = nodeBm.getHeader(oldNode.getFatherPK()); topic.setRightsDependsOn(father.getRightsDependsOn()); AdminController admin = new AdminController(null); // Topic profiles must be removed List<ProfileInst> profiles = admin.getProfilesByObject(topic.getNodePK().getId(), ObjectType.NODE.getCode(), topic.getNodePK().getInstanceId()); if (profiles != null) { for (ProfileInst profile : profiles) { if (profile != null) { admin.deleteProfileInst(profile.getId()); } } } } else { topic.setRightsDependsOnMe(); } nodeBm.updateRightsDependency(topic); } } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.updateTopic()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_MODIFIER_THEME", e); } // Update Alert topicCreationAlert(topic.getNodePK(), null, alertType); return topic.getNodePK(); } @Override public NodeDetail getSubTopicDetail(NodePK pk) { NodeDetail subTopic = null; // get the basic information (Header) of this topic try { subTopic = nodeBm.getDetail(pk); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getSubTopicDetail()", ERROR, "kmelia.EX_IMPOSSIBLE_DACCEDER_AU_THEME", e); } return subTopic; } /** * Delete a topic and all descendants. Delete all links between descendants and publications. This * publications will be visible in the Declassified zone. Delete All subscriptions and favorites * on this topics and all descendants * * @param pkToDelete the id of the topic to delete * @since 1.0 */ @Override @TransactionAttribute(TransactionAttributeType.REQUIRED) public void deleteTopic(NodePK pkToDelete) { SilverTrace.info("kmelia", "KmeliaBmEJB.deleteTopic()", "root.MSG_GEN_ENTER_METHOD"); try { // get all nodes which will be deleted Collection<NodePK> nodesToDelete = nodeBm.getDescendantPKs(pkToDelete); nodesToDelete.add(pkToDelete); SilverTrace.info("kmelia", "KmeliaBmEJB.deleteTopic()", "root.MSG_GEN_PARAM_VALUE", "nodesToDelete = " + nodesToDelete); Iterator<PublicationPK> itPub; Collection<PublicationPK> pubsToCheck; // contains all PubPKs concerned by // the delete NodePK oneNodeToDelete; // current node to delete Collection<NodePK> pubFathers; // contains all fatherPKs to a given // publication PublicationPK onePubToCheck; // current pub to check Iterator<NodePK> itNode = nodesToDelete.iterator(); List<Alias> aliases = new ArrayList<Alias>(); while (itNode.hasNext()) { oneNodeToDelete = itNode.next(); // get pubs linked to current node (includes alias) pubsToCheck = publicationBm.getPubPKsInFatherPK(oneNodeToDelete); itPub = pubsToCheck.iterator(); // check each pub contained in current node while (itPub.hasNext()) { onePubToCheck = itPub.next(); if (onePubToCheck.getInstanceId().equals(oneNodeToDelete.getInstanceId())) { // get fathers of the pub pubFathers = publicationBm.getAllFatherPK(onePubToCheck); if (pubFathers.size() >= 2) { // the pub have got many fathers // delete only the link between pub and current node publicationBm.removeFather(onePubToCheck, oneNodeToDelete); SilverTrace.info("kmelia", "KmeliaBmEJB.deleteTopic()", "root.MSG_GEN_PARAM_VALUE", "RemoveFather(pubId, fatherId) with pubId = " + onePubToCheck.getId() + ", fatherId = " + oneNodeToDelete); } else { sendPublicationToBasket(onePubToCheck); SilverTrace.info("kmelia", "KmeliaBmEJB.deleteTopic()", "root.MSG_GEN_PARAM_VALUE", "RemoveAllFather(pubId) with pubId = " + onePubToCheck.getId()); } } else { // remove alias aliases.clear(); aliases.add(new Alias(oneNodeToDelete.getId(), oneNodeToDelete.getInstanceId())); publicationBm.removeAlias(onePubToCheck, aliases); } } } // Delete all subscriptions on this topic and on its descendants removeSubscriptionsByTopic(nodesToDelete); // Delete the topic nodeBm.removeNode(pkToDelete); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.deleteTopic()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_SUPPRIMER_THEME", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.deleteTopic()", "root.MSG_GEN_EXIT_METHOD"); } @Override public void changeSubTopicsOrder(String way, NodePK subTopicPK, NodePK fatherPK) { SilverTrace.info("kmelia", "KmeliaBmEJB.changeSubTopicsOrder()", "root.MSG_GEN_ENTER_METHOD", "way = " + way + ", subTopicPK = " + subTopicPK.toString()); List<NodeDetail> subTopics = null; try { subTopics = (List<NodeDetail>) nodeBm.getChildrenDetails(fatherPK); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.changeSubTopicsOrder()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_LISTER_THEMES", e); } if (subTopics != null && !subTopics.isEmpty()) { int indexOfTopic; if (fatherPK.isRoot() && !KmeliaHelper.isToolbox(subTopicPK.getInstanceId())) { // search the place of the basket indexOfTopic = getIndexOfNode("1", subTopics); // remove the node subTopics.remove(indexOfTopic); // search the place of the declassified indexOfTopic = getIndexOfNode("2", subTopics); // remove the node subTopics.remove(indexOfTopic); } // search the place of the topic we want to move indexOfTopic = getIndexOfNode(subTopicPK.getId(), subTopics); // get the node to move NodeDetail node2move = subTopics.get(indexOfTopic); // remove the node to move subTopics.remove(indexOfTopic); if (way.equals("up")) { subTopics.add(indexOfTopic - 1, node2move); } else { subTopics.add(indexOfTopic + 1, node2move); } // for each node, change the order and store it for (int i = 0; i < subTopics.size(); i++) { NodeDetail nodeDetail = subTopics.get(i); SilverTrace.info("kmelia", "KmeliaBmEJB.changeSubTopicsOrder()", "root.MSG_GEN_PARAM_VALUE", "updating Node : nodeId = " + nodeDetail.getNodePK().getId() + ", order = " + i); try { nodeDetail.setOrder(i); nodeBm.setDetail(nodeDetail); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.changeSubTopicsOrder()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_MODIFIER_THEME", e); } } } } private int getIndexOfNode(String nodeId, List<NodeDetail> nodes) { SilverTrace.debug("kmelia", "KmeliaBmEJB.getIndexOfNode()", "root.MSG_GEN_ENTER_METHOD", "nodeId = " + nodeId); int index = 0; if (nodes != null) { for (NodeDetail node : nodes) { if (nodeId.equals(node.getNodePK().getId())) { SilverTrace.debug("kmelia", "KmeliaBmEJB.getIndexOfNode()", "root.MSG_GEN_EXIT_METHOD", "index = " + index); return index; } index++; } } SilverTrace.debug("kmelia", "KmeliaBmEJB.getIndexOfNode()", "root.MSG_GEN_EXIT_METHOD", "index = " + index); return index; } @Override public void changeTopicStatus(String newStatus, NodePK nodePK, boolean recursiveChanges) { SilverTrace.info("kmelia", "KmeliaBmEJB.changeTopicStatus()", "root.MSG_GEN_ENTER_METHOD", "newStatus = " + newStatus + ", nodePK = " + nodePK.toString() + ", recursiveChanges = " + recursiveChanges); try { if (!recursiveChanges) { NodeDetail nodeDetail = nodeBm.getHeader(nodePK); changeTopicStatus(newStatus, nodeDetail); } else { List<NodeDetail> subTree = nodeBm.getSubTree(nodePK); for (NodeDetail aSubTree : subTree) { NodeDetail nodeDetail = aSubTree; changeTopicStatus(newStatus, nodeDetail); } } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.changeTopicStatus()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_MODIFIER_THEME", e); } } @Override public void sortSubTopics(NodePK fatherPK) { sortSubTopics(fatherPK, false, null); } @Override public void sortSubTopics(NodePK fatherPK, boolean recursive, String[] criteria) { SilverTrace.info("kmelia", "KmeliaBmEJB.sortSubTopics()", "root.MSG_GEN_ENTER_METHOD", "fatherPK = " + fatherPK.toString()); List<NodeDetail> subTopics = null; try { subTopics = (List<NodeDetail>) nodeBm.getChildrenDetails(fatherPK); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.sortSubTopics()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_LISTER_THEMES", e); } if (subTopics != null && subTopics.size() > 0) { Collections.sort(subTopics, new TopicComparator(criteria)); // for each node, change the order and store it for (int i = 0; i < subTopics.size(); i++) { NodeDetail nodeDetail = subTopics.get(i); SilverTrace.info("kmelia", "KmeliaBmEJB.sortSubTopics()", "root.MSG_GEN_PARAM_VALUE", "updating Node : nodeId = " + nodeDetail.getNodePK().getId() + ", order = " + i); try { nodeDetail.setOrder(i); nodeBm.setDetail(nodeDetail); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.sortSubTopics()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_MODIFIER_THEME", e); } if (recursive) { sortSubTopics(nodeDetail.getNodePK(), true, criteria); } } } } private void changeTopicStatus(String newStatus, NodeDetail topic) { SilverTrace.info("kmelia", "KmeliaBmEJB.changeTopicStatus()", "root.MSG_GEN_ENTER_METHOD", "newStatus = " + newStatus + ", nodePK = " + topic.getNodePK().toString()); try { topic.setStatus(newStatus); nodeBm.setDetail(topic); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.changeTopicStatus()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_MODIFIER_THEME", e); } } @Override public List<NodeDetail> getTreeview(NodePK nodePK, String profile, boolean coWritingEnable, boolean draftVisibleWithCoWriting, String userId, boolean displayNb, boolean isRightsOnTopicsUsed) { String instanceId = nodePK.getInstanceId(); List<NodeDetail> tree = nodeBm.getSubTree(nodePK); if (profile == null) { profile = getProfile(userId, nodePK); } OrganisationController orga = getOrganisationController(); List<NodeDetail> allowedTree = new ArrayList<NodeDetail>(); if (isRightsOnTopicsUsed) { // filter allowed nodes for (NodeDetail node2Check : tree) { if (!node2Check.haveRights()) { node2Check.setUserRole(profile); allowedTree.add(node2Check); if (node2Check.getNodePK().isRoot()) {// case of root. Check if publications on root are // allowed int nbPublisOnRoot = Integer .parseInt(orga.getComponentParameterValue(nodePK.getInstanceId(), "nbPubliOnRoot")); if (nbPublisOnRoot != 0) { node2Check.setUserRole("user"); } } } else { int rightsDependsOn = node2Check.getRightsDependsOn(); String[] profiles = orga.getUserProfiles(userId, instanceId, rightsDependsOn, ObjectType.NODE); if (profiles != null && profiles.length > 0) { node2Check.setUserRole(KmeliaHelper.getProfile(profiles)); allowedTree.add(node2Check); } else { // check if at least one descendant is available Iterator<NodeDetail> descendants = nodeBm.getDescendantDetails(node2Check).iterator(); NodeDetail descendant; boolean node2CheckAllowed = false; while (!node2CheckAllowed && descendants.hasNext()) { descendant = descendants.next(); if (descendant.getRightsDependsOn() != rightsDependsOn) { // different rights of father check if it is available profiles = orga.getUserProfiles(userId, instanceId, descendant.getRightsDependsOn(), ObjectType.NODE); if (profiles != null && profiles.length > 0) { node2Check.setUserRole(KmeliaHelper.getProfile(profiles)); allowedTree.add(node2Check); node2CheckAllowed = true; } } } } } } } else { if (tree != null && !tree.isEmpty()) { // case of root. Check if publications on root are allowed String sNB = orga.getComponentParameterValue(nodePK.getInstanceId(), "nbPubliOnRoot"); if (!isDefined(sNB)) { sNB = "0"; } int nbPublisOnRoot = Integer.parseInt(sNB); if (nbPublisOnRoot != 0) { NodeDetail root = tree.get(0); root.setUserRole("user"); } for (NodeDetail node : tree) { if (!node.getNodePK().isRoot()) { node.setUserRole(profile); } } } allowedTree.addAll(tree); } if (displayNb) { boolean checkVisibility = false; StringBuilder statusSubQuery = new StringBuilder(); if (profile.equals("user")) { checkVisibility = true; statusSubQuery.append(" AND sb_publication_publi.pubStatus = 'Valid' "); } else if (profile.equals("writer")) { statusSubQuery.append(" AND ("); if (coWritingEnable && draftVisibleWithCoWriting) { statusSubQuery.append("sb_publication_publi.pubStatus = 'Valid' OR ") .append("sb_publication_publi.pubStatus = 'Draft' OR ") .append("sb_publication_publi.pubStatus = 'Unvalidate' "); } else { checkVisibility = true; statusSubQuery.append("sb_publication_publi.pubStatus = 'Valid' OR ") .append("(sb_publication_publi.pubStatus = 'Draft' AND ") .append("sb_publication_publi.pubUpdaterId = '").append(userId) .append("') OR (sb_publication_publi.pubStatus = 'Unvalidate' AND ") .append("sb_publication_publi.pubUpdaterId = '").append(userId).append("') "); } statusSubQuery.append("OR (sb_publication_publi.pubStatus = 'ToValidate' ") .append("AND sb_publication_publi.pubUpdaterId = '").append(userId).append("') "); statusSubQuery.append("OR sb_publication_publi.pubUpdaterId = '").append(userId).append("')"); } else { statusSubQuery.append(" AND ("); if (coWritingEnable && draftVisibleWithCoWriting) { statusSubQuery.append("sb_publication_publi.pubStatus IN ('Valid','ToValidate','Draft') "); } else { if (profile.equals("publisher")) { checkVisibility = true; } statusSubQuery.append( "sb_publication_publi.pubStatus IN ('Valid','ToValidate') OR (sb_publication_publi.pubStatus = 'Draft' AND sb_publication_publi.pubUpdaterId = '") .append(userId).append("') "); } statusSubQuery.append("OR sb_publication_publi.pubUpdaterId = '").append(userId).append("')"); } NodeTree root = publicationBm.getDistributionTree(nodePK.getInstanceId(), statusSubQuery.toString(), checkVisibility); // set right number of publications in basket NodePK trashPk = new NodePK(NodePK.BIN_NODE_ID, nodePK.getInstanceId()); int nbPubsInTrash = getPublicationsInBasket(trashPk, profile, userId).size(); for (NodeTree node : root.getChildren()) { if (node.getKey().isTrash()) { node.setNbPublications(nbPubsInTrash); } } Map<NodePK, NodeDetail> allowedNodes = new HashMap<NodePK, NodeDetail>(allowedTree.size()); for (NodeDetail allowedNode : allowedTree) { allowedNodes.put(allowedNode.getNodePK(), allowedNode); } countPublisInNodes(allowedNodes, root); } return allowedTree; } private Collection<PublicationDetail> getPublicationsInBasket(NodePK pk, String userProfile, String userId) { String currentUserId = userId; SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationsInBasket()", "root.MSG_GEN_ENTER_METHOD", "pk = " + pk.toString() + ", userProfile = " + userProfile + ", userId = " + currentUserId); try { // Give the publications associated to basket topic and visibility period expired if (SilverpeasRole.admin.isInRole(userProfile)) {// Admin can see all Publis in the basket. currentUserId = null; } Collection<PublicationDetail> pubDetails = publicationBm.getDetailsByFatherPK(pk, null, false, currentUserId); SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationsInBasket()", "root.MSG_GEN_EXIT_METHOD", "nbPublis = " + pubDetails.size()); return pubDetails; } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getPublicationsInBasket()", ERROR, "kmelia.EX_IMPOSSIBLE_DAVOIR_LE_CONTENU_DE_LA_CORBEILLE", e); } } /** * Counts number of publications recursively in allowed nodes only * * @param allowedNodes a Map of all nodes allowed to user * @param tree the whole tree which contains the number of publications in each node independently * of rights */ private void countPublisInNodes(Map<NodePK, NodeDetail> allowedNodes, NodeTree tree) { for (NodeDetail node : allowedNodes.values()) { NodeTree nodeTree = findNode(node, tree); if (nodeTree != null) { int nbPublis = countNbPublis(nodeTree); SilverTrace.debug("kmelia", "KmeliaBmEJB.countPublisInNodes", "root.MSG_GEN_PARAM_VALUE", nbPublis + " pubs in node " + node.getNodePK().getId()); node.setNbObjects(nbPublis); } } } private NodeTree findNode(NodeDetail node, NodeTree tree) { SilverTrace.debug("kmelia", "KmeliaBmEJB.findNode", "root.MSG_GEN_ENTER_METHOD", "looking for node " + node.getNodePK().getId()); String path = node.getFullPath(); if (path.length() > 1) { path = path.substring(1, path.length() - 1); // remove starting and ending slash SilverTrace.debug("kmelia", "KmeliaBmEJB.findNode", "root.MSG_GEN_PARAM_VALUE", " path = " + path); ArrayList<String> pathItems = new ArrayList<String>(Arrays.asList(path.split("/"))); pathItems.remove(0); // remove root NodeTree current = tree; for (String pathItem : pathItems) { if (current != null) { current = findNodeTree(pathItem, current.getChildren()); } } if (current != null) { SilverTrace.debug("kmelia", "KmeliaBmEJB.findNode", "root.MSG_GEN_EXIT_METHOD", "node " + current.getKey().getId() + " found"); return current; } } SilverTrace.error("kmelia", "KmeliaBmEJB.findNode", "root.MSG_GEN_EXIT_METHOD", "node " + node.getNodePK().getId() + " not found"); return null; } private NodeTree findNodeTree(String nodeId, List<NodeTree> children) { for (NodeTree node : children) { if (node.getKey().getId().equals(nodeId)) { return node; } } return null; } /** * Counts the number of publications in the node and all its descendants * * @param tree the subtree which have tree.currentNode as root * @return the number of publications in this node and all its descendants */ private int countNbPublis(NodeTree tree) { if (tree == null) { return 0; } int nb = tree.getNbPublications(); // add nb of each descendant for (NodeTree node : tree.getChildren()) { nb += countNbPublis(node); } SilverTrace.debug("kmelia", "KmeliaBmEJB.countNbPublis", "root.MSG_GEN_EXIT_METHOD", nb + " pubs in node " + tree.getKey().getId()); return nb; } /** * Subscriptions - get the subscription list of the current user * * @param userId * @param componentId * @return a Path Collection - it's a Collection of NodeDetail collection * @see com.stratelia.webactiv.util.node.model.NodeDetail * @since 1.0 */ @Override public Collection<Collection<NodeDetail>> getSubscriptionList(String userId, String componentId) { SilverTrace.info("kmelia", "KmeliaBmEJB.getSubscriptionList()", "root.MSG_GEN_ENTER_METHOD"); try { Collection<Subscription> list = getSubscribeBm() .getBySubscriberAndComponent(UserSubscriptionSubscriber.from(userId), componentId); Collection<Collection<NodeDetail>> detailedList = new ArrayList<Collection<NodeDetail>>(); // For each favorite, get the path from root to favorite for (Subscription subscription : list) { Collection<NodeDetail> path = nodeBm.getPath((NodePK) subscription.getResource().getPK()); detailedList.add(path); } SilverTrace.info("kmelia", "KmeliaBmEJB.getSubscriptionList()", "root.MSG_GEN_EXIT_METHOD"); return detailedList; } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getSubscriptionList()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LES_ABONNEMENTS", e); } } /** * Subscriptions - remove a subscription to the subscription list of the current user * * @param topicPK the subscribe topic Id to remove * @param userId * @since 1.0 */ @Override public void removeSubscriptionToCurrentUser(NodePK topicPK, String userId) { SilverTrace.info("kmelia", "KmeliaBmEJB.removeSubscriptionToCurrentUser()", "root.MSG_GEN_ENTER_METHOD"); try { getSubscribeBm().unsubscribe(new NodeSubscription(userId, topicPK)); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.removeSubscriptionToCurrentUser()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_SUPPRIMER_ABONNEMENT", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.removeSubscriptionToCurrentUser()", "root.MSG_GEN_EXIT_METHOD"); } /** * Subscriptions - remove all subscriptions from topic * * @param topicPKsToDelete the subscription topic Ids to remove * @since 1.0 */ private void removeSubscriptionsByTopic(Collection<NodePK> topicPKsToDelete) { SilverTrace.info("kmelia", "KmeliaBmEJB.removeSubscriptionsByTopic()", "root.MSG_GEN_ENTER_METHOD"); try { Collection<SubscriptionResource> subscriptionResourcesToDelete = new ArrayList<SubscriptionResource>(); for (NodePK topicPK : topicPKsToDelete) { subscriptionResourcesToDelete.add(NodeSubscriptionResource.from(topicPK)); } getSubscribeBm().unsubscribeByResources(subscriptionResourcesToDelete); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.removeSubscriptionsByTopic()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_SUPPRIMER_LES_ABONNEMENTS", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.removeSubscriptionsByTopic()", "root.MSG_GEN_EXIT_METHOD"); } /** * Subscriptions - add a subscription * * @param topicPK the subscription topic Id to add * @param userId the subscription userId * @since 1.0 */ @Override public void addSubscription(NodePK topicPK, String userId) { SilverTrace.info("kmelia", "KmeliaBmEJB.addSubscription()", "root.MSG_GEN_ENTER_METHOD"); getSubscribeBm().subscribe(new NodeSubscription(userId, topicPK)); SilverTrace.info("kmelia", "KmeliaBmEJB.addSubscription()", "root.MSG_GEN_EXIT_METHOD"); } /** * * @param topicPK * @param userId * @return true if this topic does not exists in user subscriptions and can be added to them. */ @Override public boolean checkSubscription(NodePK topicPK, String userId) { return !getSubscribeBm().existsSubscription(new NodeSubscription(userId, topicPK)); } /** * *********************************************************************************** * Interface - Gestion des publications * ********************************************************************************** */ private List<KmeliaPublication> pubDetails2userPubs(Collection<PublicationDetail> pubDetails) { List<KmeliaPublication> publications = new ArrayList<KmeliaPublication>(); int i = -1; for (PublicationDetail publicationDetail : pubDetails) { publications.add(KmeliaPublication.aKmeliaPublicationFromDetail(publicationDetail, i++)); } return publications; } /** * Return the detail of a publication (only the Header) * * @param pubPK the id of the publication * @return a PublicationDetail * @see com.stratelia.webactiv.util.publication.model.PublicationDetail * @since 1.0 */ @Override public PublicationDetail getPublicationDetail(PublicationPK pubPK) { SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationDetail()", "root.MSG_GEN_ENTER_METHOD"); try { SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationDetail()", "root.MSG_GEN_EXIT_METHOD"); return publicationBm.getDetail(pubPK); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getPublicationDetail()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LA_PUBLICATION", e); } } /** * Return list of all path to this publication - it's a Collection of NodeDetail collection * * @param pubPK the id of the publication * @return a Collection of NodeDetail collection * @see com.stratelia.webactiv.util.node.model.NodeDetail * @since 1.0 */ @Override public Collection<Collection<NodeDetail>> getPathList(PublicationPK pubPK) { SilverTrace.info("kmelia", "KmeliaBmEJB.getPathList()", "root.MSG_GEN_ENTER_METHOD"); Collection<NodePK> fatherPKs = null; try { // get all nodePK whick contains this publication fatherPKs = publicationBm.getAllFatherPK(pubPK); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getPathList()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LES_EMPLACEMENTS_DE_LA_PUBLICATION", e); } try { List<Collection<NodeDetail>> pathList = new ArrayList<Collection<NodeDetail>>(); if (fatherPKs != null) { // For each topic, get the path to it for (NodePK pk : fatherPKs) { Collection<NodeDetail> path = nodeBm.getAnotherPath(pk); // add this path pathList.add(path); } } SilverTrace.info("kmelia", "KmeliaBmEJB.getPathList()", "root.MSG_GEN_EXIT_METHOD"); return pathList; } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getPathList()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LES_EMPLACEMENTS_DE_LA_PUBLICATION", e); } } /** * Create a new Publication (only the header - parameters) to the current Topic * * @param pubDetail a PublicationDetail * @return the id of the new publication * @see com.stratelia.webactiv.util.publication.model.PublicationDetail * @since 1.0 */ @Override @TransactionAttribute(TransactionAttributeType.REQUIRED) public String createPublicationIntoTopic(PublicationDetail pubDetail, NodePK fatherPK) { PdcClassificationService classifier = PdcServiceFactory.getFactory().getPdcClassificationService(); PdcClassification predefinedClassification = classifier.findAPreDefinedClassification(fatherPK.getId(), fatherPK.getInstanceId()); return createPublicationIntoTopic(pubDetail, fatherPK, predefinedClassification); } @Override @TransactionAttribute(TransactionAttributeType.REQUIRED) public String createPublicationIntoTopic(PublicationDetail pubDetail, NodePK fatherPK, PdcClassification classification) { SilverTrace.info("kmelia", "KmeliaBmEJB.createPublicationIntoTopic()", "root.MSG_GEN_ENTER_METHOD"); String pubId = null; try { pubId = createPublicationIntoTopicWithoutNotifications(pubDetail, fatherPK, classification); // creates todos for publishers createTodosForPublication(pubDetail, true); // alert supervisors sendAlertToSupervisors(fatherPK, pubDetail); // alert subscribers sendSubscriptionsNotification(pubDetail, false, false); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.createPublicationIntoTopic()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_CREER_LA_PUBLICATION", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.createPublicationIntoTopic()", "root.MSG_GEN_EXIT_METHOD"); return pubId; } public String createPublicationIntoTopicWithoutNotifications(PublicationDetail pubDetail, NodePK fatherPK, PdcClassification classification) { SilverTrace.info("kmelia", "KmeliaBmEJB.createPublicationIntoTopic()", "root.MSG_GEN_ENTER_METHOD"); PublicationPK pubPK = null; try { pubDetail = changePublicationStatusOnCreation(pubDetail, fatherPK); // create the publication pubPK = publicationBm.createPublication(pubDetail); pubDetail.getPK().setId(pubPK.getId()); // register the new publication as a new content to content manager createSilverContent(pubDetail, pubDetail.getCreatorId()); // add this publication to the current topic addPublicationToTopicWithoutNotifications(pubPK, fatherPK, true); // classify the publication on the PdC if its classification is defined if (!classification.isEmpty()) { PdcClassificationService service = PdcServiceFactory.getFactory().getPdcClassificationService(); classification.ofContent(pubPK.getId()); // subscribers are notified later (only if publication is valid) service.classifyContent(pubDetail, classification, false); } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.createPublicationIntoTopic()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_CREER_LA_PUBLICATION", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.createPublicationIntoTopic()", "root.MSG_GEN_EXIT_METHOD"); return pubPK.getId(); } private String getProfile(String userId, NodePK nodePK) { String profile; OrganisationController orgCtrl = getOrganisationController(); if (isRightsOnTopicsEnabled(nodePK.getInstanceId())) { NodeDetail topic = nodeBm.getHeader(nodePK); if (topic.haveRights()) { profile = KmeliaHelper.getProfile(orgCtrl.getUserProfiles(userId, nodePK.getInstanceId(), topic.getRightsDependsOn(), ObjectType.NODE)); } else { profile = KmeliaHelper.getProfile(orgCtrl.getUserProfiles(userId, nodePK.getInstanceId())); } } else { profile = KmeliaHelper.getProfile(orgCtrl.getUserProfiles(userId, nodePK.getInstanceId())); } return profile; } private String getProfileOnPublication(String userId, PublicationPK pubPK) { List<NodePK> fathers = (List<NodePK>) getPublicationFathers(pubPK); NodePK nodePK = new NodePK("unknown", pubPK.getInstanceId()); if (fathers != null && !fathers.isEmpty()) { nodePK = fathers.get(0); } return getProfile(userId, nodePK); } private PublicationDetail changePublicationStatusOnCreation(PublicationDetail pubDetail, NodePK nodePK) { SilverTrace.info("kmelia", "KmeliaBmEJB.changePublicationStatusOnCreation()", "root.MSG_GEN_ENTER_METHOD", "status = " + pubDetail.getStatus()); String status = pubDetail.getStatus(); if (!isDefined(status)) { status = PublicationDetail.TO_VALIDATE; boolean draftModeUsed = isDraftModeUsed(pubDetail.getPK().getInstanceId()); if (draftModeUsed) { status = PublicationDetail.DRAFT; } else { String profile = getProfile(pubDetail.getCreatorId(), nodePK); if (SilverpeasRole.publisher.isInRole(profile) || SilverpeasRole.admin.isInRole(profile)) { status = PublicationDetail.VALID; } } } pubDetail.setStatus(status); KmeliaHelper.checkIndex(pubDetail); SilverTrace.info("kmelia", "KmeliaBmEJB.changePublicationStatusOnCreation()", "root.MSG_GEN_EXIT_METHOD", "status = " + pubDetail.getStatus() + ", indexOperation = " + pubDetail.getIndexOperation()); return pubDetail; } private boolean changePublicationStatusOnMove(PublicationDetail pub, NodePK to) { SilverTrace.info("kmelia", "KmeliaBmEJB.changePublicationStatusOnMove()", "root.MSG_GEN_ENTER_METHOD", "status = " + pub.getStatus()); String oldStatus = pub.getStatus(); String status = pub.getStatus(); if (!status.equals(PublicationDetail.DRAFT)) { status = PublicationDetail.TO_VALIDATE; String profile = getProfile(pub.getUpdaterId(), to); if (SilverpeasRole.publisher.isInRole(profile) || SilverpeasRole.admin.isInRole(profile)) { status = PublicationDetail.VALID; } } pub.setStatus(status); KmeliaHelper.checkIndex(pub); SilverTrace.info("kmelia", "KmeliaBmEJB.changePublicationStatusOnMove()", "root.MSG_GEN_EXIT_METHOD", "status = " + pub.getStatus() + ", indexOperation = " + pub.getIndexOperation()); return !oldStatus.equals(status); } /** * determine new publication's status according to actual status and current user's profile * * @param pubDetail * @return true if status has changed, false otherwise */ private boolean changePublicationStatusOnUpdate(PublicationDetail pubDetail) { String oldStatus = pubDetail.getStatus(); String newStatus = oldStatus; List<NodePK> fathers = (List<NodePK>) getPublicationFathers(pubDetail.getPK()); if (pubDetail.isStatusMustBeChecked()) { if (!pubDetail.isDraft() && !pubDetail.isClone()) { NodePK nodePK = new NodePK("unknown", pubDetail.getPK().getInstanceId()); if (fathers != null && !fathers.isEmpty()) { nodePK = fathers.get(0); } String profile = getProfile(pubDetail.getUpdaterId(), nodePK); if (SilverpeasRole.writer.isInRole(profile)) { newStatus = PublicationDetail.TO_VALIDATE; } pubDetail.setStatus(newStatus); } } KmeliaHelper.checkIndex(pubDetail); if (fathers == null || fathers.isEmpty() || (fathers.size() == 1 && fathers.get(0).isTrash())) { // la publication est dans la corbeille pubDetail.setIndexOperation(IndexManager.NONE); } return !oldStatus.equalsIgnoreCase(newStatus); } /** * Update a publication (only the header - parameters) * * @param pubDetail a PublicationDetail * @see com.stratelia.webactiv.util.publication.model.PublicationDetail * @since 1.0 */ @Override public void updatePublication(PublicationDetail pubDetail) { updatePublication(pubDetail, KmeliaHelper.PUBLICATION_HEADER, false); } @Override public void updatePublication(PublicationDetail pubDetail, boolean forceUpdateDate) { updatePublication(pubDetail, KmeliaHelper.PUBLICATION_HEADER, forceUpdateDate); } private void updatePublication(PublicationDetail pubDetail, int updateScope, boolean forceUpdateDate) { SilverTrace.info("kmelia", "KmeliaBmEJB.updatePublication()", "root.MSG_GEN_ENTER_METHOD", "updateScope = " + updateScope); try { // if pubDetail is a clone boolean isClone = isClone(pubDetail); SilverTrace.info("kmelia", "KmeliaBmEJB.updatePublication()", "root.MSG_GEN_PARAM_VALUE", "This publication is clone ? " + isClone); PublicationDetail old = getPublicationDetail(pubDetail.getPK()); // prevents to lose some data if (StringUtil.isDefined(old.getTargetValidatorId()) && !StringUtil.isDefined(pubDetail.getTargetValidatorId())) { pubDetail.setTargetValidatorId(old.getTargetValidatorId()); } final boolean isPublicationInBasket = isPublicationInBasket(pubDetail.getPK()); if (isClone) { // update only updateDate publicationBm.setDetail(pubDetail, forceUpdateDate); } else { boolean statusChanged = changePublicationStatusOnUpdate(pubDetail); publicationBm.setDetail(pubDetail, forceUpdateDate); if (!isPublicationInBasket) { if (statusChanged) { // creates todos for publishers this.createTodosForPublication(pubDetail, false); } updateSilverContentVisibility(pubDetail); // la publication a t modifi par un superviseur // le crateur de la publi doit tre averti String profile = KmeliaHelper.getProfile(getOrganisationController() .getUserProfiles(pubDetail.getUpdaterId(), pubDetail.getPK().getInstanceId())); if ("supervisor".equals(profile)) { sendModificationAlert(updateScope, pubDetail.getPK()); } boolean visibilityPeriodUpdated = isVisibilityPeriodUpdated(pubDetail, old); if (statusChanged || visibilityPeriodUpdated) { if (KmeliaHelper.isIndexable(pubDetail)) { indexExternalElementsOfPublication(pubDetail); } else { unIndexExternalElementsOfPublication(pubDetail.getPK()); } } } } // notification pour modification if (!isPublicationInBasket) { sendSubscriptionsNotification(pubDetail, true, false); } boolean isNewsManage = getBooleanValue(getOrganisationController() .getComponentParameterValue(pubDetail.getPK().getInstanceId(), "isNewsManage")); if (isNewsManage) { // mcanisme de callback CallBackManager callBackManager = CallBackManager.get(); callBackManager.invoke(CallBackManager.ACTION_HEADER_PUBLICATION_UPDATE, Integer.parseInt(pubDetail.getId()), pubDetail.getInstanceId(), pubDetail); } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.updatePublication()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_MODIFIER_LA_PUBLICATION", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.updatePublication()", "root.MSG_GEN_EXIT_METHOD"); } private boolean isVisibilityPeriodUpdated(PublicationDetail pubDetail, PublicationDetail old) { boolean beginVisibilityPeriodUpdated = ((pubDetail.getBeginDate() != null && old.getBeginDate() == null) || (pubDetail.getBeginDate() == null && old.getBeginDate() != null) || (pubDetail.getBeginDate() != null && old.getBeginDate() != null && !pubDetail.getBeginDate().equals(old.getBeginDate()))); boolean endVisibilityPeriodUpdated = ((pubDetail.getEndDate() != null && old.getEndDate() == null) || (pubDetail.getEndDate() == null && old.getEndDate() != null) || (pubDetail.getEndDate() != null && old.getEndDate() != null && !pubDetail.getEndDate().equals(old.getEndDate()))); return beginVisibilityPeriodUpdated || endVisibilityPeriodUpdated; } @Interceptors(SimulationActionProcessAnnotationEJBInterceptor.class) @SimulationActionProcess(elementLister = KmeliaPublicationSimulationElementLister.class) @Action(ActionType.MOVE) @Override public void movePublication(@SourcePK PublicationPK pubPK, @TargetPK NodePK to, String userId) { PublicationDetail pub = getPublicationDetail(pubPK); if (pub != null) { if (pubPK.getInstanceId().equals(to.getInstanceId())) { movePublicationInSameApplication(pub, to, userId); } else { movePublicationInAnotherApplication(pub, to, userId); } } } @Interceptors(SimulationActionProcessAnnotationEJBInterceptor.class) @SimulationActionProcess(elementLister = KmeliaPublicationSimulationElementLister.class) @Action(ActionType.MOVE) @Override public void movePublicationInSameApplication(@SourcePK PublicationPK pubPK, @TargetPK NodePK from, NodePK to, String userId) { PublicationDetail pub = getPublicationDetail(pubPK); // check if user can cut publication from source folder String profile = getUserTopicProfile(from, userId); boolean cutAllowed = KmeliaPublicationHelper.isCanBeCut(from.getComponentName(), userId, profile, pub.getCreator()); // check if user can paste publication into target folder String profileInTarget = getUserTopicProfile(to, userId); boolean pasteAllowed = KmeliaPublicationHelper.isCreationAllowed(to, profileInTarget); if (cutAllowed && pasteAllowed) { movePublicationInSameApplication(pub, to, userId); } } private void movePublicationInSameApplication(PublicationDetail pub, NodePK to, String userId) { if (to.isTrash()) { sendPublicationToBasket(pub.getPK()); } else { // update parent publicationBm.removeAllFather(pub.getPK()); publicationBm.addFather(pub.getPK(), to); processPublicationAfterMove(pub, to, userId); } } /** * Move a publication to another component. Moving in this order : <ul> * <li>moving the metadata</li> * <li>moving the thumbnail</li> * <li>moving the content</li> * <li>moving the wysiwyg</li> * <li>moving the images linked to the wysiwyg</li> * <li>moving the xml form content (files and images)</li> * <li>moving attachments</li> * <li>moving the pdc poistion</li> * <li>moving the statistics</li> * </ul> */ @Interceptors(SimulationActionProcessAnnotationEJBInterceptor.class) @SimulationActionProcess(elementLister = KmeliaPublicationSimulationElementLister.class) @Action(ActionType.MOVE) @Override public void movePublicationInAnotherApplication(@SourcePK PublicationDetail pub, @TargetPK NodePK to, String userId) { try { ForeignPK fromForeignPK = new ForeignPK(pub.getPK()); String fromComponentId = pub.getInstanceId(); ForeignPK toPubliForeignPK = new ForeignPK(pub.getId(), to); // remove index relative to publication unIndexExternalElementsOfPublication(pub.getPK()); // move thumbnail ThumbnailController.moveThumbnail(fromForeignPK, toPubliForeignPK); try { // move additional files List<SimpleDocument> documents = AttachmentServiceFactory.getAttachmentService() .listDocumentsByForeignKeyAndType(fromForeignPK, DocumentType.image, null); documents.addAll(AttachmentServiceFactory.getAttachmentService() .listDocumentsByForeignKeyAndType(fromForeignPK, DocumentType.wysiwyg, null)); for (SimpleDocument doc : documents) { AttachmentServiceFactory.getAttachmentService().moveDocument(doc, toPubliForeignPK); } } catch (org.silverpeas.attachment.AttachmentException e) { SilverTrace.error("kmelia", "KmeliaBmEJB.movePublicationInAnotherApplication()", "root.MSG_GEN_PARAM_VALUE", "kmelia.CANT_MOVE_ATTACHMENTS", e); } // change images path in wysiwyg WysiwygController.wysiwygPlaceHaveChanged(fromForeignPK.getInstanceId(), pub.getPK().getId(), to.getInstanceId(), pub.getPK().getId()); // move regular files List<SimpleDocument> docs = AttachmentServiceFactory.getAttachmentService() .listDocumentsByForeignKeyAndType(fromForeignPK, DocumentType.attachment, null); for (SimpleDocument doc : docs) { AttachmentServiceFactory.getAttachmentService().moveDocument(doc, toPubliForeignPK); } // move form content String infoId = pub.getInfoId(); if (infoId != null && !"0".equals(infoId)) { // register content to component PublicationTemplateManager templateManager = PublicationTemplateManager.getInstance(); GenericRecordSet toRecordSet = templateManager.addDynamicPublicationTemplate( to.getInstanceId() + ":" + pub.getInfoId(), pub.getInfoId() + ".xml"); RecordTemplate toRecordTemplate = toRecordSet.getRecordTemplate(); // get xmlContent to move PublicationTemplate pubTemplateFrom = templateManager .getPublicationTemplate(fromComponentId + ":" + pub.getInfoId()); RecordSet set = pubTemplateFrom.getRecordSet(); set.move(fromForeignPK, toPubliForeignPK, toRecordTemplate); } // move comments getCommentService().moveComments(PublicationDetail.getResourceType(), fromForeignPK, toPubliForeignPK); // move pdc positions com.stratelia.silverpeas.pdc.control.PdcBm pdcBmImpl = new PdcBmImpl(); // Careful! positions must be moved according to taxonomy restrictions of target application int fromSilverObjectId = getSilverObjectId(pub.getPK()); // get positions of cutted publication List<ClassifyPosition> positions = pdcBmImpl.getPositions(fromSilverObjectId, fromComponentId); // delete taxonomy data relative to moved publication deleteSilverContent(pub.getPK()); // move statistics statisticBm.moveStat(toPubliForeignPK, 1, "Publication"); // move publication itself publicationBm.movePublication(pub.getPK(), to, false); pub.getPK().setComponentName(to.getInstanceId()); processPublicationAfterMove(pub, to, userId); // index moved publication if (KmeliaHelper.isIndexable(pub)) { indexPublication(pub); } // reference pasted publication on taxonomy service int toSilverObjectId = getSilverObjectId(pub.getPK()); // add original positions to pasted publication pdcBmImpl.addPositions(positions, toSilverObjectId, to.getInstanceId()); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.movePublication()", ERROR, "kmelia.EX_CANT_MOVE_PUBLICATION_INTO_ANOTHER_APP", e); } } private void processPublicationAfterMove(PublicationDetail pub, NodePK to, String userId) { // update last modifier pub.setUpdaterId(userId); // status must be checked according to topic rights and last modifier (current user) boolean statusChanged = changePublicationStatusOnMove(pub, to); // update publication publicationBm.setDetail(pub, statusChanged); // check visibility on taxonomy updateSilverContentVisibility(pub); if (statusChanged) { // creates todos for publishers createTodosForPublication(pub, false); // index or unindex external elements if (KmeliaHelper.isIndexable(pub)) { indexExternalElementsOfPublication(pub); } else { unIndexExternalElementsOfPublication(pub.getPK()); } } // send notifications like a creation sendSubscriptionsNotification(pub, false, false); } private void updatePublication(PublicationPK pubPK, int updateScope) { PublicationDetail pubDetail = getPublicationDetail(pubPK); updatePublication(pubDetail, updateScope, false); } @Override public void externalElementsOfPublicationHaveChanged(PublicationPK pubPK, String userId, int action) { // check if related contribution is managed by kmelia if (pubPK != null && StringUtil.isDefined(pubPK.getInstanceId()) && (pubPK.getInstanceId().startsWith("kmelia") || pubPK.getInstanceId().startsWith("toolbox") || pubPK.getInstanceId().startsWith("kmax"))) { PublicationDetail pubDetail = null; try { pubDetail = getPublicationDetail(pubPK); } catch (Exception e) { // publication no longer exists do not throw exception because this method is called by JMS // layer // if exception is throw, JMS will attempt to execute it again and again... SilverTrace.info("kmelia", "KmeliaBmEJB.externalElementsOfPublicationHaveChanged", "kmelia.EX_IMPOSSIBLE_DOBTENIR_LA_PUBLICATION", "pubPK = " + pubPK.toString(), e); } // The treatment is stopped if publication is not found or if publication doesn't correspond // with parameter of given publication pk. The second condition could happen, for now, // with applications dealing with wysiwyg without using publication for their storage // (infoletter for example). if (pubDetail == null || (StringUtil.isDefined(pubPK.getInstanceId()) && !pubDetail.getInstanceId().equals(pubPK.getInstanceId()))) { return; } boolean clone = isClone(pubDetail); if (clone) { pubDetail.setIndexOperation(IndexManager.NONE); } if (isDefined(userId)) { pubDetail.setUpdaterId(userId); } // update publication header to store last modifier and update date if (!isDefined(userId)) { updatePublication(pubDetail, KmeliaHelper.PUBLICATION_CONTENT, false); } else { // check if user have sufficient rights to update a publication String profile = getProfileOnPublication(userId, pubDetail.getPK()); if ("supervisor".equals(profile) || SilverpeasRole.publisher.isInRole(profile) || SilverpeasRole.admin.isInRole(profile) || SilverpeasRole.writer.isInRole(profile)) { updatePublication(pubDetail, KmeliaHelper.PUBLICATION_CONTENT, false); } else { SilverTrace.warn("kmelia", "KmeliaBmEJB.externalElementsOfPublicationHaveChanged", "kmelia.PROBLEM_DETECTED", "user " + userId + " is not allowed to update publication " + pubDetail.getPK()); } } // index all attached files to taking into account visibility period indexExternalElementsOfPublication(pubDetail); } } private boolean isClone(PublicationDetail publication) { return isDefined(publication.getCloneId()) && !"-1".equals(publication.getCloneId()) && !isDefined(publication.getCloneStatus()); } /** * HEAD Delete a publication If this publication is in the basket or in the DZ, it's deleted from * the database Else it only send to the basket. * * @param pubPK the id of the publication to delete * @see com.stratelia.webactiv.kmelia.model.TopicDetail */ @Override @TransactionAttribute(TransactionAttributeType.REQUIRED) public void deletePublication(PublicationPK pubPK) { // if the publication is in the basket or in the DZ // this publication is deleted from the database SilverTrace.info("kmelia", "KmeliaBmEJB.deletePublication()", "root.MSG_GEN_ENTER_METHOD"); try { // remove form content removeXMLContentOfPublication(pubPK); // delete all reading controls associated to this publication deleteAllReadingControlsByPublication(pubPK); // delete all links publicationBm.removeAllFather(pubPK); // delete the publication publicationBm.removePublication(pubPK); // delete reference to contentManager deleteSilverContent(pubPK); removeExternalElementsOfPublications(pubPK); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.deletePublication()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_SUPPRIMER_LA_PUBLICATION", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.deletePublication()", "root.MSG_GEN_EXIT_METHOD"); } /** * Send the publication in the basket topic * * @param pubPK the id of the publication * @param kmaxMode * @see com.stratelia.webactiv.kmelia.model.TopicDetail * @since 1.0 */ @Override public void sendPublicationToBasket(PublicationPK pubPK, boolean kmaxMode) { SilverTrace.info("kmelia", "KmeliaBmEJB.sendPublicationToBasket()", "root.MSG_GEN_ENTER_METHOD"); try { // remove coordinates for Kmax if (kmaxMode) { CoordinatePK coordinatePK = new CoordinatePK("unknown", pubPK.getSpaceId(), pubPK.getComponentName()); Collection<NodePK> fatherPKs = publicationBm.getAllFatherPK(pubPK); // delete publication coordinates Iterator<NodePK> it = fatherPKs.iterator(); List<String> coordinates = new ArrayList<String>(); SilverTrace.info("kmelia", "KmeliaBmEJB.sendPublicationToBasket()", "root.MSG_GEN_PARAM_VALUE", "fatherPKs" + fatherPKs); while (it.hasNext()) { String coordinateId = (it.next()).getId(); coordinates.add(coordinateId); } if (coordinates.size() > 0) { coordinatesBm.deleteCoordinates(coordinatePK, (ArrayList<String>) coordinates); } } // remove all links between this publication and topics publicationBm.removeAllFather(pubPK); // add link between this publication and the basket topic publicationBm.addFather(pubPK, new NodePK("1", pubPK)); // remove all the todos attached to the publication removeAllTodosForPublication(pubPK); // publication is no more accessible updateSilverContentVisibility(pubPK, false); unIndexExternalElementsOfPublication(pubPK); boolean isNewsManage = getBooleanValue( getOrganisationController().getComponentParameterValue(pubPK.getInstanceId(), "isNewsManage")); if (isNewsManage) { // mcanisme de callback CallBackManager callBackManager = CallBackManager.get(); callBackManager.invoke(CallBackManager.ACTION_PUBLICATION_REMOVE, Integer.parseInt(pubPK.getId()), pubPK.getInstanceId(), ""); } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.sendPublicationToBasket()", ERROR, "kmelia.EX_IMPOSSIBLE_DENVOYER_LA_PUBLICATION_A_LA_CORBEILLE", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.sendPublicationToBasket()", "root.MSG_GEN_EXIT_METHOD"); } @Override public void sendPublicationToBasket(PublicationPK pubPK) { sendPublicationToBasket(pubPK, KmeliaHelper.isKmax(pubPK.getInstanceId())); } /** * Add a publication to a topic and send email alerts to topic subscribers * * @param pubPK the id of the publication * @param fatherPK the id of the topic * @param isACreation */ @Override public void addPublicationToTopic(PublicationPK pubPK, NodePK fatherPK, boolean isACreation) { addPublicationToTopicWithoutNotifications(pubPK, fatherPK, isACreation); SilverTrace.info("kmelia", "KmeliaBmEJB.addPublicationToTopic()", "root.MSG_GEN_ENTER_METHOD"); PublicationDetail pubDetail = getPublicationDetail(pubPK); sendSubscriptionsNotification(pubDetail, false, false); SilverTrace.info("kmelia", "KmeliaBmEJB.addPublicationToTopic()", "root.MSG_GEN_EXIT_METHOD"); } @Override @TransactionAttribute(TransactionAttributeType.REQUIRED) public void addPublicationToTopicWithoutNotifications(PublicationPK pubPK, NodePK fatherPK, boolean isACreation) { SilverTrace.info("kmelia", "KmeliaBmEJB.addPublicationToTopic()", "root.MSG_GEN_ENTER_METHOD"); PublicationDetail pubDetail = getPublicationDetail(pubPK); if (!isACreation) { try { Collection<NodePK> fathers = publicationBm.getAllFatherPK(pubPK); if (isPublicationInBasket(pubPK, fathers)) { publicationBm.removeFather(pubPK, new NodePK(NodePK.BIN_NODE_ID, fatherPK)); if (PublicationDetail.VALID.equalsIgnoreCase(pubDetail.getStatus())) { // index publication publicationBm.createIndex(pubPK); // index external elements indexExternalElementsOfPublication(pubDetail); // publication is accessible again updateSilverContentVisibility(pubDetail); } else if (PublicationDetail.TO_VALIDATE.equalsIgnoreCase(pubDetail.getStatus())) { // create validation todos for publishers createTodosForPublication(pubDetail, true); } } else if (fathers.isEmpty()) { // The publi have got no father // change the end date to make this publi visible pubDetail.setEndDate(null); publicationBm.setDetail(pubDetail); // publication is accessible again updateSilverContentVisibility(pubDetail); } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.addPublicationToTopic()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_PLACER_LA_PUBLICATION_DANS_LE_THEME", e); } } try { publicationBm.addFather(pubPK, fatherPK); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.addPublicationToTopic()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_PLACER_LA_PUBLICATION_DANS_LE_THEME", e); } } private boolean isPublicationInBasket(PublicationPK pubPK) { return isPublicationInBasket(pubPK, null); } private boolean isPublicationInBasket(PublicationPK pubPK, Collection<NodePK> fathers) { if (fathers == null) { fathers = publicationBm.getAllFatherPK(pubPK); } if (fathers.size() == 1) { Iterator<NodePK> iterator = fathers.iterator(); if (iterator.hasNext()) { NodePK pk = iterator.next(); if (pk.isTrash()) { return true; } } } return false; } private NodePK sendSubscriptionsNotification(PublicationDetail pubDetail, boolean update, final boolean sendOnlyToAliases) { NodePK oneFather = null; // We alert subscribers only if publication is Valid if (!pubDetail.haveGotClone() && pubDetail.isValid() && pubDetail.isVisible()) { // Topic subscriptions Collection<NodePK> fathers = getPublicationFathers(pubDetail.getPK()); if (!sendOnlyToAliases) { for (NodePK father : fathers) { oneFather = father; sendSubscriptionsNotification(father, pubDetail, update); } } // Subscriptions related to aliases List<Alias> aliases = (List<Alias>) getAlias(pubDetail.getPK()); for (Alias alias : aliases) { // Transform the current alias to a NodePK (even if Alias is extending NodePK) in the aim // to execute the equals method of NodePK if (!fathers.contains(new NodePK(alias.getId(), alias.getInstanceId()))) { // Perform subscription notification sendings when the alias is not the one of the // original publication pubDetail.setAlias(true); sendSubscriptionsNotification(alias, pubDetail, update); } } // PDC subscriptions try { int silverObjectId = getSilverObjectId(pubDetail.getPK()); List<ClassifyPosition> positions = pdcBm.getPositions(silverObjectId, pubDetail.getPK().getInstanceId()); PdcSubscriptionUtil pdc = new PdcSubscriptionUtil(); if (positions != null) { for (ClassifyPosition position : positions) { pdc.checkSubscriptions(position.getValues(), pubDetail.getPK().getInstanceId(), silverObjectId); } } } catch (RemoteException e) { SilverTrace.error("kmelia", "KmeliaBmEJB.sendSubscriptionsNotification", "kmelia.CANT_SEND_PDC_SUBSCRIPTIONS", e); } } return oneFather; } private void sendSubscriptionsNotification(NodePK fatherPK, PublicationDetail pubDetail, boolean update) { // Save instance id of publication String originalComponentId = pubDetail.getInstanceId(); // Change the instanceId (to make the right URL) pubDetail.getPK().setComponentName(fatherPK.getInstanceId()); // Send email alerts try { // Computing the action final NotifAction action; if (update) { action = NotifAction.UPDATE; } else { action = NotifAction.CREATE; } // Building and sending the notification UserNotificationHelper .buildAndSend(new KmeliaSubscriptionPublicationUserNotification(fatherPK, pubDetail, action)); } catch (Exception e) { SilverTrace.warn("kmelia", "KmeliaBmEJB.sendSubscriptionsNotification()", "kmelia.EX_IMPOSSIBLE_DALERTER_LES_UTILISATEURS", "fatherId = " + fatherPK.getId() + ", pubId = " + pubDetail.getPK().getId(), e); } finally { //Restore original primary key pubDetail.getPK().setComponentName(originalComponentId); } } /** * Delete a path between publication and topic * * @param pubPK * @param fatherPK */ @Override public void deletePublicationFromTopic(PublicationPK pubPK, NodePK fatherPK) { SilverTrace.info("kmelia", "KmeliaBmEJB.deletePublicationFromTopic()", "root.MSG_GEN_ENTER_METHOD"); try { Collection<NodePK> pubFathers = publicationBm.getAllFatherPK(pubPK); if (pubFathers.size() >= 2) { publicationBm.removeFather(pubPK, fatherPK); } else { // la publication n'a qu'un seul emplacement // elle est donc place dans la corbeille du crateur sendPublicationToBasket(pubPK); } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.deletePublicationFromTopic()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_SUPPRIMER_LA_PUBLICATION_DE_CE_THEME", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.deletePublicationFromTopic()", "root.MSG_GEN_EXIT_METHOD"); } @Override public void deletePublicationFromAllTopics(PublicationPK pubPK) { SilverTrace.info("kmelia", "KmeliaBmEJB.deletePublicationFromAllTopics()", "root.MSG_GEN_ENTER_METHOD"); try { publicationBm.removeAllFather(pubPK); // la publication n'a qu'un seul emplacement // elle est donc place dans la corbeille du crateur sendPublicationToBasket(pubPK); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.deletePublicationFromAllTopics()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_SUPPRIMER_LA_PUBLICATION_DE_CE_THEME", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.deletePublicationFromAllTopics()", "root.MSG_GEN_EXIT_METHOD"); } /** * get all available models * * @return a Collection of ModelDetail * @see com.stratelia.webactiv.util.publication.info.model.ModelDetail * @since 1.0 */ @Override public Collection<ModelDetail> getAllModels() { SilverTrace.info("kmelia", "KmeliaBmEJB.getAllModels()", "root.MSG_GEN_ENTER_METHOD"); return publicationBm.getAllModelsDetail(); } /** * Return the detail of a model * * @param modelId the id of the model * @return a ModelDetail * @since 1.0 */ @Override public ModelDetail getModelDetail(String modelId) { SilverTrace.info("kmelia", "KmeliaBmEJB.getModelDetail()", "root.MSG_GEN_ENTER_METHOD"); ModelPK modelPK = new ModelPK(modelId); SilverTrace.info("kmelia", "KmeliaBmEJB.getModelDetail()", "root.MSG_GEN_EXIT_METHOD"); return publicationBm.getModelDetail(modelPK); } /** * Create info attached to a publication * * @param pubPK the id of the publication * @param modelId the id of the selected model * @param infos an InfoDetail containing info * @since 1.0 */ @Override public void createInfoDetail(PublicationPK pubPK, String modelId, InfoDetail infos) { SilverTrace.info("kmelia", "KmeliaBmEJB.createInfoDetail()", "root.MSG_GEN_ENTER_METHOD"); try { ModelPK modelPK = new ModelPK(modelId, pubPK); checkIndex(pubPK, infos); publicationBm.createInfoDetail(pubPK, modelPK, infos); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.createInfoDetail()", ERROR, "kmelia.EX_IMPOSSIBLE_DENREGISTRER_LE_CONTENU_DU_MODELE", e); } updatePublication(pubPK, KmeliaHelper.PUBLICATION_CONTENT); SilverTrace.info("kmelia", "KmeliaBmEJB.createInfoDetail()", "root.MSG_GEN_EXIT_METHOD"); } /** * Create model info attached to a publication * * @param pubPK the id of the publication * @param modelId the id of the selected model * @param infos an InfoDetail containing info * @since 1.0 */ @Override public void createInfoModelDetail(PublicationPK pubPK, String modelId, InfoDetail infos) { SilverTrace.info("kmelia", "KmeliaBmEJB.createInfoModelDetail()", "root.MSG_GEN_ENTER_METHOD"); try { ModelPK modelPK = new ModelPK(modelId, pubPK); checkIndex(pubPK, infos); publicationBm.createInfoModelDetail(pubPK, modelPK, infos); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.createInfoModelDetail()", ERROR, "kmelia.EX_IMPOSSIBLE_DENREGISTRER_LE_CONTENU_DU_MODELE", e); } updatePublication(pubPK, KmeliaHelper.PUBLICATION_CONTENT); SilverTrace.info("kmelia", "KmeliaBmEJB.createInfoModelDetail()", "root.MSG_GEN_EXIT_METHOD"); } /** * get info attached to a publication * * @param pubPK the id of the publication * @return an InfoDetail * @since 1.0 */ @Override public InfoDetail getInfoDetail(PublicationPK pubPK) { SilverTrace.info("kmelia", "KmeliaBmEJB.getInfoDetail()", "root.MSG_GEN_ENTER_METHOD"); try { return publicationBm.getInfoDetail(pubPK); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getInfoDetail()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LE_CONTENU_DU_MODELE", e); } } /** * Update info attached to a publication * * @param pubPK the id of the publication * @param infos an InfoDetail containing info to updated * @since 1.0 */ @Override public void updateInfoDetail(PublicationPK pubPK, InfoDetail infos) { SilverTrace.info("kmelia", "KmeliaBmEJB.updateInfoDetail()", "root.MSG_GEN_ENTER_METHOD"); try { checkIndex(pubPK, infos); publicationBm.updateInfoDetail(pubPK, infos); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.updateInfoDetail()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_MODIFIER_LE_CONTENU_DU_MODELE", e); } updatePublication(pubPK, KmeliaHelper.PUBLICATION_CONTENT); SilverTrace.info("kmelia", "KmeliaBmEJB.updateInfoDetail()", "root.MSG_GEN_EXIT_METHOD"); } /** * Updates the publication links * * @param pubPK publication identifier which you want to update links * @param links list of publication to link with current. */ @Override @TransactionAttribute(TransactionAttributeType.REQUIRED) public void addInfoLinks(PublicationPK pubPK, List<ForeignPK> links) { SilverTrace.info("kmelia", "KmeliaBmEJB.addInfoLinks()", "root.MSG_GEN_ENTER_METHOD", "pubId = " + pubPK.getId() + ", pubIds = " + links.toString()); try { publicationBm.addLinks(pubPK, links); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.addInfoLinks()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_MODIFIER_LE_CONTENU_DU_MODELE", e); } } @Override @TransactionAttribute(TransactionAttributeType.REQUIRED) public void deleteInfoLinks(PublicationPK pubPK, List<ForeignPK> links) { SilverTrace.info("kmelia", "KmeliaBmEJB.deleteInfoLinks()", "root.MSG_GEN_ENTER_METHOD", "pubId = " + pubPK.getId() + ", pubIds = " + links.toString()); try { publicationBm.deleteInfoLinks(pubPK, links); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.deleteInfoLinks()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_MODIFIER_LE_CONTENU_DU_MODELE", e); } } @Override public CompletePublication getCompletePublication(PublicationPK pubPK) { SilverTrace.info("kmelia", "KmeliaBmEJB.getCompletePublication()", "root.MSG_GEN_ENTER_METHOD"); CompletePublication completePublication = null; try { completePublication = publicationBm.getCompletePublication(pubPK); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getCompletePublication()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LA_PUBLICATION", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.getCompletePublication()", "root.MSG_GEN_EXIT_METHOD"); return completePublication; } @Override public KmeliaPublication getPublication(PublicationPK pubPK) { SilverTrace.info("kmelia", "KmeliaBmEJB.getPublication()", "root.MSG_GEN_ENTER_METHOD", "pubPK = " + pubPK.toString()); return KmeliaPublication.aKmeliaPublicationWithPk(pubPK); } @Override public TopicDetail getPublicationFather(PublicationPK pubPK, boolean isTreeStructureUsed, String userId, boolean isRightsOnTopicsUsed) { SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationFather()", "root.MSG_GEN_ENTER_METHOD"); // fetch one of the publication fathers NodePK fatherPK = getPublicationFatherPK(pubPK, isTreeStructureUsed, userId, isRightsOnTopicsUsed); String profile = KmeliaHelper .getProfile(getOrganisationController().getUserProfiles(userId, pubPK.getInstanceId())); TopicDetail fatherDetail = goTo(fatherPK, userId, isTreeStructureUsed, profile, isRightsOnTopicsUsed); SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationFather()", "root.MSG_GEN_EXIT_METHOD"); return fatherDetail; } @Override public NodePK getPublicationFatherPK(PublicationPK pubPK, boolean isTreeStructureUsed, String userId, boolean isRightsOnTopicsUsed) { SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationFatherId()", "root.MSG_GEN_ENTER_METHOD"); // fetch one of the publication fathers Collection<NodePK> fathers = getPublicationFathers(pubPK); NodePK fatherPK = new NodePK("0", pubPK); // By default --> Root if (fathers != null) { Iterator<NodePK> it = fathers.iterator(); if (!isRightsOnTopicsUsed) { if (it.hasNext()) { fatherPK = it.next(); } } else { NodeDetail allowedFather = null; while (allowedFather == null && it.hasNext()) { fatherPK = it.next(); NodeDetail father = getNodeHeader(fatherPK); if (!father.haveRights() || getOrganisationController().isObjectAvailable( father.getRightsDependsOn(), ObjectType.NODE, fatherPK.getInstanceId(), userId)) { allowedFather = father; } } if (allowedFather != null) { fatherPK = allowedFather.getNodePK(); } } } return fatherPK; } @Override public Collection<NodePK> getPublicationFathers(PublicationPK pubPK) { SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationFathers()", "root.MSG_GEN_ENTER_METHOD", "pubPK = " + pubPK.toString()); try { Collection<NodePK> fathers = publicationBm.getAllFatherPK(pubPK); if (CollectionUtil.isEmpty(fathers)) { SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationFathers()", "root.MSG_GEN_PARAM_VALUE", "Following publication have got no fathers : pubPK = " + pubPK.toString()); // This publication have got no father ! // Check if it's a clone (a clone have got no father ever) boolean alwaysVisibleModeActivated = StringUtil.getBooleanValue(getOrganisationController() .getComponentParameterValue(pubPK.getInstanceId(), "publicationAlwaysVisible")); if (alwaysVisibleModeActivated) { SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationFathers()", "root.MSG_GEN_PARAM_VALUE", "Getting the publication"); PublicationDetail publi = publicationBm.getDetail(pubPK); if (publi != null) { boolean isClone = isClone(publi); SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationFathers()", "root.MSG_GEN_PARAM_VALUE", "This publication is clone ? " + isClone); if (isClone) { // This publication is a clone // Get fathers from main publication fathers = publicationBm.getAllFatherPK(publi.getClonePK()); SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationFathers()", "root.MSG_GEN_PARAM_VALUE", "Main publication's fathers fetched. # of fathers = " + fathers.size()); } } } } return fathers; } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getPublicationFathers()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_UN_PERE_DE_LA_PUBLICATION", e); } } /** * gets a list of PublicationDetail corresponding to the links parameter * * @param links list of publication (componentID + publicationId) * @return a list of PublicationDetail */ @Override public Collection<PublicationDetail> getPublicationDetails(List<ForeignPK> links) { SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationDetails()", "root.MSG_GEN_ENTER_METHOD"); Collection<PublicationDetail> publications = null; List<PublicationPK> publicationPKs = new ArrayList<PublicationPK>(); for (ForeignPK link : links) { PublicationPK pubPK = new PublicationPK(link.getId(), link.getInstanceId()); publicationPKs.add(pubPK); } try { publications = publicationBm.getPublications(publicationPKs); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getPublicationDetails()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LES_PUBLICATIONS", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationDetails()", "root.MSG_GEN_EXIT_METHOD"); return publications; } /** * gets a list of authorized publications * * @param links list of publication defined by his id and component id * @param userId identifier User. allow to check if the publication is accessible for current user * @param isRightsOnTopicsUsed indicates if the right must be checked * @return a collection of Kmelia publication * @since 1.0 */ @Override public Collection<KmeliaPublication> getPublications(List<ForeignPK> links, String userId, boolean isRightsOnTopicsUsed) { SilverTrace.info("kmelia", "KmeliaBmEJB.getPublications()", "root.MSG_GEN_ENTER_METHOD"); // initialization of the publications list List<ForeignPK> allowedPublicationIds = new ArrayList<ForeignPK>(links); if (isRightsOnTopicsUsed) { KmeliaSecurity security = new KmeliaSecurity(); allowedPublicationIds.clear(); // check if the publication is authorized for current user for (ForeignPK link : links) { if (security.isObjectAvailable(link.getInstanceId(), userId, link.getId(), KmeliaSecurity.PUBLICATION_TYPE)) { allowedPublicationIds.add(link); } } } Collection<PublicationDetail> publications = getPublicationDetails(allowedPublicationIds); return pubDetails2userPubs(publications); } /** * Gets the publications linked with the specified one and for which the specified user is * authorized to access. * * @param publication the publication from which linked publications are get. * @param userId the unique identifier of a user. It allows to check if a linked publication is * accessible for the specified user. * @return a list of Kmelia publications. * @ if an error occurs while communicating with the remote business service. */ @Override public List<KmeliaPublication> getLinkedPublications(KmeliaPublication publication, String userId) { KmeliaSecurity security = new KmeliaSecurity(); List<ForeignPK> allLinkIds = publication.getCompleteDetail().getLinkList(); List<KmeliaPublication> authorizedLinks = new ArrayList<KmeliaPublication>(allLinkIds.size()); for (ForeignPK linkId : allLinkIds) { if (security.isAccessAuthorized(linkId.getInstanceId(), userId, linkId.getId())) { PublicationPK pubPk = new PublicationPK(linkId.getId(), linkId.getInstanceId()); authorizedLinks.add(KmeliaPublication.aKmeliaPublicationWithPk(pubPk)); } } return authorizedLinks; } /** * Gets all the publications linked with the specified one. * * @param publication the publication from which linked publications are get. * @return a list of Kmelia publications. * @ if an error occurs while communicating with the remote business service. */ @Override public List<KmeliaPublication> getLinkedPublications(KmeliaPublication publication) { List<ForeignPK> allLinkIds = publication.getCompleteDetail().getLinkList(); List<KmeliaPublication> linkedPublications = new ArrayList<KmeliaPublication>(allLinkIds.size()); for (ForeignPK linkId : allLinkIds) { PublicationPK pubPk = new PublicationPK(linkId.getId(), linkId.getInstanceId()); linkedPublications.add(KmeliaPublication.aKmeliaPublicationWithPk(pubPk)); } return linkedPublications; } @Override public List<KmeliaPublication> getPublicationsToValidate(String componentId, String userId) { SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationsToValidate()", "root.MSG_GEN_ENTER_METHOD"); Collection<PublicationDetail> publications = new ArrayList<PublicationDetail>(); PublicationPK pubPK = new PublicationPK("useless", componentId); try { Collection<PublicationDetail> temp = publicationBm .getPublicationsByStatus(PublicationDetail.TO_VALIDATE, pubPK); // only publications which must be validated by current user must be returned for (PublicationDetail publi : temp) { boolean isClone = publi.isValidationRequired() && !"-1".equals(publi.getCloneId()); if (isClone) { if (isUserCanValidatePublication(publi.getPK(), userId)) { // publication to validate is a clone, get original one try { PublicationDetail original = getPublicationDetail( new PublicationPK(publi.getCloneId(), publi.getPK())); publications.add(original); } catch (Exception e) { // inconsistency in database ! Original publication does not exist SilverTrace.warn("kmelia", "KmeliaBmEJB.getPublicationsToValidate()", "kmelia.ORIGINAL_PUBLICATION_OF_CLONE_NOT_FOUND", "cloneId = " + publi.getId() + ", originalId=" + publi.getCloneId()); } } } else { if (isUserCanValidatePublication(publi.getPK(), userId)) { publications.add(publi); } } } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getPublicationsToValidate()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LES_PUBLICATIONS_A_VALIDER", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.getPublicationsToValidate()", "root.MSG_GEN_EXIT_METHOD"); return pubDetails2userPubs(publications); } private void sendValidationNotification(final NodePK fatherPK, final PublicationDetail pubDetail, final String refusalMotive, final String userIdWhoRefuse) { try { UserNotificationHelper.buildAndSend(new KmeliaValidationPublicationUserNotification(fatherPK, pubDetail, refusalMotive, userIdWhoRefuse)); } catch (Exception e) { SilverTrace.warn("kmelia", "KmeliaBmEJB.sendValidationNotification()", "kmelia.EX_IMPOSSIBLE_DALERTER_LES_UTILISATEURS", "fatherId = " + fatherPK.getId() + ", pubPK = " + pubDetail.getPK(), e); } } private void sendAlertToSupervisors(final NodePK fatherPK, final PublicationDetail pubDetail) { if (pubDetail.isValid()) { try { UserNotificationHelper .buildAndSend(new KmeliaSupervisorPublicationUserNotification(fatherPK, pubDetail)); } catch (Exception e) { SilverTrace.warn("kmelia", "KmeliaBmEJB.alertSupervisors()", "kmelia.EX_IMPOSSIBLE_DALERTER_LES_UTILISATEURS", "fatherId = " + fatherPK.getId() + ", pubPK = " + pubDetail.getPK(), e); } } } private int getValidationType(String instanceId) { String sParam = getOrganisationController().getComponentParameterValue(instanceId, InstanceParameters.validation); if (isDefined(sParam)) { return Integer.parseInt(sParam); } return KmeliaHelper.VALIDATION_CLASSIC; } private boolean isTargetedValidationEnabled(String componentId) { int value = getValidationType(componentId); return value == KmeliaHelper.VALIDATION_TARGET_N || value == KmeliaHelper.VALIDATION_TARGET_1; } private List<String> getValidatorIds(PublicationDetail publi) { List<String> allValidators = new ArrayList<String>(); if (isDefined(publi.getTargetValidatorId())) { StringTokenizer tokenizer = new StringTokenizer(publi.getTargetValidatorId(), ","); while (tokenizer.hasMoreTokens()) { allValidators.add(tokenizer.nextToken()); } } return allValidators; } @Override public List<String> getAllValidators(PublicationPK pubPK) { SilverTrace.debug("kmelia", "KmeliaBmEJB.getAllValidators", "root.MSG_GEN_ENTER_METHOD", "pubId = " + pubPK.getId()); // get all users who have to validate List<String> allValidators = new ArrayList<String>(); if (isTargetedValidationEnabled(pubPK.getInstanceId())) { PublicationDetail publi = publicationBm.getDetail(pubPK); allValidators = getValidatorIds(publi); } if (allValidators.isEmpty()) { // It's not a targeted validation or it is but no validators has // been selected ! List<String> roles = new ArrayList<String>(2); roles.add(SilverpeasRole.admin.name()); roles.add(SilverpeasRole.publisher.name()); if (KmeliaHelper.isKmax(pubPK.getInstanceId())) { allValidators.addAll(Arrays .asList(getOrganisationController().getUsersIdsByRoleNames(pubPK.getInstanceId(), roles))); } else { // get admin and publishers of all nodes where publication is List<NodePK> nodePKs = (List<NodePK>) getPublicationFathers(pubPK); NodePK nodePK; NodeDetail node; boolean oneNodeIsPublic = false; for (int n = 0; !oneNodeIsPublic && nodePKs != null && n < nodePKs.size(); n++) { nodePK = nodePKs.get(n); node = getNodeHeader(nodePK); if (node != null) { SilverTrace.debug("kmelia", "KmeliaBmEJB.getAllValidators", "root.MSG_GEN_PARAM_VALUE", "nodePK = " + nodePK.toString()); if (!node.haveRights()) { allValidators.addAll(Arrays.asList(getOrganisationController() .getUsersIdsByRoleNames(pubPK.getInstanceId(), roles))); oneNodeIsPublic = true; } else { allValidators.addAll(Arrays.asList( getOrganisationController().getUsersIdsByRoleNames(pubPK.getInstanceId(), Integer.toString(node.getRightsDependsOn()), ObjectType.NODE, roles))); } } } } } SilverTrace.debug("kmelia", "KmeliaBmEJB.getAllValidators", "root.MSG_GEN_EXIT_METHOD", "pubId = " + pubPK.getId() + ", allValidators = " + allValidators.toString()); return allValidators; } /** * * @param pubPK * @param allValidators * @return * @ */ private boolean isValidationComplete(PublicationPK pubPK, List<String> allValidators) { List<ValidationStep> steps = publicationBm.getValidationSteps(pubPK); // get users who have already validate List<String> stepUserIds = new ArrayList<String>(); for (ValidationStep step : steps) { stepUserIds.add(step.getUserId()); } // check if all users have validate boolean validationOK = true; for (int i = 0; validationOK && i < allValidators.size(); i++) { String validatorId = allValidators.get(i); validationOK = stepUserIds.contains(validatorId); } return validationOK; } /* (non-Javadoc) * @see com.stratelia.webactiv.kmelia.control.ejb.KmeliaBmBusinessSkeleton#validatePublication(com.stratelia.webactiv.util.publication.model.PublicationPK, java.lang.String, boolean) */ @Override public boolean validatePublication(PublicationPK pubPK, String userId, boolean force) { SilverTrace.info("kmelia", "KmeliaBmEJB.validatePublication()", "root.MSG_GEN_ENTER_METHOD"); boolean validationComplete = false; boolean update = false; try { CompletePublication currentPub = publicationBm.getCompletePublication(pubPK); PublicationDetail currentPubDetail = currentPub.getPublicationDetail(); boolean validationOnClone = currentPubDetail.haveGotClone(); PublicationPK validatedPK = pubPK; if (validationOnClone) { validatedPK = currentPubDetail.getClonePK(); } if (!isUserCanValidatePublication(validatedPK, userId)) { SilverTrace.info("kmelia", "KmeliaBmEJB.validatePublication()", "root.MSG_GEN_PARAM_VALUE", "user " + userId + " is not allowed to validate publication " + pubPK.toString()); return false; } if (force) { validationComplete = true; } else { int validationType = getValidationType(pubPK.getInstanceId()); if (validationType == KmeliaHelper.VALIDATION_CLASSIC || validationType == KmeliaHelper.VALIDATION_TARGET_1) { validationComplete = true; } else { if (validationType == KmeliaHelper.VALIDATION_TARGET_N) { // check that validators are well defined // If not, considering validation as classic one PublicationDetail publi = publicationBm.getDetail(validatedPK); if (!isDefined(publi.getTargetValidatorId())) { validationComplete = true; } } if (!validationComplete) { // get all users who have to validate List<String> allValidators = getAllValidators(validatedPK); if (allValidators.size() == 1) { // special case : only once user is concerned by validation validationComplete = true; } else if (allValidators.size() > 1) { // remove todo for this user. His job is done ! removeTodoForPublication(validatedPK, userId); if (validationOnClone) { removeTodoForPublication(pubPK, userId); } // save his decision ValidationStep validation = new ValidationStep(validatedPK, userId, PublicationDetail.VALID); publicationBm.addValidationStep(validation); // check if all validators have give their decision validationComplete = isValidationComplete(validatedPK, allValidators); } } } } if (validationComplete) { removeAllTodosForPublication(validatedPK); if (validationOnClone) { removeAllTodosForPublication(pubPK); } if (currentPubDetail.haveGotClone()) { update = currentPubDetail.isValid(); currentPubDetail = mergeClone(currentPub, userId); } else if (currentPubDetail.isValidationRequired()) { currentPubDetail.setValidatorId(userId); currentPubDetail.setValidateDate(new Date()); currentPubDetail.setStatus(PublicationDetail.VALID); } KmeliaHelper.checkIndex(currentPubDetail); publicationBm.setDetail(currentPubDetail); updateSilverContentVisibility(currentPubDetail); // index all publication's elements indexExternalElementsOfPublication(currentPubDetail); // the publication has been validated // we must alert all subscribers of the different topics NodePK oneFather = sendSubscriptionsNotification(currentPubDetail, update, false); // we have to alert publication's creator sendValidationNotification(oneFather, currentPubDetail, null, userId); // alert supervisors sendAlertToSupervisors(oneFather, currentPubDetail); } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.validatePublication()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_VALIDER_LA_PUBLICATION", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.validatePublication()", "root.MSG_GEN_EXIT_METHOD", "validationComplete = " + validationComplete); return validationComplete; } private PublicationDetail getClone(PublicationDetail refPub) { PublicationDetail clone = new PublicationDetail(); if (refPub.getAuthor() != null) { clone.setAuthor(refPub.getAuthor()); } if (refPub.getBeginDate() != null) { clone.setBeginDate(new Date(refPub.getBeginDate().getTime())); } if (refPub.getBeginHour() != null) { clone.setBeginHour(refPub.getBeginHour()); } if (refPub.getContent() != null) { clone.setContent(refPub.getContent()); } clone.setCreationDate(new Date(refPub.getCreationDate().getTime())); clone.setCreatorId(refPub.getCreatorId()); if (refPub.getDescription() != null) { clone.setDescription(refPub.getDescription()); } if (refPub.getEndDate() != null) { clone.setEndDate(new Date(refPub.getEndDate().getTime())); } if (refPub.getEndHour() != null) { clone.setEndHour(refPub.getEndHour()); } clone.setImportance(refPub.getImportance()); if (refPub.getInfoId() != null) { clone.setInfoId(refPub.getInfoId()); } if (refPub.getKeywords() != null) { clone.setKeywords(refPub.getKeywords()); } if (refPub.getName() != null) { clone.setName(refPub.getName()); } clone.setPk(new PublicationPK(refPub.getPK().getId(), refPub.getPK().getInstanceId())); if (refPub.getStatus() != null) { clone.setStatus(refPub.getStatus()); } if (refPub.getTargetValidatorId() != null) { clone.setTargetValidatorId(refPub.getTargetValidatorId()); } if (refPub.getCloneId() != null) { clone.setCloneId(refPub.getCloneId()); } if (refPub.getUpdateDate() != null) { clone.setUpdateDate(new Date(refPub.getUpdateDate().getTime())); } if (refPub.getUpdaterId() != null) { clone.setUpdaterId(refPub.getUpdaterId()); } if (refPub.getValidateDate() != null) { clone.setValidateDate(new Date(refPub.getValidateDate().getTime())); } if (refPub.getValidatorId() != null) { clone.setValidatorId(refPub.getValidatorId()); } if (refPub.getVersion() != null) { clone.setVersion(refPub.getVersion()); } return clone; } private PublicationDetail mergeClone(CompletePublication currentPub, String userId) throws FormException, PublicationTemplateException, AttachmentException { PublicationDetail currentPubDetail = currentPub.getPublicationDetail(); String memInfoId = currentPubDetail.getInfoId(); PublicationPK pubPK = currentPubDetail.getPK(); // merge du clone sur la publi de rfrence String cloneId = currentPubDetail.getCloneId(); if (!"-1".equals(cloneId)) { PublicationPK tempPK = new PublicationPK(cloneId, pubPK); CompletePublication tempPubli = publicationBm.getCompletePublication(tempPK); PublicationDetail tempPubliDetail = tempPubli.getPublicationDetail(); // le clone devient la publi de rfrence currentPubDetail = getClone(tempPubliDetail); currentPubDetail.setPk(pubPK); if (userId != null) { currentPubDetail.setValidatorId(userId); currentPubDetail.setValidateDate(new Date()); } currentPubDetail.setStatus(PublicationDetail.VALID); currentPubDetail.setCloneId("-1"); currentPubDetail.setCloneStatus(null); // merge des fichiers joints ForeignPK pkFrom = new ForeignPK(pubPK.getId(), pubPK.getInstanceId()); ForeignPK pkTo = new ForeignPK(cloneId, tempPK.getInstanceId()); Map<String, String> attachmentIds = AttachmentServiceFactory.getAttachmentService() .mergeDocuments(pkFrom, pkTo, DocumentType.attachment); // merge du contenu DBModel if (tempPubli.getModelDetail() != null) { if (currentPub.getModelDetail() != null) { currentPubDetail.setInfoId(memInfoId); // il existait dj un contenu publicationBm.updateInfoDetail(pubPK, tempPubli.getInfoDetail()); } else { // il n'y avait pas encore de contenu ModelPK modelPK = new ModelPK(tempPubli.getModelDetail().getId(), "useless", tempPK.getInstanceId()); publicationBm.createInfoModelDetail(pubPK, modelPK, tempPubli.getInfoDetail()); // recupere nouvel infoId PublicationDetail modifiedPubli = getPublicationDetail(pubPK); currentPubDetail.setInfoId(modifiedPubli.getInfoId()); } } else { // merge du contenu XMLModel String infoId = tempPubli.getPublicationDetail().getInfoId(); if (infoId != null && !"0".equals(infoId) && !isInteger(infoId)) { // register xmlForm to publication String xmlFormShortName = infoId; // get xmlContent to paste PublicationTemplateManager publicationTemplateManager = PublicationTemplateManager .getInstance(); PublicationTemplate pubTemplate = publicationTemplateManager .getPublicationTemplate(tempPK.getInstanceId() + ":" + xmlFormShortName); RecordSet set = pubTemplate.getRecordSet(); // DataRecord data = set.getRecord(fromId); if (memInfoId != null && !"0".equals(memInfoId)) { // il existait dj un contenu set.merge(cloneId, pubPK.getInstanceId(), pubPK.getId(), pubPK.getInstanceId(), attachmentIds); } else { // il n'y avait pas encore de contenu publicationTemplateManager.addDynamicPublicationTemplate( tempPK.getInstanceId() + ":" + xmlFormShortName, xmlFormShortName + ".xml"); set.clone(cloneId, pubPK.getInstanceId(), pubPK.getId(), pubPK.getInstanceId(), attachmentIds); } } } // merge du contenu Wysiwyg boolean cloneWysiwyg = WysiwygController.haveGotWysiwyg(tempPK.getInstanceId(), cloneId, tempPubli.getPublicationDetail().getLanguage()); if (cloneWysiwyg) { try { // delete wysiwyg contents of public version WysiwygController.deleteWysiwygAttachmentsOnly("useless", pubPK.getInstanceId(), pubPK.getId()); } catch (WysiwygException e) { Logger.getLogger(getClass().getSimpleName()).log(Level.SEVERE, e.getMessage(), e); } // wysiwyg contents of work version become public version ones WysiwygController.copy(tempPK.getInstanceId(), cloneId, pubPK.getInstanceId(), pubPK.getId(), tempPubli.getPublicationDetail().getUpdaterId()); } // suppression du clone deletePublication(tempPK); } return currentPubDetail; } @Override public void unvalidatePublication(PublicationPK pubPK, String userId, String refusalMotive, int validationType) { SilverTrace.info("kmelia", "KmeliaBmEJB.unvalidatePublication()", "root.MSG_GEN_ENTER_METHOD"); try { switch (validationType) { case KmeliaHelper.VALIDATION_COLLEGIATE: case KmeliaHelper.VALIDATION_TARGET_N: // reset other decisions publicationBm.removeValidationSteps(pubPK); break; case KmeliaHelper.VALIDATION_CLASSIC: case KmeliaHelper.VALIDATION_TARGET_1: default: break;// do nothing } PublicationDetail currentPubDetail = publicationBm.getDetail(pubPK); if (currentPubDetail.haveGotClone()) { String cloneId = currentPubDetail.getCloneId(); PublicationPK tempPK = new PublicationPK(cloneId, pubPK); PublicationDetail clone = publicationBm.getDetail(tempPK); // change clone's status clone.setStatus("UnValidate"); clone.setIndexOperation(IndexManager.NONE); publicationBm.setDetail(clone); // Modification de la publication de reference currentPubDetail.setCloneStatus(PublicationDetail.REFUSED); currentPubDetail.setUpdateDateMustBeSet(false); publicationBm.setDetail(currentPubDetail); // we have to alert publication's last updater List<NodePK> fathers = (List<NodePK>) getPublicationFathers(pubPK); NodePK oneFather = null; if (fathers != null && fathers.size() > 0) { oneFather = fathers.get(0); } sendValidationNotification(oneFather, clone, refusalMotive, userId); // remove tasks removeAllTodosForPublication(clone.getPK()); } else { // change publication's status currentPubDetail.setStatus("UnValidate"); KmeliaHelper.checkIndex(currentPubDetail); publicationBm.setDetail(currentPubDetail); // change visibility over PDC updateSilverContentVisibility(currentPubDetail); // we have to alert publication's creator List<NodePK> fathers = (List<NodePK>) getPublicationFathers(pubPK); NodePK oneFather = null; if (fathers != null && !fathers.isEmpty()) { oneFather = fathers.get(0); } sendValidationNotification(oneFather, currentPubDetail, refusalMotive, userId); //remove tasks removeAllTodosForPublication(currentPubDetail.getPK()); } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.unvalidatePublication()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_REFUSER_LA_PUBLICATION", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.unvalidatePublication()", "root.MSG_GEN_EXIT_METHOD"); } @Override public void suspendPublication(PublicationPK pubPK, String defermentMotive, String userId) { SilverTrace.info("kmelia", "KmeliaBmEJB.suspendPublication()", "root.MSG_GEN_ENTER_METHOD"); try { PublicationDetail currentPubDetail = publicationBm.getDetail(pubPK); // change publication's status currentPubDetail.setStatus(PublicationDetail.TO_VALIDATE); KmeliaHelper.checkIndex(currentPubDetail); publicationBm.setDetail(currentPubDetail); // change visibility over PDC updateSilverContentVisibility(currentPubDetail); unIndexExternalElementsOfPublication(currentPubDetail.getPK()); // we have to alert publication's creator sendDefermentNotification(currentPubDetail, defermentMotive, userId); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.unvalidatePublication()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_REFUSER_LA_PUBLICATION", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.suspendPublication()", "root.MSG_GEN_EXIT_METHOD"); } private void sendDefermentNotification(final PublicationDetail pubDetail, final String defermentMotive, final String senderId) { try { UserNotificationHelper .buildAndSend(new KmeliaDefermentPublicationUserNotification(pubDetail, defermentMotive)); } catch (Exception e) { SilverTrace.warn("kmelia", "KmeliaBmEJB.sendDefermentNotification()", "kmelia.EX_IMPOSSIBLE_DALERTER_LES_UTILISATEURS", "pubPK = " + pubDetail.getPK(), e); } } /** * Change publication status from draft to valid (for publisher) or toValidate (for redactor). * * @param pubPK * @param topicPK * @param userProfile */ @Override public void draftOutPublication(PublicationPK pubPK, NodePK topicPK, String userProfile) { boolean update = getPublicationDetail(pubPK).isValid(); PublicationDetail pubDetail = draftOutPublicationWithoutNotifications(pubPK, topicPK, userProfile); indexExternalElementsOfPublication(pubDetail); sendTodosAndNotificationsOnDraftOut(pubDetail, topicPK, userProfile, update); } /** * This method is here to manage correctly transactional scope of EJB (conflict between EJB and * UserPreferences service) * * @param pubPK * @return */ @Override @TransactionAttribute(TransactionAttributeType.REQUIRED) public PublicationDetail draftOutPublicationWithoutNotifications(PublicationPK pubPK, NodePK topicPK, String userProfile) { return draftOutPublication(pubPK, topicPK, userProfile, false, true); } @Override public PublicationDetail draftOutPublication(PublicationPK pubPK, NodePK topicPK, String userProfile, boolean forceUpdateDate) { return draftOutPublication(pubPK, topicPK, userProfile, forceUpdateDate, false); } private PublicationDetail draftOutPublication(PublicationPK pubPK, NodePK topicPK, String userProfile, boolean forceUpdateDate, boolean inTransaction) { SilverTrace.info("kmelia", "KmeliaBmEJB.draftOutPublication()", "root.MSG_GEN_ENTER_METHOD", "pubId = " + pubPK.getId()); try { boolean update = false; CompletePublication currentPub = publicationBm.getCompletePublication(pubPK); PublicationDetail pubDetail = currentPub.getPublicationDetail(); SilverTrace.info("kmelia", "KmeliaBmEJB.draftOutPublication()", "root.MSG_GEN_PARAM_VALUE", "actual status = " + pubDetail.getStatus()); if (userProfile.equals("publisher") || userProfile.equals("admin")) { if (pubDetail.haveGotClone()) { // special case when a publication is draft out // check public publication status to determine // if it's a creation or an update... update = pubDetail.isValid(); pubDetail = mergeClone(currentPub, null); } pubDetail.setStatus(PublicationDetail.VALID); } else { if (pubDetail.haveGotClone()) { // changement du statut du clone PublicationDetail clone = publicationBm.getDetail(pubDetail.getClonePK()); clone.setStatus(PublicationDetail.TO_VALIDATE); clone.setIndexOperation(IndexManager.NONE); clone.setUpdateDateMustBeSet(false); publicationBm.setDetail(clone); pubDetail.setCloneStatus(PublicationDetail.TO_VALIDATE); } else { pubDetail.setStatus(PublicationDetail.TO_VALIDATE); } } KmeliaHelper.checkIndex(pubDetail); publicationBm.setDetail(pubDetail, forceUpdateDate); if (!KmeliaHelper.isKmax(pubDetail.getInstanceId())) { // update visibility attribute on PDC updateSilverContentVisibility(pubDetail); } SilverTrace.info("kmelia", "KmeliaBmEJB.draftOutPublication()", "root.MSG_GEN_PARAM_VALUE", "new status = " + pubDetail.getStatus()); if (!inTransaction) { // index all publication's elements indexExternalElementsOfPublication(pubDetail); sendTodosAndNotificationsOnDraftOut(pubDetail, topicPK, userProfile, update); } return pubDetail; } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.draftOutPublication()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_MODIFIER_LA_PUBLICATION", e); } } private void sendTodosAndNotificationsOnDraftOut(PublicationDetail pubDetail, NodePK topicPK, String userProfile, boolean update) { if (SilverpeasRole.writer.isInRole(userProfile)) { createTodosForPublication(pubDetail, true); } // Subscriptions and supervisors are supported by kmelia and filebox only if (!KmeliaHelper.isKmax(pubDetail.getInstanceId())) { // alert subscribers sendSubscriptionsNotification(pubDetail, update, false); // alert supervisors if (topicPK != null) { sendAlertToSupervisors(topicPK, pubDetail); } } } /** * Change publication status from any state to draft. * * @param pubPK */ @Override public void draftInPublication(PublicationPK pubPK) { draftInPublication(pubPK, null); } @Override public void draftInPublication(PublicationPK pubPK, String userId) { SilverTrace.info("kmelia", "KmeliaBmEJB.draftInPublication()", "root.MSG_GEN_ENTER_METHOD", "pubPK = " + pubPK.toString()); try { PublicationDetail pubDetail = publicationBm.getDetail(pubPK); SilverTrace.info("kmelia", "KmeliaBmEJB.draftInPublication()", "root.MSG_GEN_PARAM_VALUE", "actual status = " + pubDetail.getStatus()); if (pubDetail.isRefused() || pubDetail.isValid()) { pubDetail.setStatus(PublicationDetail.DRAFT); pubDetail.setUpdaterId(userId); KmeliaHelper.checkIndex(pubDetail); publicationBm.setDetail(pubDetail); updateSilverContentVisibility(pubDetail); unIndexExternalElementsOfPublication(pubDetail.getPK()); removeAllTodosForPublication(pubPK); boolean isNewsManage = getBooleanValue(getOrganisationController() .getComponentParameterValue(pubDetail.getPK().getInstanceId(), "isNewsManage")); if (isNewsManage) { // mcanisme de callback CallBackManager callBackManager = CallBackManager.get(); callBackManager.invoke(CallBackManager.ACTION_PUBLICATION_REMOVE, Integer.parseInt(pubDetail.getId()), pubDetail.getInstanceId(), pubDetail); } } SilverTrace.info("kmelia", "KmeliaBmEJB.draftInPublication()", "root.MSG_GEN_PARAM_VALUE", "new status = " + pubDetail.getStatus()); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.draftInPublication()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_MODIFIER_LA_PUBLICATION", e); } } @Override public NotificationMetaData getAlertNotificationMetaData(PublicationPK pubPK, NodePK topicPK, String senderName) { SilverTrace.info("kmelia", "KmeliaBmEJB.getAlertNotificationMetaData()", "root.MSG_GEN_ENTER_METHOD"); final PublicationDetail pubDetail = getPublicationDetail(pubPK); pubDetail.setAlias(isAlias(pubDetail, topicPK)); final NotificationMetaData notifMetaData = UserNotificationHelper .build(new KmeliaNotifyPublicationUserNotification(topicPK, pubDetail, senderName)); SilverTrace.info("kmelia", "KmeliaBmEJB.getAlertNotificationMetaData()", "root.MSG_GEN_EXIT_METHOD"); return notifMetaData; } public boolean isAlias(PublicationDetail pubDetail, NodePK nodePK) { boolean result = false; Collection<Alias> aliases = getAlias(pubDetail.getPK()); for (Alias alias : aliases) { if (!alias.getInstanceId().equals(pubDetail.getInstanceId()) && nodePK.equals(alias)) { result = true; break; } } return result; } /** * @param pubPK * @param documentPk * @param topicPK * @param senderName * @return * @ */ @Override public NotificationMetaData getAlertNotificationMetaData(PublicationPK pubPK, SimpleDocumentPK documentPk, NodePK topicPK, String senderName) { SilverTrace.info("kmelia", "KmeliaBmEJB.getAlertNotificationMetaData(document)", "root.MSG_GEN_ENTER_METHOD"); final PublicationDetail pubDetail = getPublicationDetail(pubPK); final SimpleDocument document = AttachmentServiceFactory.getAttachmentService() .searchDocumentById(documentPk, null); SimpleDocument version = document.getLastPublicVersion(); if (version == null) { version = document.getVersionMaster(); } final NotificationMetaData notifMetaData = UserNotificationHelper.build( new KmeliaDocumentSubscriptionPublicationUserNotification(topicPK, pubDetail, version, senderName)); SilverTrace.info("kmelia", "KmeliaBmEJB.getAlertNotificationMetaData(document)", "root.MSG_GEN_EXIT_METHOD"); return notifMetaData; } /** * delete reading controls to a publication * * @param pubPK the id of a publication * @since 1.0 */ @Override public void deleteAllReadingControlsByPublication(PublicationPK pubPK) { SilverTrace.info("kmelia", "KmeliaBmEJB.deleteAllReadingControlsByPublication()", "root.MSG_GEN_ENTER_METHOD"); try { statisticBm.deleteStats(new ForeignPK(pubPK.getId(), pubPK.getInstanceId()), "Publication"); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.deleteAllReadingControlsByPublication()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_SUPPRIMER_LES_CONTROLES_DE_LECTURE", e); } SilverTrace.info("kmelia", "KmeliaBmEJB.deleteAllReadingControlsByPublication()", "root.MSG_GEN_EXIT_METHOD"); } @Override public List<HistoryObjectDetail> getLastAccess(PublicationPK pk, NodePK nodePK, String excludedUserId) { Collection<HistoryObjectDetail> allAccess = statisticBm.getHistoryByAction(new ForeignPK(pk), 1, "Publication"); List<String> userIds = getUserIdsOfFolder(nodePK); List<String> readerIds = new ArrayList<String>(); List<HistoryObjectDetail> lastAccess = new ArrayList<HistoryObjectDetail>(); for (HistoryObjectDetail access : allAccess) { String readerId = access.getUserId(); if ((!StringUtil.isDefined(excludedUserId) || !excludedUserId.equals(readerId)) && (userIds == null || userIds.contains(readerId)) && !readerIds.contains(readerId)) { readerIds.add(readerId); if (!UserDetail.getById(readerId).isAnonymous()) { lastAccess.add(access); } } } return lastAccess; } @Override public List<String> getUserIdsOfFolder(NodePK pk) { if (!isRightsOnTopicsEnabled(pk.getInstanceId())) { return null; } NodeDetail node = getNodeHeader(pk); // check if we have to take care of topic's rights if (node != null && node.haveRights()) { int rightsDependsOn = node.getRightsDependsOn(); List<String> profileNames = new ArrayList<String>(4); profileNames.add(KmeliaHelper.ROLE_ADMIN); profileNames.add(KmeliaHelper.ROLE_PUBLISHER); profileNames.add(KmeliaHelper.ROLE_WRITER); profileNames.add(KmeliaHelper.ROLE_READER); String[] userIds = getOrganisationController().getUsersIdsByRoleNames(pk.getInstanceId(), Integer.toString(rightsDependsOn), ObjectType.NODE, profileNames); return Arrays.asList(userIds); } else { return null; } } @Override public void indexKmelia(String componentId) { indexTopics(new NodePK("useless", componentId)); indexPublications(new PublicationPK("useless", componentId)); } private void indexPublications(PublicationPK pubPK) { Collection<PublicationDetail> pubs = null; try { pubs = publicationBm.getAllPublications(pubPK); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.indexPublications()", ERROR, "kmelia.EX_IMPOSSIBLE_DINDEXER_LES_PUBLICATIONS", e); } if (pubs != null) { for (PublicationDetail pub : pubs) { try { pubPK = pub.getPK(); List<NodePK> pubFathers; // index only valid publications if (pub.getStatus() != null && pub.isValid()) { pubFathers = (List<NodePK>) publicationBm.getAllFatherPK(pubPK); // index only valid publications which are not only in // dz or basket if (pubFathers.size() >= 2) { indexPublication(pub); } else if (pubFathers.size() == 1) { NodePK nodePK = pubFathers.get(0); // index the valid publication if it is not in the // basket if (!nodePK.isTrash()) { indexPublication(pub); } } else { // don't index publications in the dz } } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.indexPublications()", ERROR, "kmelia.EX_IMPOSSIBLE_DINDEXER_LA_PUBLICATION", "pubPK = " + pubPK.toString(), e); } } } } private void indexPublication(PublicationDetail pub) { // index publication itself publicationBm.createIndex(pub.getPK()); // index external elements indexExternalElementsOfPublication(pub); } private void indexTopics(NodePK nodePK) { try { Collection<NodeDetail> nodes = nodeBm.getAllNodes(nodePK); if (nodes != null) { for (NodeDetail node : nodes) { if (!node.getNodePK().isRoot() && !node.getNodePK().isTrash() && !node.getNodePK().getId().equals("2")) { nodeBm.createIndex(node); } } } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.indexTopics()", ERROR, "kmelia.EX_IMPOSSIBLE_DINDEXER_LES_THEMES", e); } } /* * Creates todos for all publishers of this kmelia instance * @param pubDetail publication to be validated * @param creation true if it's the creation of the publi */ private void createTodosForPublication(PublicationDetail pubDetail, boolean creation) { if (!creation) { /* remove all todos attached to that publication */ removeAllTodosForPublication(pubDetail.getPK()); } if (pubDetail.isValidationRequired() || PublicationDetail.TO_VALIDATE.equalsIgnoreCase(pubDetail.getCloneStatus())) { int validationType = getValidationType(pubDetail.getPK().getInstanceId()); if (validationType == KmeliaHelper.VALIDATION_TARGET_N || validationType == KmeliaHelper.VALIDATION_COLLEGIATE) { // removing potential older validation decision publicationBm.removeValidationSteps(pubDetail.getPK()); } List<String> validators = getAllValidators(pubDetail.getPK()); String[] users = validators.toArray(new String[validators.size()]); // For each publisher create a todo addTodo(pubDetail, users); // Send a notification to alert admins and publishers sendValidationAlert(pubDetail, users); } } private String addTodo(PublicationDetail pubDetail, String[] users) { ResourceLocator message = new ResourceLocator("com.stratelia.webactiv.kmelia.multilang.kmeliaBundle", "fr"); TodoDetail todo = new TodoDetail(); todo.setId(pubDetail.getPK().getId()); todo.setSpaceId(pubDetail.getPK().getSpace()); todo.setComponentId(pubDetail.getPK().getComponentName()); todo.setName(message.getString("ToValidateShort") + " : " + pubDetail.getName()); List<Attendee> attendees = new ArrayList<Attendee>(); for (String user : users) { if (user != null) { attendees.add(new Attendee(user)); } } todo.setAttendees(new ArrayList<Attendee>(attendees)); if (isDefined(pubDetail.getUpdaterId())) { todo.setDelegatorId(pubDetail.getUpdaterId()); } else { todo.setDelegatorId(pubDetail.getCreatorId()); } todo.setExternalId(pubDetail.getPK().getId()); TodoBackboneAccess todoBBA = new TodoBackboneAccess(); return todoBBA.addEntry(todo); } /* * Remove todos for all pubishers of this kmelia instance * @param pubDetail corresponding publication */ private void removeAllTodosForPublication(PublicationPK pubPK) { SilverTrace.info("kmelia", "KmeliaBmEJB.removeAllTodosForPublication()", "root.MSG_GEN_ENTER_METHOD", "Enter pubPK =" + pubPK.toString()); TodoBackboneAccess todoBBA = new TodoBackboneAccess(); todoBBA.removeEntriesFromExternal("useless", pubPK.getInstanceId(), pubPK.getId()); } private void removeTodoForPublication(PublicationPK pubPK, String userId) { SilverTrace.info("kmelia", "KmeliaBmEJB.removeTodoForPublication()", "root.MSG_GEN_ENTER_METHOD", "Enter pubPK =" + pubPK.toString()); TodoBackboneAccess todoBBA = new TodoBackboneAccess(); todoBBA.removeAttendeeToEntryFromExternal(pubPK.getInstanceId(), pubPK.getId(), userId); } private void sendValidationAlert(final PublicationDetail pubDetail, final String[] users) { UserNotificationHelper .buildAndSend(new KmeliaPendingValidationPublicationUserNotification(pubDetail, users)); } private void sendModificationAlert(final int modificationScope, final PublicationDetail pubDetail) { UserNotificationHelper .buildAndSend(new KmeliaModificationPublicationUserNotification(pubDetail, modificationScope)); } @Override public void sendModificationAlert(int modificationScope, PublicationPK pubPK) { sendModificationAlert(modificationScope, getPublicationDetail(pubPK)); } @Override public int getSilverObjectId(PublicationPK pubPK) { SilverTrace.info("kmelia", "KmeliaBmEJB.getSilverObjectId()", "root.MSG_GEN_ENTER_METHOD", "pubId = " + pubPK.getId()); int silverObjectId = -1; PublicationDetail pubDetail; try { silverObjectId = getKmeliaContentManager().getSilverObjectId(pubPK.getId(), pubPK.getInstanceId()); if (silverObjectId == -1) { pubDetail = getPublicationDetail(pubPK); silverObjectId = createSilverContent(pubDetail, pubDetail.getCreatorId()); } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getSilverObjectId()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LE_SILVEROBJECTID", e); } return silverObjectId; } private int createSilverContent(PublicationDetail pubDetail, String creatorId) { SilverTrace.info("kmelia", "KmeliaBmEJB.createSilverContent()", "root.MSG_GEN_ENTER_METHOD", "pubId = " + pubDetail.getPK().getId()); Connection con = null; try { con = getConnection(); return getKmeliaContentManager().createSilverContent(con, pubDetail, creatorId); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.createSilverContent()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LE_SILVEROBJECTID", e); } finally { freeConnection(con); } } @Override public void deleteSilverContent(PublicationPK pubPK) { SilverTrace.info("kmelia", "KmeliaBmEJB.deleteSilverContent()", "root.MSG_GEN_ENTER_METHOD", "pubId = " + pubPK.getId()); Connection con = getConnection(); try { getKmeliaContentManager().deleteSilverContent(con, pubPK); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.deleteSilverContent()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LE_SILVEROBJECTID", e); } finally { freeConnection(con); } } private void updateSilverContentVisibility(PublicationDetail pubDetail) { try { getKmeliaContentManager().updateSilverContentVisibility(pubDetail); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.updateSilverContentVisibility()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LE_SILVEROBJECTID", e); } } private void updateSilverContentVisibility(PublicationPK pubPK, boolean isVisible) { PublicationDetail pubDetail = getPublicationDetail(pubPK); try { getKmeliaContentManager().updateSilverContentVisibility(pubDetail, isVisible); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.updateSilverContentVisibility()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LE_SILVEROBJECTID", e); } } private KmeliaContentManager getKmeliaContentManager() { return new KmeliaContentManager(); } private void checkIndex(PublicationPK pubPK, InfoDetail infos) { infos.setIndexOperation(IndexManager.NONE); } private void indexExternalElementsOfPublication(PublicationDetail pubDetail) { if (KmeliaHelper.isIndexable(pubDetail)) { try { AttachmentServiceFactory.getAttachmentService().indexAllDocuments(pubDetail.getPK(), pubDetail.getBeginDate(), pubDetail.getEndDate()); } catch (Exception e) { SilverTrace.error("kmelia", "KmeliaBmEJB.indexExternalElementsOfPublication", "Indexing versioning documents failed", "pubPK = " + pubDetail.getPK().toString(), e); } try { // index comments getCommentService().indexAllCommentsOnPublication(pubDetail.getContributionType(), pubDetail.getPK()); } catch (Exception e) { SilverTrace.error("kmelia", "KmeliaBmEJB.indexExternalElementsOfPublication", "Indexing comments failed", "pubPK = " + pubDetail.getPK().toString(), e); } } } private void unIndexExternalElementsOfPublication(PublicationPK pubPK) { try { AttachmentServiceFactory.getAttachmentService().unindexAttachmentsOfExternalObject(pubPK); } catch (Exception e) { SilverTrace.error("kmelia", "KmeliaBmEJB.indexExternalElementsOfPublication", "Indexing versioning documents failed", "pubPK = " + pubPK.toString(), e); } try { // index comments getCommentService().unindexAllCommentsOnPublication(PublicationDetail.getResourceType(), pubPK); } catch (Exception e) { SilverTrace.error("kmelia", "KmeliaBmEJB.indexExternalElementsOfPublication", "Indexing comments failed", "pubPK = " + pubPK.toString(), e); } } private void removeExternalElementsOfPublications(PublicationPK pubPK) { // remove attachments List<SimpleDocument> documents = AttachmentServiceFactory.getAttachmentService() .listAllDocumentsByForeignKey(pubPK, null); for (SimpleDocument doc : documents) { AttachmentServiceFactory.getAttachmentService().deleteAttachment(doc); } // remove comments try { getCommentService().deleteAllCommentsOnPublication(PublicationDetail.getResourceType(), pubPK); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.removeExternalElementsOfPublications()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_SUPPRIMER_LES_COMMENTAIRES", e); } // remove Wysiwyg content try { WysiwygController.deleteWysiwygAttachments(pubPK.getInstanceId(), pubPK.getId()); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.removeExternalElementsOfPublications", ERROR, "root.EX_DELETE_ATTACHMENT_FAILED", e); } // remove Thumbnail content try { ThumbnailDetail thumbToDelete = new ThumbnailDetail(pubPK.getInstanceId(), Integer.parseInt(pubPK.getId()), ThumbnailDetail.THUMBNAIL_OBJECTTYPE_PUBLICATION_VIGNETTE); ThumbnailController.deleteThumbnail(thumbToDelete); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.removeExternalElementsOfPublications", ERROR, "root.EX_DELETE_THUMBNAIL_FAILED", e); } } @Override public void removeContentOfPublication(PublicationPK pubPK) { // remove XML content PublicationDetail publication = getPublicationDetail(pubPK); if (!com.silverpeas.util.StringUtil.isInteger(publication.getInfoId())) { removeXMLContentOfPublication(pubPK); } // reset reference to content publication.setInfoId("0"); updatePublication(publication, KmeliaHelper.PUBLICATION_CONTENT, true); } private void removeXMLContentOfPublication(PublicationPK pubPK) { try { PublicationDetail pubDetail = getPublicationDetail(pubPK); String infoId = pubDetail.getInfoId(); if (!isInteger(infoId)) { String xmlFormShortName = infoId; PublicationTemplate pubTemplate = PublicationTemplateManager.getInstance() .getPublicationTemplate(pubDetail.getPK().getInstanceId() + ":" + xmlFormShortName); RecordSet set = pubTemplate.getRecordSet(); DataRecord data = set.getRecord(pubDetail.getPK().getId()); set.delete(data); } } catch (PublicationTemplateException e) { throw new KmeliaRuntimeException("KmeliaBmEJB.removeXMLContentOfPublication()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_SUPPRIMER_LE_CONTENU_XML", e); } catch (FormException e) { throw new KmeliaRuntimeException("KmeliaBmEJB.removeXMLContentOfPublication()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_SUPPRIMER_LE_CONTENU_XML", e); } } private Connection getConnection() { try { Connection con = DBUtil.makeConnection(SILVERPEAS_DATASOURCE); return con; } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getConnection()", ERROR, "root.EX_CONNECTION_OPEN_FAILED", e); } } private void freeConnection(Connection con) { if (con != null) { try { con.close(); } catch (Exception e) { SilverTrace.error("kmelia", "KmeliaBmEJB.freeConnection()", "root.EX_CONNECTION_CLOSE_FAILED", "", e); } } } @Override public void addModelUsed(String[] models, String instanceId, String nodeId) { Connection con = getConnection(); try { ModelDAO.deleteModel(con, instanceId, nodeId); for (String modelId : models) { ModelDAO.addModel(con, instanceId, modelId, nodeId); } } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.addModelUsed()", ERROR, "kmelia.IMPOSSIBLE_D_AJOUTER_LES_MODELES", e); } finally { // fermer la connexion freeConnection(con); } } @Override public Collection<String> getModelUsed(String instanceId, String nodeId) { Connection con = getConnection(); try { // get templates defined for the given node Collection<String> result = com.silverpeas.formTemplate.dao.ModelDAO.getModelUsed(con, instanceId, nodeId); if (isDefined(nodeId) && result.isEmpty()) { // there is no templates defined for the given node, check the parent nodes Collection<NodeDetail> parents = nodeBm.getPath(new NodePK(nodeId, instanceId)); Iterator<NodeDetail> iter = parents.iterator(); while (iter.hasNext() && result.isEmpty()) { NodeDetail parent = iter.next(); result = com.silverpeas.formTemplate.dao.ModelDAO.getModelUsed(con, instanceId, parent.getNodePK().getId()); } } return result; } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getModelUsed()", ERROR, "kmelia.IMPOSSIBLE_DE_RECUPERER_LES_MODELES", e); } finally { // fermer la connexion freeConnection(con); } } @Override public List<NodeDetail> getAxis(String componentId) { ResourceLocator nodeSettings = new ResourceLocator("com.stratelia.webactiv.util.node.nodeSettings", ""); String sortField = nodeSettings.getString("sortField", "nodepath"); String sortOrder = nodeSettings.getString("sortOrder", "asc"); SilverTrace.info("kmax", "KmeliaBmEjb.getAxis()", "root.MSG_GEN_PARAM_VALUE", "componentId = " + componentId + " sortField=" + sortField + " sortOrder=" + sortOrder); List<NodeDetail> axis = new ArrayList<NodeDetail>(); try { List<NodeDetail> headers = getAxisHeaders(componentId); for (NodeDetail header : headers) { // Do not get hidden nodes (Basket and unclassified) if (!NodeDetail.STATUS_INVISIBLE.equals(header.getStatus())) { // get content of this axis axis.addAll(nodeBm.getSubTree(header.getNodePK(), sortField + " " + sortOrder)); } } } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEJB.getAxis()", ERROR, "kmax.EX_IMPOSSIBLE_DOBTENIR_LES_AXES", e); } return axis; } @Override public List<NodeDetail> getAxisHeaders(String componentId) { List<NodeDetail> axisHeaders = null; try { axisHeaders = nodeBm.getHeadersByLevel(new NodePK("useless", componentId), 2); } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEJB.getAxisHeaders()", ERROR, "kmax.EX_IMPOSSIBLE_DOBTENIR_LES_ENTETES_DES_AXES", e); } return axisHeaders; } @Override public NodePK addAxis(NodeDetail axis, String componentId) { NodePK axisPK = new NodePK("toDefine", componentId); NodeDetail rootDetail = new NodeDetail(new NodePK("0"), "Root", "desc", "unknown", "unknown", "/0", 1, new NodePK("-1"), null); rootDetail.setStatus(NodeDetail.STATUS_VISIBLE); axis.setNodePK(axisPK); CoordinatePK coordinatePK = new CoordinatePK("useless", axisPK); try { // axis creation axisPK = nodeBm.createNode(axis, rootDetail); // add this new axis to existing coordinates CoordinatePoint point = new CoordinatePoint(-1, Integer.parseInt(axisPK.getId()), true); coordinatesBm.addPointToAllCoordinates(coordinatePK, point); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.addAxis()", ERROR, "kmax.EX_IMPOSSIBLE_DE_CREER_L_AXE", e); } return axisPK; } @Override public void updateAxis(NodeDetail axis, String componentId) { axis.getNodePK().setComponentName(componentId); SilverTrace.info("kmax", "KmeliaBmEjb.updateAxis()", "root.MSG_GEN_PARAM_VALUE", "componentId = " + componentId + " nodePk.getComponentId()=" + axis.getNodePK().getInstanceId()); try { nodeBm.setDetail(axis); } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEJB.updateAxis()", ERROR, "kmax.EX_IMPOSSIBLE_DE_MODIFIER_L_AXE", e); } } @Override public void deleteAxis(String axisId, String componentId) { NodePK pkToDelete = new NodePK(axisId, componentId); PublicationPK pubPK = new PublicationPK("useless"); CoordinatePK coordinatePK = new CoordinatePK("useless", pkToDelete); List<String> fatherIds = new ArrayList<String>(); Collection<String> coordinateIds; // Delete the axis try { // delete publicationFathers if (getAxisHeaders(componentId).size() == 1) { coordinateIds = coordinatesBm.getCoordinateIdsByNodeId(coordinatePK, axisId); Iterator<String> coordinateIdsIt = coordinateIds.iterator(); String coordinateId; while (coordinateIdsIt.hasNext()) { coordinateId = coordinateIdsIt.next(); fatherIds.add(coordinateId); } if (fatherIds.size() > 0) { publicationBm.removeFathers(pubPK, fatherIds); } } // delete coordinate which contains subComponents of this component Collection<NodeDetail> subComponents = nodeBm.getDescendantDetails(pkToDelete); Iterator<NodeDetail> it = subComponents.iterator(); List<NodePK> points = new ArrayList<NodePK>(); points.add(pkToDelete); while (it.hasNext()) { points.add((it.next()).getNodePK()); } removeCoordinatesByPoints(points, componentId); // delete axis nodeBm.removeNode(pkToDelete); } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEJB.deleteAxis()", ERROR, "kmax.EX_IMPOSSIBLE_DE_SUPPRIMER_L_AXE", e); } } private void removeCoordinatesByPoints(List<NodePK> nodePKs, String componentId) { Iterator<NodePK> it = nodePKs.iterator(); List<String> coordinatePoints = new ArrayList<String>(); String nodeId; while (it.hasNext()) { nodeId = (it.next()).getId(); coordinatePoints.add(nodeId); } CoordinatePK coordinatePK = new CoordinatePK("useless", "useless", componentId); try { coordinatesBm.deleteCoordinatesByPoints(coordinatePK, (ArrayList<String>) coordinatePoints); } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEJB.removeCoordinatesByPoints()", ERROR, "kmax.EX_IMPOSSIBLE_DE_SUPPRIMER_LES_COORDONNEES_PAR_UN_POINT", e); } } @Override public NodeDetail getNodeHeader(String id, String componentId) { NodePK pk = new NodePK(id, componentId); return getNodeHeader(pk); } private NodeDetail getNodeHeader(NodePK pk) { NodeDetail nodeDetail = null; try { nodeDetail = nodeBm.getHeader(pk); } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEJB.getNodeHeader()", ERROR, "kmax.EX_IMPOSSIBLE_DOBTENIR_LE_NOEUD", e); } return nodeDetail; } @Override public NodePK addPosition(String fatherId, NodeDetail position, String componentId, String userId) { SilverTrace.info("kmax", "KmeliaBmEjb.addPosition()", "root.MSG_GEN_PARAM_VALUE", "fatherId = " + fatherId + " And position = " + position.toString()); position.getNodePK().setComponentName(componentId); position.setCreationDate(DateUtil.today2SQLDate()); position.setCreatorId(userId); NodeDetail fatherDetail; NodePK componentPK = null; fatherDetail = getNodeHeader(fatherId, componentId); SilverTrace.info("kmax", "KmeliaBmEjb.addPosition()", "root.MSG_GEN_PARAM_VALUE", "fatherDetail = " + fatherDetail.toString()); try { componentPK = nodeBm.createNode(position, fatherDetail); } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEjb.addPosition()", ERROR, "kmax.EX_IMPOSSIBLE_DAJOUTER_UNE_COMPOSANTE_A_L_AXE", e); } return componentPK; } @Override public void updatePosition(NodeDetail position, String componentId) { position.getNodePK().setComponentName(componentId); try { nodeBm.setDetail(position); } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEjb.updatePosition()", ERROR, "kmax.EX_IMPOSSIBLE_DE_MODIFIER_LA_COMPOSANTE_DE_L_AXE", e); } } @Override public void deletePosition(String positionId, String componentId) { NodePK pkToDelete = new NodePK(positionId, componentId); // Delete the axis try { // delete coordinate which contains subPositions of this position Collection<NodeDetail> subComponents = nodeBm.getDescendantDetails(pkToDelete); Iterator<NodeDetail> it = subComponents.iterator(); List<NodePK> points = new ArrayList<NodePK>(); points.add(pkToDelete); while (it.hasNext()) { points.add((it.next()).getNodePK()); } removeCoordinatesByPoints(points, componentId); // delete component nodeBm.removeNode(pkToDelete); } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEjb.deletePosition()", ERROR, "kmax.EX_IMPOSSIBLE_DE_SUPPRIMER_LA_COMPOSANTE_DE_L_AXE", e); } } @Override public Collection<NodeDetail> getPath(String id, String componentId) { Collection<NodeDetail> newPath = new ArrayList<NodeDetail>(); NodePK nodePK = new NodePK(id, componentId); // compute path from a to z try { List<NodeDetail> pathInReverse = (List<NodeDetail>) nodeBm.getPath(nodePK); // reverse the path from root to leaf for (int i = pathInReverse.size() - 1; i >= 0; i--) { newPath.add(pathInReverse.get(i)); } } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEjb.getPath()", ERROR, "kmax.EX_IMPOSSIBLE_DOBTENIR_LE_CHEMIN", e); } return newPath; } public Collection<Coordinate> getKmaxPathList(PublicationPK pubPK) { SilverTrace.info("kmax", "KmeliaBmEJB.getKmaxPathList()", "root.MSG_GEN_ENTER_METHOD"); Collection<Coordinate> coordinates = null; try { coordinates = getPublicationCoordinates(pubPK.getId(), pubPK.getInstanceId()); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getKmaxPathList()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LES_EMPLACEMENTS_DE_LA_PUBLICATION", e); } return coordinates; } @Override public List<KmeliaPublication> search(List<String> combination, String componentId) { Collection<PublicationDetail> publications = searchPublications(combination, componentId); if (publications == null) { return new ArrayList<KmeliaPublication>(); } return pubDetails2userPubs(publications); } @Override public List<KmeliaPublication> search(List<String> combination, int nbDays, String componentId) { Collection<PublicationDetail> publications = searchPublications(combination, componentId); SilverTrace.info("kmax", "KmeliaBmEjb.search()", "root.MSG_GEN_PARAM_VALUE", "publications = " + publications); return pubDetails2userPubs(filterPublicationsByBeginDate(publications, nbDays)); } private Collection<PublicationDetail> searchPublications(List<String> combination, String componentId) { PublicationPK pk = new PublicationPK("useless", componentId); CoordinatePK coordinatePK = new CoordinatePK("unknown", pk); Collection<PublicationDetail> publications = null; Collection<String> coordinates = null; try { // Remove node "Toutes catgories" (level == 2) from combination int nodeLevel; String axisValue; for (int i = 0; i < combination.size(); i++) { axisValue = combination.get(i); StringTokenizer st = new StringTokenizer(axisValue, "/"); nodeLevel = st.countTokens(); // if node is level 2, it represents "Toutes Catgories" // this axis is not used by the search if (nodeLevel == 2) { combination.remove(i); i--; } } if (combination.isEmpty()) { // all criterias is "Toutes Catgories" // get all publications classified NodePK basketPK = new NodePK("1", componentId); publications = publicationBm.getDetailsNotInFatherPK(basketPK); } else { if (combination != null && combination.size() > 0) { coordinates = coordinatesBm.getCoordinatesByFatherPaths((ArrayList<String>) combination, coordinatePK); } if (!coordinates.isEmpty()) { publications = publicationBm.getDetailsByFatherIds((ArrayList<String>) coordinates, pk, false); } } } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEJB.search()", ERROR, "kmax.EX_IMPOSSIBLE_DOBTENIR_LA_LISTE_DES_RESULTATS", e); } return publications; } @Override public Collection<KmeliaPublication> getUnbalancedPublications(String componentId) { PublicationPK pk = new PublicationPK("useless", componentId); Collection<PublicationDetail> publications = null; try { publications = publicationBm.getOrphanPublications(pk); } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEJB.getUnbalancedPublications()", ERROR, "kmax.EX_IMPOSSIBLE_DOBTENIR_LA_LISTE_DES_PUBLICATIONS_NON_CLASSEES", e); } return pubDetails2userPubs(publications); } private Collection<PublicationDetail> filterPublicationsByBeginDate(Collection<PublicationDetail> publications, int nbDays) { List<PublicationDetail> pubOK = new ArrayList<PublicationDetail>(); if (publications != null) { Calendar rightNow = Calendar.getInstance(); if (nbDays == 0) { nbDays = 1; } rightNow.add(Calendar.DATE, 0 - nbDays); Date day = rightNow.getTime(); Iterator<PublicationDetail> it = publications.iterator(); PublicationDetail pub; Date dateToCompare; while (it.hasNext()) { pub = it.next(); if (pub.getBeginDate() != null) { dateToCompare = pub.getBeginDate(); } else { dateToCompare = pub.getCreationDate(); } if (dateToCompare.compareTo(day) >= 0) { pubOK.add(pub); } } } return pubOK; } @Override public void indexKmax(String componentId) { indexAxis(componentId); indexPublications(new PublicationPK("useless", componentId)); } private void indexAxis(String componentId) { NodePK nodePK = new NodePK("useless", componentId); try { Collection<NodeDetail> nodes = nodeBm.getAllNodes(nodePK); if (nodes != null) { for (NodeDetail nodeDetail : nodes) { if ("corbeille".equalsIgnoreCase(nodeDetail.getName()) && nodeDetail.getNodePK().isTrash()) { // do not index the bin } else { nodeBm.createIndex(nodeDetail); } } } } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEjb.indexAxis()", ERROR, "kmax.EX_IMPOSSIBLE_DINDEXER_LES_AXES", e); } } @Override public KmeliaPublication getKmaxPublication(String pubId, String currentUserId) { SilverTrace.info("kmax", "KmeliaBmEjb.getKmaxCompletePublication()", "root.MSG_GEN_ENTER_METHOD"); PublicationPK pubPK; CompletePublication completePublication = null; try { pubPK = new PublicationPK(pubId); completePublication = publicationBm.getCompletePublication(pubPK); } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEjb.getKmaxCompletePublication()", ERROR, "kmax.EX_IMPOSSIBLE_DOBTENIR_LES_INFORMATIONS_DE_LA_PUBLICATION", e); } KmeliaPublication publication = KmeliaPublication.aKmeliaPublicationFromCompleteDetail(completePublication); SilverTrace.info("kmax", "KmeliaBmEjb.getKmaxCompletePublication()", "root.MSG_GEN_EXIT_METHOD"); return publication; } @Override public Collection<Coordinate> getPublicationCoordinates(String pubId, String componentId) { SilverTrace.info("kmax", "KmeliaBmEjb.getPublicationCoordinates()", "root.MSG_GEN_ENTER_METHOD"); try { return publicationBm.getCoordinates(pubId, componentId); } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEjb.getPublicationCoordinates()", ERROR, "root.MSG_GEN_PARAM_VALUE", e); } } @Override public void addPublicationToCombination(String pubId, List<String> combination, String componentId) { SilverTrace.info("kmax", "KmeliaBmEJB.addPublicationToCombination()", "root.MSG_GEN_PARAM_VALUE", "combination =" + combination.toString()); PublicationPK pubPK = new PublicationPK(pubId, componentId); CoordinatePK coordinatePK = new CoordinatePK("unknown", pubPK); try { Collection<Coordinate> coordinates = getPublicationCoordinates(pubId, componentId); if (!checkCombination(coordinates, combination)) { return; } NodeDetail nodeDetail; // enrich combination by get ancestors Iterator<String> it = combination.iterator(); List<CoordinatePoint> allnodes = new ArrayList<CoordinatePoint>(); int i = 1; while (it.hasNext()) { String nodeId = it.next(); NodePK nodePK = new NodePK(nodeId, componentId); SilverTrace.info("kmax", "KmeliaBmEjb.addPublicationToCombination()", "root.MSG_GEN_PARAM_VALUE", "avant nodeBm.getPath() ! i = " + i); Collection<NodeDetail> path = nodeBm.getPath(nodePK); SilverTrace.info("kmax", "KmeliaBmEjb.addPublicationToCombination()", "root.MSG_GEN_PARAM_VALUE", "path for nodeId " + nodeId + " = " + path.toString()); for (NodeDetail aPath : path) { nodeDetail = aPath; String anscestorId = nodeDetail.getNodePK().getId(); int nodeLevel = nodeDetail.getLevel(); if (!nodeDetail.getNodePK().isRoot()) { CoordinatePoint point; if (anscestorId.equals(nodeId)) { point = new CoordinatePoint(-1, Integer.parseInt(anscestorId), true, nodeLevel, i); } else { point = new CoordinatePoint(-1, Integer.parseInt(anscestorId), false, nodeLevel, i); } allnodes.add(point); } } i++; } int coordinateId = coordinatesBm.addCoordinate(coordinatePK, allnodes); publicationBm.addFather(pubPK, new NodePK(String.valueOf(coordinateId), pubPK)); } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEjb.addPublicationToCombination()", ERROR, "kmax.EX_IMPOSSIBLE_DAJOUTER_LA_PUBLICATION_A_CETTE_COMBINAISON", e); } } protected boolean checkCombination(Collection<Coordinate> coordinates, List<String> combination) { for (Coordinate coordinate : coordinates) { Collection<CoordinatePoint> points = coordinate.getCoordinatePoints(); if (points.isEmpty()) { continue; } boolean matchFound = false; for (CoordinatePoint point : points) { if (!checkPoint(point, combination)) { matchFound = false; break; } matchFound = true; } if (matchFound) { return false; } } return true; } protected boolean checkPoint(CoordinatePoint point, List<String> combination) { for (String intVal : combination) { if (Integer.parseInt(intVal) == point.getNodeId()) { return true; } } return false; } @Override public void deleteCoordinates(CoordinatePK coordinatePK, List<String> coordinates) { coordinatesBm.deleteCoordinates(coordinatePK, coordinates); } @Override public void deletePublicationFromCombination(String pubId, String combinationId, String componentId) { SilverTrace.info("kmax", "KmeliaBmEjb.deletePublicationFromCombination()", "root.MSG_GEN_PARAM_VALUE", "combinationId = " + combinationId); PublicationPK pubPK = new PublicationPK(pubId, componentId); NodePK fatherPK = new NodePK(combinationId, componentId); CoordinatePK coordinatePK = new CoordinatePK(combinationId, pubPK); try { // remove publication fathers publicationBm.removeFather(pubPK, fatherPK); // remove coordinate List<String> coordinateIds = new ArrayList<String>(1); coordinateIds.add(combinationId); coordinatesBm.deleteCoordinates(coordinatePK, coordinateIds); } catch (Exception e) { throw new KmaxRuntimeException("KmeliaBmEjb.deletePublicationFromCombination()", ERROR, "kmax.EX_IMPOSSIBLE_DE_SUPPRIMER_LA_COMBINAISON_DE_LA_PUBLICATION", e); } } /** * Create a new Publication (only the header - parameters) * * @param pubDetail a PublicationDetail * @return the id of the new publication * @see com.stratelia.webactiv.util.publication.model.PublicationDetail * @since 1.0 */ @Override public String createKmaxPublication(PublicationDetail pubDetail) { SilverTrace.info("kmax", "KmeliaBmEJB.createKmaxPublication()", "root.MSG_GEN_ENTER_METHOD"); PublicationPK pubPK = null; Connection con = getConnection(); try { // create the publication pubDetail = changePublicationStatusOnCreation(pubDetail, new NodePK("useless", pubDetail.getPK())); pubPK = publicationBm.createPublication(pubDetail); pubDetail.getPK().setId(pubPK.getId()); // creates todos for publishers this.createTodosForPublication(pubDetail, true); // register the new publication as a new content to content manager createSilverContent(pubDetail, pubDetail.getCreatorId()); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.createKmaxPublication()", ERROR, "kmelia.EX_IMPOSSIBLE_DE_CREER_LA_PUBLICATION", e); } finally { freeConnection(con); } SilverTrace.info("kmax", "KmeliaBmEJB.createKmaxPublication()", "root.MSG_GEN_EXIT_METHOD"); return pubPK.getId(); } @Override public Collection<Alias> getAlias(PublicationPK pubPK) { try { return publicationBm.getAlias(pubPK); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getAlias()", ERROR, "kmelia.EX_IMPOSSIBLE_DAVOIR_LES_ALIAS_DE_PUBLICATION", e); } } @Override public void setAlias(PublicationPK pubPK, List<Alias> alias) { publicationBm.setAlias(pubPK, alias); // Send subscriptions to aliases subscribers PublicationDetail pubDetail = getPublicationDetail(pubPK); sendSubscriptionsNotification(pubDetail, StringUtil.isDefined(pubDetail.getUpdaterId()), true); } @Override public void addAttachmentToPublication(PublicationPK pubPK, String userId, String filename, String description, byte[] contents) { try { Date creationDate = new Date(); SimpleAttachment file = new SimpleAttachment(FileUtil.getFilename(filename), I18NHelper.defaultLanguage, filename, "", contents.length, FileUtil.getMimeType(filename), userId, creationDate, null); boolean versioningActive = getBooleanValue( getOrganisationController().getComponentParameterValue(pubPK.getComponentName(), VERSION_MODE)); SimpleDocument document; if (versioningActive) { document = new HistorisedDocument(new SimpleDocumentPK(null, pubPK.getComponentName()), pubPK.getId(), 0, file); document.setPublicDocument(true); } else { document = new SimpleDocument(new SimpleDocumentPK(null, pubPK.getComponentName()), pubPK.getId(), 0, false, file); } AttachmentServiceFactory.getAttachmentService().createAttachment(document, new ByteArrayInputStream(contents)); } catch (org.silverpeas.attachment.AttachmentException fnfe) { throw new KmeliaRuntimeException("KmeliaBmEJB.addAttachmentToPublication()", ERROR, "kmelia.EX_IMPOSSIBLE_DAJOUTER_ATTACHEMENT", fnfe); } } /** * Creates or updates a publication. * * @param componentId The id of the component containing the publication. * @param topicId The id of the topic containing the publication. * @param spaceId The id of the space containing the publication. * @param userId The id of the user creating or updating the publication. * @param publiParams The publication's parameters. * @param formParams The parameters of the publication's form. * @param language The language of the publication. * @param xmlFormName The name of the publication's form. * @param discrimatingParameterName The name of the field included in the form which allowes to * retrieve the eventually existing publication to update. * @param userProfile The user's profile used to draft out the publication. * @return True if the publication is created, false if it is updated. * @ */ @Override public boolean importPublication(String componentId, String topicId, String spaceId, String userId, Map<String, String> publiParams, Map<String, String> formParams, String language, String xmlFormName, String discrimatingParameterName, String userProfile) { PublicationImport publicationImport = new PublicationImport(this, componentId, topicId, spaceId, userId); return publicationImport.importPublication(publiParams, formParams, language, xmlFormName, discrimatingParameterName, userProfile); } @Override public boolean importPublication(String componentId, String topicId, String userId, Map<String, String> publiParams, Map<String, String> formParams, String language, String xmlFormName, String discriminantParameterName, String userProfile, boolean ignoreMissingFormFields) { PublicationImport publicationImport = new PublicationImport(this, componentId, topicId, null, userId); publicationImport.setIgnoreMissingFormFields(ignoreMissingFormFields); return publicationImport.importPublication(publiParams, formParams, language, xmlFormName, discriminantParameterName, userProfile); } /** * Creates or updates a publication. * * @param publicationId The id of the publication to update. * @param componentId The id of the component containing the publication. * @param topicId The id of the topic containing the publication. * @param spaceId The id of the space containing the publication. * @param userId The id of the user creating or updating the publication. * @param publiParams The publication's parameters. * @param formParams The parameters of the publication's form. * @param language The language of the publication. * @param xmlFormName The name of the publication's form. * @param userProfile The user's profile used to draft out the publication. * @return True if the publication is created, false if it is updated. * @ */ @Override public boolean importPublication(String publicationId, String componentId, String topicId, String spaceId, String userId, Map<String, String> publiParams, Map<String, String> formParams, String language, String xmlFormName, String userProfile) { PublicationImport publicationImport = new PublicationImport(this, componentId, topicId, spaceId, userId); return publicationImport.importPublication(publicationId, publiParams, formParams, language, xmlFormName, userProfile); } @Override public void importPublications(String componentId, String topicId, String spaceId, String userId, List<Map<String, String>> publiParamsList, List<Map<String, String>> formParamsList, String language, String xmlFormName, String discrimatingParameterName, String userProfile) { PublicationImport publicationImport = new PublicationImport(this, componentId, topicId, spaceId, userId); publicationImport.importPublications(publiParamsList, formParamsList, language, xmlFormName, discrimatingParameterName, userProfile); } @Override public List<XMLField> getPublicationXmlFields(String publicationId, String componentId, String spaceId, String userId) { PublicationImport publicationImport = new PublicationImport(this, componentId, null, spaceId, userId); return publicationImport.getPublicationXmlFields(publicationId); } @Override public List<XMLField> getPublicationXmlFields(String publicationId, String componentId, String spaceId, String userId, String language) { PublicationImport publicationImport = new PublicationImport(this, componentId, null, spaceId, userId); return publicationImport.getPublicationXmlFields(publicationId, language); } @Override public String createTopic(String componentId, String topicId, String spaceId, String userId, String name, String description) { PublicationImport publicationImport = new PublicationImport(this, componentId, topicId, spaceId, userId); return publicationImport.createTopic(name, description); } @Override public Collection<String> getPublicationsSpecificValues(String componentId, String xmlFormName, String fieldName) { PublicationImport publicationImport = new PublicationImport(this, componentId); return publicationImport.getPublicationsSpecificValues(componentId, xmlFormName, fieldName); } @Override public void draftInPublication(String componentId, String xmlFormName, String fieldName, String fieldValue) { PublicationImport publicationImport = new PublicationImport(this, componentId); publicationImport.draftInPublication(xmlFormName, fieldName, fieldValue); } @Override public void updatePublicationEndDate(String componentId, String spaceId, String userId, String xmlFormName, String fieldName, String fieldValue, Date endDate) { PublicationImport publicationImport = new PublicationImport(this, componentId, null, spaceId, userId); publicationImport.updatePublicationEndDate(xmlFormName, fieldName, fieldValue, endDate); } /** * Find a publication imported only by a xml field (old id for example) * * @param componentId * @param xmlFormName * @param fieldName * @param fieldValue * @param topicId * @param spaceId * @param userId * @return pubId * @ */ @Override public String findPublicationIdBySpecificValue(String componentId, String xmlFormName, String fieldName, String fieldValue, String topicId, String spaceId, String userId) { PublicationImport publicationImport = new PublicationImport(this, componentId, topicId, spaceId, userId); return publicationImport.getPublicationId(xmlFormName, fieldName, fieldValue); } @Override public void doAutomaticDraftOut() { // get all clones with draftoutdate <= current date // pubCloneId <> -1 AND pubCloneStatus == 'Draft' Collection<PublicationDetail> pubs = publicationBm.getPublicationsToDraftOut(true); // for each clone, call draftOutPublication method for (PublicationDetail pub : pubs) { draftOutPublication(pub.getClonePK(), null, "admin", true); } } @Override public String clonePublication(CompletePublication refPubComplete, PublicationDetail pubDetail, String nextStatus) { String cloneId; try { // rcupration de la publi de rfrence PublicationDetail refPub = refPubComplete.getPublicationDetail(); String fromId = refPub.getPK().getId(); String fromComponentId = refPub.getPK().getInstanceId(); PublicationDetail clone = getClone(refPub); ResourceLocator publicationSettings = new ResourceLocator( "org.silverpeas.util.publication.publicationSettings", ""); String imagesSubDirectory = publicationSettings.getString("imagesSubDirectory"); String absolutePath = FileRepositoryManager.getAbsolutePath(fromComponentId); if (pubDetail != null) { clone.setAuthor(pubDetail.getAuthor()); clone.setBeginDate(pubDetail.getBeginDate()); clone.setBeginHour(pubDetail.getBeginHour()); clone.setDescription(pubDetail.getDescription()); clone.setEndDate(pubDetail.getEndDate()); clone.setEndHour(pubDetail.getEndHour()); clone.setImportance(pubDetail.getImportance()); clone.setKeywords(pubDetail.getKeywords()); clone.setName(pubDetail.getName()); clone.setTargetValidatorId(pubDetail.getTargetValidatorId()); } if (isInteger(refPub.getInfoId())) { // Case content = DB clone.setInfoId(null); } clone.setStatus(nextStatus); clone.setCloneId(fromId); clone.setIndexOperation(IndexManager.NONE); PublicationPK clonePK = publicationBm.createPublication(clone); clonePK.setComponentName(fromComponentId); cloneId = clonePK.getId(); // clone attachments List<SimpleDocument> documents = AttachmentServiceFactory.getAttachmentService() .listDocumentsByForeignKey(new ForeignPK(fromId, fromComponentId), null); Map<String, String> attachmentIds = new HashMap<String, String>(documents.size()); for (SimpleDocument document : documents) { AttachmentServiceFactory.getAttachmentService().cloneDocument(document, cloneId); } // eventually, paste the model content if (refPubComplete.getModelDetail() != null && refPubComplete.getInfoDetail() != null) { // Paste images of model if (refPubComplete.getInfoDetail().getInfoImageList() != null) { for (InfoImageDetail attachment : refPubComplete.getInfoDetail().getInfoImageList()) { String from = absolutePath + imagesSubDirectory + File.separator + attachment.getPhysicalName(); String type = attachment.getPhysicalName().substring( attachment.getPhysicalName().lastIndexOf('.') + 1, attachment.getPhysicalName().length()); String newName = Long.toString(System.currentTimeMillis()) + "." + type; attachment.setPhysicalName(newName); String to = absolutePath + imagesSubDirectory + File.separator + newName; FileRepositoryManager.copyFile(from, to); } } // Paste model content createInfoModelDetail(clonePK, refPubComplete.getModelDetail().getId(), refPubComplete.getInfoDetail()); } else { String xmlFormShortName = refPub.getInfoId(); if (xmlFormShortName != null && !"0".equals(xmlFormShortName) && !isInteger(xmlFormShortName)) { PublicationTemplateManager templateManager = PublicationTemplateManager.getInstance(); // Content = XMLForm // register xmlForm to publication templateManager.addDynamicPublicationTemplate(fromComponentId + ":" + xmlFormShortName, xmlFormShortName + ".xml"); PublicationTemplate pubTemplate = templateManager .getPublicationTemplate(fromComponentId + ":" + xmlFormShortName); RecordSet set = pubTemplate.getRecordSet(); // clone dataRecord set.clone(fromId, fromComponentId, cloneId, fromComponentId, attachmentIds); } } // paste only links, reverseLinks can't be cloned because it'is a new content not referenced // by any publication if (refPubComplete.getLinkList() != null && refPubComplete.getLinkList().size() > 0) { addInfoLinks(clonePK, refPubComplete.getLinkList()); } // paste wysiwyg WysiwygController.copy(fromComponentId, fromId, fromComponentId, cloneId, clone.getCreatorId()); // affectation de l'id du clone la publication de rfrence refPub.setCloneId(cloneId); refPub.setCloneStatus(nextStatus); refPub.setStatusMustBeChecked(false); refPub.setUpdateDateMustBeSet(false); updatePublication(refPub); // paste vignette String vignette = refPub.getImage(); if (vignette != null) { ThumbnailDetail thumbDetail = new ThumbnailDetail(clone.getPK().getInstanceId(), Integer.valueOf(clone.getPK().getId()), ThumbnailDetail.THUMBNAIL_OBJECTTYPE_PUBLICATION_VIGNETTE); thumbDetail.setMimeType(refPub.getImageMimeType()); if (vignette.startsWith("/")) { thumbDetail.setOriginalFileName(vignette); } else { String thumbnailsSubDirectory = publicationSettings.getString("imagesSubDirectory"); String from = absolutePath + thumbnailsSubDirectory + File.separator + vignette; String type = FilenameUtils.getExtension(vignette); String newVignette = Long.toString(System.currentTimeMillis()) + "." + type; String to = absolutePath + thumbnailsSubDirectory + File.separator + newVignette; FileRepositoryManager.copyFile(from, to); thumbDetail.setOriginalFileName(newVignette); } ThumbnailServiceFactory.getThumbnailService().createThumbnail(thumbDetail); } } catch (IOException e) { throw new KmeliaRuntimeException("KmeliaBmEJB.clonePublication", ERROR, "kmelia.CANT_CLONE_PUBLICATION", e); } catch (FormException fe) { throw new KmeliaRuntimeException("KmeliaBmEJB.clonePublication", ERROR, "kmelia.CANT_CLONE_PUBLICATION_XMLCONTENT", fe); } catch (PublicationTemplateException pe) { throw new KmeliaRuntimeException("KmeliaBmEJB.clonePublication", ERROR, "kmelia.CANT_CLONE_PUBLICATION_XMLCONTENT", pe); } catch (ThumbnailException e) { throw new KmeliaRuntimeException("KmeliaBmEJB.clonePublication", ERROR, "kmelia.CANT_CLONE_PUBLICATION", e); } return cloneId; } /** * Gets a service object on the comments. * * @return a DefaultCommentService instance. */ private CommentService getCommentService() { if (commentService == null) { commentService = CommentServiceFactory.getFactory().getCommentService(); } return commentService; } private ResourceLocator getMultilang() { return new ResourceLocator("org.silverpeas.kmelia.multilang.kmeliaBundle", "fr"); } @Override public NodeDetail getRoot(String componentId, String userId) { return getRoot(componentId, userId, null); } private NodeDetail getRoot(String componentId, String userId, List<NodeDetail> treeview) { NodePK rootPK = new NodePK(NodePK.ROOT_NODE_ID, componentId); NodeDetail root = nodeBm.getDetail(rootPK); setRole(root, userId); root.setChildrenDetails(getRootChildren(root, userId, treeview)); return root; } private List<NodeDetail> getRootChildren(NodeDetail root, String userId, List<NodeDetail> treeview) { String instanceId = root.getNodePK().getInstanceId(); List<NodeDetail> children = new ArrayList<NodeDetail>(); try { setAllowedSubfolders(root, userId); List<NodeDetail> nodes = (List<NodeDetail>) root.getChildrenDetails(); // set nb objects in nodes setNbItemsOfSubfolders(root, treeview, userId); NodeDetail trash = null; for (NodeDetail node : nodes) { if (node.getNodePK().isTrash()) { trash = node; } else if (node.getNodePK().isUnclassed()) { // do not return it cause it is useless } else { children.add(node); } } // adding special folder "to validate" if (isUserCanValidate(instanceId, userId)) { NodeDetail temp = new NodeDetail(); temp.getNodePK().setId("tovalidate"); temp.setName(getMultilang().getString("ToValidateShort")); if (isNbItemsDisplayed(instanceId)) { int nbPublisToValidate = getPublicationsToValidate(instanceId, userId).size(); temp.setNbObjects(nbPublisToValidate); } children.add(temp); } // adding special folder "trash" if (isUserCanWrite(instanceId, userId) && trash != null) { children.add(trash); } root.setChildrenDetails(children); } catch (Exception e) { throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR); } return children; } @Override public Collection<NodeDetail> getFolderChildren(NodePK nodePK, String userId) { NodeDetail node = nodeBm.getDetail(nodePK); if (node.getNodePK().isRoot()) { node.setChildrenDetails(getRootChildren(node, userId, null)); } else { setAllowedSubfolders(node, userId); } // set nb objects in nodes setNbItemsOfSubfolders(node, null, userId); return node.getChildrenDetails(); } private void setNbItemsOfSubfolders(NodeDetail node, List<NodeDetail> treeview, String userId) { String instanceId = node.getNodePK().getInstanceId(); if (isNbItemsDisplayed(instanceId)) { if (treeview == null) { treeview = getTreeview(node.getNodePK(), userId); } // set nb objects in each nodes setNbItemsOfFolders(instanceId, node.getChildrenDetails(), treeview); } } private List<NodeDetail> getTreeview(NodePK pk, String userId) { String instanceId = pk.getInstanceId(); if (isUserComponentAdmin(instanceId, userId)) { return getTreeview(pk, "admin", isCoWritingEnable(instanceId), isDraftVisibleWithCoWriting(), userId, isNbItemsDisplayed(instanceId), false); } else { return getTreeview(pk, getUserTopicProfile(pk, userId), isCoWritingEnable(instanceId), isDraftVisibleWithCoWriting(), userId, isNbItemsDisplayed(instanceId), isRightsOnTopicsEnabled(instanceId)); } } private void setNbItemsOfFolders(String componentId, Collection<NodeDetail> nodes, List<NodeDetail> treeview) { if (isNbItemsDisplayed(componentId)) { for (NodeDetail child : nodes) { int index = treeview.indexOf(child); if (index != -1) { child.setNbObjects(treeview.get(index).getNbObjects()); } } } } @SuppressWarnings("StatementWithEmptyBody") private void setAllowedSubfolders(NodeDetail node, String userId) { String instanceId = node.getNodePK().getInstanceId(); if (isRightsOnTopicsEnabled(instanceId)) { if (isUserComponentAdmin(instanceId, userId)) { // user is admin of application, all folders must be shown setRole(node.getChildrenDetails(), userId); } else { Collection<NodeDetail> allowedChildren = getAllowedSubfolders(node, userId); setRole(allowedChildren, userId); node.setChildrenDetails(allowedChildren); } } else { // no rights are used // keep children as they are } } private boolean isUserComponentAdmin(String componentId, String userId) { return "admin".equalsIgnoreCase(KmeliaHelper.getProfile(getUserRoles(componentId, userId))); } private void setRole(NodeDetail node, String userId) { if (isRightsOnTopicsEnabled(node.getNodePK().getInstanceId())) { node.setUserRole(getUserTopicProfile(node.getNodePK(), userId)); } } private void setRole(Collection<NodeDetail> nodes, String userId) { for (NodeDetail node : nodes) { setRole(node, userId); } } private boolean isRightsOnTopicsEnabled(String componentId) { return StringUtil.getBooleanValue(getOrganisationController().getComponentParameterValue(componentId, InstanceParameters.rightsOnFolders)); } private boolean isNbItemsDisplayed(String componentId) { return StringUtil.getBooleanValue(getOrganisationController().getComponentParameterValue(componentId, InstanceParameters.displayNbItemsOnFolders)); } private boolean isCoWritingEnable(String componentId) { return StringUtil.getBooleanValue( getOrganisationController().getComponentParameterValue(componentId, InstanceParameters.coWriting)); } private boolean isDraftVisibleWithCoWriting() { return getComponentSettings().getBoolean("draftVisibleWithCoWriting", false); } @Override public String getUserTopicProfile(NodePK pk, String userId) { if (!isRightsOnTopicsEnabled(pk.getInstanceId()) || KmeliaHelper.isToValidateFolder(pk.getId())) { return KmeliaHelper.getProfile(getUserRoles(pk.getInstanceId(), userId)); } NodeDetail node = getNodeHeader(pk.getId(), pk.getInstanceId()); // check if we have to take care of topic's rights if (node != null && node.haveRights()) { int rightsDependsOn = node.getRightsDependsOn(); return KmeliaHelper.getProfile(getOrganisationController().getUserProfiles(userId, pk.getInstanceId(), rightsDependsOn, ObjectType.NODE)); } else { return KmeliaHelper.getProfile(getUserRoles(pk.getInstanceId(), userId)); } } private String[] getUserRoles(String componentId, String userId) { return getOrganisationController().getUserProfiles(userId, componentId); } private NodePK getRootPK(String componentId) { return new NodePK(NodePK.ROOT_NODE_ID, componentId); } /** * This method verifies if the user behind the given user identifier can validate the publication * represented by the given primary key. * The verification is strictly applied on the given primary key, that is to say that no * publication clone information are retrieved. * To perform a verification on a publication clone, the primary key of the clone must be given. * @param pubPK the primary key of the publication or of the clone of a publication. * @param userId the identifier of the user fo which rights must be verified. * @return true if the user can validate, false otherwise. */ @Override public boolean isUserCanValidatePublication(PublicationPK pubPK, String userId) { PublicationDetail publi = getPublicationDetail(pubPK); if (!publi.isValidationRequired()) { // publication is not in a state which allow a validation return false; } List<String> validatorIds = getAllValidators(pubPK); if (!validatorIds.contains(userId)) { // current user is not part of users who are able to validate this publication return false; } if (getValidationType(pubPK.getInstanceId()) == KmeliaHelper.VALIDATION_TARGET_N) { ValidationStep validationStep = publicationBm.getValidationStepByUser(pubPK, userId); // user has not yet validated publication, so validation is allowed return validationStep == null; } return true; } @Override public boolean isUserCanValidate(String componentId, String userId) { if (KmeliaHelper.isToolbox(componentId)) { return false; } return isUserCanPublish(componentId, userId); } @Override public boolean isUserCanWrite(String componentId, String userId) { String[] grantedRoles = new String[] { SilverpeasRole.admin.name(), SilverpeasRole.publisher.name(), SilverpeasRole.writer.name() }; return checkUserRoles(componentId, userId, grantedRoles); } @Override public boolean isUserCanPublish(String componentId, String userId) { String[] grantedRoles = new String[] { SilverpeasRole.admin.name(), SilverpeasRole.publisher.name() }; return checkUserRoles(componentId, userId, grantedRoles); } private boolean checkUserRoles(String componentId, String userId, String... roles) { SilverpeasRole userProfile = SilverpeasRole .from(KmeliaHelper.getProfile(getUserRoles(componentId, userId))); boolean checked = userProfile.isInRole(roles); if (!checked && isRightsOnTopicsEnabled(componentId)) { // check if current user is publisher or admin on at least one descendant Iterator<NodeDetail> descendants = nodeBm.getDescendantDetails(getRootPK(componentId)).iterator(); while (!checked && descendants.hasNext()) { NodeDetail descendant = descendants.next(); AdminController admin = null; if (descendant.haveLocalRights()) { // check if user is admin, publisher or writer on this topic admin = new AdminController(userId); String[] profiles = admin.getProfilesByObjectAndUserId(descendant.getId(), ObjectType.NODE.getCode(), componentId, userId); if (profiles != null && profiles.length > 0) { userProfile = SilverpeasRole.from(KmeliaHelper.getProfile(profiles)); checked = userProfile.isInRole(roles); } } } } return checked; } @Override public NodeDetail getExpandedPathToNode(NodePK pk, String userId) { String instanceId = pk.getInstanceId(); List<NodeDetail> nodes = new ArrayList<NodeDetail>(nodeBm.getPath(pk)); Collections.reverse(nodes); nodes.remove(0); List<NodeDetail> treeview = null; if (isNbItemsDisplayed(instanceId)) { treeview = getTreeview(getRootPK(instanceId), userId); } NodeDetail root = getRoot(instanceId, userId, treeview); // set nb objects in nodes if (treeview != null) { // set nb objects on root root.setNbObjects(treeview.get(0).getNbObjects()); // set nb objects in each allowed nodes setNbItemsOfFolders(instanceId, nodes, treeview); } NodeDetail currentNode = root; for (NodeDetail node : nodes) { currentNode = find(currentNode.getChildrenDetails(), node); // get children of each node on path to target node Collection<NodeDetail> children = nodeBm.getChildrenDetails(node.getNodePK()); node.setChildrenDetails(children); setAllowedSubfolders(node, userId); if (treeview != null) { setNbItemsOfSubfolders(node, treeview, userId); } currentNode.setChildrenDetails(node.getChildrenDetails()); } return root; } private NodeDetail find(Collection<NodeDetail> nodes, NodeDetail toFind) { for (NodeDetail node : nodes) { if (node.getNodePK().getId().equals(toFind.getNodePK().getId())) { return node; } } return null; } /** * Removes publications according to given ids. Before a publication is removed, user priviledges * are controlled. If node defines the trash, publications are definitively deleted. Otherwise, * publications move into trash. * * @param ids the ids of publications to delete * @param nodePK the node where the publications are * @param userId the user who wants to perform deletion * @return the list of publication ids which has been really deleted * @ */ @Override public List<String> deletePublications(List<String> ids, NodePK nodePK, String userId) { List<String> removedIds = new ArrayList<String>(); String profile = getProfile(userId, nodePK); for (String id : ids) { PublicationPK pk = new PublicationPK(id, nodePK); if (isUserCanDeletePublication(new PublicationPK(id, nodePK), profile, userId)) { try { if (nodePK.isTrash()) { deletePublication(pk); } else { sendPublicationToBasket(pk); } SilverTrace.spy("kmelia", "KmeliaBmEJB.deletePublications", null, nodePK.getInstanceId(), id, userId, SilverTrace.SPY_ACTION_DELETE); removedIds.add(id); } catch (Exception e) { SilverTrace.error("kmelia", "KmeliaBmEJB.deletePublications()", "kmelia.EX_IMPOSSIBLE_DE_SUPPRIMER_LA_PUBLICATION", "pk = " + pk.toString(), e); } } } return removedIds; } private boolean isUserCanDeletePublication(PublicationPK pubPK, String profile, String userId) { UserDetail owner = getPublication(pubPK).getCreator(); return KmeliaPublicationHelper.isRemovable(pubPK.getInstanceId(), userId, profile, owner); } @Override public String getWysiwyg(PublicationPK pubPK, String language) { try { return WysiwygController.load(pubPK.getInstanceId(), pubPK.getId(), I18NHelper.checkLanguage(language)); } catch (Exception e) { throw new KmeliaRuntimeException("KmeliaBmEJB.getAttachments()", ERROR, "kmelia.EX_IMPOSSIBLE_DOBTENIR_LE_WYSIWYG", e); } } @Override public KmeliaPublication getContentById(String contentId) { return getPublication(new PublicationPK(contentId)); } @Override public ResourceLocator getComponentSettings() { return settings; } @Override public ResourceLocator getComponentMessages(String language) { return new ResourceLocator(MESSAGES_PATH, language); } @Interceptors(SimulationActionProcessAnnotationEJBInterceptor.class) @SimulationActionProcess(elementLister = KmeliaNodeSimulationElementLister.class) @Action(ActionType.MOVE) @Override public NodeDetail moveNode(@SourcePK NodePK nodePK, @TargetPK NodePK to, String userId) { List<NodeDetail> treeToPaste = nodeBm.getSubTree(nodePK); // move node and subtree nodeBm.moveNode(nodePK, to); AdminController admin = new AdminController(userId); for (NodeDetail fromNode : treeToPaste) { if (fromNode != null) { NodePK toNodePK = new NodePK(fromNode.getNodePK().getId(), to); // remove rights if (fromNode.haveLocalRights()) { List<ProfileInst> profiles = admin.getProfilesByObject(fromNode.getNodePK().getId(), ObjectType.NODE.getCode(), fromNode.getNodePK().getInstanceId()); if (profiles != null) { for (ProfileInst profile : profiles) { if (profile != null && StringUtil.isDefined(profile.getId())) { admin.deleteProfileInst(profile.getId()); } } } } // move rich description of node if (!nodePK.getInstanceId().equals(to.getInstanceId())) { WysiwygController.move(fromNode.getNodePK().getInstanceId(), "Node_" + fromNode.getId(), to.getInstanceId(), "Node_" + toNodePK.getId()); } // move publications of node movePublicationsOfTopic(fromNode.getNodePK(), toNodePK, userId); } } nodePK.setComponentName(to.getInstanceId()); return getNodeHeader(nodePK); } private void movePublicationsOfTopic(NodePK fromPK, NodePK toPK, String userId) { Collection<PublicationDetail> publications = publicationBm.getDetailsByFatherPK(fromPK); for (PublicationDetail publi : publications) { movePublication(publi.getPK(), toPK, userId); } } @Interceptors(SimulationActionProcessAnnotationEJBInterceptor.class) @SimulationActionProcess(elementLister = KmeliaNodeSimulationElementLister.class) @Action(ActionType.COPY) @Override public NodeDetail copyNode(@SourcePK @TargetPK KmeliaCopyDetail copyDetail) { HashMap<Integer, Integer> oldAndNewIds = new HashMap<Integer, Integer>(); return copyNode(copyDetail, oldAndNewIds); } private NodeDetail copyNode(KmeliaCopyDetail copyDetail, HashMap<Integer, Integer> oldAndNewIds) { NodePK nodePKToCopy = copyDetail.getFromNodePK(); NodePK targetPK = copyDetail.getToNodePK(); String userId = copyDetail.getUserId(); SilverTrace.debug("kmelia", "KmeliaBmEJB.copyNode()", "root.MSG_GEN_ENTER_METHOD", "from = " + nodePKToCopy.toString() + ", to = " + targetPK.toString()); NodeDetail nodeToCopy = nodeBm.getDetail(nodePKToCopy); NodeDetail father = getNodeHeader(targetPK); // paste topic NodePK nodePK = new NodePK("unknown", targetPK); NodeDetail node = nodeToCopy.clone(); node.setNodePK(nodePK); node.setCreatorId(userId); node.setRightsDependsOn(father.getRightsDependsOn()); node.setCreationDate(DateUtil.today2SQLDate()); nodePK = nodeBm.createNode(node, father); // duplicate rights if (copyDetail.isNodeRightsMustBeCopied()) { oldAndNewIds.put(Integer.parseInt(nodePKToCopy.getId()), Integer.parseInt(nodePK.getId())); if (nodeToCopy.haveRights()) { if (nodeToCopy.haveLocalRights()) { node.setRightsDependsOn(Integer.parseInt(nodePK.getId())); } else { int oldRightsDependsOn = nodeToCopy.getRightsDependsOn(); Integer newRightsDependsOn = oldAndNewIds.get(Integer.valueOf(oldRightsDependsOn)); node.setRightsDependsOn(newRightsDependsOn); } nodeBm.updateRightsDependency(node); } // Set topic rights if necessary if (nodeToCopy.haveLocalRights()) { AdminController admin = new AdminController(userId); List<ProfileInst> topicProfiles = admin.getProfilesByObject(nodeToCopy.getNodePK().getId(), ObjectType.NODE.getCode(), nodeToCopy.getNodePK().getInstanceId()); for (ProfileInst nodeToPasteProfile : topicProfiles) { if (nodeToPasteProfile != null) { ProfileInst nodeProfileInst = (ProfileInst) nodeToPasteProfile.clone(); nodeProfileInst.setId("-1"); nodeProfileInst.setComponentFatherId(nodePK.getInstanceId()); nodeProfileInst.setObjectId(Integer.parseInt(nodePK.getId())); nodeProfileInst.setObjectFatherId(father.getId()); // Add the profile admin.addProfileInst(nodeProfileInst, userId); } } } } // paste wysiwyg attached to node WysiwygController.copy(nodePKToCopy.getInstanceId(), "Node_" + nodePKToCopy.getId(), nodePK.getInstanceId(), "Node_" + nodePK.getId(), userId); // paste publications of topics KmeliaCopyDetail folderContentCopy = new KmeliaCopyDetail(copyDetail); folderContentCopy.setFromNodePK(nodePKToCopy); folderContentCopy.setToNodePK(nodePK); if (copyDetail.isPublicationHeaderMustBeCopied()) { copyPublications(folderContentCopy); } // paste subtopics Collection<NodeDetail> subtopics = nodeToCopy.getChildrenDetails(); for (NodeDetail subTopic : subtopics) { if (subTopic != null) { folderContentCopy.setFromNodePK(subTopic.getNodePK()); copyNode(folderContentCopy, oldAndNewIds); } } return node; } @Interceptors(SimulationActionProcessAnnotationEJBInterceptor.class) @SimulationActionProcess(elementLister = KmeliaPublicationSimulationElementLister.class) @Action(ActionType.COPY) @Override public void copyPublications(@SourcePK @TargetPK KmeliaCopyDetail copyDetail) { Collection<PublicationDetail> publications = publicationBm.getDetailsByFatherPK(copyDetail.getFromNodePK()); for (PublicationDetail publi : publications) { copyPublication(publi, copyDetail); } } @Interceptors(SimulationActionProcessAnnotationEJBInterceptor.class) @SimulationActionProcess(elementLister = KmeliaPublicationSimulationElementLister.class) @Action(ActionType.COPY) @Override public PublicationPK copyPublication(@SourcePK PublicationDetail publi, @TargetPK NodePK nodePK, String userId) { KmeliaCopyDetail copyDetail = new KmeliaCopyDetail(userId); copyDetail.setToNodePK(nodePK); return copyPublication(publi, copyDetail); } private PublicationPK copyPublication(PublicationDetail publi, KmeliaCopyDetail copyDetail) { NodePK nodePK = copyDetail.getToNodePK(); String userId = copyDetail.getUserId(); try { publi.setCloneId(null); publi.setCloneStatus(""); String fromId = publi.getPK().getId(); String fromComponentId = publi.getPK().getInstanceId(); ForeignPK fromForeignPK = new ForeignPK(publi.getPK().getId(), fromComponentId); PublicationPK fromPubPK = new PublicationPK(publi.getPK().getId(), fromComponentId); ForeignPK toForeignPK = new ForeignPK("unknown", nodePK); PublicationPK toPubPK = new PublicationPK("unknown", nodePK); String toComponentId = nodePK.getInstanceId(); publi.setUpdaterId(userId); // ignore initial parameters publi.setPk(toPubPK); if (KmeliaHelper.ROLE_WRITER.equals(getUserTopicProfile(nodePK, userId))) { // in case of writers, status of new publication must be processed publi.setStatus(null); } if (!copyDetail.isPublicationContentMustBeCopied()) { publi.setInfoId(null); } String id = createPublicationIntoTopic(publi, nodePK); // update id cause new publication is created toPubPK.setId(id); toForeignPK.setId(id); SilverTrace.spy("kmelia", "KmeliaBmEJB.copyPublication", "unknown", nodePK.getInstanceId(), id, userId, SilverTrace.SPY_ACTION_CREATE); // paste vignette ThumbnailController.copyThumbnail(fromForeignPK, toForeignPK); // Paste positions on Pdc if (copyDetail.isPublicationPositionsMustBeCopied()) { copyPdcPositions(fromPubPK, toPubPK); } Map<String, String> fileIds = new HashMap<String, String>(); if (copyDetail.isPublicationContentMustBeCopied()) { // paste wysiwyg fileIds = WysiwygController.copy(fromComponentId, fromId, toPubPK.getInstanceId(), id, userId); } if (copyDetail.isPublicationFilesMustBeCopied()) { fileIds.putAll(copyFiles(fromPubPK, toPubPK)); } if (copyDetail.isPublicationContentMustBeCopied()) { String xmlFormShortName = publi.getInfoId(); if (xmlFormShortName != null && !"0".equals(xmlFormShortName)) { // Content = XMLForm // register xmlForm to publication PublicationTemplateManager publicationTemplateManager = PublicationTemplateManager .getInstance(); GenericRecordSet toRecordset = publicationTemplateManager.addDynamicPublicationTemplate( toComponentId + ":" + xmlFormShortName, xmlFormShortName + ".xml"); PublicationTemplate pubTemplate = publicationTemplateManager .getPublicationTemplate(fromComponentId + ":" + xmlFormShortName); RecordSet set = pubTemplate.getRecordSet(); set.copy(fromForeignPK, toForeignPK, toRecordset.getRecordTemplate(), fileIds); } } // force the update PublicationDetail newPubli = getPublicationDetail(toPubPK); newPubli.setStatusMustBeChecked(false); updatePublication(newPubli); return newPubli.getPK(); } catch (Exception ex) { SilverTrace.error("kmelia", getClass().getSimpleName() + ".pastePublication()", "root.EX_NO_MESSAGE", ex); } return null; } private Map<String, String> copyFiles(PublicationPK fromPK, PublicationPK toPK) throws IOException { Map<String, String> fileIds = new HashMap<String, String>(); List<SimpleDocument> origins = AttachmentServiceFactory.getAttachmentService() .listDocumentsByForeignKeyAndType(fromPK, DocumentType.attachment, null); for (SimpleDocument origin : origins) { SimpleDocumentPK copyPk = AttachmentServiceFactory.getAttachmentService().copyDocument(origin, new ForeignPK(toPK)); fileIds.put(origin.getId(), copyPk.getId()); } return fileIds; } private void copyPdcPositions(PublicationPK fromPK, PublicationPK toPK) throws RemoteException, PdcException { int fromSilverObjectId = getSilverObjectId(fromPK); int toSilverObjectId = getSilverObjectId(toPK); new PdcBmImpl().copyPositions(fromSilverObjectId, fromPK.getInstanceId(), toSilverObjectId, toPK.getInstanceId()); } public List<KmeliaPublication> filterPublications(List<KmeliaPublication> publications, String instanceId, SilverpeasRole profile, String userId) { boolean coWriting = isCoWritingEnable(instanceId); List<KmeliaPublication> filteredPublications = new ArrayList<KmeliaPublication>(); for (KmeliaPublication userPub : publications) { if (isPublicationVisible(userPub.getDetail(), profile, userId, coWriting)) { filteredPublications.add(userPub); } } return filteredPublications; } public boolean isPublicationVisible(PublicationDetail detail, SilverpeasRole profile, String userId) { boolean coWriting = isCoWritingEnable(detail.getInstanceId()); return isPublicationVisible(detail, profile, userId, coWriting); } private boolean isPublicationVisible(PublicationDetail detail, SilverpeasRole profile, String userId, boolean coWriting) { if (detail.getStatus() != null) { if (detail.isValid()) { if (detail.isVisible()) { return true; } else { if (profile == SilverpeasRole.admin || userId.equals(detail.getUpdaterId()) || (profile != SilverpeasRole.user && coWriting)) { return true; } } } else { if (detail.isDraft()) { // si le theme est en co-rdaction et si on autorise le mode brouillon visible par tous // toutes les publications en mode brouillon sont visibles par tous, sauf les lecteurs // sinon, seule les publications brouillon de l'utilisateur sont visibles if (userId.equals(detail.getCreatorId()) || userId.equals(detail.getUpdaterId()) || (coWriting && isDraftVisibleWithCoWriting() && profile != SilverpeasRole.user)) { return true; } } else { // si le thme est en co-rdaction, toutes les publications sont visibles par tous, // sauf les lecteurs if (profile == SilverpeasRole.admin || profile == SilverpeasRole.publisher || userId.equals(detail.getCreatorId()) || userId.equals(detail.getUpdaterId()) || (profile != SilverpeasRole.user && coWriting)) { return true; } } } } return false; } }