Package com.agiletec.plugins.jpcontentnotifier.aps.system.services.contentnotifier

Source Code of com.agiletec.plugins.jpcontentnotifier.aps.system.services.contentnotifier.ContentNotifierManager

/*
*
* Copyright 2013 Entando S.r.l. (http://www.entando.com) All rights reserved.
*
* This file is part of Entando software.
* Entando is a free software;
* You can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) as published by the Free Software Foundation; version 2.
*
* See the file License for the specific language governing permissions  
* and limitations under the License
*
*
*
* Copyright 2013 Entando S.r.l. (http://www.entando.com) All rights reserved.
*
*/
package com.agiletec.plugins.jpcontentnotifier.aps.system.services.contentnotifier;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.agiletec.aps.system.ApsSystemUtils;
import com.agiletec.aps.system.SystemConstants;
import com.agiletec.aps.system.common.AbstractService;
import com.agiletec.aps.system.exception.ApsSystemException;
import com.agiletec.aps.system.services.authorization.IAuthorizationManager;
import com.agiletec.aps.system.services.authorization.authorizator.IApsAuthorityManager;
import com.agiletec.aps.system.services.baseconfig.ConfigInterface;
import com.agiletec.aps.system.services.group.Group;
import com.agiletec.aps.system.services.lang.ILangManager;
import com.agiletec.aps.system.services.role.Permission;
import com.agiletec.aps.system.services.user.AbstractUser;
import com.agiletec.aps.system.services.user.IUserManager;
import com.agiletec.aps.system.services.user.UserDetails;
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.event.PublicContentChangedEvent;
import com.agiletec.plugins.jacms.aps.system.services.content.event.PublicContentChangedObserver;
import com.agiletec.plugins.jacms.aps.system.services.content.model.SmallContentType;
import com.agiletec.plugins.jpcontentnotifier.aps.system.JpcontentnotifierSystemConstants;
import com.agiletec.plugins.jpcontentnotifier.aps.system.services.contentnotifier.model.ContentMailInfo;
import com.agiletec.plugins.jpcontentnotifier.aps.system.services.contentnotifier.model.NotifierConfig;
import com.agiletec.plugins.jpcontentnotifier.aps.system.services.contentnotifier.parse.ContentNotifierConfigDOM;
import com.agiletec.plugins.jpcontentnotifier.aps.system.services.contentnotifier.scheduler.MailSenderTask;
import com.agiletec.plugins.jpcontentnotifier.aps.system.services.contentnotifier.scheduler.Scheduler;
import com.agiletec.plugins.jpcontentnotifier.aps.system.services.contentnotifier.scheduler.Task;
import com.agiletec.plugins.jpmail.aps.services.mail.IMailManager;

import org.entando.entando.aps.system.services.userprofile.IUserProfileManager;
import org.entando.entando.aps.system.services.userprofile.model.IUserProfile;

/**
* Service to notify to users the content creation or update,
* the communication happens by email .
* @author E.Santoboni
*/
public class ContentNotifierManager extends AbstractService implements PublicContentChangedObserver, IContentNotifierManager {

  @Override
  public void init() throws ApsSystemException {
    this.loadConfigs();
    this.openScheduler();
    ApsSystemUtils.getLogger().debug(this.getName() + ": service for notifications on contents changes initialized");
  }

  @Override
  public void release() {
    this.closeScheduler();
  }

  @Override
  public void destroy() {
    this.closeScheduler();
  }

  @Override
  public void updateFromPublicContentChanged(PublicContentChangedEvent event) {
    NotifierConfig config = this.getConfig();
    if (config.isActive()) {
      if ((config.isNotifyRemove() || PublicContentChangedEvent.REMOVE_OPERATION_CODE!=event.getOperationCode())) {
        try {
          this.getContentNotifierDao().saveEvent(event);
          ApsSystemUtils.getLogger().trace("Traced operation " + event.getOperationCode() + " on Content " + event.getContent().getId());
        } catch (ApsSystemException e) {
          ApsSystemUtils.logThrowable(e, this, "updateFromPublicContentChanged");
          throw new RuntimeException("error in updateFromPublicContentChanged", e);
        }
      }
    }
  }

  @Override
  public void updateNotifierConfig(NotifierConfig config) throws ApsSystemException {
    try {
      String xml = new ContentNotifierConfigDOM().createConfigXml(config);
      this.getConfigManager().updateConfigItem(JpcontentnotifierSystemConstants.CONTENT_NOTIFIER_CONFIG_ITEM, xml);
      this.setSchedulerConfig(config);
      this.openScheduler();
      ApsSystemUtils.getLogger().trace("Updated Content Notifier Configuration");
    } catch (Throwable t) {
      ApsSystemUtils.logThrowable(t, this, "updateNotifierConfig");
      throw new ApsSystemException("Errore in aggiornamento configurazione ContentNotifier", t);
    }
  }

