/* * Copyright 2015-Present Entando Inc. (http://www.entando.com) All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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 Lesser General Public License for more * details. */ package org.entando.entando.aps.system.services.actionlog; import com.agiletec.aps.system.common.AbstractService; import com.agiletec.aps.system.common.FieldSearchFilter; import com.agiletec.aps.system.exception.ApsSystemException; import com.agiletec.aps.system.services.authorization.Authorization; import com.agiletec.aps.system.services.group.Group; import com.agiletec.aps.system.services.keygenerator.IKeyGeneratorManager; import com.agiletec.aps.system.services.user.UserDetails; import com.agiletec.aps.util.DateConverter; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Set; import org.entando.entando.aps.system.services.actionlog.model.ActionLogRecord; import org.entando.entando.aps.system.services.actionlog.model.ActivityStreamSeachBean; import org.entando.entando.aps.system.services.actionlog.model.IActionLogRecordSearchBean; import org.entando.entando.aps.system.services.actionlog.model.IActivityStreamSearchBean; import org.entando.entando.aps.system.services.actionlog.model.ManagerConfiguration; import org.entando.entando.aps.system.services.cache.ICacheInfoManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; /** * @author E.Santoboni - S.Puddu */ public class ActionLogManager extends AbstractService implements IActionLogManager/*, ProfileChangedObserver*/ { private static final Logger _logger = LoggerFactory.getLogger(ActionLogManager.class); @Override public void init() throws Exception { _logger.debug("{} ready",this.getClass().getName()); } @Override public void addActionRecord(ActionLogRecord actionRecord) throws ApsSystemException { try { ActionLogAppenderThread thread = new ActionLogAppenderThread(actionRecord, this); String threadName = LOG_APPENDER_THREAD_NAME_PREFIX + DateConverter.getFormattedDate(new Date(), "yyyyMMddHHmmss"); thread.setName(threadName); thread.start(); } catch (Throwable t) { _logger.error("Error adding an actionlogger record", t); throw new ApsSystemException("Error adding an actionlogger record", t); } } @Override public void updateRecordDate(int id) throws ApsSystemException { try { this.getActionLogDAO().updateRecordDate(id); } catch (Throwable t) { _logger.error("Error updating data record", t); throw new ApsSystemException("Error updating data record", t); } } protected synchronized void addActionRecordByThread(ActionLogRecord actionRecord) throws ApsSystemException { try { Integer key = null; List<Integer> ids = null; do { key = this.getKeyGeneratorManager().getUniqueKeyCurrentValue(); FieldSearchFilter filter = new FieldSearchFilter("id", key, true); FieldSearchFilter[] filters = {filter}; ids = this.getActionLogDAO().getActionRecords(filters); } while (!ids.isEmpty()); actionRecord.setId(key); actionRecord.setActionDate(new Date()); this.getActionLogDAO().addActionRecord(actionRecord); } catch (Throwable t) { _logger.error("Error adding an actionlogger record", t); throw new ApsSystemException("Error adding an actionlogger record", t); } } @Override @CacheEvict(value = ICacheInfoManager.DEFAULT_CACHE_NAME, key = "'ActionLogRecord_'.concat(#id)") public void deleteActionRecord(int id) throws ApsSystemException { try { this.getActionLogDAO().deleteActionRecord(id); } catch (Throwable t) { _logger.error("Error deleting the actionlogger record: {}", id, t); throw new ApsSystemException("Error deleting the actionlogger record: " + id, t); } } @Override public List<Integer> getActionRecords(IActionLogRecordSearchBean searchBean) throws ApsSystemException { List<Integer> records = new ArrayList<Integer>(); try { records = this.getActionLogDAO().getActionRecords(searchBean); } catch (Throwable t) { _logger.error("Error loading actionlogger records", t); throw new ApsSystemException("Error loading actionlogger records", t); } return records; } @Override @Cacheable(value = ICacheInfoManager.DEFAULT_CACHE_NAME, key = "'ActionLogRecord_'.concat(#id)") public ActionLogRecord getActionRecord(int id) throws ApsSystemException { ActionLogRecord record = null; try { record = this.getActionLogDAO().getActionRecord(id); } catch (Throwable t) { _logger.error("Error loading actionlogger record with id: {}", id, t); throw new ApsSystemException("Error loading actionlogger record with id: " + id, t); } return record; } @Override public List<Integer> getActivityStream(List<String> userGroupCodes) throws ApsSystemException { List<Integer> recordIds = null; try { recordIds = this.getActionLogDAO().getActivityStream(userGroupCodes); ManagerConfiguration config = this.getManagerConfiguration(); if (null != recordIds && null != config && config.getCleanOldActivities() && config.getMaxActivitySizeByGroup() < recordIds.size()) { ActivityStreamCleanerThread thread = new ActivityStreamCleanerThread(config.getNumberOfStreamsOnHistory(), this); String threadName = LOG_CLEANER_THREAD_NAME_PREFIX + DateConverter.getFormattedDate(new Date(), "yyyyMMddHHmmss"); thread.setName(threadName); thread.start(); } if (null != config && null != recordIds && recordIds.size() > config.getMaxActivitySizeByGroup()) { recordIds = recordIds.subList(0, config.getMaxActivitySizeByGroup()); } } catch (Throwable t) { _logger.error("Error loading activity stream records", t); throw new ApsSystemException("Error loading activity stream records", t); } return recordIds; } @Override public List<Integer> getActivityStream(IActivityStreamSearchBean activityStreamSearchBean) { List<Integer> recordIds = null; recordIds = this.getActionLogDAO().getActionRecords(activityStreamSearchBean); ManagerConfiguration config = this.getManagerConfiguration(); if (null != config && null != recordIds && recordIds.size() > config.getMaxActivitySizeByGroup()) { recordIds = recordIds.subList(0, config.getMaxActivitySizeByGroup()); } return recordIds; } /* @Override @CacheEvict(value = ICacheInfoManager.DEFAULT_CACHE_NAME, key = "'ActivityStreamLikeRecords_id_'.concat(#id)") public void editActionLikeRecord(int id, String username, boolean add) throws ApsSystemException { try { this.getActionLogDAO().editActionLikeRecord(id, username, add); } catch (Throwable t) { _logger.error("Error editing activity stream like records", t); throw new ApsSystemException("Error editing activity stream like records", t); } } @Override @Cacheable(value = ICacheInfoManager.DEFAULT_CACHE_NAME, key = "'ActivityStreamLikeRecords_id_'.concat(#id)") @CacheableInfo(groups = "'ActivityStreamLikeRecords_cacheGroup'") public List<ActivityStreamLikeInfo> getActionLikeRecords(int id) throws ApsSystemException { List<ActivityStreamLikeInfo> infos = null; try { infos = this.getActionLogDAO().getActionLikeRecords(id); if (null != infos) { for (int i = 0; i < infos.size(); i++) { ActivityStreamLikeInfo asli = infos.get(i); String username = asli.getUsername(); IUserProfile profile = this.getUserProfileManager().getProfile(username); String displayName = (null != profile) ? profile.getDisplayName() : username; asli.setDisplayName(displayName); } } } catch (Throwable t) { _logger.error("Error extracting activity stream like records", t); throw new ApsSystemException("Error extracting activity stream like records", t); } return infos; } @Override public void updateFromProfileChanged(ProfileChangedEvent event) { try { ICacheInfoManager cacheInfoManager = (ICacheInfoManager) this.getBeanFactory().getBean(SystemConstants.CACHE_INFO_MANAGER); cacheInfoManager.flushGroup(ICacheInfoManager.DEFAULT_CACHE_NAME, "ActivityStreamLikeRecords_cacheGroup"); } catch (Throwable t) { _logger.error("Error flushing cache group", t); } } */ @Override public List<Integer> getActivityStream(UserDetails loggedUser) throws ApsSystemException { List<String> userGroupCodes = this.extractUserGroupCodes(loggedUser); return this.getActivityStream(userGroupCodes); } /* @Override @CacheEvict(value = ICacheInfoManager.DEFAULT_CACHE_NAME, key = "'ActivityStreamCommentRecords_id_'.concat(#streamId)") public void addActionCommentRecord(String username, String commentText, int streamId) throws ApsSystemException { try { Integer key = null; List<Integer> ids = null; do { key = this.getKeyGeneratorManager().getUniqueKeyCurrentValue(); FieldSearchFilter filter = new FieldSearchFilter("id", key, true); FieldSearchFilter[] filters = {filter}; ids = this.getActionLogDAO().getActionRecords(filters); } while (!ids.isEmpty()); this.getActionLogDAO().addActionCommentRecord(key, streamId, username, commentText); } catch (Throwable t) { _logger.error("Error adding a comment record to stream with id:{}", streamId, t); throw new ApsSystemException("Error adding a comment record", t); } } @Override @CacheEvict(value = ICacheInfoManager.DEFAULT_CACHE_NAME, key = "'ActivityStreamCommentRecords_id_'.concat(#streamId)") public void deleteActionCommentRecord(int id, int streamId) throws ApsSystemException { try { this.getActionLogDAO().deleteActionCommentRecord(id, streamId); } catch (Throwable t) { _logger.error("Error deleting comment with id {} from stream with id {}", id, streamId, t); throw new ApsSystemException("Error deleting comment", t); } } */ @Override public Date lastUpdateDate(UserDetails loggedUser) throws ApsSystemException { List<Integer> actionRecordIds = null; Date lastUpdate = new Date(); try { ActivityStreamSeachBean searchBean = new ActivityStreamSeachBean(); searchBean.setUserGroupCodes(this.extractUserGroupCodes(loggedUser)); searchBean.setEndUpdate(lastUpdate); actionRecordIds = this.getActionRecords(searchBean); if(null != actionRecordIds && actionRecordIds.size() > 0) { ActionLogRecord actionRecord = this.getActionRecord(actionRecordIds.get(0)); lastUpdate = actionRecord.getUpdateDate(); } } catch (Throwable t) { _logger.error("Error on loading updated activities", t); throw new ApsSystemException("Error on loading updated activities", t); } return lastUpdate; } /* @Override @Cacheable(value = ICacheInfoManager.DEFAULT_CACHE_NAME, key = "'ActivityStreamCommentRecords_id_'.concat(#id)") @CacheableInfo(groups = "'ActivityStreamCommentRecords_cacheGroup'") public List<ActivityStreamComment> getActionCommentRecords(int id) throws ApsSystemException { List<ActivityStreamComment> infos = null; try { infos = this.getActionLogDAO().getActionCommentRecords(id); if (null != infos) { for (int i = 0; i < infos.size(); i++) { ActivityStreamComment comment = infos.get(i); String username = comment.getUsername(); IUserProfile profile = this.getUserProfileManager().getProfile(username); String displayName = (null != profile) ? profile.getDisplayName() : username; comment.setDisplayName(displayName); } } } catch (Throwable t) { _logger.error("Error extracting activity stream like records for stream with id {}", id, t); throw new ApsSystemException("Error extracting activity stream like records", t); } return infos; } */ private List<String> extractUserGroupCodes(UserDetails loggedUser) { List<String> codes = new ArrayList<String>(); List<Authorization> auths = (null != loggedUser) ? loggedUser.getAuthorizations() : null; if (null != auths) { for (int i = 0; i < auths.size(); i++) { Authorization auth = auths.get(i); if (null != auth && null != auth.getGroup()) { codes.add(auth.getGroup().getName()); } } } if (!codes.contains(Group.FREE_GROUP_NAME)) { codes.add(Group.FREE_GROUP_NAME); } return codes; } @Override public Set<Integer> extractOldRecords(Integer maxActivitySizeByGroup) throws ApsSystemException { Set<Integer> actionRecordIds = null; try { actionRecordIds = this.getActionLogDAO().extractOldRecords(maxActivitySizeByGroup); } catch (Throwable t) { _logger.error("Error extracting old records", t); throw new ApsSystemException("Error extracting old records", t); } return actionRecordIds; } protected ManagerConfiguration getManagerConfiguration() { return _managerConfiguration; } public void setManagerConfiguration(ManagerConfiguration managerConfiguration) { this._managerConfiguration = managerConfiguration; } protected IActionLogDAO getActionLogDAO() { return _actionLogDAO; } public void setActionLogDAO(IActionLogDAO actionLogDAO) { this._actionLogDAO = actionLogDAO; } protected IKeyGeneratorManager getKeyGeneratorManager() { return _keyGeneratorManager; } public void setKeyGeneratorManager(IKeyGeneratorManager keyGeneratorManager) { this._keyGeneratorManager = keyGeneratorManager; } private ManagerConfiguration _managerConfiguration; private IActionLogDAO _actionLogDAO; private IKeyGeneratorManager _keyGeneratorManager; }