This is an automated email from the git hooks/post-receive script. New commit to branch feature/7017 in repository observe. See http://git.codelutin.com/observe.git commit 6dd624e73ffe037bf5d06d354f306c4d0d00044c Author: Tony CHEMIT <chemit@codelutin.com> Date: Tue May 5 15:27:29 2015 +0200 mise en place du cache sur les listes de référentiels (refs #7017) --- .../main/java/fr/ird/observe/ObserveContext.java | 30 +- .../ird/observe/ui/content/ContentUIHandler.java | 34 +- .../observe/ui/content/ContentUIInitializer.java | 513 +++++++++------------ .../ird/observe/ui/content/ObserveContentUI.java | 2 - .../ird/observe/ui/content/ReferentialCache.java | 115 +++++ .../ui/content/ref/ContentReferenceUIHandler.java | 76 ++- .../ref/ReferentialContentUIInitializer.java | 122 ++--- .../table/impl/longline/CatchLonglineUI.css | 3 - .../ui/content/table/impl/longline/TdrUI.css | 3 - .../ui/util/ReferentielListCellRenderer.java | 80 ++++ .../observe/ui/util/TooltipListCellRenderer.java | 44 ++ 11 files changed, 619 insertions(+), 403 deletions(-) diff --git a/observe-swing/src/main/java/fr/ird/observe/ObserveContext.java b/observe-swing/src/main/java/fr/ird/observe/ObserveContext.java index 8eafd51..e63103e 100644 --- a/observe-swing/src/main/java/fr/ird/observe/ObserveContext.java +++ b/observe-swing/src/main/java/fr/ird/observe/ObserveContext.java @@ -28,6 +28,7 @@ import fr.ird.observe.db.constants.DbMode; import fr.ird.observe.db.event.DataSourceEvent; import fr.ird.observe.db.event.DataSourceListenerAdapter; import fr.ird.observe.db.impl.H2DataSource; +import fr.ird.observe.entities.referentiel.ReferenceEntity; import fr.ird.observe.services.ObserveService; import fr.ird.observe.services.ObserveServiceFactory; import fr.ird.observe.services.ObserveServicesCache; @@ -51,6 +52,7 @@ import fr.ird.observe.ui.actions.shared.SaveEditUIAction; import fr.ird.observe.ui.actions.shared.SelectNodeUIAction; import fr.ird.observe.ui.actions.shared.SelectOpenNodeUIAction; import fr.ird.observe.ui.content.ContentUI; +import fr.ird.observe.ui.content.ReferentialCache; import fr.ird.observe.ui.tree.ObserveTreeHelper; import jaxx.runtime.context.JAXXContextEntryDef; import jaxx.runtime.swing.CardLayout2; @@ -106,6 +108,12 @@ public class ObserveContext extends ObserveApplicationContext { public static final JAXXContextEntryDef<List<String>> NODE_TO_RESELECT_ENTRY_DEF = UIHelper.newListContextEntryDef("nodeToReselect"); + protected final ObserveServiceFactory serviceFactory = new ObserveServiceFactory(this); + + protected final ObserveServicesCache servicesCache = new ObserveServicesCache(serviceFactory); + + protected final ReferentialCache referentialCache = new ReferentialCache(); + /** * Récupération du contexte applicatif. * @@ -247,6 +255,14 @@ public class ObserveContext extends ObserveApplicationContext { return service; } + public static <R extends ReferenceEntity> ReferentialCache.ReferentialList<R> getReferentialList(Class<R> referentialCache) { + return get().referentialCache.getReferentialList(referentialCache); + } + + public static <R extends ReferenceEntity> void invalidateReferentialList(Class<R> referentialCache) { + get().referentialCache.clearEntry(referentialCache); + } + public void initStorage(ObserveConfig config, ObserveMainUI mainUI, boolean askToCreate) { try { if (config.isLocalStorageExist()) { @@ -385,9 +401,10 @@ public class ObserveContext extends ObserveApplicationContext { @Override public void onOpening(DataSourceEvent event) { + DataSource s = event.getSource(); - UIHelper.displayInfo( - t("observe.message.db.loading", s.getLabel())); + UIHelper.displayInfo(t("observe.message.db.loading", s.getLabel())); + } @Override @@ -423,8 +440,6 @@ public class ObserveContext extends ObserveApplicationContext { super.onClosing(event); - DataSource source = event.getSource(); - // on désenregistre la source du service de données ObserveServiceHelper.get().setDataSource(null); @@ -440,6 +455,9 @@ public class ObserveContext extends ObserveApplicationContext { mainUI.getTreeHelper().cleanNavigationUI(mainUI); + // clear referential cache + referentialCache.clear(); + // on met a jour l'état dans la config getConfig().setMainStorageOpened(false); } @@ -543,8 +561,4 @@ public class ObserveContext extends ObserveApplicationContext { actionMap.put(actionId, action); } - private final ObserveServiceFactory serviceFactory = new ObserveServiceFactory(this); - - protected final ObserveServicesCache servicesCache = new ObserveServicesCache(serviceFactory); - } diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/content/ContentUIHandler.java b/observe-swing/src/main/java/fr/ird/observe/ui/content/ContentUIHandler.java index 68732e2..8dc2c90 100644 --- a/observe-swing/src/main/java/fr/ird/observe/ui/content/ContentUIHandler.java +++ b/observe-swing/src/main/java/fr/ird/observe/ui/content/ContentUIHandler.java @@ -40,6 +40,7 @@ import fr.ird.observe.ui.tree.ObserveTreeHelper; import jaxx.runtime.JAXXContext; import jaxx.runtime.swing.ErrorDialogUI; import jaxx.runtime.swing.JAXXButtonGroup; +import jaxx.runtime.swing.editor.bean.BeanComboBox; import jaxx.runtime.swing.editor.bean.BeanListHeader; import jaxx.runtime.validator.swing.SwingValidatorMessageTableModel; import jaxx.runtime.validator.swing.SwingValidatorUtil; @@ -50,6 +51,7 @@ import org.nuiton.decorator.Decorator; import org.nuiton.decorator.DecoratorUtil; import org.nuiton.decorator.JXPathDecorator; import org.nuiton.jaxx.widgets.gis.absolute.CoordinatesEditor; +import org.nuiton.jaxx.widgets.select.FilterableDoubleList; import org.nuiton.topia.persistence.TopiaEntity; import org.nuiton.topia.persistence.util.TopiaEntityBinder; import org.nuiton.validator.NuitonValidatorScope; @@ -67,6 +69,7 @@ import java.awt.Component; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; +import java.util.Set; import static org.nuiton.i18n.I18n.t; @@ -345,6 +348,8 @@ public abstract class ContentUIHandler<E extends TopiaEntity> { ui.setContentIcon(render.getNavigationIcon(node)); updateActions(); + + updateReferentials(); } public Icon getErrorIconIfFalse(boolean valid) { @@ -637,9 +642,34 @@ public abstract class ContentUIHandler<E extends TopiaEntity> { } protected final String getValidatorContextName(ContentMode mode) { - String contextName = - mode == ContentMode.CREATE ? "n1-create" : "n1-update"; + + String contextName = mode == ContentMode.CREATE ? "n1-create" : "n1-update"; return contextName; + + } + + @SuppressWarnings("unchecked") + protected void updateReferentials() { + + Set<String> referentialComponantNames = (Set<String>) ((JComponent) getUi()).getClientProperty(ContentUIInitializer.CLIENT_PROPERTY_REFERENTIAL_COMPONANTS); + for (String referentialComponantName : referentialComponantNames) { + + Object o = getUi().get$objectMap().get(referentialComponantName); + if (o instanceof BeanComboBox) { + + ContentUIInitializer.reload((BeanComboBox<ReferenceEntity>) o); + + } else if (o instanceof BeanListHeader) { + + ContentUIInitializer.reload((BeanListHeader<ReferenceEntity>) o); + + } else if (o instanceof FilterableDoubleList) { + + ContentUIInitializer.reload((FilterableDoubleList<ReferenceEntity>) o); + + } + } + } protected final <S extends ObserveService> S getService(Class<S> serviceType) { diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/content/ContentUIInitializer.java b/observe-swing/src/main/java/fr/ird/observe/ui/content/ContentUIInitializer.java index ac16b84..bd78fdd 100644 --- a/observe-swing/src/main/java/fr/ird/observe/ui/content/ContentUIInitializer.java +++ b/observe-swing/src/main/java/fr/ird/observe/ui/content/ContentUIInitializer.java @@ -23,18 +23,19 @@ package fr.ird.observe.ui.content; */ import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import fr.ird.observe.DecoratorService; import fr.ird.observe.ObserveContext; import fr.ird.observe.db.DataSource; import fr.ird.observe.db.DataSourceException; -import fr.ird.observe.entities.constants.ReferenceStatus; import fr.ird.observe.entities.referentiel.ReferenceEntities; import fr.ird.observe.entities.referentiel.ReferenceEntity; -import fr.ird.observe.services.referential.ReferentialService; import fr.ird.observe.ui.UIHelper; import fr.ird.observe.ui.actions.shared.AbstractUIAction; import fr.ird.observe.ui.util.BooleanEditor; +import fr.ird.observe.ui.util.ReferentielListCellRenderer; +import fr.ird.observe.ui.util.TooltipListCellRenderer; import fr.ird.observe.ui.util.tripMap.ObserveMapPane; import fr.ird.observe.util.DBHelper; import fr.ird.observe.validation.ObserveValidator; @@ -73,7 +74,6 @@ import javax.swing.ActionMap; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; -import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JScrollBar; import javax.swing.JSpinner; @@ -85,7 +85,6 @@ import javax.swing.SwingUtilities; import javax.swing.border.LineBorder; import javax.swing.table.TableCellEditor; import java.awt.Color; -import java.awt.Component; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -95,8 +94,6 @@ import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collections; import java.util.Date; @@ -104,8 +101,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import static org.nuiton.i18n.I18n.t; - /** * To initialize ui. * @@ -124,9 +119,17 @@ public class ContentUIInitializer<E extends TopiaEntity, UI extends ObserveConte public static final String CLIENT_PROPERTY_NOT_BLOCKING = "notBlocking"; + public static final String CLIENT_PROPERTY_REFERENTIAL_COMPONANTS = "referentialComponants"; + /** Logger. */ private static final Log log = LogFactory.getLog(ContentUIInitializer.class); + public static final String CLIENT_PROPERTY_REFERENTIAL_LIST_TIME_STAMP = "referentialListTimeStamp"; + + public static final String CLIENT_PROPERTY_DECORATOR = "decorator"; + + public static final String CLIENT_PROPERTY_DATA = "data"; + protected final UI ui; public ContentUIInitializer(UI ui) { @@ -212,6 +215,8 @@ public class ContentUIInitializer<E extends TopiaEntity, UI extends ObserveConte DecoratorService decoratorService = ObserveContext.get().getDecoratorService(); + Set<String> referentialLists = new HashSet<String>(); + for (String name : ui.get$objectMap().keySet()) { Object o = ui.getObjectById(name); @@ -244,17 +249,17 @@ public class ContentUIInitializer<E extends TopiaEntity, UI extends ObserveConte } if (o instanceof BeanComboBox<?>) { - init(dataSource, (BeanComboBox<?>) o); + init(referentialLists, (BeanComboBox<?>) o); continue; } if (o instanceof BeanListHeader<?>) { - init(dataSource, decoratorService, (BeanListHeader<?>) o); + init(referentialLists, decoratorService, (BeanListHeader<?>) o); continue; } if (o instanceof FilterableDoubleList<?>) { - init(dataSource, (FilterableDoubleList<?>) o); + init(referentialLists, (FilterableDoubleList<?>) o); continue; } @@ -307,6 +312,9 @@ public class ContentUIInitializer<E extends TopiaEntity, UI extends ObserveConte initBlockLayerUI(acceptedComponentNames); } + + ((JComponent) ui).putClientProperty(CLIENT_PROPERTY_REFERENTIAL_COMPONANTS, referentialLists); + } protected void initBlockLayerUI(String... doNotBlockComponentIds) { @@ -384,18 +392,18 @@ public class ContentUIInitializer<E extends TopiaEntity, UI extends ObserveConte } @SuppressWarnings("unchecked") - protected void init(DataSource dataSource, BeanComboBox beanComboBox) { - Class<ReferenceEntity> klass = (Class<ReferenceEntity>) beanComboBox.getHandler().getBeanType(); + protected void init(Set<String> referentialLists, BeanComboBox beanComboBox) { + Class<TopiaEntity> klass = (Class<TopiaEntity>) beanComboBox.getHandler().getBeanType(); if (log.isDebugEnabled()) { log.debug("init combobox for " + klass); } beanComboBox.setI18nPrefix("observe.common."); beanComboBox.setMinimumSize(new Dimension(0, 24)); - prepareBeanComboBox(dataSource, klass, beanComboBox); + prepareBeanComboBox(referentialLists, klass, beanComboBox); } @SuppressWarnings("unchecked") - protected void init(DataSource dataSource, DecoratorService decoratorService, BeanListHeader beanList) { + protected void init(Set<String> referentialLists, DecoratorService decoratorService, BeanListHeader beanList) { beanList.setI18nPrefix("observe.common."); @@ -403,7 +411,7 @@ public class ContentUIInitializer<E extends TopiaEntity, UI extends ObserveConte log.info("init list for " + beanList.getBeanType()); } - prepareEntityList(dataSource, beanList.getBeanType(), beanList); + prepareEntityList(referentialLists, beanList.getBeanType(), beanList); JList jlist = beanList.getList(); @@ -411,25 +419,23 @@ public class ContentUIInitializer<E extends TopiaEntity, UI extends ObserveConte if (init != null) { Class<TopiaEntity> klass = (Class<TopiaEntity>) init; if (log.isDebugEnabled()) { - log.debug("addDecorator to list " + - jlist.getName()); + log.debug("addDecorator to list " + jlist.getName()); } Decorator<TopiaEntity> decorator = decoratorService.getDecoratorByType(klass); - jlist.putClientProperty("decorator", decorator); + jlist.putClientProperty(CLIENT_PROPERTY_DECORATOR, decorator); } init = jlist.getClientProperty("addToogleListSelectionModel"); if (init != null && init instanceof Boolean && (Boolean) init) { if (log.isDebugEnabled()) { - log.debug("addToogleListSelectionModel to list " + - jlist.getName()); + log.debug("addToogleListSelectionModel to list " + jlist.getName()); } prepareToogleListSelectionModel(jlist); } } @SuppressWarnings("unchecked") - protected void init(DataSource dataSource, FilterableDoubleList beanList) throws DataSourceException { + protected void init(Set<String> referentialLists, FilterableDoubleList beanList) throws DataSourceException { beanList.setI18nPrefix("observe.common."); @@ -437,7 +443,7 @@ public class ContentUIInitializer<E extends TopiaEntity, UI extends ObserveConte log.info("init list for " + beanList.getBeanType()); } - prepareEntityList(dataSource, beanList.getBeanType(), beanList); + prepareEntityList(referentialLists, beanList.getBeanType(), beanList); } @@ -636,41 +642,45 @@ public class ContentUIInitializer<E extends TopiaEntity, UI extends ObserveConte * Remplit le modèle d'une liste graphique avec la liste des entités d'un * type donné sur un service de persistance donné. * - * @param dataSource le service de persistance à utiliser pour - * récupérer les entités - * @param entityClass le type de l'entité - * @param list le component graphique à initialiser + * @param referentialLists l'ensemble pour conserver les noms des composants utilisant des listes de référentiels + * @param entityClass le type de l'entité + * @param list le component graphique à initialiser * @since 1.5 */ @SuppressWarnings("unchecked") - protected <E extends TopiaEntity> void prepareEntityList(DataSource dataSource, Class<E> entityClass, FilterableDoubleList<E> list) { + protected <EE extends TopiaEntity> void prepareEntityList(Set<String> referentialLists, Class<EE> entityClass, FilterableDoubleList<EE> list) { - ObserveContext context = ObserveContext.get(); + List<EE> data; - // init list - Decorator<E> decorator = context.getDecorator(entityClass); - if (log.isDebugEnabled()) { - log.debug("Will use decorator " + decorator); - } + if (ReferenceEntity.class.isAssignableFrom(entityClass)) { - list.putClientProperty("decorator", decorator); - List<E> data; + // On charge la liste depuis le cache de référentiels + ReferentialCache.ReferentialList referentialList = ObserveContext.getReferentialList((Class) entityClass); - if (ReferenceEntity.class.isAssignableFrom(entityClass)) { + data = getReferentialList(list, referentialList, false); - Predicate<E> predicate = (Predicate<E>) list.getClientProperty(ObserveContentUI.CLIENT_PROPERTY_LIST_PREDICATE); - ReferentialService service = ObserveContext.getService(dataSource, ReferentialService.class); - data = service.getList(entityClass, predicate); + // on conserve le widget (il sera rechargé si nécessaire à l'ouverture de l'écran) + referentialLists.add(list.getName()); } else { - data = new ArrayList<E>(); + + data = new ArrayList<EE>(); + + } + + ObserveContext context = ObserveContext.get(); + Decorator<EE> decorator = context.getDecorator(entityClass); + if (log.isDebugEnabled()) { + log.debug("Will use decorator " + decorator); } + list.putClientProperty(CLIENT_PROPERTY_DECORATOR, decorator); + // sort data from first decorator context - DecoratorUtil.sort((JXPathDecorator<E>) decorator, data, 0); + DecoratorUtil.sort((JXPathDecorator<EE>) decorator, data, 0); // set datas to list and init renderer - list.init((JXPathDecorator<E>) decorator, data, Collections.<E>emptyList()); + list.init((JXPathDecorator<EE>) decorator, data, Collections.<EE>emptyList()); // get the renderer initialized ListCellRenderer renderer = list.getSelectedList().getCellRenderer(); @@ -679,56 +689,59 @@ public class ContentUIInitializer<E extends TopiaEntity, UI extends ObserveConte list.getSelectedList().setCellRenderer(new ReferentielListCellRenderer(renderer)); list.getUniverseList().setCellRenderer(new ReferentielListCellRenderer(renderer)); - list.putClientProperty("data", data); - - // listen on cache modification - EntityDoubleListPropertyChangeListener<E> listener = - new EntityDoubleListPropertyChangeListener<E>(entityClass, list); + list.putClientProperty(CLIENT_PROPERTY_DATA, data); - //FIXME Remove this -// DataService service = context.getDataService(); -// service.addReferentielPropertyChangeListener(entityClass, listener); } /** * Remplit le modèle d'une liste graphique avec la liste des entités d'un * type donné sur un service de persistance donné. * - * @param dataSource le service de persistance à utiliser pour - * récupérer les entités - * @param entityClass le type de l'entité - * @param list le component graphique à initialiser + * @param referentialLists l'ensemble pour conserver les noms des composants utilisant des listes de référentiels + * @param entityClass le type de l'entité + * @param list le component graphique à initialiser * @since 1.5 */ @SuppressWarnings("unchecked") - protected <E extends TopiaEntity> void prepareEntityList(DataSource dataSource, Class<E> entityClass, BeanListHeader<E> list) { + protected <EE extends TopiaEntity> void prepareEntityList(Set<String> referentialLists, Class<EE> entityClass, BeanListHeader<EE> list) { - ObserveContext context = ObserveContext.get(); + List<EE> data; - // init list - Decorator<E> decorator = context.getDecorator(entityClass); - if (log.isDebugEnabled()) { - log.debug("Will use decorator " + decorator); - } + if (ReferenceEntity.class.isAssignableFrom(entityClass)) { - list.putClientProperty("decorator", decorator); - List<E> data; + // On charge la liste depuis le cache de référentiels + ReferentialCache.ReferentialList referentialList = ObserveContext.getReferentialList((Class) entityClass); - if (ReferenceEntity.class.isAssignableFrom(entityClass)) { + data = getReferentialList(list, referentialList, false); - Predicate<E> predicate = (Predicate<E>) list.getClientProperty(ObserveContentUI.CLIENT_PROPERTY_LIST_PREDICATE); - ReferentialService service = ObserveContext.getService(dataSource, ReferentialService.class); - data = service.getList(entityClass, predicate); + // on conserve le widget (il sera rechargé si nécessaire à l'ouverture de l'écran) + referentialLists.add(list.getName()); } else { - data = new ArrayList<E>(); + + data = new ArrayList<EE>(); + } + if (log.isInfoEnabled()) { + log.info("entity list [" + entityClass.getName() + "] : " + data.size()); + } + + ObserveContext context = ObserveContext.get(); + + // init list + Decorator<EE> decorator = context.getDecorator(entityClass); + if (log.isDebugEnabled()) { + log.debug("Will use decorator " + decorator); + } + + list.putClientProperty(CLIENT_PROPERTY_DECORATOR, decorator); + // sort data from first decorator context - DecoratorUtil.sort((JXPathDecorator<E>) decorator, data, 0); + DecoratorUtil.sort((JXPathDecorator<EE>) decorator, data, 0); // set datas to list and init renderer - list.init((JXPathDecorator<E>) decorator, data); + list.init((JXPathDecorator<EE>) decorator, data); // get the renderer initialized ListCellRenderer renderer = list.getList().getCellRenderer(); @@ -736,342 +749,228 @@ public class ContentUIInitializer<E extends TopiaEntity, UI extends ObserveConte // add the specific renderer list.getList().setCellRenderer(new ReferentielListCellRenderer(renderer)); - list.putClientProperty("data", data); - - // listen on cache modification - EntityListPropertyChangeListener<E> listener = new EntityListPropertyChangeListener<E>(entityClass, list); + list.putClientProperty(CLIENT_PROPERTY_DATA, data); - //FIXME Remove this!!! -// DataService service = context.getDataService(); -// service.addReferentielPropertyChangeListener(entityClass, listener); } /** * Prépare un component de choix d'entités pour un type d'entité donné et * pour un service de persistance donné. * - * @param <E> le type de l'entité - * @param dataSource le service de persistance à utiliser pour récupérer - * les entités - * @param entityClass le type de l'entité - * @param comboBox le component graphique à initialiser + * @param <EE> le type de l'entité + * @param referentialLists l'ensemble pour conserver les noms des composants utilisant des listes de référentiels + * @param entityClass le type de l'entité + * @param comboBox le component graphique à initialiser */ @SuppressWarnings("unchecked") - protected <E extends TopiaEntity> void prepareBeanComboBox(DataSource dataSource, Class<E> entityClass, BeanComboBox<E> comboBox) { + protected <EE extends TopiaEntity> void prepareBeanComboBox(Set<String> referentialLists, Class<EE> entityClass, BeanComboBox<EE> comboBox) { - ObserveContext context = ObserveContext.get(); + List<EE> data; - // init combobox - Decorator<E> decorator = context.getDecorator(entityClass); + boolean referenceEntity = ReferenceEntity.class.isAssignableFrom(entityClass); - Boolean noLoad = (Boolean) comboBox.getClientProperty(ObserveContentUI.CLIENT_PROPERTY_LIST_NO_LOAD); + if (referenceEntity) { - List<E> data; + // On charge la liste depuis le cache de référentiels + ReferentialCache.ReferentialList referentialList = ObserveContext.getReferentialList((Class) entityClass); - if (noLoad != null && noLoad) { + data = getReferentialList(comboBox, referentialList, true); - if (log.isInfoEnabled()) { - log.info("Skip loading of entity list [" + entityClass.getName() + "] (listNoLoad property found)"); - } - data = Collections.emptyList(); + // on conserve le widget (il sera rechargé si nécessaire à l'ouverture de l'écran) + referentialLists.add(comboBox.getName()); } else { - // get complete data list from service - Predicate<E> predicate = (Predicate<E>) comboBox.getClientProperty(ObserveContentUI.CLIENT_PROPERTY_LIST_PREDICATE); - ReferentialService service = ObserveContext.getService(dataSource, ReferentialService.class); - data = service.getList(entityClass, predicate); + if (log.isDebugEnabled()) { + log.debug("Skip loading of entity list [" + entityClass.getName() + "] (Not a referential type)"); + } + data = Collections.emptyList(); } - boolean referenceEntity = ReferenceEntity.class.isAssignableFrom(entityClass); - - if (referenceEntity) { - - //TC-20100208 : on ne veut pas voir les elements du referentiel non actif - ReferenceEntities.filterReferentielListByStatus((List) data); - + if (log.isInfoEnabled()) { + log.info("entity list: " + entityClass.getName() + "] : " + data.size()); } + ObserveContext context = ObserveContext.get(); - if (log.isInfoEnabled()) { - log.info("entity list [" + entityClass.getName() + "] : " + data.size()); - } + // init combobox + Decorator<EE> decorator = context.getDecorator(entityClass); // add data list to combo box - comboBox.init((JXPathDecorator<E>) decorator, data); + comboBox.init((JXPathDecorator<EE>) decorator, data); final ListCellRenderer renderer = comboBox.getCombobox().getRenderer(); - ListCellRenderer toolTipRenderer = new ListCellRenderer() { + ListCellRenderer toolTipRenderer = new TooltipListCellRenderer(renderer); - @Override - public Component getListCellRendererComponent(JList list, - Object value, - int index, - boolean isSelected, - boolean cellHasFocus) { - Component comp = renderer.getListCellRendererComponent( - list, - value, - index, - isSelected, - cellHasFocus - ); - if (comp instanceof JLabel) { - JLabel jcomp = (JLabel) comp; - jcomp.setToolTipText(jcomp.getText()); - } - return comp; - } - }; comboBox.getCombobox().setRenderer(toolTipRenderer); if (log.isDebugEnabled()) { - log.debug("combo list [" + entityClass.getName() + "] : " + - comboBox.getData().size()); + log.debug("combo list [" + entityClass.getName() + "] : " + comboBox.getData().size()); } - if (referenceEntity) { - - // listen on cache modification - BeanComboBoxPropertyChangeListener listener = - new BeanComboBoxPropertyChangeListener(entityClass, comboBox) { + } - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (log.isDebugEnabled()) { - log.debug("entity list [" + evt.getPropertyName() + "]"); - } - super.propertyChange(evt); - } - }; + @SuppressWarnings("unchecked") + public static <EE extends ReferenceEntity> void reload(BeanListHeader<EE> list) { - //FIXME Remove this -// context.getDataService().addReferentielPropertyChangeListener(entityClass, listener); + Date timeStamp = (Date) list.getClientProperty(CLIENT_PROPERTY_REFERENTIAL_LIST_TIME_STAMP); - } + Class<EE> beanType = list.getBeanType(); - } + ReferentialCache.ReferentialList<EE> referentialList = ObserveContext.getReferentialList(beanType); - /** - * Un écouteur de changement les entités d'un type donné contenues dans une - * liste graphique donnée. - * - * @param <E> le type des entités - */ - protected static class EntityListPropertyChangeListener - <E extends TopiaEntity> implements PropertyChangeListener { + Date lastUpdate = referentialList.getTimeStamp(); - /** le type des entités */ - private Class<E> entityClass; + if (lastUpdate.after(timeStamp)) { - /** la liste graphique */ - private BeanListHeader<E> list; + // reload list + List<EE> data = getReferentialList(list, referentialList, false); - public EntityListPropertyChangeListener(Class<E> entityClass, - BeanListHeader<E> list) { - this.entityClass = entityClass; - this.list = list; - } + if (log.isInfoEnabled()) { + log.info("reloading entities list: " + referentialList); + } - @SuppressWarnings({"unchecked"}) - @Override - public void propertyChange(PropertyChangeEvent evt) { + Decorator<EE> decorator = (Decorator<EE>) list.getClientProperty(CLIENT_PROPERTY_DECORATOR); - List<E> newValue = (List<E>) evt.getNewValue(); + DecoratorUtil.sort((JXPathDecorator<EE>) decorator, data, 0); + EE selectedValue = list.getSelectedValue(); + list.putClientProperty(CLIENT_PROPERTY_DATA, data); + list.setData(Collections.<EE>emptyList()); + list.setData(data); + if (selectedValue != null && data.contains(selectedValue)) { - Decorator<E> decorator = (Decorator<E>) - list.getClientProperty("decorator"); + // reselect it + list.getList().setSelectedValue(selectedValue, true); - if (log.isDebugEnabled()) { - log.debug("reloading entities list for [" + entityClass + - "], size : " + newValue.size()); } - DecoratorUtil.sort((JXPathDecorator<E>) decorator, newValue, 0); - E selectedValue = list.getSelectedValue(); - list.putClientProperty("data", newValue); - list.setData(Collections.<E>emptyList()); - list.setData(newValue); - if (selectedValue != null && newValue.contains(selectedValue)) { + } else { - // reselect it - list.getList().setSelectedValue(selectedValue, true); + if (log.isInfoEnabled()) { + log.info("Up-to-date entities list: " + referentialList); } + } + } - /** - * Un écouteur de changement les entités d'un type donné contenues dans une - * liste graphique donnée. - * - * @param <E> le type des entités - */ - protected static class EntityDoubleListPropertyChangeListener - <E extends TopiaEntity> implements PropertyChangeListener { + @SuppressWarnings("unchecked") + public static <EE extends ReferenceEntity> void reload(FilterableDoubleList<EE> list) { - /** le type des entités */ - private Class<E> entityClass; + Date timeStamp = (Date) list.getClientProperty(CLIENT_PROPERTY_REFERENTIAL_LIST_TIME_STAMP); - /** la liste graphique */ - private FilterableDoubleList<E> list; + Class<EE> beanType = list.getBeanType(); - public EntityDoubleListPropertyChangeListener(Class<E> entityClass, - FilterableDoubleList<E> list) { - this.entityClass = entityClass; - this.list = list; - } + ReferentialCache.ReferentialList<EE> referentialList = ObserveContext.getReferentialList(beanType); - @SuppressWarnings({"unchecked"}) - @Override - public void propertyChange(PropertyChangeEvent evt) { + Date lastUpdate = referentialList.getTimeStamp(); - List<E> newValue = (List<E>) evt.getNewValue(); + if (lastUpdate.after(timeStamp)) { - Decorator<E> decorator = (Decorator<E>) - list.getClientProperty("decorator"); + // reload list + List<EE> data = getReferentialList(list, referentialList, false); - if (log.isDebugEnabled()) { - log.debug("reloading entities list for [" + entityClass + - "], size : " + newValue.size()); + if (log.isInfoEnabled()) { + log.info("reloading entities list: " + referentialList); } - DecoratorUtil.sort((JXPathDecorator<E>) decorator, newValue, 0); - list.putClientProperty("data", newValue); + Decorator<EE> decorator = (Decorator<EE>) list.getClientProperty(CLIENT_PROPERTY_DECORATOR); + DecoratorUtil.sort((JXPathDecorator<EE>) decorator, data, 0); - List<E> selectedValues = new ArrayList<E>(list.getModel().getSelected()); + List<EE> selectedValues = new ArrayList<EE>(list.getModel().getSelected()); - list.setUniverse(Collections.<E>emptyList()); - list.setUniverse(newValue); + list.setUniverse(Collections.<EE>emptyList()); + list.setUniverse(data); - selectedValues.retainAll(newValue); + selectedValues.retainAll(data); // reselect it list.setSelected(selectedValues); + } else { + + if (log.isInfoEnabled()) { + log.info("Up-to-date entities list: " + referentialList); + } + } + } - /** - * Un renderer de liste d'entites d'un referentiel dans le quel on veut - * differencier les entites qui sont desactivees. - * - * @author Tony Chemit - chemit@codelutin.com - * @since 1.2 - */ - public static class ReferentielListCellRenderer implements ListCellRenderer { + @SuppressWarnings("unchecked") + public static <EE extends ReferenceEntity> void reload(BeanComboBox<EE> comboBox) { - /** la couleur normal pour les entites non desactivees */ - protected Color normalColor; + Date timeStamp = (Date) comboBox.getClientProperty(CLIENT_PROPERTY_REFERENTIAL_LIST_TIME_STAMP); - /** la couleur a utiliser pour les entites desactivees */ - protected Color disableColor = Color.LIGHT_GRAY; + Class<EE> beanType = comboBox.getBeanType(); - protected ListCellRenderer delegate; + ReferentialCache.ReferentialList<EE> referentialList = ObserveContext.getReferentialList(beanType); - public ReferentielListCellRenderer(ListCellRenderer delegate) { - this.delegate = delegate; - } + Date lastUpdate = referentialList.getTimeStamp(); + + if (lastUpdate.after(timeStamp)) { - @Override - public Component getListCellRendererComponent(JList list, - Object value, - int index, - boolean isSelected, - boolean cellHasFocus) { - JComponent comp; - comp = (JComponent) delegate.getListCellRendererComponent( - list, - value, - index, - isSelected, - cellHasFocus); - if (normalColor == null) { - // premiere fois, on intialise la couleur dite normale - normalColor = comp.getForeground(); + // reload list + List<EE> data = getReferentialList(comboBox, referentialList, true); + + if (log.isInfoEnabled()) { + log.info("reloading entities list: " + referentialList); } - String tip = ((JLabel) comp).getText(); + EE selectedItem = (EE) comboBox.getSelectedItem(); + + comboBox.setData(data); + + if (selectedItem != null) { - // par defaut, on utilise la couleur normale - Color col = normalColor; - if (value != null && - value instanceof ReferenceEntity) { + // obtain back the selected item from the new list - ReferenceEntity e = (ReferenceEntity) value; - ReferenceStatus status = e.getStatus(); + EE newSelectedItem = UIHelper.getEntity(data, selectedItem); - if (status == ReferenceStatus.disabled) { - // l'entite est desactivee - // on la grise pour bien la differencier - col = disableColor; - tip = t("observe.common.obsolete.entity", tip); + comboBox.setSelectedItem(null); - } else { - tip = null; + if (newSelectedItem != null) { + comboBox.setSelectedItem(newSelectedItem); } - } else { - tip = null; } - comp.setForeground(col); - comp.setToolTipText(tip); - return comp; - } - } - /** - * Un écouteur de changement des entités d'un type donnés contenues dans le - * modèle d'une liste déroulante graphique donnée. - * - * @param <E> le type des entités - */ - protected static class BeanComboBoxPropertyChangeListener - <E extends ReferenceEntity> implements PropertyChangeListener { - - /** le type des entités à écouter */ - private final Class<E> entityClass; + } else { - /** la liste à choix graphique */ - private final BeanComboBox<E> comboBox; + if (log.isInfoEnabled()) { + log.info("Up-to-date entities list: " + referentialList); + } - public BeanComboBoxPropertyChangeListener(Class<E> entityClass, BeanComboBox<E> comboBox) { - this.entityClass = entityClass; - this.comboBox = comboBox; } - @SuppressWarnings({"unchecked"}) - @Override - public void propertyChange(PropertyChangeEvent evt) { + } - // recuperation de la liste des entites - //TC-20100209 : on veut une copie de la liste puisqu'on peut la - // modifer via le filtre sur les entites sur le caractère actif - List<E> newValue = new ArrayList<E>((List<E>) evt.getNewValue()); + @SuppressWarnings("unchecked") + public static <EE extends ReferenceEntity> List<EE> getReferentialList(JComponent component, ReferentialCache.ReferentialList<EE> referentialList, boolean removeObsolete) { - if (log.isDebugEnabled()) { - log.debug("reloading entities list for [" + entityClass + - "], size : " + newValue.size()); - } - //TC-20100208 : on ne veut pas voir les elements du referentiel non actif - ReferenceEntities.filterReferentielListByStatus(newValue); + List<EE> data = new ArrayList<EE>(referentialList.getData()); - E selectedItem = (E) comboBox.getSelectedItem(); + Predicate<EE> predicate = (Predicate<EE>) component.getClientProperty(ObserveContentUI.CLIENT_PROPERTY_LIST_PREDICATE); - comboBox.setData(newValue); + if (predicate != null) { - if (selectedItem != null) { + // on applique le prédicat + data = Lists.newArrayList(Iterables.filter(data, predicate)); - // obtain back the selected item from the new list + } - E newSelectedItem = UIHelper.getEntity(newValue, selectedItem); + if (removeObsolete) { - comboBox.setSelectedItem(null); + //TC-20100208 : on ne veut pas voir les elements du referentiel non actif + ReferenceEntities.filterReferentielListByStatus((List) data); - if (newSelectedItem != null) { - comboBox.setSelectedItem(newSelectedItem); - } - } } + + // on conserve aussi la date de dernière mise à jour + component.putClientProperty(CLIENT_PROPERTY_REFERENTIAL_LIST_TIME_STAMP, referentialList.getTimeStamp()); + + return data; + } } diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/content/ObserveContentUI.java b/observe-swing/src/main/java/fr/ird/observe/ui/content/ObserveContentUI.java index 0c30ee3..ce9d974 100644 --- a/observe-swing/src/main/java/fr/ird/observe/ui/content/ObserveContentUI.java +++ b/observe-swing/src/main/java/fr/ird/observe/ui/content/ObserveContentUI.java @@ -42,8 +42,6 @@ public interface ObserveContentUI<E extends TopiaEntity> extends JAXXObject { String CLIENT_PROPERTY_LIST_PREDICATE = "listPredicate"; - String CLIENT_PROPERTY_LIST_NO_LOAD = "listNoLoad"; - ContentUIModel<E> getModel(); DataContext getDataContext(); diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/content/ReferentialCache.java b/observe-swing/src/main/java/fr/ird/observe/ui/content/ReferentialCache.java new file mode 100644 index 0000000..92ea2cc --- /dev/null +++ b/observe-swing/src/main/java/fr/ird/observe/ui/content/ReferentialCache.java @@ -0,0 +1,115 @@ +package fr.ird.observe.ui.content; + +import com.google.common.base.Preconditions; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import fr.ird.observe.ObserveContext; +import fr.ird.observe.ObserveTechnicalException; +import fr.ird.observe.entities.referentiel.ReferenceEntity; +import fr.ird.observe.services.referential.ReferentialService; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Date; +import java.util.List; +import java.util.concurrent.ExecutionException; + +/** + * Pour gérer un cache de référentiel. + * + * Pour obtenir une liste d'un référentiel, on passe toujours dans cette classe qui gère les modifications de + * référentiels. + * + * Created on 5/5/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class ReferentialCache { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ReferentialCache.class); + + protected final LoadingCache<Class<? extends ReferenceEntity>, ReferentialList<? extends ReferenceEntity>> cache; + + public ReferentialCache() { + this.cache = CacheBuilder.newBuilder().build(new CacheLoader<Class<? extends ReferenceEntity>, ReferentialList<? extends ReferenceEntity>>() { + + @SuppressWarnings("unchecked") + @Override + public ReferentialList<? extends ReferenceEntity> load(Class<? extends ReferenceEntity> key) throws Exception { + + Preconditions.checkNotNull(key, "key can't be null"); + + ReferentialService service = ObserveContext.get().getService(ReferentialService.class); + List<? extends ReferenceEntity> list = service.getList(key); + + if (log.isInfoEnabled()) { + log.info("Adding referential list " + key.getName() + " in cache"); + } + + ReferentialList<? extends ReferenceEntity> referentialList = new ReferentialList(key, list); + return referentialList; + + } + }); + + } + + @SuppressWarnings("unchecked") + public <R extends ReferenceEntity> ReferentialList<R> getReferentialList(Class<R> referentialType) { + + try { + + ReferentialList<R> result = (ReferentialList<R>) cache.get(referentialType); + return result; + + } catch (ExecutionException e) { + throw new ObserveTechnicalException("Could not get referential list: " + referentialType, e); + } + + } + + public void clearEntry(Class<? extends ReferenceEntity> referentialType) { + cache.invalidate(referentialType); + } + + public void clear() { + cache.invalidateAll(); + } + + public static class ReferentialList<R extends ReferenceEntity> { + + private final Date timeStamp; + + private final List<R> data; + + private final Class<R> entityType; + + ReferentialList(Class<R> entityType, List<R> data) { + this.entityType = entityType; + this.timeStamp = new Date(); + this.data = data; + } + + public Date getTimeStamp() { + return timeStamp; + } + + public List<R> getData() { + return data; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("entityType", entityType.getName()) + .append("timeStamp", timeStamp) + .append("size", data.size()) + .toString(); + } + } +} diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/content/ref/ContentReferenceUIHandler.java b/observe-swing/src/main/java/fr/ird/observe/ui/content/ref/ContentReferenceUIHandler.java index c30a337..a924eef 100644 --- a/observe-swing/src/main/java/fr/ird/observe/ui/content/ref/ContentReferenceUIHandler.java +++ b/observe-swing/src/main/java/fr/ird/observe/ui/content/ref/ContentReferenceUIHandler.java @@ -27,6 +27,7 @@ import fr.ird.observe.ObserveContext; import fr.ird.observe.ObserveServiceHelper; import fr.ird.observe.db.DataContext; import fr.ird.observe.db.DataSource; +import fr.ird.observe.entities.Entities; import fr.ird.observe.entities.EntityMap; import fr.ird.observe.entities.constants.ReferenceLocale; import fr.ird.observe.entities.constants.ReferenceStatus; @@ -182,6 +183,7 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten } public void selectBean(E selectedBean) { + getModel().setSelectedBean(selectedBean); // copy right now the selected bean to the model bean to respect contract @@ -393,11 +395,11 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten } }); -// UIHelper.getLayer(ui.getEditKeyTable()).setUI(ui.getEditKeyTableLayerUI()); } @Override public void openUI() throws Exception { + super.openUI(); ContentReferenceUIModel<E> model = getModel(); @@ -433,6 +435,7 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten ((JComponent) ui.getObjectById("libelle" + i)).setFont(font); } } + ContentMode mode = computeContentMode(); model.setMode(mode); if (mode != ContentMode.READ) { @@ -440,6 +443,7 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten ui.processDataBinding( ContentReferenceUI.BINDING_DELETE_FROM_LIST_ENABLED); } + } @Override @@ -467,6 +471,7 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten ContentMode mode = model.getMode(); boolean canEdit = mode != ContentMode.READ; if (canEdit) { + removeAllMessages(ui); String contextName = getValidatorContextName(mode); if (log.isDebugEnabled()) { @@ -475,26 +480,19 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten ui.getValidator().setContext(contextName); if (mode == ContentMode.CREATE) { + addInfoMessage(t("observe.message.creating.referentiel")); // creation mode - E preCreate = getService(ReferentialService.class).preCreate(model.getBeanType()); + ReferentialService service = getService(ReferentialService.class); + E preCreate = service.preCreate(model.getBeanType()); copy(model.getBeanType(), BinderService.EDIT, preCreate, bean, true); -// try { -// getDataService().preCreate(getDataSource(), -// null, -// bean, -// getLoadBinder(), -// getPreCreateExecutor() -// ); -// } catch (DataSourceException e) { -// ErrorDialogUI.showError(e); -// } - } else { + addInfoMessage(t("observe.message.updating.referentiel")); + } // do edit @@ -504,7 +502,9 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten // nothing has changed just after starting editing ui.getValidator().setChanged(false); + } + } else { // reset all validators @@ -515,12 +515,15 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten // pass in editing mode (without any modification possible) model.setEditing(true); + ObserveServiceHelper.get().getValidationContext().cleanCache(); + } } @Override protected void prepareValidationContext() { + super.prepareValidationContext(); BeanListHeader<E> jList = getUi().getListHeader(); List<E> data = jList.getData(); @@ -530,6 +533,7 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten log.debug("Set referentiel list [" + getBeanType().getSimpleName() + "] in validation context : " + data.size()); } validationContext.setEditingReferentielList(data); + } public final void createUI() { @@ -544,10 +548,10 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten } copy(getModel().getBeanType(), BinderService.EDIT, null, getBean()); -// getLoadBinder().load(null, getBean(), true); // on demarre l'edition ui.startEdit(null); + } public void modifyUI() { @@ -560,13 +564,14 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten } copy(getModel().getBeanType(), BinderService.EDIT, model.getSelectedBean(), getBean()); -// getLoadBinder().load(model.getSelectedBean(), getBean(), true); getUi().startEdit(null); + } @Override public void stopEditUI() { + super.stopEditUI(); ContentReferenceUI<E> ui = getUi(); @@ -578,7 +583,9 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten model.setMode(ContentMode.UPDATE); removeAllMessages(ui); addInfoMessage(t("observe.message.referentiel.editable")); + } + } @Override @@ -591,18 +598,23 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten } else { modifyUI(); } + } public void backToList() { + ContentReferenceUIModel<E> model = getModel(); + if (!model.isModified() || checkEdit(getUi())) { + getUi().stopEdit(); - // then resynch the selected bean to edit bean (used for - // example to delete)... + // then resynch the selected bean to edit bean (used for example to delete)... // repush selected bean to bean getLoadBinder().load(model.getSelectedBean(), getBean(), true); + } + } @Override @@ -610,7 +622,7 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten ContentReferenceUIModel<E> model = getModel(); - boolean create = bean.getTopiaId() == null; + boolean create = Entities.isNew(bean); ReferentialService service = getService(ReferentialService.class); @@ -636,6 +648,7 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten log.info("No usage found, no warning to display"); } } else { + // some usages were found boolean willsave = showUsagesForDesactivated(getUi(), bean, usages); if (!willsave) { @@ -644,6 +657,7 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten } return false; } + } } @@ -673,6 +687,7 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten } return true; + } @Override @@ -718,33 +733,48 @@ public class ContentReferenceUIHandler<E extends ReferenceEntity> extends Conten // remove the program in tree ObserveTreeHelper treeHelper = getTreeHelper(getUi()); treeHelper.removeProgram(beanId); + } + return true; + } @Override protected void afterDelete() { + + ObserveContext.invalidateReferentialList(getBeanType()); + + // Reload list + ReferentialContentUIInitializer.loadData(getUi().getListHeader(), false); + super.afterDelete(); } @Override protected void afterSave(boolean refresh) { + + ObserveContext.invalidateReferentialList(getBeanType()); + + // Reload list + ReferentialContentUIInitializer.loadData(getUi().getListHeader(), false); + super.afterSave(refresh); getUi().stopEdit(); + } public boolean canSeeI18nTable(E bean) { - return bean instanceof I18nReferenceEntity || - bean instanceof VesselSizeCategory; + return bean instanceof I18nReferenceEntity || bean instanceof VesselSizeCategory; } public String updateView(boolean editing) { + if (log.isDebugEnabled()) { log.debug("Editing has changed : " + editing); } - return editing ? - ContentReferenceUI.DETAIL_VIEW : - ContentReferenceUI.LIST_VIEW; + return editing ? ContentReferenceUI.DETAIL_VIEW : ContentReferenceUI.LIST_VIEW; + } } diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/content/ref/ReferentialContentUIInitializer.java b/observe-swing/src/main/java/fr/ird/observe/ui/content/ref/ReferentialContentUIInitializer.java index bd4aea1..e2a8130 100644 --- a/observe-swing/src/main/java/fr/ird/observe/ui/content/ref/ReferentialContentUIInitializer.java +++ b/observe-swing/src/main/java/fr/ird/observe/ui/content/ref/ReferentialContentUIInitializer.java @@ -24,10 +24,10 @@ package fr.ird.observe.ui.content.ref; import fr.ird.observe.DecoratorService; import fr.ird.observe.ObserveContext; -import fr.ird.observe.db.DataSource; import fr.ird.observe.entities.referentiel.ReferenceEntity; import fr.ird.observe.services.referential.ReferentialService; import fr.ird.observe.ui.content.ContentUIInitializer; +import fr.ird.observe.ui.util.ReferentielListCellRenderer; import jaxx.runtime.swing.editor.bean.BeanListHeader; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -39,6 +39,7 @@ import org.nuiton.topia.persistence.TopiaEntity; import javax.swing.JList; import javax.swing.ListCellRenderer; import java.util.List; +import java.util.Set; /** * Created on 11/28/14. @@ -55,55 +56,8 @@ public class ReferentialContentUIInitializer<E extends ReferenceEntity, UI exten super(ui); } - /** - * Remplit le modèle d'une liste graphique avec la liste des entités d'un - * type donné sur un service de persistance donné. - * - * @param dataSource la data source - * @param entityClass le type de l'entité - * @param list le component graphique à initialiser - * @since 1.5 - */ - public static <E extends ReferenceEntity> void prepareMainEntityList(DataSource dataSource, - Class<E> entityClass, - BeanListHeader<E> list) { - - ObserveContext context = ObserveContext.get(); - - // init list - Decorator<E> decorator = context.getDecorator(entityClass); - if (log.isDebugEnabled()) { - log.debug("Will use decorator " + decorator); - } - - list.putClientProperty("decorator", decorator); - ReferentialService service = ObserveContext.getService(dataSource, ReferentialService.class); - - List<E> data = service.loadListForEdit(entityClass); - - // sort data from first decorator context - DecoratorUtil.sort((JXPathDecorator<E>) decorator, data, 0); - - // set datas to list and init renderer - list.init((JXPathDecorator<E>) decorator, data); - - // get the renderer initialized - ListCellRenderer renderer = list.getList().getCellRenderer(); - - // add the specific renderer - list.getList().setCellRenderer(new ReferentielListCellRenderer(renderer)); - - list.putClientProperty("data", data); - - //FIXME Remove this!!! - // listen on cache modification -// EntityListPropertyChangeListener<E> listener = new EntityListPropertyChangeListener<E>(entityClass, list); -// DataService dataService = ObserveContext.get().getDataService(); -// dataService.addReferentielPropertyChangeListener(entityClass, listener); - } - @SuppressWarnings("unchecked") - protected void init(DataSource dataSource, DecoratorService decoratorService, BeanListHeader beanList) { + protected void init(Set<String> referentialLists, DecoratorService decoratorService, BeanListHeader beanList) { beanList.setI18nPrefix("observe.common."); @@ -114,11 +68,11 @@ public class ReferentialContentUIInitializer<E extends ReferenceEntity, UI exten if ("listHeader".equals(beanList.getName())) { // use the binder for loading - prepareMainEntityList(dataSource, beanList.getBeanType(), beanList); + prepareMainEntityList(beanList); } else { - super.init(dataSource, decoratorService, beanList); + super.init(referentialLists, decoratorService, beanList); } @@ -128,8 +82,7 @@ public class ReferentialContentUIInitializer<E extends ReferenceEntity, UI exten if (init != null) { Class<TopiaEntity> klass = (Class<TopiaEntity>) init; if (log.isDebugEnabled()) { - log.debug("addDecorator to list " + - jlist.getName()); + log.debug("addDecorator to list " + jlist.getName()); } Decorator<TopiaEntity> decorator; decorator = decoratorService.getDecoratorByType(klass); @@ -139,8 +92,7 @@ public class ReferentialContentUIInitializer<E extends ReferenceEntity, UI exten init = jlist.getClientProperty("addToogleListSelectionModel"); if (init != null && init instanceof Boolean && (Boolean) init) { if (log.isDebugEnabled()) { - log.debug("addToogleListSelectionModel to list " + - jlist.getName()); + log.debug("addToogleListSelectionModel to list " + jlist.getName()); } prepareToogleListSelectionModel(jlist); } @@ -155,4 +107,64 @@ public class ReferentialContentUIInitializer<E extends ReferenceEntity, UI exten ui.getEditKeyTableLayerUI().setAcceptedComponentNames(doNotBlockComponentIds); } + + /** + * Remplit le modèle d'une liste graphique avec la liste des entités d'un + * type donné sur un service de persistance donné. + * + * @param list le component graphique à initialiser + * @since 1.5 + */ + @SuppressWarnings("unchecked") + public static <EE extends ReferenceEntity> void prepareMainEntityList(BeanListHeader<EE> list) { + + Class<EE> entityClass = list.getBeanType(); + ObserveContext context = ObserveContext.get(); + + // init list + Decorator<EE> decorator = context.getDecorator(entityClass); + if (log.isDebugEnabled()) { + log.debug("Will use decorator " + decorator); + } + + list.putClientProperty(CLIENT_PROPERTY_DECORATOR, decorator); + + // get the renderer initialized + ListCellRenderer renderer = list.getList().getCellRenderer(); + + // add the specific renderer + list.getList().setCellRenderer(new ReferentielListCellRenderer(renderer)); + + loadData(list, true); + + } + + @SuppressWarnings("unchecked") + public static <EE extends ReferenceEntity> void loadData(BeanListHeader<EE> list, boolean init) { + + Class<EE> entityClass = list.getBeanType(); + + ReferentialService service = ObserveContext.get().getService(ReferentialService.class); + + List<EE> data = service.loadListForEdit(entityClass); + + Decorator<EE> decorator = (Decorator<EE>) list.getClientProperty(CLIENT_PROPERTY_DECORATOR); + + // sort data from first decorator context + DecoratorUtil.sort((JXPathDecorator<EE>) decorator, data, 0); + + if (init) { + + // set datas to list and init renderer + list.init((JXPathDecorator<EE>) decorator, data); + + } else { + + list.setData(data); + + } + list.putClientProperty(CLIENT_PROPERTY_DATA, data); + + } + } diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/longline/CatchLonglineUI.css b/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/longline/CatchLonglineUI.css index e73822c..5a72b8c 100644 --- a/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/longline/CatchLonglineUI.css +++ b/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/longline/CatchLonglineUI.css @@ -73,7 +73,6 @@ #section { property:{CatchLongline.PROPERTY_SECTION}; selectedItem:{tableEditBean.getSection()}; - _listNoLoad:{true}; } #basketLabel { @@ -84,7 +83,6 @@ #basket { property:{CatchLongline.PROPERTY_BASKET}; selectedItem:{tableEditBean.getBasket()}; - _listNoLoad:{true}; } #branchlineLabel { @@ -95,7 +93,6 @@ #branchline { property:{CatchLongline.PROPERTY_BRANCHLINE}; selectedItem:{tableEditBean.getBranchline()}; - _listNoLoad:{true}; } #speciesCatchLabel { diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/longline/TdrUI.css b/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/longline/TdrUI.css index 209344f..5a00864 100644 --- a/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/longline/TdrUI.css +++ b/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/longline/TdrUI.css @@ -133,7 +133,6 @@ #section { property:{Tdr.PROPERTY_SECTION}; selectedItem:{tableEditBean.getSection()}; - _listNoLoad:{true}; _validatorLabel: {t("observe.tdr.section")}; } @@ -145,7 +144,6 @@ #basket { property:{Tdr.PROPERTY_BASKET}; selectedItem:{tableEditBean.getBasket()}; - _listNoLoad:{true}; _validatorLabel: {t("observe.tdr.basket")}; } @@ -157,7 +155,6 @@ #branchline { property:{Tdr.PROPERTY_BRANCHLINE}; selectedItem:{tableEditBean.getBranchline()}; - _listNoLoad:{true}; _validatorLabel: {t("observe.tdr.branchline")}; } diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/util/ReferentielListCellRenderer.java b/observe-swing/src/main/java/fr/ird/observe/ui/util/ReferentielListCellRenderer.java new file mode 100644 index 0000000..a00402c --- /dev/null +++ b/observe-swing/src/main/java/fr/ird/observe/ui/util/ReferentielListCellRenderer.java @@ -0,0 +1,80 @@ +package fr.ird.observe.ui.util; + +import fr.ird.observe.entities.constants.ReferenceStatus; +import fr.ird.observe.entities.referentiel.ReferenceEntity; + +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.ListCellRenderer; +import java.awt.Color; +import java.awt.Component; + +import static org.nuiton.i18n.I18n.t; + +/** + * Un renderer de liste d'entites d'un referentiel dans le quel on veut + * differencier les entites qui sont desactivees. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.2 + */ +public class ReferentielListCellRenderer implements ListCellRenderer { + + /** la couleur normal pour les entites non desactivees */ + protected Color normalColor; + + /** la couleur a utiliser pour les entites desactivees */ + protected Color disableColor = Color.LIGHT_GRAY; + + protected ListCellRenderer delegate; + + public ReferentielListCellRenderer(ListCellRenderer delegate) { + this.delegate = delegate; + } + + @Override + public Component getListCellRendererComponent(JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + JComponent comp; + comp = (JComponent) delegate.getListCellRendererComponent( + list, + value, + index, + isSelected, + cellHasFocus); + if (normalColor == null) { + // premiere fois, on intialise la couleur dite normale + normalColor = comp.getForeground(); + } + + String tip = ((JLabel) comp).getText(); + + // par defaut, on utilise la couleur normale + Color col = normalColor; + if (value != null && + value instanceof ReferenceEntity) { + + ReferenceEntity e = (ReferenceEntity) value; + ReferenceStatus status = e.getStatus(); + + if (status == ReferenceStatus.disabled) { + // l'entite est desactivee + // on la grise pour bien la differencier + col = disableColor; + tip = t("observe.common.obsolete.entity", tip); + + } else { + tip = null; + } + } else { + tip = null; + } + comp.setForeground(col); + comp.setToolTipText(tip); + return comp; + } +} diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/util/TooltipListCellRenderer.java b/observe-swing/src/main/java/fr/ird/observe/ui/util/TooltipListCellRenderer.java new file mode 100644 index 0000000..6bc2f0e --- /dev/null +++ b/observe-swing/src/main/java/fr/ird/observe/ui/util/TooltipListCellRenderer.java @@ -0,0 +1,44 @@ +package fr.ird.observe.ui.util; + +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.ListCellRenderer; +import java.awt.Component; + +/** + * Created on 5/5/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.0 + */ +public class TooltipListCellRenderer implements ListCellRenderer { + + private final ListCellRenderer renderer; + + public TooltipListCellRenderer(ListCellRenderer renderer) { + this.renderer = renderer; + } + + @Override + public Component getListCellRendererComponent(JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + + Component comp = renderer.getListCellRendererComponent( + list, + value, + index, + isSelected, + cellHasFocus + ); + + if (comp instanceof JLabel) { + JLabel jcomp = (JLabel) comp; + jcomp.setToolTipText(jcomp.getText()); + } + return comp; + + } +} -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@list.forge.codelutin.com>.