  public List<ContentMailInfo> getContentsToNotify() throws ApsSystemException {
    return this.getContentNotifierDao().getContentsToNotify();
  }

  /**
   * Notifica via eMail la modifica dei contenuti.
   */
  @Override
  public void sendEMails() throws ApsSystemException {
    if (!this.getConfig().isActive()) {
      ApsSystemUtils.getLogger().info("Content Notifier not active");
      return;
    }
    try {
      List<ContentMailInfo> contentsToNotify = this.getContentsToNotify();
      ApsSystemUtils.getLogger().info("Starting to notify " + contentsToNotify.size() + " Contents");
      processContents(contentsToNotify);
    } catch (Throwable t) {
      ApsSystemUtils.logThrowable(t, this, "sendEMails");
      throw new ApsSystemException("Error sending emails", t);
    }
  }

  public List<ContentMailInfo> getContentsToNotifyToUser(UserDetails user, List<ContentMailInfo> contentsToNotify) {
    IAuthorizationManager authManager = this.getAuthorizationManager();
    if (authManager.isAuthOnGroup(user, Group.ADMINS_GROUP_NAME)) {
      return contentsToNotify;
    } else {
      List<ContentMailInfo> contentsToNotifyToUser = new ArrayList<ContentMailInfo>();
      boolean onlyOwner = this.getConfig().isOnlyOwner();
      for (ContentMailInfo info : contentsToNotify) {
        String mainGroup = info.getMainGroup();
        boolean allowedContent = authManager.isAuthOnGroup(user, mainGroup);
        if (!allowedContent && !onlyOwner && info.getGroups()!=null) {
          for (String group : info.getGroups()) {
            if (authManager.isAuthOnGroup(user, group)) {
              allowedContent = true;
              break;
            }
          }
        }
        if (allowedContent) {
          contentsToNotifyToUser.add(info);
        }
      }
      return contentsToNotifyToUser;
    }
  }

  protected void loadConfigs() throws ApsSystemException {
    try {
      ConfigInterface configManager = this.getConfigManager();
      String xml = configManager.getConfigItem(JpcontentnotifierSystemConstants.CONTENT_NOTIFIER_CONFIG_ITEM);
      if (xml == null) {
        throw new ApsSystemException("Missing content item: " + JpcontentnotifierSystemConstants.CONTENT_NOTIFIER_CONFIG_ITEM);
      }
      ApsSystemUtils.getLogger().trace(JpcontentnotifierSystemConstants.CONTENT_NOTIFIER_CONFIG_ITEM + ": " + xml);
      ContentNotifierConfigDOM configDOM = new ContentNotifierConfigDOM();
      this.setSchedulerConfig(configDOM.extractConfig(xml));
    } catch (Throwable t) {
      ApsSystemUtils.logThrowable(t, this, "loadConfigs");
      throw new ApsSystemException("Error loading config", t);
    }
  }

  /**
   * Apre lo scheduler istanziando il task relativo
   * alla spedizione degli sms con i rilevamenti meteo.
   */
  protected void openScheduler() {
    this.closeScheduler();
    NotifierConfig config = this.getConfig();
    if (config.isActive()) {
      Date startTime = config.getStartScheduler();
      long milliSecondsDelay = config.getHoursDelay() * 3600000l; // x minuti secondi millisecondi
      startTime = this.calculateStartTime(startTime, milliSecondsDelay);
      Task task = new MailSenderTask(this);
      this._mailSenderScheduler = new Scheduler(task, startTime, milliSecondsDelay);
    }
  }

  protected void closeScheduler() {
    if (this._mailSenderScheduler != null) {
      this._mailSenderScheduler.cancel();
      this._mailSenderScheduler = null;
    }
  }

  protected List<UserDetails> findContentOperators() throws ApsSystemException {
    IAuthorizationManager authManager = this.getAuthorizationManager();
    IUserManager userManager = this.getUserManager();
    IUserProfileManager profileManager = this.getProfileManager();
    List<UserDetails> systemUsers = userManager.getUsers();
    List<UserDetails> allowedUsers = new ArrayList<UserDetails>();
    for (UserDetails user : systemUsers){
      user.addAutorities(this.getRoleManager().getAuthorizationsByUser(user));
      if (authManager.isAuthOnPermission(user, Permission.SUPERVISOR) || authManager.isAuthOnPermission(user, "editContents")) {
        try {
          AbstractUser userDetails = (AbstractUser) user;
          IUserProfile profile = profileManager.getProfile(userDetails.getUsername());
          userDetails.setProfile(profile);
        } catch (Throwable t) {
          ApsSystemUtils.logThrowable(t, this, "findContentOperators", "Error searching profile for user " + user.getUsername());
        }
        user.addAutorities(this.getGroupManager().getAuthorizationsByUser(user));
        allowedUsers.add(user);
      }
    }
    return allowedUsers;
  }

