Java tutorial
package nc.noumea.mairie.organigramme.core.viewmodel; /* * #%L * Logiciel de Gestion des Organigrammes de la Ville de Nouma * $Id:$ * $HeadURL:$ * %% * Copyright (C) 2015 Mairie de Nouma * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import java.lang.reflect.ParameterizedType; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import nc.noumea.mairie.organigramme.core.dto.AbstractEntityDto; import nc.noumea.mairie.organigramme.core.entity.AbstractEntity; import nc.noumea.mairie.organigramme.core.event.FermeOngletAbstractEntityEvent; import nc.noumea.mairie.organigramme.core.event.OuvreOngletAbstractEntityEvent; import nc.noumea.mairie.organigramme.core.event.RechargeOngletAbstractEntityEvent; import nc.noumea.mairie.organigramme.core.event.UpdateOngletAbstractEntityEvent; import nc.noumea.mairie.organigramme.core.services.GenericService; import nc.noumea.mairie.organigramme.core.utility.ApplicationContextUtils; import nc.noumea.mairie.organigramme.core.utility.MessageErreur; import nc.noumea.mairie.organigramme.core.utility.MessageErreurUtil; import nc.noumea.mairie.organigramme.core.utility.OrganigrammeUtil; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.CollectionUtils; import org.zkoss.bind.BindUtils; import org.zkoss.bind.annotation.BindingParam; import org.zkoss.bind.annotation.Command; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.event.EventQueues; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zul.ListModelList; import org.zkoss.zul.Messagebox; import org.zkoss.zul.Window; /** * ViewModel abstrait parent des ViewModel de l'application qui manipulent une * entit (cration, modification, et mme liste o on considre que l'entit * est celle slectionne dans la liste) * * @author AgileSoft.NC * @param <T> * Type paramtr (reprsente une classe d'entit en pratique) */ public abstract class AbstractViewModel<T extends AbstractEntityDto> { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractViewModel.class); protected T entity; /** * @return l'entit concerne */ public T getEntity() { return entity; } /** * Fixe l'entit concern par le ViewModel * * @param entity * entit concerne */ public void setEntity(T entity) { this.entity = entity; } /** * Mthode utilitaire, pour lister les valeurs d'une numration (dans * l'ordre de leur dclaration). * * @param enumClassName * nom complet de la classe (avec le package, ex : * "nc.noumea.mairie.organigramme.enums.Civilite") * @return la liste des valeurs numres, dans l'ordre de leur dclaration. */ public ListModelList<?> getListeEnum(String enumClassName) { return getListeEnum(enumClassName, false); } /** * Mthode utilitaire, pour lister les valeurs d'une numration (dans * l'ordre de leur dclaration), avec la possibilit d'insrer en tte la * valeur null. * * @param enumClassName * nom complet de la classe (avec le package, ex : * "nc.noumea.mairie.organigramme.enums.Civilite") * @param insertNull * indique s'il faut insrer en tte de la liste rsultat la * valeur null * @return la liste des valeurs numres, dans l'ordre de leur dclaration * (avec null en tte optionnellement) */ @SuppressWarnings({ "unchecked", "rawtypes" }) public ListModelList<?> getListeEnum(String enumClassName, boolean insertNull) { try { Class<?> classe = Class.forName(enumClassName); ListModelList result = new ListModelList(classe.getEnumConstants()); if (insertNull) { result.add(0, null); } return result; } catch (ClassNotFoundException e) { LOGGER.error("erreur sur getListeEnum", e); Messagebox.show(e.toString()); } return null; } /** * Publie un vnement de demande d'ouverture d'une entity dans un nouvel * onglet (ou dans un onglet existant si l'entity est dj ouverte) * * @param abstractEntity * entit concerne * @param selectedTabIndex * index de l'onglet ouvrir */ @Command public void ouvreOnglet(@BindingParam("entity") T abstractEntity, Integer selectedTabIndex) { EventQueues.lookup("organigrammeQueue", EventQueues.DESKTOP, true) .publish(new OuvreOngletAbstractEntityEvent(abstractEntity, selectedTabIndex)); } /** * Publie un vnement de demande de fermeture d'un onglet qui concerne une * entity * * @param abstractEntity * entit concerne */ public void fermeOnglet(@BindingParam("entity") T abstractEntity) { EventQueues.lookup("organigrammeQueue", EventQueues.DESKTOP, true) .publish(new FermeOngletAbstractEntityEvent(abstractEntity)); } /** * Publie un vnement de demande de recharge de l'entity, dans l'onglet * couramment slectionn */ @Command public void rechargeOnglet() { rechargeOnglet(null); } /** * Publie un vnement de demande de recharge de l'entity, dans l'onglet * couramment slectionn (ou dans l'onglet indiqu) * * @param indexSousOnglet * si null ignor, permet d'indiquer un ventuel sous-onglet sur * lequel se positionner aprs rechargement de l'entity */ protected void rechargeOnglet(Integer indexSousOnglet) { EventQueues.lookup("organigrammeQueue", EventQueues.DESKTOP, true) .publish(new RechargeOngletAbstractEntityEvent(entity, indexSousOnglet)); } /** * Publie un vnement de demande de mise jour du libell de l'onglet qui * gre l'entity passe en argument. * * @param abstractEntity * entit concerne */ @Command public void updateOnglet(@BindingParam("entity") T abstractEntity) { EventQueues.lookup("organigrammeQueue", EventQueues.DESKTOP, true) .publish(new UpdateOngletAbstractEntityEvent(abstractEntity, null)); } /** * Retourne le service spring associe la classe de l'entit * * @return le service spring associe la classe de l'entit */ @SuppressWarnings("unchecked") public GenericService<T> getService() { return (GenericService<T>) ApplicationContextUtils.getApplicationContext() .getBean(StringUtils.uncapitalize(getEntityName()) + "Service"); } /** * Retourne le nom simple de la classe de l'entit T * * @return ex : "EntiteDTO" */ public String getEntityName() { return OrganigrammeUtil.getSimpleNameOfClass(getEntityClass()); } /** * Retourne la classe paramtre de l'AbstractViewModel courant. * * @return la classe paramtre de l'AbstractViewModel courant. */ @SuppressWarnings("unchecked") private Class<T> getEntityClass() { return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } /** * Instancie un nouvel objet T * * @return instance cre * @throws InstantiationException * en cas d'erreur la cration de l'entity * @throws IllegalAccessException * en cas d'erreur la cration de l'entity */ protected T createEntity() throws InstantiationException, IllegalAccessException { return getEntityClass().newInstance(); } /** * Poste une commande globale pour signaler la mise jour de l'entity gre * par le ViewModel courant, en prcisant en argument l'entit concerne. * Exemple de commande globale : "updateEntiteDto" */ public void notifyUpdateEntity() { Map<String, Object> args = new HashMap<String, Object>(); args.put("entity", entity); BindUtils.postGlobalCommand(null, null, "update" + getEntityName(), args); } /** * Poste une commande globale pour signaler la mise jour d'une entity * quelconque. Exemple de commande globale : "updateDemandeur" * * @param entityUpdated * entity concerne */ protected void notifyUpdateEntity(AbstractEntity entityUpdated) { if (entityUpdated == null) { return; } Map<String, Object> args = new HashMap<String, Object>(); args.put("entity", entityUpdated); BindUtils.postGlobalCommand(null, null, "update" + OrganigrammeUtil.getSimpleClassNameOfObject(entityUpdated), args); } public static void notifyChange(String prop, Object bean) { BindUtils.postNotifyChange(null, null, bean, prop); } public void notifyChange(String prop) { notifyChange(prop, this); } public static void notifyChange(String[] listProperty, Object bean) { if (listProperty == null) { return; } if (Executions.getCurrent() == null) { return; } for (String prop : listProperty) { if (!StringUtils.isBlank(prop)) { notifyChange(prop, bean); } } } public void notifyChange(String[] listProperty) { notifyChange(listProperty, this); } public void postGlobalCommandRefreshListe() { BindUtils.postGlobalCommand(null, null, "refreshListe" + getEntityName(), null); } /** * Affiche une popup d'erreur, concernant une liste d'erreurs (si la liste * est null ou fait 0 lment, la mthode ne fait rien) * * @param listeMessageErreur * liste de messages d'erreur afficher * @return true si au moins un message a t affich */ public static boolean showErrorPopup(List<MessageErreur> listeMessageErreur) { if (CollectionUtils.isEmpty(listeMessageErreur)) { return false; } Messagebox.show(MessageErreurUtil.construitReprListeMessageErreur(listeMessageErreur), "Erreur", Messagebox.OK, Messagebox.ERROR); return true; } /** * Affiche une popup modale de messages d'erreur concernant l'entit (les * erreurs spcifiques mtier et les violations de contraintes observes sur * l'entit) * * @param entity * entit concerne * @return true si des erreurs ont t affiches, false si aucune erreur */ public static boolean showErrorPopup(AbstractEntity entity) { return showErrorPopup(entity.construitListeMessageErreur()); } /** * Affiche une popup d'erreur, concernant une erreur unique * * @param message * Message d'erreur (si le message est "blanc", la mthode ne * fait rien) * @return true si un message (non vide) a t affich, false sinon */ public static boolean showErrorPopup(String message) { if (StringUtils.isBlank(message)) { return false; } List<MessageErreur> listeMessageErreur = new ArrayList<>(); listeMessageErreur.add(new MessageErreur(message)); return AbstractViewModel.showErrorPopup(listeMessageErreur); } public void showNotificationStandard(String message) { Clients.showNotification(message, "info", null, "top_center", 0); } public Integer getMaxLength(Object object, String property) throws Exception { return OrganigrammeUtil.getMaxLength(object, property); } public Integer getMaxLengthClassProperty(String className, String property) throws Exception { return OrganigrammeUtil.getMaxLengthClassProperty(className, property); } public void ouvrePopupCreation(String template) throws InstantiationException, IllegalAccessException { Map<String, Object> arguments = new HashMap<String, Object>(); arguments.put("entity", getEntityClass().newInstance()); Window window = (Window) Executions.createComponents(template, null, arguments); window.doModal(); } public void initPopupEdition(T entity, String template) { Map<String, Object> arguments = new HashMap<String, Object>(); arguments.put("entity", entity); Executions.createComponents(template, null, arguments); BindUtils.postGlobalCommand(null, null, "ouvrePopupEdition" + getEntityName(), arguments); } }