Java tutorial
/* * Copyright (C) 2000 - 2018 Silverpeas * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * As a special exception to the terms and conditions of version 3.0 of * the GPL, you may redistribute this Program in connection with Free/Libre * Open Source Software ("FLOSS") applications as described in Silverpeas's * FLOSS exception. You should have received a copy of the text describing * the FLOSS exception, and it is also available here: * "https://www.silverpeas.org/legal/floss_exception.html" * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.silverpeas.components.kmelia.control; import org.apache.commons.fileupload.FileItem; import org.apache.commons.io.FileUtils; import org.owasp.encoder.Encode; import org.silverpeas.components.kmelia.FileImport; import org.silverpeas.components.kmelia.InstanceParameters; import org.silverpeas.components.kmelia.KmeliaAuthorization; import org.silverpeas.components.kmelia.KmeliaCopyDetail; import org.silverpeas.components.kmelia.KmeliaPasteDetail; import org.silverpeas.components.kmelia.KmeliaPublicationHelper; import org.silverpeas.components.kmelia.SearchContext; import org.silverpeas.components.kmelia.export.ExportFileNameProducer; import org.silverpeas.components.kmelia.export.KmeliaPublicationExporter; import org.silverpeas.components.kmelia.model.*; import org.silverpeas.components.kmelia.search.KmeliaSearchServiceProvider; import org.silverpeas.components.kmelia.service.KmeliaHelper; import org.silverpeas.components.kmelia.service.KmeliaService; import org.silverpeas.core.ResourceReference; import org.silverpeas.core.admin.ObjectType; import org.silverpeas.core.admin.component.model.ComponentInst; import org.silverpeas.core.admin.component.model.GlobalContext; import org.silverpeas.core.admin.service.AdminController; import org.silverpeas.core.admin.space.SpaceInstLight; import org.silverpeas.core.admin.user.model.Group; import org.silverpeas.core.admin.user.model.ProfileInst; import org.silverpeas.core.admin.user.model.SilverpeasRole; import org.silverpeas.core.admin.user.model.UserDetail; import org.silverpeas.core.clipboard.ClipboardException; import org.silverpeas.core.clipboard.ClipboardSelection; import org.silverpeas.core.comment.model.Comment; import org.silverpeas.core.comment.service.CommentService; import org.silverpeas.core.comment.service.CommentServiceProvider; import org.silverpeas.core.contribution.attachment.AttachmentServiceProvider; import org.silverpeas.core.contribution.attachment.model.Attachments; import org.silverpeas.core.contribution.attachment.model.DocumentType; import org.silverpeas.core.contribution.attachment.model.SimpleDocument; import org.silverpeas.core.contribution.attachment.model.SimpleDocumentPK; import org.silverpeas.core.contribution.content.form.DataRecord; import org.silverpeas.core.contribution.content.form.Form; import org.silverpeas.core.contribution.content.form.PagesContext; import org.silverpeas.core.contribution.content.form.RecordSet; import org.silverpeas.core.contribution.content.wysiwyg.service.WysiwygController; import org.silverpeas.core.contribution.converter.DocumentFormat; import org.silverpeas.core.contribution.model.LocalizedContribution; import org.silverpeas.core.contribution.publication.datereminder.PublicationNoteReference; import org.silverpeas.core.contribution.publication.model.Alias; import org.silverpeas.core.contribution.publication.model.CompletePublication; import org.silverpeas.core.contribution.publication.model.PublicationDetail; import org.silverpeas.core.contribution.publication.model.PublicationPK; import org.silverpeas.core.contribution.publication.model.PublicationSelection; import org.silverpeas.core.contribution.publication.model.ValidationStep; import org.silverpeas.core.contribution.publication.service.PublicationService; import org.silverpeas.core.contribution.template.publication.PublicationTemplate; import org.silverpeas.core.contribution.template.publication.PublicationTemplateException; import org.silverpeas.core.contribution.template.publication.PublicationTemplateImpl; import org.silverpeas.core.contribution.template.publication.PublicationTemplateManager; import org.silverpeas.core.datereminder.exception.DateReminderException; import org.silverpeas.core.datereminder.persistence.DateReminderDetail; import org.silverpeas.core.datereminder.persistence.PersistentResourceDateReminder; import org.silverpeas.core.datereminder.persistence.service.DateReminderServiceProvider; import org.silverpeas.core.datereminder.persistence.service.PersistentDateReminderService; import org.silverpeas.core.i18n.I18NHelper; import org.silverpeas.core.importexport.ExportDescriptor; import org.silverpeas.core.importexport.attachment.AttachmentImportExport; import org.silverpeas.core.importexport.model.ImportExportException; import org.silverpeas.core.importexport.report.ComponentReport; import org.silverpeas.core.importexport.report.ImportReport; import org.silverpeas.core.importexport.report.MassiveReport; import org.silverpeas.core.importexport.report.UnitReport; import org.silverpeas.core.index.indexing.model.IndexManager; import org.silverpeas.core.index.search.SearchEngineProvider; import org.silverpeas.core.index.search.model.MatchingIndexEntry; import org.silverpeas.core.index.search.model.QueryDescription; import org.silverpeas.core.io.media.image.thumbnail.ThumbnailSettings; import org.silverpeas.core.io.upload.UploadedFile; import org.silverpeas.core.node.coordinates.model.Coordinate; import org.silverpeas.core.node.model.NodeDetail; import org.silverpeas.core.node.model.NodePK; import org.silverpeas.core.node.model.NodeSelection; import org.silverpeas.core.node.service.NodeService; import org.silverpeas.core.notification.user.ManualUserNotificationSupplier; import org.silverpeas.core.notification.user.NotificationContext; import org.silverpeas.core.notification.user.UserNotification; import org.silverpeas.core.pdc.pdc.model.ClassifyPosition; import org.silverpeas.core.pdc.pdc.model.PdcClassification; import org.silverpeas.core.pdc.pdc.model.PdcException; import org.silverpeas.core.pdc.pdc.model.PdcPosition; import org.silverpeas.core.pdc.pdc.service.PdcClassificationService; import org.silverpeas.core.pdc.pdc.service.PdcManager; import org.silverpeas.core.security.authorization.AccessControlContext; import org.silverpeas.core.security.authorization.NodeAccessController; import org.silverpeas.core.security.authorization.PublicationAccessController; import org.silverpeas.core.silverstatistics.access.model.HistoryObjectDetail; import org.silverpeas.core.silverstatistics.access.service.StatisticService; import org.silverpeas.core.subscription.service.NodeSubscriptionResource; import org.silverpeas.core.template.SilverpeasTemplate; import org.silverpeas.core.template.SilverpeasTemplateFactory; import org.silverpeas.core.util.*; import org.silverpeas.core.util.file.FileFolderManager; import org.silverpeas.core.util.file.FileRepositoryManager; import org.silverpeas.core.util.file.FileUploadUtil; import org.silverpeas.core.util.file.FileUtil; import org.silverpeas.core.util.logging.SilverLogger; import org.silverpeas.core.web.mvc.controller.AbstractComponentSessionController; import org.silverpeas.core.web.mvc.controller.ComponentContext; import org.silverpeas.core.web.mvc.controller.MainSessionController; import org.silverpeas.core.web.selection.Selection; import org.silverpeas.core.web.selection.SelectionUsersGroups; import org.silverpeas.core.web.subscription.SubscriptionContext; import org.silverpeas.core.webapi.pdc.PdcClassificationEntity; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.text.ParseException; import java.util.*; import java.util.stream.Collectors; import static org.silverpeas.components.kmelia.control.KmeliaSessionController.CLIPBOARD_STATE.*; import static org.silverpeas.components.kmelia.export.KmeliaPublicationExporter.*; import static org.silverpeas.core.cache.service.CacheServiceProvider.getSessionCacheService; import static org.silverpeas.core.cache.service.VolatileIdentifierProvider.newVolatileIntegerIdentifierOn; import static org.silverpeas.core.contribution.attachment.AttachmentService.VERSION_MODE; import static org.silverpeas.core.pdc.pdc.model.PdcClassification.NONE_CLASSIFICATION; import static org.silverpeas.core.pdc.pdc.model.PdcClassification.aPdcClassificationOfContent; public class KmeliaSessionController extends AbstractComponentSessionController implements ExportFileNameProducer { /** * The different export formats the KmeliaPublicationExporter should support. */ private static final String EXPORT_FORMATS = "kmelia.export.formats.active"; /** * All the formats that are available for the export of publications. */ private static final String[] AVAILABLE_EXPORT_FORMATS = { "zip", "pdf", "odt", "doc" }; private static final int DEFAULT_NBPUBLIS_PER_PAGE = 10; private static final String INACCESSIBLE_ATTACHMENT = "liaisonInaccessible"; private static final String KMELIA = "kmelia"; private static final String PUBLICATION = "Publication"; private static final String USELESS = "useless"; private static final String PUB_LIST_SESSION_CACHE_KEY = KmeliaSessionController.class.getSimpleName() + "#publicationList"; // Session objects private TopicDetail sessionTopic = null; private String currentFolderId = NodePK.ROOT_NODE_ID; private KmeliaPublication sessionPublication = null; private KmeliaPublication sessionClone = null; // sessionPath html link with <a href=""> private String sessionPath = null; // sessionPathString html string only private String sessionPathString = null; private TopicDetail sessionTopicToLink = null; private boolean sessionOwner = false; // Specific Kmax private List<String> sessionCombination = null; // Specific Kmax private String sessionTimeCriteria = null; private String sortValue = null; private String defaultSortValue = "2"; private int rang = 0; public static final String TAB_PREVIEW = "tabpreview"; public static final String TAB_HEADER = "tabheader"; public static final String TAB_CONTENT = "tabcontent"; public static final String TAB_COMMENT = "tabcomments"; public static final String TAB_ATTACHMENTS = "tabattachments"; public static final String TAB_SEE_ALSO = "tabseealso"; public static final String TAB_ACCESS_PATHS = "tabaccesspaths"; public static final String TAB_READER_LIST = "tabreaderslist"; // For import files public static final String UNITARY_IMPORT_MODE = "0"; public static final String MASSIVE_IMPORT_MODE_ONE_PUBLICATION = "1"; public static final String MASSIVE_IMPORT_MODE_MULTI_PUBLICATIONS = "2"; // Versioning options public static final String VER_USE_WRITERS_AND_READERS = "0"; // utilisation de userPanel/ userpanelPeas String[] idSelectedUser = null; // pagination de la liste des publications private int indexOfFirstPubToDisplay = 0; private int nbPublicationsPerPage = DEFAULT_NBPUBLIS_PER_PAGE; // Specific for Kmax private List<Integer> timeAxis = null; private List<String> currentCombination = null; private boolean isKmaxMode = false; // i18n private String currentLanguage = null; boolean isDragAndDropEnableByUser = false; boolean componentManageable = false; private List<PublicationPK> selectedPublicationPKs = new ArrayList<>(); private boolean customPublicationTemplateUsed = false; private String customPublicationTemplateName = null; private SearchContext searchContext = null; /** * Creates new sessionClientController * @param mainSessionCtrl * @param context */ public KmeliaSessionController(MainSessionController mainSessionCtrl, ComponentContext context) { super(mainSessionCtrl, context, "org.silverpeas.kmelia.multilang.kmeliaBundle", "org.silverpeas.kmelia.settings.kmeliaIcons", "org.silverpeas.kmelia.settings.kmeliaSettings"); init(); } public static List<String> getLanguagesOfAttachments(ResourceReference resourceReference) { List<String> languages = new ArrayList<>(); for (String availableLanguage : I18NHelper.getAllSupportedLanguages()) { List<SimpleDocument> attachments = AttachmentServiceProvider.getAttachmentService() .listDocumentsByForeignKeyAndType(resourceReference, DocumentType.attachment, availableLanguage); for (SimpleDocument attachment : attachments) { if (availableLanguage.equalsIgnoreCase(attachment.getLanguage())) { languages.add(availableLanguage); break; } } } return languages; } private void init() { // Remove all data store by this SessionController removeSessionObjects(); currentLanguage = getLanguage(); if (StringUtil.getBooleanValue(getSettings().getString("massiveDragAndDropAllowed"))) { isDragAndDropEnableByUser = isDragAndDropEnableByUser(); } componentManageable = ResourceLocator.getGeneralSettingBundle().getBoolean("AdminFromComponentEnable", true); if (componentManageable) { componentManageable = getOrganisationController().isComponentManageable(getComponentId(), getUserId()); } defaultSortValue = getComponentParameterValue("publicationSort"); if (!StringUtil.isDefined(defaultSortValue)) { defaultSortValue = getSettings().getString("publications.sort.default", "2"); } // check if this instance use a specific template of publication SilverpeasTemplate template = SilverpeasTemplateFactory.createSilverpeasTemplateOnComponents(); customPublicationTemplateName = "publication_" + getComponentId(); customPublicationTemplateUsed = template.isCustomTemplateExists(KMELIA, customPublicationTemplateName); cacheDirectlyPublicationsListInSession(Collections.emptyList()); nbPublicationsPerPage = getSettings().getInteger("NbPublicationsParPage", 10); String parameterValue = getComponentParameterValue("nbPubliPerPage"); if (StringUtil.isInteger(parameterValue)) { nbPublicationsPerPage = Integer.parseInt(parameterValue); } } public boolean isKmaxMode() { return isKmaxMode; } public KmeliaSessionController setKmaxMode(final boolean kmaxMode) { isKmaxMode = kmaxMode; return this; } /** * Gets a business service of comments. * @return a DefaultCommentService instance. */ protected CommentService getCommentService() { return CommentServiceProvider.getCommentService(); } public KmeliaService getKmeliaService() { return ServiceProvider.getService(KmeliaService.class); } public StatisticService getStatisticService() { return ServiceProvider.getService(StatisticService.class); } /** * Gets a business service of dateReminder. * * @return a DefaultDateReminderService instance. */ protected PersistentDateReminderService getDateReminderService() { return DateReminderServiceProvider.getDateReminderService(); } public int getNbPublicationsOnRoot() { int nbPublicationsOnRoot = 0; String parameterValue = getComponentParameterValue("nbPubliOnRoot"); if (StringUtil.isDefined(parameterValue)) { nbPublicationsOnRoot = Integer.parseInt(parameterValue); } else { if (KmeliaHelper.isKmelia(getComponentId())) { // lecture du properties nbPublicationsOnRoot = getSettings().getInteger("HomeNbPublications", 15); } } return nbPublicationsOnRoot; } public int getNbPublicationsPerPage() { return nbPublicationsPerPage; } public void setNbPublicationsPerPage(int nb) { nbPublicationsPerPage = nb; } public boolean isDraftVisibleWithCoWriting() { return getSettings().getBoolean("draftVisibleWithCoWriting", false); } public boolean isTreeStructure() { return KmeliaPublicationHelper.isTreeEnabled(getComponentId()); } public boolean isTreeviewUsed() { String param = getComponentParameterValue("istree"); if (!StringUtil.isDefined(param)) { return true; } return "0".equals(param); } public boolean isPdcUsed() { return StringUtil.getBooleanValue(getComponentParameterValue("usepdc")); } public boolean isDraftEnabled() { return StringUtil.getBooleanValue(getComponentParameterValue("draft")); } public boolean isOrientedWebContent() { return StringUtil.getBooleanValue(getComponentParameterValue("webContent")); } public boolean isSortedTopicsEnabled() { return StringUtil.getBooleanValue(getComponentParameterValue("sortedTopics")); } public boolean isTopicManagementDelegated() { return StringUtil.getBooleanValue(getComponentParameterValue("delegatedTopicManagement")); } public boolean isAuthorUsed() { return StringUtil.getBooleanValue(getComponentParameterValue("useAuthor")); } public boolean isReminderUsed() { return StringUtil.getBooleanValue(getComponentParameterValue("useReminder")); } public boolean isStatisticAllowed() { boolean statisticEnabled = getSettings().getBoolean("kmelia.stats.enable", false); return statisticEnabled && !isToolbox() && (getHighestSilverpeasUserRole().isGreaterThanOrEquals(SilverpeasRole.publisher) || getSilverpeasUserRoles().contains(SilverpeasRole.supervisor)); } public boolean openSingleAttachmentAutomatically() { return StringUtil.getBooleanValue(getComponentParameterValue("openSingleAttachment")); } public boolean isImportFileAllowed() { String parameterValue = getComponentParameterValue("importFiles"); if (!StringUtil.isDefined(parameterValue)) { return false; } else { return "1".equalsIgnoreCase(parameterValue) || "3".equalsIgnoreCase(parameterValue); } } public boolean isImportFilesAllowed() { String parameterValue = this.getComponentParameterValue("importFiles"); if (parameterValue == null || parameterValue.length() <= 0) { return false; } else { return "2".equalsIgnoreCase(parameterValue) || "3".equalsIgnoreCase(parameterValue); } } public boolean isExportZipAllowed() { String parameterValue = this.getComponentParameterValue("exportComponent"); if (parameterValue == null || parameterValue.length() <= 0) { return false; } else { return StringUtil.getBooleanValue(parameterValue) || "both".equalsIgnoreCase(parameterValue); } } public boolean isExportPdfAllowed() { String parameterValue = this.getComponentParameterValue("exportComponent"); if (parameterValue == null || parameterValue.length() <= 0) { return false; } else { return "pdf".equalsIgnoreCase(parameterValue) || "both".equalsIgnoreCase(parameterValue); } } public boolean isExportComponentAllowed() { return StringUtil.getBooleanValue(getSettings().getString("exportComponentAllowed")); } public boolean isExportAllowedToUsers() { return getSettings().getBoolean("export.allowed.users", false); } public boolean isMassiveDragAndDropAllowed() { return StringUtil.getBooleanValue(getComponentParameterValue("massiveDragAndDrop")); } public boolean isPublicationAlwaysVisibleEnabled() { return StringUtil.getBooleanValue(getComponentParameterValue("publicationAlwaysVisible")); } public boolean displayNbPublis() { return StringUtil.getBooleanValue(getComponentParameterValue(InstanceParameters.displayNbItemsOnFolders)); } public boolean isRightsOnTopicsEnabled() { return StringUtil.getBooleanValue(getComponentParameterValue(InstanceParameters.rightsOnFolders)); } private boolean isRightsOnTopicsEnabled(String componentId) { return StringUtil.getBooleanValue(getOrganisationController().getComponentParameterValue(componentId, InstanceParameters.rightsOnFolders)); } public boolean isFoldersLinkedEnabled() { return StringUtil.getBooleanValue(getComponentParameterValue("isLink")); } public boolean attachmentsInPubList() { return StringUtil.getBooleanValue(getComponentParameterValue("attachmentsInPubList")); } public boolean isPublicationIdDisplayed() { return StringUtil.getBooleanValue(getComponentParameterValue("codification")); } public boolean isSuppressionOnlyForAdmin() { return StringUtil.getBooleanValue(getComponentParameterValue("suppressionOnlyForAdmin")); } public boolean isContentEnabled() { String parameterValue = getComponentParameterValue("tabContent"); if (!StringUtil.isDefined(parameterValue)) { return false; } return StringUtil.getBooleanValue(parameterValue); } public boolean isSeeAlsoEnabled() { return StringUtil.getBooleanValue(getComponentParameterValue("tabSeeAlso")); } public boolean isPublicationRatingAllowed() { return StringUtil.getBooleanValue(getComponentParameterValue("publicationRating")); } public boolean showUserNameInList() { return getSettings().getBoolean("showUserNameInList", true); } /** * @return */ public String getVersionningFileRightsMode() { String parameterValue = this.getComponentParameterValue("versionUseFileRights"); if (parameterValue == null || parameterValue.length() <= 0) { return VER_USE_WRITERS_AND_READERS; } return parameterValue; } public boolean isLastVisitorsEnabled() { String parameterValue = getComponentParameterValue("tabLastVisitors"); if (!StringUtil.isDefined(parameterValue)) { return true; } return StringUtil.getBooleanValue(parameterValue); } public List<String> getInvisibleTabs() { List<String> invisibleTabs = new ArrayList<>(0); if (!isContentEnabled()) { invisibleTabs.add(TAB_CONTENT); } if (isToolbox()) { invisibleTabs.add(TAB_PREVIEW); } String parameterValue = this.getComponentParameterValue("tabAttachments"); if (!isToolbox() && StringUtil.isDefined(parameterValue) && !StringUtil.getBooleanValue(parameterValue)) { // attachments tab is always visible with toolbox invisibleTabs.add(TAB_ATTACHMENTS); } if (!isSeeAlsoEnabled()) { invisibleTabs.add(TAB_SEE_ALSO); } parameterValue = this.getComponentParameterValue("tabAccessPaths"); if (StringUtil.isDefined(parameterValue) && !StringUtil.getBooleanValue(parameterValue)) { invisibleTabs.add(TAB_ACCESS_PATHS); } parameterValue = this.getComponentParameterValue("tabReadersList"); if (StringUtil.isDefined(parameterValue) && !StringUtil.getBooleanValue(parameterValue)) { invisibleTabs.add(TAB_READER_LIST); } parameterValue = this.getComponentParameterValue("tabComments"); if (!StringUtil.isDefined(parameterValue)) { invisibleTabs.add(TAB_COMMENT); } else { if (!StringUtil.getBooleanValue(parameterValue)) { invisibleTabs.add(TAB_COMMENT); } } return invisibleTabs; } /** * Generates a document in the specified format from the specified publication. * @param inFormat the format of the document to generate. * @param fromPubId the unique identifier of the publication from which the document will be * generated. * @return the generated document as a File instance. */ public File generateDocument(final DocumentFormat inFormat, String fromPubId) { if (!isFormatSupported(inFormat.name())) { throw new KmeliaRuntimeException("Document format " + inFormat.name() + " not yet supported"); } File document = null; if (fromPubId != null) { try { KmeliaPublication publication = KmeliaPublication .aKmeliaPublicationWithPk(new PublicationPK(fromPubId, getComponentId())); String fileName = getPublicationExportFileName(publication, getLanguage()); document = new File(FileRepositoryManager.getTemporaryPath() + fileName + "." + inFormat.name()); FileOutputStream output = new FileOutputStream(document); ExportDescriptor descriptor = ExportDescriptor.withOutputStream(output) .withParameter(EXPORT_FOR_USER, getUserDetail()) .withParameter(EXPORT_LANGUAGE, getLanguage()) .withParameter(EXPORT_TOPIC, getCurrentFolderId()).inMimeType(inFormat.name()); aKmeliaPublicationExporter().exports(descriptor, () -> publication); } catch (Exception ex) { SilverLogger.getLogger(this).error("Publication export failure", ex); if (document != null) { FileUtils.deleteQuietly(document); } throw new KmeliaRuntimeException(ex); } } return document; } /** * Gets a new exporter of Kmelia publications. * @return a KmeliaPublicationExporter instance. */ public static KmeliaPublicationExporter aKmeliaPublicationExporter() { return ServiceProvider.getService(KmeliaPublicationExporter.class); } @Override public SilverpeasRole getHighestSilverpeasUserRole() { SilverpeasRole userRole = SilverpeasRole.from(getProfile()); return userRole != null ? userRole : super.getHighestSilverpeasUserRole(); } public String getProfile() { return getUserTopicProfile(); } public String getUserTopicProfile() { return getUserTopicProfile(null); } public String getUserTopicProfile(String id) { String nodeId = id; if (!StringUtil.isDefined(id)) { nodeId = getCurrentFolderId(); if (!KmeliaHelper.isToValidateFolder(nodeId)) { try { // check that current node still exists getKmeliaService().getNodeHeader(nodeId, getComponentId()); } catch (Exception e) { SilverLogger.getLogger(this).warn(e); setCurrentFolderId(NodePK.ROOT_NODE_ID, true); nodeId = NodePK.ROOT_NODE_ID; } } } return getKmeliaService().getUserTopicProfile(getNodePK(nodeId), getUserId()); } public List<String> getUserIdsOfTopic() { return getKmeliaService().getUserIdsOfFolder(getCurrentFolderPK()); } public boolean isCurrentTopicAvailable() { if (isRightsOnTopicsEnabled()) { if (KmeliaHelper.isToValidateFolder(getCurrentFolderId())) { return true; } NodeDetail node = getNodeHeader(getCurrentFolderId()); if (node.haveRights()) { int rightsDependsOn = node.getRightsDependsOn(); return getOrganisationController().isObjectAvailable(rightsDependsOn, ObjectType.NODE, getComponentId(), getUserId()); } } return true; } public boolean isUserComponentAdmin() { return SilverpeasRole.admin.isInRole(KmeliaHelper.getProfile(getUserRoles())); } /* * Topic management */ public synchronized TopicDetail getTopic(String id) { return getTopic(id, true); } public synchronized TopicDetail getTopic(String id, boolean resetSessionPublication) { if (resetSessionPublication) { setSessionPublication(null); } if (!id.equals(getCurrentFolderId())) { indexOfFirstPubToDisplay = 0; } TopicDetail currentTopic; if (isUserComponentAdmin()) { currentTopic = getKmeliaService().goTo(getNodePK(id), getUserId(), isTreeStructure(), "admin", false); } else { currentTopic = getKmeliaService().goTo(getNodePK(id), getUserId(), isTreeStructure(), getUserTopicProfile(id), isRightsOnTopicsEnabled()); } if (displayNbPublis()) { prepareForPublicationNbDisplaying(currentTopic); } setSessionTopic(currentTopic); applyVisibilityFilter(); return currentTopic; } private void prepareForPublicationNbDisplaying(final TopicDetail currentTopic) { List<NodeDetail> treeview = getTreeview("0"); // set nb objects of current root currentTopic.getNodeDetail().setNbObjects(treeview.get(0).getNbObjects()); // set nb objects of children Collection<NodeDetail> children = currentTopic.getNodeDetail().getChildrenDetails(); for (NodeDetail node : children) { if (node != null) { int index = treeview.indexOf(node); if (index != -1) { NodeDetail nodeTreeview = treeview.get(index); if (nodeTreeview != null) { node.setNbObjects(nodeTreeview.getNbObjects()); } } } } } public List<NodeDetail> getTreeview(String nodeId) { if (isUserComponentAdmin()) { return getKmeliaService().getTreeview(getNodePK(nodeId), "admin", isCoWritingEnable(), isDraftVisibleWithCoWriting(), getUserId(), displayNbPublis(), false); } else { return getKmeliaService().getTreeview(getNodePK(nodeId), getProfile(), isCoWritingEnable(), isDraftVisibleWithCoWriting(), getUserId(), displayNbPublis(), isRightsOnTopicsEnabled()); } } public synchronized TopicDetail getPublicationTopic(String pubId) { TopicDetail currentTopic = getKmeliaService().getPublicationFather(getPublicationPK(pubId), isTreeStructure(), getUserId(), isRightsOnTopicsEnabled()); setSessionTopic(currentTopic); applyVisibilityFilter(); return currentTopic; } public synchronized List<NodeDetail> getAllTopics() { return getNodeService().getSubTree(getNodePK(NodePK.ROOT_NODE_ID)); } public synchronized void flushTrashCan() { TopicDetail td = getKmeliaService().goTo(getNodePK(NodePK.BIN_NODE_ID), getUserId(), false, getUserTopicProfile("1"), isRightsOnTopicsEnabled()); setSessionTopic(td); Collection<KmeliaPublication> pds = td.getKmeliaPublications(); Iterator<KmeliaPublication> ipds = pds.iterator(); while (ipds.hasNext()) { String theId = (ipds.next()).getDetail().getPK().getId(); deletePublication(theId); } indexOfFirstPubToDisplay = 0; } public synchronized NodePK updateTopicHeader(NodeDetail nd, String alertType) { nd.getNodePK().setSpace(getSpaceId()); nd.getNodePK().setComponentName(getComponentId()); if (isTopicAdmin(nd.getNodePK().getId())) { nd.setCreatorId(getUserId()); nd.setCreationDate(DateUtil.today2SQLDate()); return getKmeliaService().updateTopic(nd, alertType); } SilverLogger.getLogger(this).warn("Security alert from {0}", getUserId()); return null; } public synchronized NodeDetail getSubTopicDetail(String subTopicId) { return getKmeliaService().getSubTopicDetail(getNodePK(subTopicId)); } public synchronized NodePK addSubTopic(NodeDetail nd, String alertType, String parentId) { nd.getNodePK().setSpace(getSpaceId()); nd.getNodePK().setComponentName(getComponentId()); nd.setCreatorId(getUserId()); return getKmeliaService().addSubTopic(getNodePK(parentId), nd, alertType); } public synchronized String deleteTopic(String topicId) { if (NodePK.ROOT_NODE_ID.equals(topicId) || NodePK.BIN_NODE_ID.equals(topicId)) { return null; } NodeDetail node = getNodeHeader(topicId); // check if user is allowed to delete this topic if (SilverpeasRole.admin.isInRole(getUserTopicProfile(topicId)) || SilverpeasRole.admin.isInRole(getUserTopicProfile(NodePK.ROOT_NODE_ID)) || SilverpeasRole.admin.isInRole(getUserTopicProfile(node.getFatherPK().getId()))) { // First, remove rights on topic and its descendants List<NodeDetail> treeview = getNodeService().getSubTree(getNodePK(topicId)); for (NodeDetail nodeToDelete : treeview) { deleteTopicRoles(nodeToDelete); } // Then, remove the topic itself getKmeliaService().deleteTopic(getNodePK(topicId)); return node.getFatherPK().getId(); } return null; } public synchronized void changeTopicStatus(String newStatus, String topicId, boolean recursiveChanges) { getKmeliaService().changeTopicStatus(newStatus, getNodePK(topicId), recursiveChanges); } public synchronized Collection<Collection<NodeDetail>> getSubscriptionList() { return getKmeliaService().getSubscriptionList(getUserId(), getComponentId()); } public synchronized void removeSubscription(String topicId) { getKmeliaService().removeSubscriptionToCurrentUser(getNodePK(topicId), getUserId()); } public synchronized void addSubscription(String topicId) { getKmeliaService().addSubscription(getNodePK(topicId), getUserId()); } /** * @param pubId a publication identifier * @return */ public synchronized PublicationDetail getPublicationDetail(String pubId) { return getKmeliaService().getPublicationDetail(getPublicationPK(pubId)); } private Collection<Collection<NodeDetail>> getPathList(PublicationPK pk) { return getKmeliaService().getPathList(pk); } public synchronized Collection<NodePK> getPublicationFathers(String pubId) { return getKmeliaService().getPublicationFathers(getPublicationPK(pubId)); } public NodePK getAllowedPublicationFather(String pubId) { return getKmeliaService().getPublicationFatherPK(getPublicationPK(pubId), isTreeStructure(), getUserId(), isRightsOnTopicsEnabled()); } public synchronized String createPublication(PublicationDetail pubDetail, final PdcClassificationEntity classification) { pubDetail.getPK().setSpace(getSpaceId()); pubDetail.getPK().setComponentName(getComponentId()); pubDetail.setCreatorId(getUserId()); pubDetail.setCreationDate(new Date()); setCurrentLanguage(pubDetail.getLanguage()); String result; if (isKmaxMode) { result = getKmeliaService().createKmaxPublication(pubDetail); } else { if (classification.isUndefined()) { result = getKmeliaService().createPublicationIntoTopic(pubDetail, getCurrentFolderPK()); } else { List<PdcPosition> pdcPositions = classification.getPdcPositions(); PdcClassification withClassification = aPdcClassificationOfContent(pubDetail) .withPositions(pdcPositions); result = getKmeliaService().createPublicationIntoTopic(pubDetail, getCurrentFolderPK(), withClassification); } } return result; } /** * attach uploaded files to the specified publication * * @param uploadedFiles list of uploaded files * @param pubDetail publication on which you want to attach files */ public synchronized void addUploadedFilesToPublication(Collection<UploadedFile> uploadedFiles, PublicationDetail pubDetail) { Attachments.from(uploadedFiles).attachTo(LocalizedContribution.from(pubDetail, pubDetail.getLanguage())); } public synchronized void updatePublication(PublicationDetail pubDetail) { pubDetail.getPK().setSpace(getSpaceId()); pubDetail.getPK().setComponentName(getComponentId()); pubDetail.setUpdaterId(getUserId()); setCurrentLanguage(pubDetail.getLanguage()); if (isCloneNeeded()) { clonePublication(pubDetail); } else { if (NodePK.BIN_NODE_ID.equals(getCurrentFolderId())) { // publication is in the trash can pubDetail.setIndexOperation(IndexManager.NONE); } if (getSessionClone() != null && getSessionClone().getId().equals(pubDetail.getId())) { // update the clone, clone stay in same status pubDetail.setStatusMustBeChecked(false); // clone must not be indexed pubDetail.setIndexOperation(IndexManager.NONE); } getKmeliaService().updatePublication(pubDetail); } } public boolean isCloneNeeded() { if (getSessionPublication() == null) { return false; } String currentStatus = getSessionPublication().getDetail().getStatus(); return (isPublicationAlwaysVisibleEnabled() && "writer".equals(getUserTopicProfile()) && (getSessionClone() == null) && PublicationDetail.VALID_STATUS.equals(currentStatus)); } public boolean isCloneNeededWithDraft() { return (isPublicationAlwaysVisibleEnabled() && (getSessionClone() == null)); } public String clonePublication() { return clonePublication(null); } public String clonePublication(PublicationDetail pubDetail) { String cloneStatus = PublicationDetail.TO_VALIDATE_STATUS; if (isDraftEnabled()) { cloneStatus = PublicationDetail.DRAFT_STATUS; } return clonePublication(pubDetail, cloneStatus); } /** * Clone current publication. Create new publication based on pubDetail object if not null or * sessionPublication otherwise. Original publication must not be modified (except references to * clone : cloneId and cloneStatus). * @param pubDetail If not null, attribute values are set to the clone * @param nextStatus Draft or ToValidate * @return */ private String clonePublication(PublicationDetail pubDetail, String nextStatus) { String cloneId = null; // rcupration de la publi de rfrence CompletePublication refPubComplete = getSessionPublication().getCompleteDetail(); try { cloneId = getKmeliaService().clonePublication(refPubComplete, pubDetail, nextStatus); setSessionClone(getPublication(cloneId)); } catch (Exception e) { throw new KmeliaRuntimeException(e); } return cloneId; } public synchronized void deletePublication(String pubId) { getKmeliaService().deletePublications(Collections.singletonList(pubId), getCurrentFolderPK(), getUserId()); } public List<String> deleteSelectedPublications() { List<String> removed = getKmeliaService().deletePublications(getLocalSelectedPublicationIds(), getCurrentFolderPK(), getUserId()); resetSelectedPublicationPKs(); return removed; } private List<String> getLocalSelectedPublicationIds() { List<String> ids = new ArrayList<>(); for (PublicationPK pubPK : getSelectedPublicationPKs()) { if (pubPK != null && pubPK.getInstanceId().equals(getComponentId())) { ids.add(pubPK.getId()); } } return ids; } public synchronized void deleteClone() { if (getSessionClone() != null) { // delete clone String cloneId = getSessionClone().getDetail().getPK().getId(); PublicationPK clonePK = getPublicationPK(cloneId); getKmeliaService().deletePublication(clonePK); setSessionClone(null); refreshSessionPubliAndClone(); // delete references on clone PublicationDetail pubDetail = getSessionPublication().getDetail(); pubDetail.setCloneId(null); pubDetail.setCloneStatus(null); pubDetail.setStatusMustBeChecked(false); pubDetail.setUpdateDateMustBeSet(false); getKmeliaService().updatePublication(pubDetail); } } private static boolean isInteger(String id) { return StringUtil.isInteger(id); } public synchronized void addPublicationToTopic(String pubId, String fatherId) { getKmeliaService().addPublicationToTopic(getPublicationPK(pubId), getNodePK(fatherId), false); } public synchronized void deletePublicationFromAllTopics(String pubId) { getKmeliaService().deletePublicationFromAllTopics(getPublicationPK(pubId)); } public void refreshSessionPubliAndClone() { if (getSessionClone() != null) { // Clone refresh KmeliaPublication pub = getPublication(getSessionClone().getDetail().getPK().getId()); setSessionClone(pub); } else { // refresh publication master KmeliaPublication pub = getPublication(getSessionPublication().getDetail().getPK().getId()); setSessionPublication(pub); } } /** * adds links between specified publication and other publications contained in links parameter * @param pubId publication which you want removes the external link * @param links list of links to remove */ private void addInfoLinks(String pubId, List<ResourceReference> links) { getKmeliaService().addInfoLinks(getPublicationPK(pubId), links); // reset current publication KmeliaPublication completPub = getKmeliaService().getPublication(getPublicationPK(pubId)); setSessionPublication(completPub); } public synchronized KmeliaPublication getPublication(String pubId) { return getPublication(pubId, false); } public synchronized KmeliaPublication getPublication(String pubId, boolean processIndex) { PublicationPK pubPK = getPublicationPK(pubId); // get publication KmeliaPublication publication = getKmeliaService().getPublication(pubPK); PublicationDetail publicationDetail = publication.getDetail(); ResourceReference resourceReference = new ResourceReference(pubId, getComponentId()); if (!publicationDetail.getPK().getInstanceId().equals(getComponentId())) { // it's an alias resourceReference.setComponentName(publicationDetail.getPK().getInstanceId()); } if (getSessionPublication() != null) { if (!pubId.equals(getSessionPublication().getId())) { // memorize the reading of the publication by the user getStatisticService().addStat(getUserId(), resourceReference, 1, PUBLICATION); } } else { getStatisticService().addStat(getUserId(), resourceReference, 1, PUBLICATION); } if (processIndex) { // getting rank of publication KmeliaPublication pub = KmeliaPublication.aKmeliaPublicationFromDetail(publicationDetail); if (getSessionPublicationsList() != null) { rang = getSessionPublicationsList().indexOf(pub); if (rang != -1 && getSearchContext() != null) { getSessionPublicationsList().get(rang).setAsRead(); } } } return publication; } public int getNbPublis() { if (getSessionPublicationsList() != null) { return getSessionPublicationsList().size(); } return 1; } public synchronized CompletePublication getCompletePublication(String pubId) { return getKmeliaService().getCompletePublication(getPublicationPK(pubId)); } public synchronized void orderPubs() { if (!StringUtil.isDefined(getSortValue())) { orderPubs(-1); } else { orderPubs(Integer.parseInt(getSortValue())); } } private void applyVisibilityFilter() { final List<KmeliaPublication> publications = getSessionPublicationsList(); setSessionPublicationsList(getKmeliaService().filterPublications(publications, getComponentId(), SilverpeasRole.from(getProfile()), getUserId())); } private synchronized void orderPubs(int sortType) { cacheDirectlyPublicationsListInSession(sort(getSessionPublicationsList(), sortType)); } private List<KmeliaPublication> sort(Collection<KmeliaPublication> publications, int sortType) { if (publications == null) { return Collections.emptyList(); } List<KmeliaPublication> publicationsToSort = new ArrayList<>(publications); int sort = sortType; if (isManualSortingUsed(publicationsToSort) && sort == -1) { // display publications according to manual order defined by admin sort = 99; } else if (sort == -1) { // display publications according to default sort defined on application level or instance // level sort = Integer.parseInt(defaultSortValue); } switch (sort) { case 0: Collections.sort(publicationsToSort, new PubliAuthorComparatorAsc()); break; case 1: Collections.sort(publicationsToSort, new PubliUpdateDateComparatorAsc()); break; case 2: Collections.sort(publicationsToSort, new PubliUpdateDateComparatorAsc()); Collections.reverse(publicationsToSort); break; case 3: Collections.sort(publicationsToSort, new PubliImportanceComparatorDesc()); break; case 4: publicationsToSort = sortByTitle(publicationsToSort); break; case 5: Collections.sort(publicationsToSort, new PubliCreationDateComparatorAsc()); break; case 6: Collections.sort(publicationsToSort, new PubliCreationDateComparatorAsc()); Collections.reverse(publicationsToSort); break; case 7: publicationsToSort = sortByDescription(publicationsToSort); break; default: // display publications according to manual order defined by admin Collections.sort(publicationsToSort, new PubliRankComparatorAsc()); } return publicationsToSort; } private boolean isManualSortingUsed(List<KmeliaPublication> publications) { for (KmeliaPublication publication : publications) { if (publication.getDetail().getExplicitRank() > 0) { return true; } } return false; } private List<KmeliaPublication> sortByTitle(List<KmeliaPublication> publications) { KmeliaPublication[] pubs = publications.toArray(new KmeliaPublication[publications.size()]); for (int i = pubs.length; --i >= 0;) { boolean swapped = false; for (int j = 0; j < i; j++) { if (pubs[j].getDetail().getName(getCurrentLanguage()) .compareToIgnoreCase(pubs[j + 1].getDetail().getName(getCurrentLanguage())) > 0) { KmeliaPublication pub = pubs[j]; pubs[j] = pubs[j + 1]; pubs[j + 1] = pub; swapped = true; } } if (!swapped) { break; } } return Arrays.asList(pubs); } private List<KmeliaPublication> sortByDescription(List<KmeliaPublication> publications) { KmeliaPublication[] pubs = publications.toArray(new KmeliaPublication[publications.size()]); for (int i = pubs.length; --i >= 0;) { boolean swapped = false; for (int j = 0; j < i; j++) { String p1 = pubs[j].getDetail().getDescription(getCurrentLanguage()); if (p1 == null) { p1 = ""; } String p2 = pubs[j + 1].getDetail().getDescription(getCurrentLanguage()); if (p2 == null) { p2 = ""; } if (p1.compareToIgnoreCase(p2) > 0) { KmeliaPublication pub = pubs[j]; pubs[j] = pubs[j + 1]; pubs[j + 1] = pub; swapped = true; } } if (!swapped) { break; } } return Arrays.asList(pubs); } public void orderPublications(List<String> sortedPubIds) { getPublicationService().changePublicationsOrder(sortedPubIds, getCurrentFolderPK()); } public Collection<PublicationDetail> getAllPublications() { return getAllPublications(null); } /** * Get all publications sorted * @param sortedBy (example: pubName asc) * @return Collection of Publications */ public Collection<PublicationDetail> getAllPublications(String sortedBy) { String publicationDefaultSorting = getSettings().getString("publication_defaultsorting", "pubId desc"); if (StringUtil.isDefined(sortedBy)) { publicationDefaultSorting = sortedBy; } return getPublicationService().getAllPublications(new PublicationPK(USELESS, getComponentId()), publicationDefaultSorting); } public Collection<PublicationDetail> getAllPublicationsByTopic(PublicationPK pubPK, List<String> fatherIds) { return getPublicationService().getDetailsByFatherIdsAndStatus(fatherIds, pubPK, "P.pubUpdateDate desc, P.pubId desc", PublicationDetail.VALID_STATUS); } /** * Get all visible publications * @return List of WAAtributeValuePair (Id and InstanceId) */ public List<WAAttributeValuePair> getAllVisiblePublications() { List<WAAttributeValuePair> allVisiblesPublications = new ArrayList<>(); Collection<PublicationDetail> allPublications = getAllPublications(); for (PublicationDetail pubDetail : allPublications) { if (pubDetail.getStatus().equals(PublicationDetail.VALID_STATUS)) { allVisiblesPublications.add(new WAAttributeValuePair(pubDetail.getId(), pubDetail.getInstanceId())); } } return allVisiblesPublications; } public List<WAAttributeValuePair> getAllVisiblePublicationsByTopic(String topicId) { List<WAAttributeValuePair> allVisiblesPublications = new ArrayList<>(); // rcuprer la liste des sous thmes de topicId List<String> fatherIds = new ArrayList<>(); NodePK nodePK = new NodePK(topicId, getComponentId()); List<NodeDetail> nodes = getNodeService().getSubTree(nodePK); for (NodeDetail node : nodes) { fatherIds.add(Integer.toString(node.getId())); } // cration de pubPK PublicationPK pubPK = getPublicationPK(USELESS); Collection<PublicationDetail> allPublications = getAllPublicationsByTopic(pubPK, fatherIds); for (PublicationDetail pubDetail : allPublications) { if (pubDetail.getStatus().equals(PublicationDetail.VALID_STATUS)) { allVisiblesPublications.add(new WAAttributeValuePair(pubDetail.getId(), pubDetail.getInstanceId())); } } return allVisiblesPublications; } public List<WAAttributeValuePair> getAllPublicationsIds() { List<WAAttributeValuePair> allPublicationsIds = new ArrayList<>(); Collection<PublicationDetail> allPublications = getAllPublications("pubName asc"); for (PublicationDetail pubDetail : allPublications) { if (pubDetail.getStatus().equals(PublicationDetail.VALID_STATUS)) { allPublicationsIds.add(new WAAttributeValuePair(pubDetail.getId(), pubDetail.getInstanceId())); } } return allPublicationsIds; } public int getIndexOfFirstPubToDisplay() { return indexOfFirstPubToDisplay; } public void setIndexOfFirstPubToDisplay(String index) { this.indexOfFirstPubToDisplay = Integer.parseInt(index); } public List<Comment> getAllComments(String id) { return getCommentService().getAllCommentsOnPublication(PublicationDetail.getResourceType(), getPublicationPK(id)); } public void processTopicWysiwyg(String topicId) { getNodeService().processWysiwyg(getNodePK(topicId)); } /** * Si le mode brouillon est activ et que le classement PDC est possible alors une publication ne * peut sortir du mode brouillon que si elle est classe sur le PDC * @return true si le PDC n'est pas utilis ou si aucun axe n'est utilis par le composant ou si * la publication est classe sur le PDC */ public boolean isPublicationTaxonomyOK() { if (!isPdcUsed() || getSessionPublication() == null || !isPDCClassifyingMandatory()) { // Classification is not used or mandatory so we don't care about the current // classification of the content return true; } String pubId = getSessionPublication().getDetail().getPK().getId(); return isPublicationClassifiedOnPDC(pubId); } public boolean isPublicationValidatorsOK() { if (getSessionPubliOrClone() != null && SilverpeasRole.writer.isInRole(getUserTopicProfile()) && (isTargetValidationEnable() || isTargetMultiValidationEnable())) { return CollectionUtil .isNotEmpty(getKmeliaService().getActiveValidatorIds(getSessionPubliOrClone().getPk())); } return true; } /** * @param links * @return */ public synchronized Collection<KmeliaPublication> getPublications(List<ResourceReference> links) { return getKmeliaService().getPublications(links, getUserId(), true); } public synchronized boolean validatePublication(String publicationId) { boolean validationComplete = getKmeliaService().validatePublication(getPublicationPK(publicationId), getUserId(), false, false); if (validationComplete) { setSessionClone(null); refreshSessionPubliAndClone(); } return validationComplete; } public synchronized boolean forcePublicationValidation(String publicationId) { return getKmeliaService().validatePublication(getPublicationPK(publicationId), getUserId(), true, false); } public synchronized void unvalidatePublication(String publicationId, String refusalMotive) { getKmeliaService().unvalidatePublication(getPublicationPK(publicationId), getUserId(), refusalMotive, getValidationType()); refreshSessionPubliAndClone(); } public synchronized void suspendPublication(String publicationId, String defermentMotive) { getKmeliaService().suspendPublication(getPublicationPK(publicationId), defermentMotive, getUserId()); } public List<ValidationStep> getValidationSteps() { List<ValidationStep> steps = getPublicationService() .getValidationSteps(getSessionPubliOrClone().getDetail().getPK()); // Get users who have already validate this publication List<String> validators = new ArrayList<>(); for (ValidationStep step : steps) { step.setUserFullName(getOrganisationController().getUserDetail(step.getUserId()).getDisplayedName()); validators.add(step.getUserId()); } List<String> allValidators = getKmeliaService() .getAllValidators(getSessionPubliOrClone().getDetail().getPK()); for (String allValidator : allValidators) { if (!validators.contains(allValidator)) { ValidationStep step = new ValidationStep(); step.setUserFullName(getOrganisationController().getUserDetail(allValidator).getDisplayedName()); steps.add(step); } } return steps; } public boolean isUserCanValidatePublication() { return getKmeliaService().isUserCanValidatePublication(getSessionPubliOrClone().getDetail().getPK(), getUserId()); } public ValidationStep getValidationStep() { if (getValidationType() == KmeliaHelper.VALIDATION_TARGET_N) { return getPublicationService().getValidationStepByUser(getSessionPubliOrClone().getDetail().getPK(), getUserId()); } return null; } public synchronized void draftOutPublication() { NodePK currentFolderPK = getCurrentFolderPK(); if (isKmaxMode) { currentFolderPK = null; } getKmeliaService().draftOutPublication(getSessionPublication().getDetail().getPK(), currentFolderPK, getProfile()); if (!KmeliaHelper.ROLE_WRITER.equals(getUserTopicProfile())) { // always reset clone setSessionClone(null); } refreshSessionPubliAndClone(); } /** * Change publication status from any state to draft * @since 3.0 */ public synchronized void draftInPublication() { if (isCloneNeededWithDraft()) { clonePublication(); } else { getKmeliaService().draftInPublication(getSessionPubliOrClone().getDetail().getPK(), getUserId()); } refreshSessionPubliAndClone(); } public boolean isIndexable(PublicationDetail pubDetail) { return KmeliaHelper.isIndexable(pubDetail); } /** * adds links between specified publication and other publications contained in links parameter * @param pubId publication which you want removes the external link * @param links list of links to remove * @return the number of links created */ public int addPublicationsToLink(String pubId, Set<String> links) { List<ResourceReference> infoLinks = new ArrayList<>(); for (String link : links) { StringTokenizer tokens = new StringTokenizer(link, "-"); infoLinks.add(new ResourceReference(tokens.nextToken(), tokens.nextToken())); } addInfoLinks(pubId, infoLinks); return infoLinks.size(); } /** * @param topicDetail the topic detail */ public void setSessionTopic(TopicDetail topicDetail) { this.sessionTopic = topicDetail; if (topicDetail != null) { setCurrentFolderId(topicDetail.getNodePK().getId(), true); Collection<KmeliaPublication> publications = topicDetail.getKmeliaPublications(); setSessionPublicationsList((List<KmeliaPublication>) publications); } } public void setSessionTopicToLink(TopicDetail topicDetail) { this.sessionTopicToLink = topicDetail; } public void setSessionPublication(KmeliaPublication pubDetail) { this.sessionPublication = pubDetail; setSessionClone(null); } public void setSessionClone(KmeliaPublication clone) { this.sessionClone = clone; } public void setSessionPath(String path) { this.sessionPath = path; } public void setSessionPathString(String path) { this.sessionPathString = path; } public void setSessionOwner(boolean owner) { this.sessionOwner = owner; } public void setSessionPublicationsList(List<KmeliaPublication> publications) { setSessionPublicationsList(publications, true); } private void setSessionPublicationsList(List<KmeliaPublication> publications, boolean sort) { cacheDirectlyPublicationsListInSession(publications == null ? null : new ArrayList<>(publications)); if (sort) { orderPubs(); } } private void cacheDirectlyPublicationsListInSession(final List<KmeliaPublication> publications) { getSessionCacheService().getCache().put(PUB_LIST_SESSION_CACHE_KEY, publications); } public void setSessionCombination(List<String> combination) { this.sessionCombination = (combination == null ? null : new ArrayList<>(combination)); } public void setSessionTimeCriteria(String timeCriteria) { this.sessionTimeCriteria = timeCriteria; } public String getSortValue() { return this.sortValue; } public void setSortValue(String sort) { if (isDefined(sort)) { this.sortValue = sort; } orderPubs(); } public TopicDetail getSessionTopic() { return this.sessionTopic; } public String getCurrentFolderId() { return currentFolderId; } public NodePK getCurrentFolderPK() { return new NodePK(getCurrentFolderId(), getComponentId()); } public NodeDetail getCurrentFolder() { return getNodeHeader(getCurrentFolderId()); } public void setCurrentFolderId(String id, boolean resetSessionPublication) { if (!id.equals(currentFolderId)) { indexOfFirstPubToDisplay = 0; resetSelectedPublicationPKs(); if (!KmeliaHelper.SPECIALFOLDER_TOVALIDATE.equalsIgnoreCase(id)) { Collection<NodeDetail> pathColl = getTopicPath(id); String linkedPathString = displayPath(pathColl, true, 3); String pathString = displayPath(pathColl, false, 3); setSessionPath(linkedPathString); setSessionPathString(pathString); } } if (resetSessionPublication) { setSessionPublication(null); } setSearchContext(null); currentFolderId = id; } public TopicDetail getSessionTopicToLink() { return this.sessionTopicToLink; } public KmeliaPublication getSessionPublication() { return this.sessionPublication; } public KmeliaPublication getSessionClone() { return this.sessionClone; } public KmeliaPublication getSessionPubliOrClone() { KmeliaPublication publication = getSessionClone(); if (publication == null) { publication = getSessionPublication(); } return publication; } public String getSessionPath() { return this.sessionPath; } public String getSessionPathString() { return this.sessionPathString; } public boolean getSessionOwner() { return this.sessionOwner; } @SuppressWarnings("unchecked") public List<KmeliaPublication> getSessionPublicationsList() { return (List) getSessionCacheService().getCache().get(PUB_LIST_SESSION_CACHE_KEY); } public List<String> getSessionCombination() { return this.sessionCombination; } public String getSessionTimeCriteria() { return this.sessionTimeCriteria; } private void removeSessionObjects() { setSessionTopic(null); setSessionTopicToLink(null); setSessionPublication(null); setSessionClone(null); setSessionPath(null); setSessionPathString(null); setSessionOwner(false); setSessionPublicationsList(null); } public String initUPToSelectValidator(String formElementName, String formElementId, String folderId) { String mContext = URLUtil.getApplicationURL(); Pair<String, String> hostComponentName = new Pair<>(getComponentLabel(), ""); Pair<String, String>[] hostPath = new Pair[1]; hostPath[0] = new Pair<>(getString("kmelia.SelectValidator"), ""); String hostUrl = mContext + URLUtil.getURL(USELESS, getComponentId()) + "SetValidator"; String cancelUrl = mContext + URLUtil.getURL(USELESS, getComponentId()) + "SetValidator"; Selection sel = getSelection(); sel.resetAll(); sel.setHostSpaceName(getSpaceLabel()); sel.setHostComponentName(hostComponentName); sel.setHostPath(hostPath); sel.setGoBackURL(hostUrl); sel.setCancelURL(cancelUrl); sel.setHtmlFormName("pubForm"); if (!StringUtil.isDefined(formElementName)) { formElementName = "Valideur"; } sel.setHtmlFormElementName(formElementName); if (!StringUtil.isDefined(formElementId)) { formElementId = "ValideurId"; } sel.setHtmlFormElementId(formElementId); sel.setMultiSelect(isTargetMultiValidationEnable()); sel.setPopupMode(true); sel.setSetSelectable(false); if (getSessionPubliOrClone() != null) { String[] userIds = getKmeliaService().getActiveValidatorIds(getSessionPubliOrClone().getPk()) .toArray(new String[0]); sel.setSelectedElements(userIds); } // Add extra params SelectionUsersGroups sug = new SelectionUsersGroups(); sug.setComponentId(getComponentId()); List<String> profiles = new ArrayList<>(); profiles.add(SilverpeasRole.publisher.toString()); profiles.add(SilverpeasRole.admin.toString()); NodeDetail node = getNodeHeader(getCurrentFolderId()); if (StringUtil.isDefined(folderId) && !getCurrentFolderId().equals(folderId)) { node = getNodeHeader(folderId); } boolean haveRights = isRightsOnTopicsEnabled() && node.haveRights(); if (haveRights) { sug.setObjectId(ObjectType.NODE.getCode() + node.getRightsDependsOn()); } sug.setProfileNames(profiles); sel.setExtraParams(sug); return Selection.getSelectionURL(); } public boolean isVersionControlled() { if (isPublicationAlwaysVisibleEnabled()) { // This mode is not compatible, for now, with the possibility to manage versioned // attachments. return false; } return StringUtil.getBooleanValue(getComponentParameterValue(VERSION_MODE)); } public boolean isVersionControlled(String anotherComponentId) { String strPublicationAlwaysVisible = getOrganisationController() .getComponentParameterValue(anotherComponentId, "publicationAlwaysVisible"); if (StringUtil.getBooleanValue(strPublicationAlwaysVisible)) { // This mode is not compatible, for now, with the possibility to manage versioned // attachments. return false; } String strVersionControlled = getOrganisationController().getComponentParameterValue(anotherComponentId, VERSION_MODE); return StringUtil.getBooleanValue(strVersionControlled); } public boolean isWriterApproval() { return false; } public boolean isTargetValidationEnable() { return String.valueOf(KmeliaHelper.VALIDATION_TARGET_1) .equalsIgnoreCase(getComponentParameterValue(InstanceParameters.validation)); } public boolean isTargetMultiValidationEnable() { return String.valueOf(KmeliaHelper.VALIDATION_TARGET_N) .equalsIgnoreCase(getComponentParameterValue(InstanceParameters.validation)); } public boolean isCollegiateValidationEnable() { return String.valueOf(KmeliaHelper.VALIDATION_COLLEGIATE) .equalsIgnoreCase(getComponentParameterValue(InstanceParameters.validation)); } public boolean isValidationTabVisible() { boolean tabVisible = PublicationDetail.TO_VALIDATE_STATUS .equalsIgnoreCase(getSessionPubliOrClone().getDetail().getStatus()); return tabVisible && (getValidationType() == KmeliaHelper.VALIDATION_COLLEGIATE || getValidationType() == KmeliaHelper.VALIDATION_TARGET_N); } public int getValidationType() { if (isTargetValidationEnable()) { return KmeliaHelper.VALIDATION_TARGET_1; } if (isTargetMultiValidationEnable()) { return KmeliaHelper.VALIDATION_TARGET_N; } if (isCollegiateValidationEnable()) { return KmeliaHelper.VALIDATION_COLLEGIATE; } return KmeliaHelper.VALIDATION_CLASSIC; } public boolean isCoWritingEnable() { return StringUtil.getBooleanValue(getComponentParameterValue(InstanceParameters.coWriting)); } public String[] getSelectedUsers() { return idSelectedUser; } public int getSilverObjectId(String objectId) { int silverObjectId = -1; try { silverObjectId = getKmeliaService().getSilverObjectId(getPublicationPK(objectId)); } catch (Exception e) { SilverLogger.getLogger(this).error(e.getMessage(), e); } return silverObjectId; } private boolean isPublicationClassifiedOnPDC(String pubId) { if (pubId != null && pubId.length() > 0) { try { int silverObjectId = getKmeliaService().getSilverObjectId(getPublicationPK(pubId)); List<ClassifyPosition> positions = getPdcManager().getPositions(silverObjectId, getComponentId()); return !positions.isEmpty(); } catch (Exception e) { throw new KmeliaRuntimeException(e); } } return false; } public boolean isCurrentPublicationHaveContent() { return (StringUtil.isDefined( WysiwygController.load(getComponentId(), getSessionPublication().getId(), getCurrentLanguage())) || !isInteger(getSessionPublication().getCompleteDetail().getPublicationDetail().getInfoId())); } public boolean isPDCClassifyingMandatory() { try { return getPdcManager().isClassifyingMandatory(getComponentId()); } catch (Exception e) { throw new KmeliaRuntimeException(e); } } /** * @return */ public PdcManager getPdcManager() { return ServiceProvider.getService(PdcManager.class); } public NodeService getNodeService() { return NodeService.get(); } public PublicationService getPublicationService() { return ServiceProvider.getService(PublicationService.class); } /** * @param fileUploaded : File uploaded in temp directory * @param importMode * @param draftMode * @param versionType * @return a report of the import * @throws ImportExportException */ public ImportReport importFile(File fileUploaded, String importMode, boolean draftMode, int versionType) throws ImportExportException { ImportReport importReport = null; FileImport fileImport = new FileImport(this, fileUploaded); boolean draft = draftMode; if (isDraftEnabled() && isPDCClassifyingMandatory()) { // classifying on PDC is mandatory, set publication in draft mode draft = true; } fileImport.setVersionType(versionType); if (UNITARY_IMPORT_MODE.equals(importMode)) { importReport = fileImport.importFile(draft); } else if (MASSIVE_IMPORT_MODE_ONE_PUBLICATION.equals(importMode) && FileUtil.isArchive(fileUploaded.getName())) { importReport = fileImport.importFiles(draft); } else if (MASSIVE_IMPORT_MODE_MULTI_PUBLICATIONS.equals(importMode) && FileUtil.isArchive(fileUploaded.getName())) { importReport = fileImport.importFilesMultiPubli(draft); } //print a log file of the report LocalizationBundle multilang = ResourceLocator .getLocalizationBundle("org.silverpeas.importExportPeas.multilang.importExportPeasBundle"); MultiSilverpeasBundle resource = new MultiSilverpeasBundle(multilang, "fr"); fileImport.writeImportToLog(importReport, resource); return importReport; } private PublicationPK getPublicationPK(String id) { return new PublicationPK(id, getSpaceId(), getComponentId()); } private NodePK getNodePK(String id) { return new NodePK(id, getSpaceId(), getComponentId()); } /** * Return if publication is deleted * @param pk publication identifier * @return true or false */ public boolean isPublicationDeleted(PublicationPK pk) { boolean isPublicationDeleted = false; try { Collection<Collection<NodeDetail>> pathList = getPathList(pk); if (pathList.size() == 1) { for (Collection<NodeDetail> path : pathList) { for (NodeDetail nodeInPath : path) { if (nodeInPath.getNodePK().isTrash()) { isPublicationDeleted = true; } } } } } catch (Exception e) { throw new KmeliaRuntimeException(e); } return isPublicationDeleted; } public void setModelUsed(String[] models) { String objectId = getCurrentFolderId(); getKmeliaService().setModelUsed(models, getComponentId(), objectId); } public List<String> getModelUsed() { List models = new ArrayList(); String formNameAppLevel = getXMLFormNameForPublications(); if (StringUtil.isDefined(formNameAppLevel)) { models.add(formNameAppLevel); } else { String objectId = getCurrentFolderId(); models.addAll(getKmeliaService().getModelUsed(getComponentId(), objectId)); } return models; } /** * Parameter for time Axis visibility * @return */ public boolean isTimeAxisUsed() { return StringUtil.getBooleanValue(getComponentParameterValue("timeAxisUsed")); } /** * Parameter for fields visibility of the publication * @return */ public boolean isFieldDescriptionVisible() { String paramValue = getComponentParameterValue("useDescription"); return "1".equalsIgnoreCase(paramValue) || "2".equalsIgnoreCase(paramValue) || "".equals(paramValue); } public boolean isFieldDescriptionMandatory() { return "2".equalsIgnoreCase(getComponentParameterValue("useDescription")); } public boolean isFieldKeywordsVisible() { String paramValue = getComponentParameterValue("useKeywords"); return StringUtil.getBooleanValue(paramValue) || "".equals(paramValue); } public boolean isFieldImportanceVisible() { if (isKmaxMode) { return StringUtil.getBooleanValue(getComponentParameterValue("useImportance")); } return getSettings().getBoolean("showImportance", true); } public boolean isFieldVersionVisible() { if (isKmaxMode) { return StringUtil.getBooleanValue(getComponentParameterValue("useVersion")); } return getSettings().getBoolean("showPubVersion", true); } public List<Integer> getTimeAxisKeys() { if (this.timeAxis == null) { LocalizationBundle timeSettings = ResourceLocator .getLocalizationBundle("org.silverpeas.kmelia.multilang.timeAxisBundle", getLanguage()); Enumeration<String> keys = timeSettings.getSpecificKeys(); List<Integer> orderKeys = new ArrayList<>(); while (keys.hasMoreElements()) { String keyStr = keys.nextElement(); Integer key = Integer.parseInt(keyStr); orderKeys.add(key); } Collections.sort(orderKeys); this.timeAxis = orderKeys; } return this.timeAxis; } public synchronized List<NodeDetail> getAxis() { return getKmeliaService().getAxis(getComponentId()); } public synchronized List<NodeDetail> getAxisHeaders() { return getKmeliaService().getAxisHeaders(getComponentId()); } public synchronized NodePK addAxis(NodeDetail axis) { return getKmeliaService().addAxis(axis, getComponentId()); } public synchronized NodeDetail getNodeHeader(String id) { return getKmeliaService().getNodeHeader(id, getComponentId()); } public synchronized void updateAxis(NodeDetail axis) { getKmeliaService().updateAxis(axis, getComponentId()); } public synchronized void deleteAxis(String axisId) { getKmeliaService().deleteAxis(axisId, getComponentId()); } public synchronized List<KmeliaPublication> search(List<String> combination) { cacheDirectlyPublicationsListInSession( new ArrayList<>(getKmeliaService().search(combination, getComponentId()))); applyVisibilityFilter(); return getSessionPublicationsList(); } public synchronized List<KmeliaPublication> search(List<String> combination, int nbDays) { cacheDirectlyPublicationsListInSession( new ArrayList<>(getKmeliaService().search(combination, nbDays, getComponentId()))); applyVisibilityFilter(); return getSessionPublicationsList(); } public synchronized List<KmeliaPublication> getUnbalancedPublications() { return (List<KmeliaPublication>) getKmeliaService().getUnbalancedPublications(getComponentId()); } public synchronized NodePK addPosition(String fatherId, NodeDetail position) { return getKmeliaService().addPosition(fatherId, position, getComponentId(), getUserId()); } public synchronized void updatePosition(NodeDetail position) { getKmeliaService().updatePosition(position, getComponentId()); } public synchronized void deletePosition(String positionId) { getKmeliaService().deletePosition(positionId, getComponentId()); } /* * /* Kmax - Publications */ /** * ********************************************************************************** */ public synchronized KmeliaPublication getKmaxCompletePublication(String pubId) { return getKmeliaService().getKmaxPublication(pubId, getUserId()); } public synchronized Collection<Coordinate> getPublicationCoordinates(String pubId) { return getKmeliaService().getPublicationCoordinates(pubId, getComponentId()); } public synchronized void addPublicationToCombination(String pubId, List<String> combination) { getKmeliaService().addPublicationToCombination(pubId, combination, getComponentId()); } public synchronized void deletePublicationFromCombination(String pubId, String combinationId) { getKmeliaService().deletePublicationFromCombination(pubId, combinationId, getComponentId()); } /** * Get session publications * @return List of WAAtributeValuePair (Id and InstanceId) */ public List<WAAttributeValuePair> getCurrentPublicationsList() { List<WAAttributeValuePair> currentPublications = new ArrayList<>(); Collection<KmeliaPublication> allPublications = getSessionPublicationsList(); for (KmeliaPublication aPubli : allPublications) { PublicationDetail pubDetail = aPubli.getDetail(); if (pubDetail.getStatus().equals(PublicationDetail.VALID_STATUS)) { currentPublications.add(new WAAttributeValuePair(pubDetail.getId(), pubDetail.getInstanceId())); } } return currentPublications; } public synchronized Collection<NodeDetail> getPath(String positionId) { return getKmeliaService().getPath(positionId, getComponentId()); } public void setCurrentCombination(List<String> combination) { this.currentCombination = new ArrayList<>(combination); } public List<String> getCurrentCombination() { return currentCombination; } /** * Transform combination axis from String /0/1037,/0/1038 in ArrayList /0/1037 then /0/1038 * etc... * @param axisValuesStr * @return Collection of combination */ private List<String> convertStringCombination2List(String axisValuesStr) { List<String> combination = new ArrayList<>(); StringTokenizer st = new StringTokenizer(axisValuesStr, ","); while (st.hasMoreTokens()) { String axisValue = st.nextToken(); combination.add(axisValue); } return combination; } /** * Get combination Axis (ie: /0/1037) * @param axisValuesStr * @return Collection of combination */ public List<String> getCombination(String axisValuesStr) { return convertStringCombination2List(axisValuesStr); } private String getNearPublication(int direction) { // rechercher le rang de la publication prcdente int rangNext = rang + direction; KmeliaPublication pub = getSessionPublicationsList().get(rangNext); String pubId = pub.getDetail().getId(); // on est sur la prcdente, mettre jour le rang avec la publication courante rang = rangNext; return pubId; } /** * getPrevious * @return previous publication id */ public String getPrevious() { return getNearPublication(-1); } /** * getNext * @return next publication id */ public String getNext() { return getNearPublication(1); } public int getRang() { return rang; } private boolean isDefined(String param) { return (param != null && param.length() > 0 && !"".equals(param) && !"null".equals(param)); } private synchronized boolean isDragAndDropEnableByUser() { return getPersonalization().isDragAndDropEnabled(); } public boolean isDragAndDropEnable() { return isDragAndDropEnableByUser && isMassiveDragAndDropAllowed(); } public String getCurrentLanguage() { return currentLanguage; } public void setCurrentLanguage(String currentLanguage) { this.currentLanguage = currentLanguage; } public String initUserPanelForTopicProfile(String role, String nodeId, String[] groupIds, String[] userIds) { String context = URLUtil.getApplicationURL(); Pair<String, String>[] hostPath = new Pair[1]; hostPath[0] = new Pair<>(getString("kmelia.SelectValidator"), ""); Selection sel = getSelection(); sel.resetAll(); sel.setHostSpaceName(getSpaceLabel()); sel.setHostComponentName(new Pair<>(getComponentLabel(), "")); sel.setHostPath(hostPath); String hostUrl = context + URLUtil.getURL(USELESS, getComponentId()) + "TopicProfileSetUsersAndGroups?Role=" + role + "&NodeId=" + nodeId; String cancelUrl = context + URLUtil.getURL(USELESS, getComponentId()) + "CloseWindow"; sel.setGoBackURL(hostUrl); sel.setCancelURL(cancelUrl); sel.setPopupMode(true); sel.setHtmlFormElementId("roleItems"); sel.setHtmlFormName("dummy"); List<ProfileInst> profiles = getAdmin().getProfilesByObject(nodeId, ObjectType.NODE.getCode(), getComponentId()); ProfileInst topicProfile = getProfile(profiles, role); SelectionUsersGroups sug = new SelectionUsersGroups(); sug.setComponentId(getComponentId()); sel.setExtraParams(sug); if (topicProfile != null) { sel.setSelectedElements(userIds); sel.setSelectedSets(groupIds); } return Selection.getSelectionURL(); } private void deleteTopicRoles(NodeDetail node) { if (node != null && node.haveLocalRights()) { List<ProfileInst> profiles = getTopicProfiles(node.getNodePK().getId()); if (profiles != null) { for (ProfileInst profile : profiles) { if (profile != null && StringUtil.isDefined(profile.getId())) { deleteTopicRole(profile.getId()); } } } } } private void deleteTopicRole(String profileId) { // Remove the profile getAdmin().deleteProfileInst(profileId); } public void updateTopicRole(String role, String nodeId, String[] groupIds, String[] userIds) { ProfileInst profile = getTopicProfile(role, nodeId); // Update the topic NodeDetail topic = getNodeHeader(nodeId); topic.setRightsDependsOnMe(); getNodeService().updateRightsDependency(topic); profile.removeAllGroups(); profile.removeAllUsers(); profile.setGroupsAndUsers(groupIds, userIds); if (StringUtil.isDefined(profile.getId())) { if (profile.isEmpty()) { deleteTopicRole(profile.getId()); } else { // Update the profile getAdmin().updateProfileInst(profile); } } else { profile.setObjectId(Integer.parseInt(nodeId)); profile.setObjectType(ObjectType.NODE.getCode()); profile.setComponentFatherId(getComponentId()); // Create the profile getAdmin().addProfileInst(profile); } } public ProfileInst getTopicProfile(String role, String topicId) { List<ProfileInst> profiles = getAdmin().getProfilesByObject(topicId, ObjectType.NODE.getCode(), getComponentId()); for (ProfileInst profile : profiles) { if (profile.getName().equals(role)) { return profile; } } ProfileInst profile = new ProfileInst(); profile.setName(role); return profile; } public ProfileInst getTopicProfile(String role) { return getTopicProfile(role, getCurrentFolderId()); } public ProfileInst getProfile(String role) { ComponentInst componentInst = getAdmin().getComponentInst(getComponentId()); ProfileInst profile = componentInst.getProfileInst(role); ProfileInst inheritedProfile = componentInst.getInheritedProfileInst(role); if (profile == null && inheritedProfile == null) { profile = new ProfileInst(); profile.setName(role); return profile; } else if (profile != null && inheritedProfile == null) { return profile; } else if (profile == null) { return inheritedProfile; } else { // merge des profiles ProfileInst newProfile = (ProfileInst) profile.clone(); newProfile.setObjectFatherId(profile.getObjectFatherId()); newProfile.setObjectType(profile.getObjectType()); newProfile.setInherited(profile.isInherited()); newProfile.addGroups(inheritedProfile.getAllGroups()); newProfile.addUsers(inheritedProfile.getAllUsers()); return newProfile; } } public List<ProfileInst> getTopicProfiles() { return getTopicProfiles(getCurrentFolderId()); } public List<ProfileInst> getTopicProfiles(String topicId) { List<ProfileInst> alShowProfile = new ArrayList<>(); String[] asAvailProfileNames = getAdmin().getAllProfilesNames(KMELIA); for (String asAvailProfileName : asAvailProfileNames) { ProfileInst profile = getTopicProfile(asAvailProfileName, topicId); profile.setLabel(getAdmin().getProfileLabelfromName(KMELIA, asAvailProfileName, getLanguage())); alShowProfile.add(profile); } return alShowProfile; } public List<Group> groupIds2Groups(List<String> groupIds) { List<Group> res = new ArrayList<>(); for (int nI = 0; groupIds != null && nI < groupIds.size(); nI++) { Group theGroup = getAdmin().getGroupById(groupIds.get(nI)); if (theGroup != null) { res.add(theGroup); } } return res; } public List<UserDetail> userIds2Users(List<String> userIds) { List<UserDetail> res = new ArrayList<>(); if (userIds != null) { for (String userId : userIds) { UserDetail user = UserDetail.getById(userId); if (user != null) { res.add(user); } } } return res; } private AdminController getAdmin() { return ServiceProvider.getService(AdminController.class); } private ProfileInst getProfile(List<ProfileInst> profiles, String role) { for (ProfileInst profile : profiles) { if (role.equals(profile.getName())) { return profile; } } return null; } public boolean isUserCanValidate() { return getKmeliaService().isUserCanValidate(getComponentId(), getUserId()); } public boolean isUserCanWrite() { return getKmeliaService().isUserCanWrite(getComponentId(), getUserId()); } public void copyPublication(String pubId) throws ClipboardException { PublicationDetail pub = getPublicationDetail(pubId); // Can only copy user accessed publication PublicationAccessController publicationAccessController = ServiceProvider .getService(PublicationAccessController.class); if (publicationAccessController.isUserAuthorized(getUserId(), pub.getPK())) { PublicationSelection pubSelect = new PublicationSelection(pub); addClipboardSelection(pubSelect); } else { SilverLogger.getLogger(this).warn("Security alert from user {0} trying to copy publication {1}", getUserId(), pubId); throw new ClipboardException("Security purpose, access to publication is forbidden"); } } private void copyPublications(List<PublicationPK> pubPKs) throws ClipboardException { for (PublicationPK pubPK : pubPKs) { if (pubPK != null) { copyPublication(pubPK.getId()); } } } public void copySelectedPublications() throws ClipboardException { copyPublications(getSelectedPublicationPKs()); } public void cutPublication(String pubId) throws ClipboardException { PublicationDetail pub = getPublicationDetail(pubId); // Can only copy user accessed publication PublicationAccessController publicationAccessController = ServiceProvider .getService(PublicationAccessController.class); if (publicationAccessController.isUserAuthorized(getUserId(), pub.getPK())) { PublicationSelection pubSelect = new PublicationSelection(pub); pubSelect.setCutted(true); addClipboardSelection(pubSelect); } else { SilverLogger.getLogger(this).warn("Security alert from user {0} trying to cut publication {1}", getUserId(), pubId); throw new ClipboardException("Security purpose, access to publication is forbidden"); } } private void cutPublications(List<PublicationPK> pubPKs) throws ClipboardException { for (PublicationPK pubPK : pubPKs) { if (pubPK != null && pubPK.getInstanceId().equals(getComponentId())) { cutPublication(pubPK.getId()); } } } public void cutSelectedPublications() throws ClipboardException { cutPublications(getSelectedPublicationPKs()); } public void copyTopic(String id) throws ClipboardException { NodeDetail nodeDetail = getNodeHeader(id); NodeAccessController nodeAccessController = ServiceProvider.getService(NodeAccessController.class); if (nodeAccessController.isUserAuthorized(getUserId(), nodeDetail.getNodePK())) { NodeSelection nodeSelect = new NodeSelection(getNodeHeader(id)); addClipboardSelection(nodeSelect); } else { SilverLogger.getLogger(this).warn("Security alert from user {0} trying to copy topic {1}", getUserId(), id); throw new ClipboardException("Security purpose : access to node is forbidden"); } } public void cutTopic(String id) throws ClipboardException { NodeDetail nodeDetail = getNodeHeader(id); NodeAccessController nodeAccessController = ServiceProvider.getService(NodeAccessController.class); if (nodeAccessController.isUserAuthorized(getUserId(), nodeDetail.getNodePK())) { NodeSelection nodeSelect = new NodeSelection(getNodeHeader(id)); nodeSelect.setCutted(true); addClipboardSelection(nodeSelect); } else { SilverLogger.getLogger(this).warn("Security alert from user {0} trying to cut topic {1}", getUserId(), id); throw new ClipboardException("Security purpose : access to node is forbidden"); } } public List<Object> paste(KmeliaPasteDetail pasteDetail) throws ClipboardException { resetSelectedPublicationPKs(); pasteDetail.setUserId(getUserId()); List<Object> pastedItems = new ArrayList<>(); try { Collection<ClipboardSelection> selectedObjects = getClipboardSelectedObjects(); for (ClipboardSelection selection : selectedObjects) { if (selection == null) { continue; } Object pastedItem = pasteClipboardSelection(selection, pasteDetail); if (pastedItem != null) { pastedItems.add(pastedItem); } } } catch (ClipboardException | UnsupportedFlavorException e) { throw new KmeliaRuntimeException(e); } clipboardPasteDone(); return pastedItems; } private Object pasteClipboardSelection(ClipboardSelection selection, KmeliaPasteDetail pasteDetail) throws UnsupportedFlavorException { NodeDetail folder = getNodeHeader(pasteDetail.getToPK().getId()); if (selection.isDataFlavorSupported(PublicationSelection.PublicationDetailFlavor)) { PublicationDetail pub = (PublicationDetail) selection .getTransferData(PublicationSelection.PublicationDetailFlavor); if (selection.isCutted()) { movePublication(pub.getPK(), folder.getNodePK(), pasteDetail); } else { KmeliaCopyDetail copyDetail = KmeliaCopyDetail.fromPasteDetail(pasteDetail); getKmeliaService().copyPublication(pub, copyDetail); } return pub; } else if (selection.isDataFlavorSupported(NodeSelection.NodeDetailFlavor)) { NodeDetail node = (NodeDetail) selection.getTransferData(NodeSelection.NodeDetailFlavor); // check if current topic is a subTopic of node boolean pasteAllowed = !node.equals(folder) && !node.isFatherOf(folder); if (pasteAllowed) { if (selection.isCutted()) { // move node getKmeliaService().moveNode(node.getNodePK(), folder.getNodePK(), pasteDetail); } else { // copy node KmeliaCopyDetail copyDetail = KmeliaCopyDetail.fromPasteDetail(pasteDetail); copyDetail.setFromNodePK(node.getNodePK()); getKmeliaService().copyNode(copyDetail); } return node; } } return null; } public CLIPBOARD_STATE getClipboardState() { try { final Set<CLIPBOARD_STATE> states = getClipboardSelectedObjects().stream().filter(Objects::nonNull) .filter(c -> c.isDataFlavorSupported(PublicationSelection.PublicationDetailFlavor) || c.isDataFlavorSupported(NodeSelection.NodeDetailFlavor)) .map(c -> c.isCutted() ? HAS_CUTS : HAS_COPIES).collect(Collectors.toSet()); final CLIPBOARD_STATE state; if (states.size() == 1) { state = states.iterator().next(); } else if (states.size() > 1) { state = HAS_COPIES_AND_CUTS; } else { state = IS_EMPTY; } return state; } catch (ClipboardException e) { throw new KmeliaRuntimeException(e); } } private void movePublication(PublicationPK pubPK, NodePK nodePK, KmeliaPasteDetail pasteContext) { try { NodePK currentNodePK = nodePK; if (currentNodePK == null) { // Ajoute au thme courant currentNodePK = getCurrentFolderPK(); } getKmeliaService().movePublication(pubPK, currentNodePK, pasteContext); } catch (Exception ex) { SilverLogger.getLogger(this).error(ex.getMessage(), ex); } } /** * get languages of publication header and attachments * @return a List of String (language codes) */ public List<String> getPublicationLanguages() { List<String> languages = new ArrayList<>(); PublicationDetail pubDetail = getSessionPubliOrClone().getDetail(); // get publicationdetail languages Collection<String> pubLanguages = pubDetail.getLanguages(); for (String language : pubLanguages) { languages.add(language); } if (languages.size() == I18NHelper.getNumberOfLanguages()) { // Publication is translated in all supported languages return languages; } else { // get attachments languages List<String> attLanguages = getAttachmentLanguages(); for (String language : attLanguages) { if (!languages.contains(language)) { languages.add(language); } } } return languages; } public List<String> getAttachmentLanguages() { PublicationPK pubPK = getSessionPubliOrClone().getDetail().getPK(); // get attachments languages List<String> languages = new ArrayList<>(); List<String> attLanguages = getLanguagesOfAttachments( new ResourceReference(pubPK.getId(), pubPK.getInstanceId())); for (String language : attLanguages) { if (!languages.contains(language)) { languages.add(language); } } return languages; } public void setAliases(List<Alias> aliases) { getKmeliaService().setAlias(getSessionPublication().getDetail().getPK(), aliases); } public void setAliases(PublicationPK pubPK, List<Alias> aliases) { getKmeliaService().setAlias(pubPK, aliases); } public List<Alias> getAliases() { List<Alias> aliases = (List<Alias>) getKmeliaService() .getAlias(getSessionPublication().getDetail().getPK()); // add user's displayed name for (Alias object : aliases) { if (StringUtil.isDefined(object.getUserId())) { object.setUserName(getUserDetail(object.getUserId()).getDisplayedName()); } } return aliases; } /** * @return a List of Treeview */ public List<Treeview> getComponents(List<Alias> aliases) { List<Treeview> result = new ArrayList<>(); List<NodeDetail> tree = null; NodePK root = new NodePK(NodePK.ROOT_NODE_ID); List<SpaceInstLight> spaces = getOrganisationController().getSpaceTreeview(getUserId()); for (SpaceInstLight space : spaces) { StringBuilder path = new StringBuilder(); String[] componentIds = getOrganisationController().getAvailCompoIdsAtRoot(space.getId(), getUserId()); for (String componentId : componentIds) { String instanceId = componentId; if (instanceId.startsWith(KMELIA) && (getKmeliaService().isUserCanPublish(instanceId, getUserId()) || instanceId.equals(getComponentId()))) { tree = initTreeView(aliases, result, tree, root, space, path, instanceId); } } } return result; } private List<NodeDetail> initTreeView(final List<Alias> aliases, final List<Treeview> result, List<NodeDetail> tree, final NodePK root, final SpaceInstLight space, final StringBuilder path, final String instanceId) { root.setComponentName(instanceId); if (instanceId.equals(getComponentId())) { tree = getKmeliaService().getTreeview(root, null, false, false, getUserId(), false, isRightsOnTopicsEnabled()); } if (path.length() == 0) { List<SpaceInstLight> sPath = getOrganisationController().getPathToSpace(space.getId()); boolean first = true; for (SpaceInstLight spaceInPath : sPath) { if (!first) { path.append(" > "); } path.append(spaceInPath.getName()); first = false; } } Treeview treeview = new Treeview( path.toString() + " > " + getOrganisationController().getComponentInstLight(instanceId).getLabel(), tree, instanceId); treeview.setNbAliases(getNbAliasesInComponent(aliases, instanceId)); if (instanceId.equals(getComponentId())) { result.add(0, treeview); } else { result.add(treeview); } return tree; } public List<NodeDetail> getAliasTreeview() { return getAliasTreeview(getComponentId()); } public List<NodeDetail> getAliasTreeview(String instanceId) { List<NodeDetail> tree = null; if (getKmeliaService().isUserCanPublish(instanceId, getUserId())) { NodePK root = new NodePK(NodePK.ROOT_NODE_ID, instanceId); tree = getKmeliaService().getTreeview(root, null, false, false, getUserId(), false, isRightsOnTopicsEnabled(instanceId)); } return tree; } private int getNbAliasesInComponent(List<Alias> aliases, String instanceId) { int nb = 0; for (Alias alias : aliases) { if (alias.getInstanceId().equals(instanceId)) { nb++; } } return nb; } private boolean isToolbox() { return KmeliaHelper.isToolbox(getComponentId()); } /** * Returns URL of single attached file for the current publication. * If publication contains more than one file, null is returned * * @return URL of single attached file for the current publication. Null if publication * contains more than one file. */ public String getSingleAttachmentURLOfCurrentPublication(boolean alias) { PublicationPK pubPK = getSessionPublication().getDetail().getPK(); List<SimpleDocument> attachments = AttachmentServiceProvider.getAttachmentService() .listDocumentsByForeignKey(pubPK.toResourceReference(), getLanguage()); if (attachments.size() == 1) { SimpleDocument document = attachments.get(0); return getDocumentVersionURL(document, alias); } return null; } /** * Return the url to access the file * @param fileId the id of the file (attachment or document id). * @return the url to the file. */ public String getAttachmentURL(String fileId, boolean alias) { SimpleDocument attachment = AttachmentServiceProvider.getAttachmentService() .searchDocumentById(new SimpleDocumentPK(fileId), getLanguage()); return getDocumentVersionURL(attachment, alias); } /** * Returns URL of the right version of the given document according to current folder rights * if user is a reader, returns last public version (null if it does not exist) * if user is not a reader, returns last version (public or working one) * @param document * @return the URL of right version or null */ private String getDocumentVersionURL(SimpleDocument document, boolean alias) { SimpleDocument version = document.getLastPublicVersion(); if (document.getVersionMaster().canBeAccessedBy(getUserDetail())) { version = document.getVersionMaster(); } if (version != null) { if (alias) { return version.getAliasURL(); } return URLUtil.getApplicationURL() + version.getAttachmentURL(); } return null; } public synchronized List<NodeDetail> getSubTopics(String rootId) { return getNodeService().getSubTree(getNodePK(rootId)); } public String getXmlFormForFiles() { return getComponentParameterValue("XmlFormForFiles"); } public File exportPublication() { if (!isFormatSupported("zip")) { throw new KmeliaRuntimeException("Export format not yet supported"); } PublicationPK pubPK = getSessionPublication().getDetail().getPK(); File pdf = null; try { // create subdir to zip String subdir = "ExportPubli_" + pubPK.getId() + "_" + System.currentTimeMillis(); String fileName = getPublicationExportFileName(getSessionPublication(), getLanguage()); String subDirPath = FileRepositoryManager.getTemporaryPath() + subdir + File.separator + fileName; FileFolderManager.createFolder(subDirPath); // generate from the publication a document in PDF if (isFormatSupported(DocumentFormat.pdf.name())) { pdf = generateDocument(DocumentFormat.pdf, pubPK.getId()); // copy pdf into zip FileRepositoryManager.copyFile(pdf.getPath(), subDirPath + File.separator + pdf.getName()); } // copy files new AttachmentImportExport(getUserDetail()).getAttachments(pubPK.toResourceReference(), subDirPath, USELESS, null); String zipFileName = FileRepositoryManager.getTemporaryPath() + fileName + ".zip"; // zip PDF and files ZipUtil.compressPathToZip(subDirPath, zipFileName); return new File(zipFileName); } catch (Exception e) { throw new KmeliaRuntimeException(e); } finally { if (pdf != null) { try { Files.delete(pdf.toPath()); } catch (IOException e) { SilverLogger.getLogger(this).warn(e); } } } } public boolean isNotificationAllowed() { String parameterValue = getComponentParameterValue("notifications"); if (!StringUtil.isDefined(parameterValue)) { return true; } return StringUtil.getBooleanValue(parameterValue); } public boolean isWysiwygOnTopicsEnabled() { return StringUtil.getBooleanValue(getComponentParameterValue("wysiwygOnTopics")); } public String getWysiwygOnTopic(String id) { String currentId = id; if (isWysiwygOnTopicsEnabled()) { if (!StringUtil.isDefined(currentId)) { currentId = getCurrentFolderId(); } return WysiwygController.load(getComponentId(), "Node_" + currentId, getCurrentLanguage()); } return ""; } public String getWysiwygOnTopic() { return getWysiwygOnTopic(null); } public List<NodeDetail> getTopicPath(String topicId) { try { List<NodeDetail> pathInReverse = getNodeService().getPath(new NodePK(topicId, getComponentId())); Collections.reverse(pathInReverse); return pathInReverse; } catch (Exception e) { throw new KmeliaRuntimeException(e); } } public ThumbnailSettings getThumbnailSettings() { int width = getSettings().getInteger("vignetteWidth", -1); int height = getSettings().getInteger("vignetteHeight", -1); return ThumbnailSettings.getInstance(getComponentId(), width, height); } /** * return the value of component parameter "axisIdGlossary". This paramater indicate the axis of * pdc to use to highlight word in publication content * @return an indentifier of Pdc axis */ public String getAxisIdGlossary() { return getComponentParameterValue("axisIdGlossary"); } public String getRole() { return getProfile(); } public String displayPath(Collection<NodeDetail> path, boolean linked, int beforeAfter) { StringBuilder linkedPathString = new StringBuilder(); StringBuilder pathString = new StringBuilder(); int nbItemInPath = path.size(); Iterator<NodeDetail> iterator = path.iterator(); boolean alreadyCut = false; int i = 0; while (iterator.hasNext()) { NodeDetail nodeInPath = iterator.next(); if ((i <= beforeAfter) || (i + beforeAfter >= nbItemInPath - 1)) { if (!nodeInPath.getNodePK().isRoot()) { setPathNode(linkedPathString, pathString, iterator, nodeInPath); } } else { if (!alreadyCut) { linkedPathString.append(" ... > "); pathString.append(" ... > "); alreadyCut = true; } } i++; } if (linked) { return linkedPathString.toString(); } else { return pathString.toString(); } } private void setPathNode(final StringBuilder linkedPathString, final StringBuilder pathString, final Iterator<NodeDetail> iterator, final NodeDetail nodeInPath) { String nodeName; if (nodeInPath.getNodePK().isTrash()) { nodeName = getString("kmelia.basket"); } else { if (getCurrentLanguage() != null) { nodeName = nodeInPath.getName(getCurrentLanguage()); } else { nodeName = nodeInPath.getName(); } } linkedPathString.append("<a href=\"javascript:onClick=topicGoTo('").append(nodeInPath.getNodePK().getId()) .append("')\">").append(Encode.forHtml(nodeName)).append("</a>"); pathString.append(nodeName); if (iterator.hasNext()) { linkedPathString.append(" > "); pathString.append(" > "); } } /** * Is search in topics enabled * @return boolean */ public boolean isSearchOnTopicsEnabled() { return StringUtil.getBooleanValue(getComponentParameterValue("searchOnTopics").toLowerCase()); } public boolean isAttachmentsEnabled() { return StringUtil.getBooleanValue(getComponentParameterValue("tabAttachments")); } /** * Get publications and aliases of this topic and its subtopics answering to the query * @param query the query * @return List of Kmelia publications */ public synchronized List<KmeliaPublication> search(String query) { SearchContext previousSearch = getSearchContext(); boolean newSearch = previousSearch == null || !previousSearch.getQuery().equalsIgnoreCase(query); if (!newSearch) { // process cached results return getSessionPublicationsList(); } // Insert this new search inside persistence layer in order to compute statistics TopicSearch newTS = new TopicSearch(getComponentId(), Integer.parseInt(getCurrentFolderId()), Integer.parseInt(getUserId()), getLanguage(), query.toLowerCase(), new Date()); KmeliaSearchServiceProvider.getTopicSearchService().createTopicSearch(newTS); List<KmeliaPublication> userPublications = new ArrayList<>(); QueryDescription queryDescription = new QueryDescription(query); queryDescription.setSearchingUser(getUserId()); queryDescription.setRequestedFolder(getCurrentFolder().getFullPath()); queryDescription.addComponent(getComponentId()); try { List<MatchingIndexEntry> results = SearchEngineProvider.getSearchEngine().search(queryDescription) .getEntries(); List<String> pubIds = new ArrayList<>(); KmeliaAuthorization security = new KmeliaAuthorization(); security.enableCache(); for (MatchingIndexEntry result : results) { if (PUBLICATION.equals(result.getObjectType()) && security.isObjectAvailable(getComponentId(), getUserId(), result.getObjectId(), PUBLICATION)) { // Add the publications // return publication if user can consult it only (check rights on folder) pubIds.add(result.getObjectId()); } } for (String pubId : pubIds) { KmeliaPublication publication = KmeliaPublication .aKmeliaPublicationFromDetail(getPublicationDetail(pubId)); userPublications.add(publication); } } catch (Exception pe) { throw new KmeliaRuntimeException(pe); } // store "in session" current search context SearchContext aSearchContext = new SearchContext(query); setSearchContext(aSearchContext); // store results and keep search results order setSessionPublicationsList(userPublications, false); return userPublications; } /** * @return the list of SpaceInst from current space identifier (in session) to root space <br> * (all the subspace) */ public List<SpaceInstLight> getSpacePath() { return this.getOrganisationController().getPathToSpace(this.getSpaceId()); } /** * Gets an instance of PublicationTemplateManager. * @return an instance of PublicationTemplateManager. */ private PublicationTemplateManager getPublicationTemplateManager() { return PublicationTemplateManager.getInstance(); } public List<PublicationTemplate> getForms() { List<PublicationTemplate> templates = new ArrayList<>(); try { GlobalContext aContext = new GlobalContext(getSpaceId(), getComponentId()); templates = getPublicationTemplateManager().getPublicationTemplates(aContext); } catch (PublicationTemplateException e) { SilverLogger.getLogger(this).error(e.getMessage(), e); } return templates; } @Override public String getPublicationExportFileName(KmeliaPublication publication, String language) { String lang = getLanguage(); StringBuilder fileName = new StringBuilder(250); fileName.append(getUserDetail().getLogin()).append('-'); // add space path to filename List<SpaceInstLight> listSpaces = getSpacePath(); for (SpaceInstLight space : listSpaces) { fileName.append(space.getName(lang)).append('-'); } // add component name to filename fileName.append(getComponentLabel()); if (!isKmaxMode) { List<NodeDetail> path = getNodeService().getPath(getCurrentFolder().getNodePK()); Collections.reverse(path); path.remove(0); // remove root folder for (NodeDetail node : path) { fileName.append('-').append(node.getName(lang)); } } fileName.append('-').append(publication.getDetail().getTitle()).append('-'); fileName.append(publication.getPk().getId()); return StringUtil.toAcceptableFilename(fileName.toString()); } public void removePublicationContent() { KmeliaPublication publication = getSessionPubliOrClone(); PublicationPK pubPK = publication.getPk(); getKmeliaService().removeContentOfPublication(pubPK); // reset reference to content publication.getDetail().setInfoId("0"); } public boolean isComponentManageable() { return componentManageable; } /** * Gets all available export formats. * @return a list of export formats Silverpeas supports for export. */ public List<String> getAvailableFormats() { return Arrays.asList(AVAILABLE_EXPORT_FORMATS); } /** * Gets the export formats that are supported by the current Kmelia component instance. As some * of * the export formats can be deactivated in the Kmelia settings file, this method returns all the * formats that are currently active. * @return a list of export formats. */ public List<String> getSupportedFormats() { String exportFormats = getSettings().getString(EXPORT_FORMATS, ""); List<String> supportedFormats = new ArrayList<>(); if (!exportFormats.trim().isEmpty()) { List<String> availableFormats = getAvailableFormats(); for (String exportFormat : exportFormats.trim().split(" ")) { if (!availableFormats.contains(exportFormat)) { throw new KmeliaRuntimeException("Unknown format " + exportFormat); } supportedFormats.add(exportFormat); } } return supportedFormats; } /** * Is the specified export format is supported by the Kmelia component instance? * @param format a recognized export format. * @return true if the specified format is currently supported for the publication export, false * otherwise. */ public boolean isFormatSupported(String format) { return getSupportedFormats().contains(format); } /** * Is the specified publication classified on the PdC. * @param publication a publication; * @return true if the publication is classified, false otherwise. * @throws PdcException if an error occurs while verifying the publication is classified. */ public boolean isClassifiedOnThePdC(final PublicationDetail publication) throws PdcException { List<ClassifyPosition> positions = getPdcManager().getPositions( Integer.valueOf(publication.getSilverObjectId()), publication.getComponentInstanceId()); return !positions.isEmpty(); } /** * Is the default classification on the PdC used to classify the publications published in the * specified topic of the specified component instance can be modified during the * multi-publications import process? If no default classification is defined for the specified * topic (and for any of its parent topics), then false is returned. * @param topicId the unique identifier of the topic. * @param componentId the unique identifier of the component instance. * @return true if the default classification can be modified during the automatical * classification of the imported publications. False otherwise. */ public boolean isDefaultClassificationModifiable(String topicId, String componentId) { PdcClassificationService classificationService = PdcClassificationService.get(); PdcClassification defaultClassification = classificationService.findAPreDefinedClassification(topicId, componentId); return defaultClassification != NONE_CLASSIFICATION && defaultClassification.isModifiable(); } public void resetSelectedPublicationPKs() { this.selectedPublicationPKs.clear(); } public List<PublicationPK> processSelectedPublicationIds(String selectedPublicationIds, String notSelectedPublicationIds) { StringTokenizer tokenizer; if (selectedPublicationIds != null) { tokenizer = new StringTokenizer(selectedPublicationIds, ","); while (tokenizer.hasMoreTokens()) { String[] str = StringUtil.splitByWholeSeparator(tokenizer.nextToken(), "-"); PublicationPK pk = new PublicationPK(str[0], str[1]); PublicationAccessController publicationAccessController = ServiceProvider .getService(PublicationAccessController.class); if (publicationAccessController.isUserAuthorized(getUserId(), pk, AccessControlContext.init())) { this.selectedPublicationPKs.add(pk); } } } if (notSelectedPublicationIds != null) { tokenizer = new StringTokenizer(notSelectedPublicationIds, ","); while (tokenizer.hasMoreTokens()) { String[] str = StringUtil.splitByWholeSeparator(tokenizer.nextToken(), "-"); PublicationPK pk = new PublicationPK(str[0], str[1]); this.selectedPublicationPKs.remove(pk); } } return this.selectedPublicationPKs; } public List<PublicationPK> getSelectedPublicationPKs() { return selectedPublicationPKs; } public boolean isCustomPublicationTemplateUsed() { return customPublicationTemplateUsed; } public String getCustomPublicationTemplateName() { return customPublicationTemplateName; } public List<KmeliaPublication> getLatestPublications() { List<KmeliaPublication> publicationsToDisplay = new ArrayList<>(); List<KmeliaPublication> toCheck = getKmeliaService().getLatestPublications(getComponentId(), getNbPublicationsOnRoot(), isRightsOnTopicsEnabled(), getUserId()); for (KmeliaPublication aPublication : toCheck) { if (!isPublicationDeleted(aPublication.getPk())) { publicationsToDisplay.add(aPublication); } } return publicationsToDisplay; } public List<KmeliaPublication> getPublicationsOfCurrentFolder() { List<KmeliaPublication> publications; if (!KmeliaHelper.SPECIALFOLDER_TOVALIDATE.equalsIgnoreCase(currentFolderId)) { publications = getKmeliaService().getPublicationsOfFolder(new NodePK(currentFolderId, getComponentId()), getUserTopicProfile(currentFolderId), getUserId(), isTreeStructure(), isRightsOnTopicsEnabled()); } else { publications = getKmeliaService().getPublicationsToValidate(getComponentId(), getUserId()); } setSessionPublicationsList(publications); applyVisibilityFilter(); return getSessionPublicationsList(); } public String getContentLanguage() { if (getPublicationLanguages().contains(getCurrentLanguage())) { return getCurrentLanguage(); } return I18NHelper.checkLanguage(getSessionPublication().getDetail().getLanguage()); } private void setSearchContext(SearchContext searchContext) { this.searchContext = searchContext; } public SearchContext getSearchContext() { return searchContext; } public String manageSubscriptions() { SubscriptionContext subscriptionContext = getSubscriptionContext(); List<NodeDetail> nodePath = getTopicPath(getCurrentFolderId()); nodePath.remove(0); subscriptionContext.initializeFromNode(NodeSubscriptionResource.from(getCurrentFolderPK()), nodePath); return subscriptionContext.getDestinationUrl(); } /** * @param importReport * @return the number of publications created */ public int getNbPublicationImported(ImportReport importReport) { int nbPublication = 0; List<ComponentReport> listComponentReport = importReport.getListComponentReport(); for (ComponentReport componentRpt : listComponentReport) { nbPublication += componentRpt.getNbPublicationsCreated(); } return nbPublication; } /** * @param importReport * @param importMode * @return an error message or null */ public String getErrorMessageImportation(ImportReport importReport, String importMode) { String message = null; LocalizationBundle attachmentResourceLocator = ResourceLocator .getLocalizationBundle("org.silverpeas.util.attachment.multilang.attachment", this.getLanguage()); ComponentReport componentRpt = importReport.getListComponentReport().get(0); if (UNITARY_IMPORT_MODE.equals(importMode)) { //Unitary mode message = getReportOnOnePublicationImport(attachmentResourceLocator, componentRpt); } else if (MASSIVE_IMPORT_MODE_ONE_PUBLICATION.equals(importMode)) { //Massive mode, one publication message = getReportOnOnePublicationImport(attachmentResourceLocator, componentRpt); } else if (MASSIVE_IMPORT_MODE_MULTI_PUBLICATIONS.equals(importMode)) { //Massive mode, several publications message = getReportOnSeveralPublicationImport(message, attachmentResourceLocator, componentRpt); } return message; } private String getReportOnSeveralPublicationImport(String message, final LocalizationBundle attachmentResourceLocator, final ComponentReport componentRpt) { MassiveReport massiveReport = componentRpt.getListMassiveReports().get(0); for (UnitReport unitReport : massiveReport.getListUnitReports()) { if (unitReport.getError() == UnitReport.ERROR_FILE_SIZE_EXCEEDS_LIMIT) { message = getMaxSizeErrorMessage(attachmentResourceLocator); } else if (unitReport.getError() != UnitReport.ERROR_NO_ERROR) { message = attachmentResourceLocator.getString(INACCESSIBLE_ATTACHMENT); break; } } return message; } private String getReportOnOnePublicationImport(final LocalizationBundle attachmentResourceLocator, final ComponentReport componentRpt) { final String message; MassiveReport massiveReport = componentRpt.getListMassiveReports().get(0); UnitReport unitReport = massiveReport.getListUnitReports().get(0); if (unitReport.getError() == UnitReport.ERROR_NO_ERROR) { return null; } else if (unitReport.getError() == UnitReport.ERROR_FILE_SIZE_EXCEEDS_LIMIT) { message = getMaxSizeErrorMessage(attachmentResourceLocator); } else { message = attachmentResourceLocator.getString(INACCESSIBLE_ATTACHMENT); } return message; } /** * @param importReport * @param importMode * @return a list of publication */ public List<PublicationDetail> getListPublicationImported(ImportReport importReport, String importMode) { List<PublicationDetail> listPublicationDetail = new ArrayList<>(); ComponentReport componentRpt = importReport.getListComponentReport().get(0); //Unitary mode if (UNITARY_IMPORT_MODE.equals(importMode)) { MassiveReport massiveReport = componentRpt.getListMassiveReports().get(0); UnitReport unitReport = massiveReport.getListUnitReports().get(0); if (unitReport.getStatus() == UnitReport.STATUS_PUBLICATION_CREATED) { String idPubli = unitReport.getLabel(); PublicationDetail publicationDetail = this.getPublicationDetail(idPubli); listPublicationDetail.add(publicationDetail); } } //Massive mode, one publication else if (MASSIVE_IMPORT_MODE_ONE_PUBLICATION.equals(importMode)) { UnitReport unitReport = componentRpt.getListUnitReports().get(0); if (unitReport.getStatus() == UnitReport.STATUS_PUBLICATION_CREATED) { String idPubli = unitReport.getLabel(); PublicationDetail publicationDetail = this.getPublicationDetail(idPubli); listPublicationDetail.add(publicationDetail); } //Massive mode, several publications } else if (MASSIVE_IMPORT_MODE_MULTI_PUBLICATIONS.equals(importMode)) { MassiveReport massiveReport = componentRpt.getListMassiveReports().get(0); for (UnitReport unitReport : massiveReport.getListUnitReports()) { if (unitReport.getStatus() == UnitReport.STATUS_PUBLICATION_CREATED) { String idPubli = unitReport.getLabel(); PublicationDetail publicationDetail = this.getPublicationDetail(idPubli); listPublicationDetail.add(publicationDetail); } } } return listPublicationDetail; } private String getMaxSizeErrorMessage(LocalizationBundle messages) { long maximumFileSize = FileRepositoryManager.getUploadMaximumFileSize(); String maximumFileSizeMo = UnitUtil.formatMemSize(maximumFileSize); return messages.getString("attachment.dialog.errorAtLeastOneFileSize") + " " + messages.getString("attachment.dialog.maximumFileSize") + " (" + maximumFileSizeMo + ")"; } public List<HistoryObjectDetail> getLastAccess(PublicationPK pk) { return getKmeliaService().getLastAccess(pk, getCurrentFolderPK(), getUserId(), 4); } public void setPublicationValidator(String userIds) { getKmeliaService().setValidators(getSessionPubliOrClone().getDetail().getPK(), userIds); refreshSessionPubliAndClone(); } /** * Check user access right on folder * @param nodeId the topic/folder identifier to check * @return true if current user has admin access on topic given in parameter */ public boolean isTopicAdmin(final String nodeId) { String profile = getUserTopicProfile(nodeId); if (profile != null) { return SilverpeasRole.getHighestFrom(SilverpeasRole.from(profile)) .isGreaterThanOrEquals(SilverpeasRole.admin); } return isUserComponentAdmin(); } /* * Persist the date reminder for the given publication * @param pubDetail * @param dateReminderDate * @param messageReminder * @throws DateReminderException */ private void createResourceDateReminder(final PublicationDetail pubDetail, final Date dateReminderDate, final String messageReminder) throws DateReminderException { if (dateReminderDate != null) { DateReminderDetail dateReminderDetail = new DateReminderDetail(dateReminderDate, messageReminder, DateReminderDetail.REMINDER_NOT_PROCESSED, pubDetail.getUpdaterId(), pubDetail.getUpdaterId()); PublicationNoteReference publicationNoteReference = PublicationNoteReference .fromPublicationDetail(pubDetail); getDateReminderService().create(publicationNoteReference, dateReminderDetail); } } /** * Create the date reminder for the given publication * @param pubDetail * @param parameters * @throws DateReminderException */ public void addPublicationReminder(PublicationDetail pubDetail, List<FileItem> parameters) throws DateReminderException { String dateReminder = FileUploadUtil.getParameter(parameters, "DateReminder"); String messageReminder = FileUploadUtil.getParameter(parameters, "MessageReminder"); Date dateReminderDate = null; try { if (StringUtil.isDefined(dateReminder)) { dateReminderDate = DateUtil.stringToDate(dateReminder, this.getLanguage()); } } catch (ParseException e) { dateReminderDate = null; } //Create date reminder createResourceDateReminder(pubDetail, dateReminderDate, messageReminder); } /** * Save Or remove the date reminder for the given publication * @param pubId * @param parameters * @throws DateReminderException */ public void updatePublicationReminder(String pubId, List<FileItem> parameters) throws DateReminderException { String dateReminder = FileUploadUtil.getParameter(parameters, "DateReminder"); String messageReminder = FileUploadUtil.getParameter(parameters, "MessageReminder"); Date dateReminderDate = null; try { if (StringUtil.isDefined(dateReminder)) { dateReminderDate = DateUtil.stringToDate(dateReminder, this.getLanguage()); } } catch (ParseException e) { dateReminderDate = null; } PublicationDetail pubDetail = getPublicationDetail(pubId); PublicationNoteReference publicationNoteReference = PublicationNoteReference .fromPublicationDetail(pubDetail); PersistentResourceDateReminder actualResourceDateReminder = getDateReminderService() .get(publicationNoteReference); if (actualResourceDateReminder.isDefined()) { if (dateReminderDate != null) {//Update reminder DateReminderDetail actualDateReminderDetail = actualResourceDateReminder.getDateReminder(); String actualDateReminder = DateUtil.dateToString(actualDateReminderDetail.getDateReminder(), this.getLanguage()); int processStatus; if (!actualDateReminder.equals(dateReminder)) {// the date reminder has been updated // the date reminder must be processed by the scheduler processStatus = DateReminderDetail.REMINDER_NOT_PROCESSED; } else {// the date reminder has not been updated // keep the same process status processStatus = actualDateReminderDetail.getProcessStatus(); } DateReminderDetail dateReminderDetail = new DateReminderDetail(dateReminderDate, messageReminder, processStatus, actualDateReminderDetail.getCreatorId(), pubDetail.getUpdaterId()); getDateReminderService().set(publicationNoteReference, dateReminderDetail); } else {//Delete reminder getDateReminderService().remove(publicationNoteReference); } } else {//Create reminder createResourceDateReminder(pubDetail, dateReminderDate, messageReminder); } } public boolean isTemplatesSelectionEnabledForRole(SilverpeasRole role) { return !isXMLFormEnabledForPublications() && isContentEnabled() && SilverpeasRole.admin.equals(role); } private String getXMLFormNameForPublications() { return getComponentParameterValue("XmlFormForPublis"); } private boolean isXMLFormEnabledForPublications() { return StringUtil.isDefined(getXMLFormNameForPublications()); } public Form getXmlFormForPublications() { Form formUpdate = null; List<String> forms = getModelUsed(); if (forms.size() == 1 && !"WYSIWYG".equals(forms.get(0))) { String form = forms.get(0); String formShort = form.substring(0, form.indexOf('.')); try { // register xmlForm to publication getPublicationTemplateManager().addDynamicPublicationTemplate(getComponentId() + ":" + formShort, form); PublicationTemplateImpl pubTemplate = (PublicationTemplateImpl) getPublicationTemplateManager() .getPublicationTemplate(getComponentId() + ':' + formShort, form); formUpdate = pubTemplate.getUpdateForm(); RecordSet recordSet = pubTemplate.getRecordSet(); DataRecord record = recordSet.getEmptyRecord(); formUpdate.setData(record); } catch (Exception e) { SilverLogger.getLogger(this).error(e); } } return formUpdate; } public void saveXMLFormToPublication(PublicationDetail pubDetail, List<FileItem> items, boolean forceUpdatePublication) throws org.silverpeas.core.SilverpeasException { String xmlFormShortName; // Is it the creation of the content or an update ? String infoId = pubDetail.getInfoId(); if (infoId == null || "0".equals(infoId)) { xmlFormShortName = FileUploadUtil.getParameter(items, "KmeliaPubFormName"); // The publication have no content // We have to register xmlForm to publication pubDetail.setInfoId(xmlFormShortName); updatePublication(pubDetail); } else { xmlFormShortName = pubDetail.getInfoId(); } String pubId = pubDetail.getPK().getId(); try { PublicationTemplate pub = getPublicationTemplateManager() .getPublicationTemplate(getComponentId() + ":" + xmlFormShortName); RecordSet set = pub.getRecordSet(); Form form = pub.getUpdateForm(); String language = pubDetail.getLanguageToDisplay(getCurrentLanguage()); DataRecord data = set.getRecord(pubId, language); if (data == null || (language != null && !language.equals(data.getLanguage()))) { // This publication haven't got any content at all or for requested language data = set.getEmptyRecord(); data.setId(pubId); data.setLanguage(language); } PagesContext context = new PagesContext(); context.setLanguage(getLanguage()); context.setComponentId(getComponentId()); context.setUserId(getUserId()); context.setEncoding(Charsets.UTF_8.name()); if (!isKmaxMode) { context.setNodeId(getCurrentFolderId()); } context.setObjectId(pubId); if (forceUpdatePublication) { // case of a modification of the publication context.setContentLanguage(getContentLanguage()); } else { // the publication is just created context.setContentLanguage(pubDetail.getLanguage()); } form.update(items, data, context); set.save(data); } catch (Exception e) { throw new org.silverpeas.core.SilverpeasException("Can't save XML form of publication", e); } String volatileId = FileUploadUtil.getParameter(items, "VolatileId"); if (StringUtil.isDefined(volatileId)) { // Attaching all documents linked to volatile publication to the persisted one List<SimpleDocumentPK> movedDocumentPks = AttachmentServiceProvider.getAttachmentService() .moveAllDocuments(getPublicationPK(volatileId).toResourceReference(), pubDetail.getPK().toResourceReference()); if (!movedDocumentPks.isEmpty()) { // Change images path in wysiwyg WysiwygController.wysiwygPlaceHaveChanged(getComponentId(), volatileId, getComponentId(), pubId); } } if (forceUpdatePublication) { // update publication to change updateDate and updaterId updatePublication(pubDetail); } } public void saveXMLForm(List<FileItem> items, boolean forceUpdatePublication) throws org.silverpeas.core.SilverpeasException { if (isCloneNeeded()) { clonePublication(); } final String currentLanguageCopy = getCurrentLanguage(); PublicationDetail pubDetail = getSessionPubliOrClone().getDetail(); saveXMLFormToPublication(pubDetail, items, forceUpdatePublication); setCurrentLanguage(currentLanguageCopy); } public PublicationDetail prepareNewPublication() { String volatileId = newVolatileIntegerIdentifierOn(getComponentId()); PublicationDetail publication = new PublicationDetail(); publication.setPk(getPublicationPK(volatileId)); return publication; } @Override public ManualUserNotificationSupplier getManualUserNotificationSupplier() { return c -> { final String componentId = c.get(NotificationContext.COMPONENT_ID); final String folderId = c.get("folderId"); final UserNotification notification; if (c.containsKey(NotificationContext.CONTRIBUTION_ID)) { final String pubId = c.get(NotificationContext.CONTRIBUTION_ID); if (c.containsKey("docId")) { final String docId = c.get("docId"); notification = getUserNotification(componentId, folderId, pubId, docId); } else { notification = getUserNotification(componentId, folderId, pubId); } } else { notification = getUserNotification(componentId, folderId); } return notification; }; } private UserNotification getUserNotification(final String cmpId, final String nodeId, final String pubId, final String docId) { final NodePK nodePK = getNodePK(cmpId, nodeId); final PublicationPK pubPk = new PublicationPK(pubId, cmpId); SimpleDocumentPK documentPk = new SimpleDocumentPK(docId, cmpId); return getKmeliaService().getUserNotification(pubPk, documentPk, nodePK); } private UserNotification getUserNotification(final String cmpId, final String nodeId, final String pubId) { final NodePK nodePK = getNodePK(cmpId, nodeId); final PublicationPK pubPk = new PublicationPK(pubId, cmpId); return getKmeliaService().getUserNotification(pubPk, nodePK); } private UserNotification getUserNotification(final String cmpId, final String nodeId) { final NodePK nodePK = new NodePK(nodeId, cmpId); return getKmeliaService().getUserNotification(nodePK); } private static NodePK getNodePK(final String cmpId, final String nodeId) { NodePK nodePK = null; if (!cmpId.startsWith("kmax") && StringUtil.isDefined(nodeId)) { nodePK = new NodePK(nodeId, cmpId); } return nodePK; } public enum CLIPBOARD_STATE { IS_EMPTY, HAS_COPIES, HAS_CUTS, HAS_COPIES_AND_CUTS } }