/** * Axelor Business Solutions * * Copyright (C) 2016 Axelor (<http://axelor.com>). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.axelor.apps.base.service.alarm; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.axelor.apps.base.db.Alarm; import com.axelor.apps.base.db.AlarmEngine; import com.axelor.apps.base.db.AlarmMessage; import com.axelor.apps.base.db.repo.AlarmEngineRepository; import com.axelor.apps.base.service.administration.GeneralService; import com.axelor.db.JPA; import com.axelor.db.Model; import com.axelor.db.mapper.Mapper; import com.axelor.meta.service.MetaModelService; import com.axelor.text.Templates; import com.google.inject.Inject; /** * Classe implémentant l'ensemble des fonctions utiles au moteur d'alarmes. */ public class AlarmEngineService <T extends Model> { protected GeneralService generalService; private static final Logger LOG = LoggerFactory.getLogger(AlarmEngineService.class); private DateTime dateTime; private Templates templates; @Inject private AlarmEngineRepository alarmEngineRepo; @Inject public AlarmEngineService(GeneralService generalService) { this.generalService = generalService; dateTime = this.generalService.getTodayDateTime(); } public AlarmEngineService(DateTime dateTime) { this.dateTime = dateTime; } public Alarm get(String alarmEngineCode, T t, boolean isExternal){ AlarmEngine alarmEngine = alarmEngineRepo.all().filter("self.code = ?1 AND externalOk = ?2 AND activeOk = true", alarmEngineCode, isExternal).fetchOne(); if (alarmEngine != null) { return createAlarm(alarmEngine, t); } else return null; } /** * Obtenir le tuple model cible et sa liste d'alarmes pour un type de moteur précis. * * @param klass * Le modèle cible des requête. * @param params * Liste de paramètre de la requête. * * @return * Un dictionnaire contenant l'ensemble des éléments remonté par la requête avec la liste des alarmes concernées. * * @throws Exception */ public Map<T, List<Alarm>> get(Class<T> klass, T... params) { List<? extends AlarmEngine> alarmEngines = alarmEngineRepo.all().filter("metaModel = ?1 AND activeOk = true AND externalOk = false", MetaModelService.getMetaModel(klass)).fetch(); LOG.debug("Lancement des moteurs de type {} : {} moteurs à lancer", klass, alarmEngines.size()); return get(alarmEngines, klass, params); } /** * Obtenir le tuple model cible et sa liste d'alarmes. * * @param alarmEngineLines * Une liste d'éléments (lignes) d'un ou plusieurs moteur d'alarme. * @param klass * Le modèle cible des requête. * @param inList * Une liste d'éléments du modèle cible pré-établies limitant le champs de recherche à ces éléments. * @param params * Liste de paramètre de la requête. * * @return * Un dictionnaire contenant l'ensemble des éléments remonté par la requête avec la liste des alarmes concernées. * * @throws Exception */ protected Map<T, List<Alarm>> get(List<? extends AlarmEngine> alarmEngines, Class<T> klass, T... params) { Map<T, List<Alarm>> map = new HashMap<T, List<Alarm>>(); Map<T, Alarm> alarmMap = new HashMap<T, Alarm>(); for (AlarmEngine alarmEngine : alarmEngines){ alarmMap.clear(); alarmMap.putAll( get(alarmEngine, klass, params) ); for (T t : alarmMap.keySet()){ if (!map.containsKey(t)) { map.put(t, new ArrayList<Alarm>()); } map.get(t).add(alarmMap.get(t)); } } return map; } /** * Obtenir le tuple model cible et alarme. * * @param message * Le message à attribuer à l'alarme. * @param query * La condition de la requête (Clause WHERE). * @param klass * Le modèle cible de la requête. * @param inList * Une liste d'éléments du modèle cible pré-établies limitant le champs de recherche à ces éléments. * @param params * Liste de paramètre de la requête. * * @return * Un dictionnaire contenant l'ensemble des éléments remonté par la requête avec l'alarme concernée. * * @throws Exception */ protected Map<T, Alarm> get(AlarmEngine alarmEngine, Class<T> klass, T... params) { Map<T, Alarm> map = new HashMap<T, Alarm>(); for (T t : this.results(alarmEngine.getQuery(), klass, params)){ if (!map.containsKey(t)) { map.put(t, createAlarm(alarmEngine, t)); } } LOG.debug("{} objets en alarmes", map.size()); return map; } /** * Lancer une requête pour un model défini. * * @param query * La condition de la requête (Clause WHERE). * @param klass * Le modèle cible de la requête. * @param inList * Une liste d'éléments du modèle cible pré-établies limitant le champs de recherche à ces éléments. * @param params * Liste de paramètre de la requête. * * @return * Liste d'élément correspondant au modèle cible. * * @throws Exception */ public List<T> results(String query, Class<T> klass, T... params) { LOG.debug("Lancement de la requête {} => Objet: {}, params: {}", new Object[]{query, klass.getSimpleName(), params}); if (params != null && params.length > 0){ String query2 = String.format("self in ?1 AND (%s)", query); return JPA.all(klass).filter(query2, Arrays.asList(params)).fetch(); } return JPA.all(klass).filter(query).fetch(); } public Alarm createAlarm(AlarmEngine alarmEngine, T t){ Alarm alarm = new Alarm(); alarm.setDate(dateTime); alarm.setAlarmEngine(alarmEngine); alarm.setContent( content(alarmEngine.getAlarmMessage(), t) ); if ( alarm.getAlarmEngine().getLockingOk()) { alarm.setAcquitOk(false); } else { alarm.setAcquitOk(true); } return alarm; } protected String content(AlarmMessage alarmMessage, T t){ return templates.fromText(alarmMessage.getMessage()).make(Mapper.toMap(t)).render(); } }