  protected boolean sendEMailToUser(UserDetails user, List<ContentMailInfo> contentsToNotify, Map<String, SmallContentType> smallContentTypes) throws ApsSystemException {
    boolean sent = false;
    NotifierConfig config = this.getConfig();
    IUserProfile profile = (IUserProfile) user.getProfile();
    if (profile!=null) {
      String emailAttributeName = config.getMailAttrName();
      Object eMailValue = profile.getValue(emailAttributeName);
      String eMail = eMailValue!=null ? eMailValue.toString() : null;
      if (eMail != null && eMail.length() > 0) {
        List<ContentMailInfo> contentsToNotifyToUser = this.getContentsToNotifyToUser(user, contentsToNotify);
        if (!contentsToNotifyToUser.isEmpty()) {
          String[] eMailAddresses = {eMail};
          String mailBody = this.createBody(user, contentsToNotifyToUser, smallContentTypes);
          String contentType = config.isHtml() ? IMailManager.CONTENTTYPE_TEXT_HTML : IMailManager.CONTENTTYPE_TEXT_PLAIN;
          sent = this.getMailManager().sendMail(mailBody, config.getSubject(),
              eMailAddresses, null, null, config.getSenderCode(), contentType);
        }
      }
    }
    return sent;
  }

  protected void signNotifiedContents(List<ContentMailInfo> contentsNotified) throws ApsSystemException, SQLException {
    try {
      this.getContentNotifierDao().signNotifiedContents(contentsNotified);
    } catch (Throwable t) {
      ApsSystemUtils.logThrowable(t, this, "signNotifiedContents");
      throw new ApsSystemException ("Error sign Notified Contents ", t);
    }
  }

  protected String createLink(ContentMailInfo info, String langCode) {
    StringBuilder link = new StringBuilder();
    String applicationBaseUrl = this.getConfigManager().getParam(SystemConstants.PAR_APPL_BASE_URL);
    link.append(applicationBaseUrl);
    link.append(langCode);
    link.append("/");
    link.append(this.getContentManager().getViewPage(info.getContentId()));
    link.append(".page?contentId=");
    link.append(info.getContentId());
    return link.toString();
  }

  /**
   * @param defaultText Il testo di partenza, contenente le stringhe da rimpiazzare secondo la sintassi {chiaveStringa}.
   * @param params La mappa dei parametri da rimpiazzare (solo il nome, esluse le { })<br />
   * ATTENZIONE: le chiavi non devono contenere caratteri speciali per le regular expressions.<br />
   * In tal caso vanno utilizzati i caratteri di escape.
   * @return Il testo con tutte le occorrenze delle parole chiave sostituite.
   */
  protected String replaceParams(String defaultText, Map<String, String> params) {
    String body = defaultText;
    for (Entry<String, String> pairs : params.entrySet()) {
      String field = "\\{" + pairs.getKey() + "\\}";
      body = body.replaceAll(field, (String) pairs.getValue());
    }
    return body;
  }

  protected Map<String, String> prepareContentParams(ContentMailInfo info, SmallContentType smallContentType, String link) {
    Map<String, String> params = new HashMap<String, String>();
    params.put("link", link);
    params.put("type", smallContentType.getDescr());
    params.put("descr", info.getContentDescr());
    params.put("date", DateConverter.getFormattedDate(info.getDate(), "dd MMMM yyyy"));
    params.put("time", DateConverter.getFormattedDate(info.getDate(), "HH:mm"));
    return params;
  }

  private void processContents(List<ContentMailInfo> contentsToNotify) throws ApsSystemException, SQLException {
    if (contentsToNotify.isEmpty()) return;
    List<UserDetails> allowedUsers = this.findContentOperators();
    ApsSystemUtils.getLogger().info("Starting to notify contents to " + allowedUsers.size() + " Operators");
    Map<String, SmallContentType> smallContentTypes = this.getContentManager().getSmallContentTypesMap();
    int notified = 0;
    for (UserDetails user : allowedUsers) {
      boolean sent = this.sendEMailToUser(user, contentsToNotify, smallContentTypes);
      if (sent) notified++;
    }
    ApsSystemUtils.getLogger().info("Notified " + contentsToNotify.size() + " Contents to " + notified + " Operators");
    if (notified > 0) {
      this.signNotifiedContents(contentsToNotify);
    }
  }

