Créer un prérequis aux actions automatiques
Table des matières
- Introduction
- Ajouter un type de prérequis
- Prérequis avec configuration
- Formulaire HTML de création et de modification du prérequis
Introduction
Au sein d’un workflow, il est possible de définir des prérequis à l’exécution des actions désignées comme automatiques de manière à ce que lorsqu’une ressource arrive dans l’état de départ de l’action, celle-ci ne soit exécutée que si la ressource vérifie la totalité des prérequis.
La liste des prérequis d’une action peut être modifiée en Back Office, dans la page de modification de l’action.
Ajouter un type de prérequis
La création d’un nouveau type de prérequis nécessite d’implémenter l’interface fr.paris.lutece.plugins.workflowcore.service.prerequisite.IAutomaticActionPrerequisiteService.
Exemple d’implémentation d’un service de prérequis sans configuration :
/**
* Exemple de prérequis sans configuration
*/
public class NoConfigPrerequisiteService implements IAutomaticActionPrerequisiteService
{
private static final String PREREQUISITE_TYPE = "no_config_prerequisite";
private static final String MESSAGE_PREREQUISITE_TITLE = "portal.util.labelNo";
/**
* Obtenir le type de prérequis associé à ce service
* @return Le type de prérequis associé à ce service
*/
@Override
public String getPrerequisiteType()
{
return PREREQUISITE_TYPE;
}
/**
* Obtenir la clé I18n du titre du prérequis
* @return la clé I18n du titre du prérequis
*/
@Override
public String getTitleI18nKey()
{
return MESSAGE_PREREQUISITE_TITLE;
}
/**
* Vérifier si le type de prérequis de ce service nécessite une configuration
* @return Vrai si le type de prérequis nécessite une configuration, faux sinon
*/
@Override
public boolean hasConfiguration()
{
return false;
}
/**
* Obtenir une nouvelle instance de la configuration de ce type de prérequis.
* La bean de configuration doit implémenter l'interface
* {@link fr.paris.lutece.plugins.workflowcore.business.prerequisite.IPrerequisiteConfig
* IPrerequisiteConfig}
* @return Une nouvelle instance de la configuration de ce type de prérequis, ou
* null si le prérequis n'a pas de configuration
*/
@Override
public IPrerequisiteConfig getEmptyConfiguration()
{
return null;
}
/**
* Obtenir le nom de la bean du DAO pour les configurations de ce type de prérequis.
* La bean de configuration doit implémenter l'interface
* {@link fr.paris.lutece.plugins.workflowcore.business.prerequisite.IPrerequisiteConfigDAO
* IPrerequisiteConfigDAO}
* @return Le nom de la bean de la configuration, ou null si le
* prérequis n'a pas de configuration
*/
@Override
public String getConfigurationDaoBeanName()
{
return null;
}
/**
* Obtenir le formulaire HTML pour créer ou modifier une configuration pour un nouveau
* prérequis.
* Le HTML retourné sera inséré dans un frameset HTML qui contient déjà
* une balise form.
* Les données saisies par l'utilisateur seront sauvegardées dans la bean de configuration avec
* des méthodes de peuplement. La bean sera également validée avant d'être sauvegardée.
* @param config La configuration pour afficher le formulaire
* @param request La requête
* @param locale La locale
* @return Le contenu HTML à afficher, ou null s'il n'y a pas de formulaire à
* afficher
*/
@Override
public String getConfigHtml(IPrerequisiteConfig config, HttpServletRequest request, Locale locale)
{
return null;
}
/**
* Vérifier si une ressource correspond à ce prérequis.
* @param nIdResource L'id de la ressource
* @param strResourceType Le type de ressource
* @param config La configuration du prérequis, ou null si le
* prérequis n'a pas de configuration
* @param nIdAction L'id de l'action qui sera effectuée si la
* ressource correspond à tous les prérequis
* @return Vrai si la ressource correspond à ce prérequis, faux sinon
*/
@Override
public boolean canActionBePerformed(int nIdResource, String strResourceType, IPrerequisiteConfig config,
int nIdAction)
{
return false;
}
}
L’implémentation doit être déclarée comme un bean Spring (avec le scope par défaut, c’est-à-dire singleton).
Prérequis avec configuration
Si le type de prérequis nécessite une configuration spécifique à chaque instance de prérequis, il est également nécessaire d’implémenter les interfaces suivantes :
- fr.paris.lutece.plugins.workflowcore.business.prerequisite.IPrerequisiteConfigDAO
- fr.paris.lutece.plugins.workflowcore.business.prerequisite.IPrerequisiteConfig
La classe abstraite fr.paris.lutece.plugins.workflowcore.business.prerequisite.DefaultPrerequisiteConfig fournit une implémentation par défaut de certaines méthodes de la dernière interface.
L’implémentation de l’interface IPrerequisiteConfig permet de spécifier la classe métier dans laquelle les données de la configuration des prérequis seront stockées. L’implémentation de l’interface IPrerequisiteConfigDAO permet de fournir le DAO qui gérera la persistance des configurations. Cette dernière implémentation doit être déclarée comme un bean Spring, et le nom du bean correspondant doit être fourni par la méthode String getConfigurationDaoBeanName() du service de prérequis.
Exemple d’implémentation d’un service de prérequis avec configuration :
/**
* Prérequis pour vérifier que la ressource n'a pas été modifiée depuis un nombre donné
* de jours avant de traiter une action automatique
*/
public class DateModificationPrerequisiteService implements IAutomaticActionPrerequisiteService
{
private static final String PREREQUISITE_TYPE = "date_modificiation_prerequisite";
private static final String MESSAGE_PREREQUISITE_TITLE = "portal.util.labelYes";
private static final String DATE_MODIFICATION_PREREQUISITE_DAO_BEAN_NAME = "workflow.dateModificationPrerequisiteConfigDAO";
/**
* Obtenir le type de prérequis associé à ce service
* @return Le type de prérequis associé à ce service
*/
@Override
public String getPrerequisiteType()
{
return PREREQUISITE_TYPE;
}
/**
* Obtenir la clé I18n du titre du prérequis
* @return la clé I18n du titre du prérequis
*/
@Override
public String getTitleI18nKey()
{
return MESSAGE_PREREQUISITE_TITLE;
}
/**
* Vérifier si le type de prérequis de ce service nécessite une configuration
* @return Vrai si le type de prérequis nécessite une configuration, faux sinon
*/
@Override
public boolean hasConfiguration()
{
return true;
}
/**
* Obtenir une nouvelle instance de la configuration de ce type de prérequis.
* La bean de configuration doit implémenter l'interface
* {@link fr.paris.lutece.plugins.workflowcore.business.prerequisite.IPrerequisiteConfig
* IPrerequisiteConfig}
* @return Une nouvelle instance de la configuration de ce type de prérequis, ou
* null si le prérequis n'a pas de configuration
*/
@Override
public IPrerequisiteConfig getEmptyConfiguration()
{
return new DateModificationPrerequisiteConfig();
}
/**
* Obtenir le nom de la bean du DAO pour les configurations de ce type de prérequis.
* La bean de configuration doit implémenter l'interface
* {@link fr.paris.lutece.plugins.workflowcore.business.prerequisite.IPrerequisiteConfigDAO
* IPrerequisiteConfigDAO}
* @return Le nom de la bean de la configuration, ou null si le
* prérequis n'a pas de configuration
*/
@Override
public String getConfigurationDaoBeanName()
{
return DATE_MODIFICATION_PREREQUISITE_DAO_BEAN_NAME;
}
/**
* Obtenir le formulaire HTML pour créer ou modifier une configuration pour un nouveau
* prérequis.
* Le HTML retourné sera inséré dans un frameset HTML qui contient déjà
* une balise form.
* Les données saisies par l'utilisateur seront sauvegardées dans la bean de configuration avec
* des méthodes de peuplement. La bean sera également validée avant d'être sauvegardée.
* @param config La configuration pour afficher le formulaire
* @param request La requête
* @param locale La locale
* @return Le contenu HTML à afficher, ou null s'il n'y a pas de formulaire à
* afficher
*/
@Override
public String getConfigHtml(IPrerequisiteConfig config, HttpServletRequest request, Locale locale)
{
return "<div class=\"control-group\"><label class=\"control-label\">Nombre de jour d'attente avant l'exécution de l'action :</label><div class=\"controls\"><input type='text' name='nb_days' value='"
+ ((DateModificationPrerequisiteConfig) config).getNbDays() + "'></div></div>";
}
/**
* Vérifier si une ressource correspond à ce prérequis.
* @param nIdResource L'id de la ressource
* @param strResourceType Le type de ressource
* @param config La configuration du prérequis, ou null si le
* prérequis n'a pas de configuration
* @param nIdAction L'id de l'action qui sera effectuée si la
* ressource correspond à tous les prérequis
* @return Vrai si la ressource correspond à ce prérequis, faux sinon
*/
@Override
public boolean canActionBePerformed(int nIdResource, String strResourceType, IPrerequisiteConfig config,
int nIdAction)
{
DateModificationPrerequisiteConfig dateconfig = (DateModificationPrerequisiteConfig) config;
IResourceWorkflowService resourceWorkflowService = SpringContextService
.getBean(ResourceWorkflowService.BEAN_SERVICE);
IActionService actionService = SpringContextService.getBean(ActionService.BEAN_SERVICE);
Action action = actionService.findByPrimaryKey(nIdAction);
ResourceWorkflow resource = resourceWorkflowService.findByPrimaryKey(nIdResource, strResourceType, action
.getWorkflow().getId());
IResourceHistoryService resourceHistoryService = SpringContextService
.getBean(ResourceHistoryService.BEAN_SERVICE);
ResourceHistory resourceHistory = resourceHistoryService.getLastHistoryResource(resource.getIdResource(),
resource.getResourceType(), action.getWorkflow().getId());
Calendar calendar = GregorianCalendar.getInstance();
calendar.add(-1 * Calendar.DAY_OF_MONTH, dateconfig.getNbDays());
return calendar.getTime().getTime() > resourceHistory.getCreationDate().getTime();
}
}
Exemple d’implémentation de configuration de prérequis :
/**
* Configuration de prérequis qui exige que la ressource ne soit pas modifiée
* pendant un nombre donné de jours
*/
public class DateModificationPrerequisiteConfig extends DefaultPrerequisiteConfig
{
@Min(value = 2, message = "portal.util.labelWarning")
private int _nNbDays;
/**
* Obtenir le nombre de jours à attendre avant que l'action soit effectuée
* @return Le nombre de jours à attendre avant que l'action soit effectuée
*/
public int getNbDays()
{
return _nNbDays;
}
/**
* Définir le nombre de jours à attendre avant que l'action soit effectuée
* @param nNbDays Le nombre de jours à attendre avant que l'action soit effectuée
*/
public void setNbDays(int nNbDays)
{
this._nNbDays = nNbDays;
}
}
Exemple d’implémentation du DAO de la configuration d’un prérequis :
/**
* DAO pour gérer DateModificationPrerequisiteConfig
*/
public class DateModificationPrerequisiteConfigDAO implements IPrerequisiteConfigDAO
{
@Override
public void createConfig(IPrerequisiteConfig config)
{
DAOUtil daoUtil = new DAOUtil("insert into days (id_config, nb_days) values (" + config.getIdPrerequisite()
+ "," + ((DateModificationPrerequisiteConfig) config).getNbDays() + ")");
daoUtil.executeUpdate();
daoUtil.free();
}
@Override
public void updateConfig(IPrerequisiteConfig config)
{
DAOUtil daoUtil = new DAOUtil("update days set nb_days = "
+ ((DateModificationPrerequisiteConfig) config).getNbDays() + " where id_config = "
+ config.getIdPrerequisite());
daoUtil.executeUpdate();
daoUtil.free();
}
@Override
public void removeConfig(int nIdPrerequisite)
{
DAOUtil daoUtil = new DAOUtil("delete from days where id_config = " + nIdPrerequisite);
daoUtil.executeUpdate();
daoUtil.free();
}
@Override
public IPrerequisiteConfig findByPrimaryKey(int nIdPrerequisite)
{
DAOUtil daoUtil = new DAOUtil("select id_config, nb_days from days where id_config = " + nIdPrerequisite);
daoUtil.executeQuery();
DateModificationPrerequisiteConfig config = null;
if (daoUtil.next())
{
config = new DateModificationPrerequisiteConfig();
config.setIdPrerequisite(daoUtil.getInt(1));
config.setNbDays(daoUtil.getInt(2));
}
daoUtil.free();
return config;
}
}
Formulaire HTML de création et de modification du prérequis
Le formulaire HTML de création et de modification du prérequis est généré par la méthode String getConfigHtml() de IAutomaticActionPrerequisiteService. Le HTML renvoyé par cette méthode ne doit pas contenir de balise <form>
.
Le peuplement des données soumises par l’utilisateur dans la configuration est fait par introspection. Les noms des input doivent donc correspondre aux noms des attributs de la configuration.
Avant toute sauvegarde des données soumises par l’utilisateur, la configuration est validée. Si la validation échoue, la configuration n’est pas créée ou modifiée.