/* * Copyright 2015-Present Entando Inc. (http://www.entando.com) All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.agiletec.plugins.jpcmstagcloud.aps.system.services.tagcloud; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.agiletec.aps.system.common.AbstractService; import com.agiletec.aps.system.common.entity.model.EntitySearchFilter; import com.agiletec.aps.system.common.tree.ITreeNode; import com.agiletec.aps.system.exception.ApsSystemException; import com.agiletec.aps.system.services.authorization.Authorization; import com.agiletec.aps.system.services.baseconfig.ConfigInterface; import com.agiletec.aps.system.services.category.Category; import com.agiletec.aps.system.services.category.ICategoryManager; import com.agiletec.aps.system.services.group.Group; import com.agiletec.aps.system.services.group.IGroupManager; import com.agiletec.aps.system.services.user.UserDetails; import com.agiletec.aps.util.ApsProperties; import com.agiletec.aps.util.DateConverter; import com.agiletec.plugins.jacms.aps.system.services.content.IContentManager; import com.agiletec.plugins.jacms.aps.system.services.content.IPublicContentSearcherDAO; import com.agiletec.plugins.jacms.aps.system.services.content.event.PublicContentChangedEvent; import com.agiletec.plugins.jacms.aps.system.services.content.event.PublicContentChangedObserver; import com.agiletec.plugins.jpcmstagcloud.aps.system.JpcmstagcloudSystemConstants; /** * @author E.Santoboni */ public class TagCloudManager extends AbstractService implements ITagCloudManager, PublicContentChangedObserver { private static final Logger _logger = LoggerFactory.getLogger(TagCloudManager.class); @Override public void init() throws Exception { this.checkCategoryRoot(); _logger.debug("{}: ready ", this.getClass().getName()); } private void checkCategoryRoot() { Category tagCloudRoot = this.getCategoryManager().getCategory(this.getTagCloudCategoryRoot()); if (null != tagCloudRoot) { return; } try { tagCloudRoot = new Category(); tagCloudRoot.setCode(this.getTagCloudCategoryRoot()); Category root = this.getCategoryManager().getRoot(); ApsProperties titles = new ApsProperties(); Set<Object> langCodes = root.getTitles().keySet(); Iterator<Object> iter = langCodes.iterator(); while (iter.hasNext()) { Object langCode = (Object) iter.next(); titles.put(langCode, "Tag Cloud Root"); } tagCloudRoot.setTitles(titles); tagCloudRoot.setParent(root); tagCloudRoot.setParentCode(root.getCode()); this.getCategoryManager().addCategory(tagCloudRoot); _logger.debug("TagCloud category root Created "); } catch (Throwable t) { _logger.error("Error on adding tag cloud category root", t); throw new RuntimeException("Error on adding tag cloud category root", t); } } @Override public void updateFromPublicContentChanged(PublicContentChangedEvent event) { try { this.refresh(); } catch (Throwable t) { _logger.error("Error refreshing service", t); } } @Override protected void release() { this.setElaborationDate(null); this.getGlobalCloudInfos().clear(); } @Override public Map<ITreeNode, Integer> getCloudInfos(UserDetails currentUser) throws ApsSystemException { Map<ITreeNode, Integer> cloudInfos = null; if (null == this.getElaborationDate() || !this.getElaborationDate().equals(DateConverter.getFormattedDate(new Date(), "yyyyMMdd"))) { this.release(); this.setElaborationDate(DateConverter.getFormattedDate(new Date(), "yyyyMMdd")); } try { Category root = this.getCategoryManager().getCategory(this.getTagCloudCategoryRoot()); if (root == null || root.getChildren() == null || root.getChildren().length == 0) { _logger.error("Category Root '{}' null or dosn't has children", this.getTagCloudCategoryRoot()); return new HashMap<ITreeNode, Integer>(); } Set<String> userGroupCodes = this.getGroupsForSearch(currentUser); String key = this.createGroupMappingKey(userGroupCodes); Map<String, Integer> cloudInfosSmall = this.getGlobalCloudInfos().get(key); if (null == cloudInfosSmall) { cloudInfosSmall = new HashMap<String, Integer>(); this.getGlobalCloudInfos().put(key, cloudInfosSmall); EntitySearchFilter[] filters = (null != this.getDelayDays() && this.getDelayDays().intValue() > 0) ? new EntitySearchFilter[]{this.getStartDateFilter()} : null; Category[] children = root.getChildren(); for (int i = 0; i < children.length; i++) { Category child = children[i]; List<String> contentsId = this.getTagCloudDAO().loadPublicContentsId(new String[]{child.getCode()}, filters, userGroupCodes); cloudInfosSmall.put(child.getCode(), new Integer(contentsId.size())); } } cloudInfos = new HashMap<ITreeNode, Integer>(cloudInfosSmall.size()); Iterator<String> iterCodes = cloudInfosSmall.keySet().iterator(); while (iterCodes.hasNext()) { String categoryCode = iterCodes.next(); cloudInfos.put(this.getCategoryManager().getCategory(categoryCode), cloudInfosSmall.get(categoryCode)); } } catch (Throwable t) { _logger.error("Error extracting cloud Infos by user {}", currentUser, t); throw new ApsSystemException("Error extracting cloud Infos by user " + currentUser, t); } return cloudInfos; } @Override public List<String> loadPublicTaggedContentsId(String categoryCode, UserDetails currentUser) throws ApsSystemException { List<String> contentsId = null; try { EntitySearchFilter[] filters = (null != this.getDelayDays() && this.getDelayDays().intValue() > 0) ? new EntitySearchFilter[]{this.getStartDateFilter()} : null; Set<String> userGroupCodes = this.getGroupsForSearch(currentUser); String[] categories = {categoryCode}; contentsId = this.getContentManager().loadPublicContentsId(categories, filters, userGroupCodes); } catch (Throwable t) { _logger.error("Error extracting cloud Infos by user {}", currentUser, t); throw new ApsSystemException("Error extracting cloud Infos by user " + currentUser, t); } return contentsId; } private String createGroupMappingKey(Set<String> groupSet) { if (groupSet.contains(Group.ADMINS_GROUP_NAME)) { return Group.ADMINS_GROUP_NAME; } else { StringBuilder buffer = new StringBuilder(); List<String> groups = new ArrayList<String>(groupSet); Collections.sort(groups); for (int i = 0; i < groups.size(); i++) { if (i > 0) { buffer.append("-"); } buffer.append(groups.get(i)); } return buffer.toString(); } } private Set<String> getGroupsForSearch(UserDetails currentUser) { Set<String> groupForSearch = new HashSet<String>(); groupForSearch.add(Group.FREE_GROUP_NAME); List<Authorization> authorizations = currentUser.getAuthorizations(); for (int i = 0; i < authorizations.size(); i++) { Authorization authorization = authorizations.get(i); Group group = (null != authorization) ? authorization.getGroup() : null; if (null != group) { groupForSearch.add(group.getName()); } } return groupForSearch; } private EntitySearchFilter getStartDateFilter() { Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_YEAR, -this.getDelayDays()); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 1); Date startDate = calendar.getTime(); String DATE_FORMAT = "yyyyMMddHHmmss"; String formattedDate = DateConverter.getFormattedDate(startDate, DATE_FORMAT); EntitySearchFilter filter = new EntitySearchFilter(IContentManager.CONTENT_MODIFY_DATE_FILTER_KEY, false, formattedDate, null); filter.setOrder(EntitySearchFilter.DESC_ORDER); return filter; } protected String getElaborationDate() { return _elaborationDate; } protected void setElaborationDate(String elaborationDate) { this._elaborationDate = elaborationDate; } protected Integer getDelayDays() { Integer delay = null; String delayParamName = JpcmstagcloudSystemConstants.DELAY_DAYS_PARAM_NAME; try { delay = Integer.parseInt(this.getConfigManager().getParam(delayParamName)); } catch (Throwable e) { //nothing to catch } if (null == delay) { return JpcmstagcloudSystemConstants.DEFAULT_DELAY_DAYS; } return delay; } protected String getTagCloudCategoryRoot() { String categoryRootParamName = JpcmstagcloudSystemConstants.CATEGORY_ROOT_PARAM_NAME; String categoryRoot = this.getConfigManager().getParam(categoryRootParamName); if (null == categoryRoot || categoryRoot.trim().length() == 0) { return JpcmstagcloudSystemConstants.DEFAULT_CATEGORY_ROOT; } return categoryRoot; } protected Map<String, Map<String, Integer>> getGlobalCloudInfos() { return _globalCloudInfos; } protected void setGlobalCloudInfos(Map<String, Map<String, Integer>> globalCloudInfos) { this._globalCloudInfos = globalCloudInfos; } protected IContentManager getContentManager() { return _contentManager; } public void setContentManager(IContentManager contentManager) { this._contentManager = contentManager; } protected ICategoryManager getCategoryManager() { return _categoryManager; } public void setCategoryManager(ICategoryManager categoryManager) { this._categoryManager = categoryManager; } protected IGroupManager getGroupManager() { return _groupManager; } public void setGroupManager(IGroupManager groupManager) { this._groupManager = groupManager; } protected ConfigInterface getConfigManager() { return _configManager; } public void setConfigManager(ConfigInterface configManager) { this._configManager = configManager; } protected IPublicContentSearcherDAO getTagCloudDAO() { return _tagCloudDAO; } public void setTagCloudDAO(IPublicContentSearcherDAO tagCloudDAO) { this._tagCloudDAO = tagCloudDAO; } private String _elaborationDate; private Map<String, Map<String, Integer>> _globalCloudInfos = new HashMap<String, Map<String, Integer>>(); private IContentManager _contentManager; private ICategoryManager _categoryManager; private IGroupManager _groupManager; private ConfigInterface _configManager; private IPublicContentSearcherDAO _tagCloudDAO; }