  private String createBody(UserDetails user, List<ContentMailInfo> contentsToNotifyToUser, Map<String, SmallContentType> smallContentTypes) {
    String defaultLangCode = this.getLangManager().getDefaultLang().getCode();
    NotifierConfig config = this.getConfig();
    StringBuffer body = new StringBuffer(config.getHeader());
    for (ContentMailInfo info : contentsToNotifyToUser) {
      SmallContentType smallContentType = (SmallContentType) smallContentTypes.get(info.getContentTypeCode());
      String link = this.createLink(info, defaultLangCode);

      Map<String, String> params = this.prepareContentParams(info, smallContentType, link);
      switch (info.getOperationCode()) {
      case PublicContentChangedEvent.INSERT_OPERATION_CODE:
        body.append(this.replaceParams(config.getTemplateInsert(), params));
        break;
      case PublicContentChangedEvent.UPDATE_OPERATION_CODE:
        body.append(this.replaceParams(config.getTemplateUpdate(), params));
        break;
      case PublicContentChangedEvent.REMOVE_OPERATION_CODE:
        body.append(this.replaceParams(config.getTemplateRemove(), params));
        break;
      }
    }
    body.append(config.getFooter());
    return body.toString();
  }

  private Date calculateStartTime(Date startTime, long delay) {
    Date current = new Date();

    long waitTime = current.getTime() - startTime.getTime();
    if (waitTime > 0) {
      startTime = new Date((current.getTime() + delay) - (waitTime % delay));
    }
    return startTime;
  }

  @Override
  public NotifierConfig getConfig() {
    return this._schedulerConfig;
  }
  public void setSchedulerConfig(NotifierConfig schedulerConfig) {
    this._schedulerConfig = schedulerConfig;
  }

  protected ConfigInterface getConfigManager() {
    return _configManager;
  }
  public void setConfigManager(ConfigInterface configManager) {
    this._configManager = configManager;
  }

  protected IContentManager getContentManager() {
    return _contentManager;
  }
  public void setContentManager(IContentManager contentManager) {
    this._contentManager = contentManager;
  }

  protected ILangManager getLangManager() {
    return _langManager;
  }
  public void setLangManager(ILangManager langManager) {
    this._langManager = langManager;
  }

  protected IUserManager getUserManager() {
    return _userManager;
  }
  public void setUserManager(IUserManager userManager) {
    this._userManager = userManager;
  }

  protected IMailManager getMailManager() {
    return _mailManager;
  }
  public void setMailManager(IMailManager mailManager) {
    this._mailManager = mailManager;
  }

  protected IAuthorizationManager getAuthorizationManager() {
    return _authorizationManager;
  }
  public void setAuthorizationManager(IAuthorizationManager authorizationManager) {
    this._authorizationManager = authorizationManager;
  }

  public IUserProfileManager getProfileManager() {
    return _profileManager;
  }
  public void setProfileManager(IUserProfileManager profileManager) {
    this._profileManager = profileManager;
  }

  public IApsAuthorityManager getRoleManager() {
    return _roleManager;
  }
  public void setRoleManager(IApsAuthorityManager roleManager) {
    this._roleManager = roleManager;
  }

  public IApsAuthorityManager getGroupManager() {
    return _groupManager;
  }
  public void setGroupManager(IApsAuthorityManager groupManager) {
    this._groupManager = groupManager;
  }

  protected IContentNotifierDAO getContentNotifierDao() {
    return _contentNotifierDao;
  }
  public void setContentNotifierDao(IContentNotifierDAO contentNotifierDao) {
    this._contentNotifierDao = contentNotifierDao;
  }

  protected Scheduler _mailSenderScheduler;

  private NotifierConfig _schedulerConfig;

  private ConfigInterface _configManager;
  private IContentManager _contentManager;
  private ILangManager _langManager;
  private IUserManager _userManager;
  private IMailManager _mailManager;
  private IAuthorizationManager _authorizationManager;
  private IUserProfileManager _profileManager;
  private IApsAuthorityManager _roleManager;
  private IApsAuthorityManager _groupManager;

  private IContentNotifierDAO _contentNotifierDao;

}
TOP

Related Classes of com.agiletec.plugins.jpcontentnotifier.aps.system.services.contentnotifier.ContentNotifierManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.