All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.ultreia.java4all.bean.monitor.BeanMonitor Maven / Gradle / Ivy

The newest version!
package io.ultreia.java4all.bean.monitor;

/*-
 * #%L
 * Java Beans extends by Ultreia.io
 * %%
 * Copyright (C) 2018 - 2022 Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser 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 Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import io.ultreia.java4all.bean.JavaBean;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;

/**
 * Created on 10/06/2021.
 * A monitor of beans.
 * 

* You indicates which properties to monitor (via the constructor). *

* Then attach a bean to monitor via the method {@link #setBean(JavaBean)}. *

* The method {@link #clearModified()} reset the states about modified * properties. *

* The method {@link #wasModified()} tells if there was any modification on * monitored properties for the attached bean since the last call to * {@link #clearModified()} (or {@link #setBean(JavaBean)}. *

* the method {@link #getModifiedProperties()} gives you the names of monitored * properties for the attached bean since the last call to * {@link #clearModified()} (or {@link #setBean(JavaBean)}. * * @author Tony Chemit - [email protected] * @since 0.1.5 * @deprecated since 0.2.2, prefer use now {@link JavaBeanMonitor} */ @Deprecated public class BeanMonitor { /** * Names of properties to watch or not on attached bean. */ protected final List propertyNames; /** * Names of monitored and modified properties for the attached bean. */ protected final Map propertyDiffs; /** * The {@link PropertyChangeListener} which listen modification on bean * only on monitored properties. */ protected final PropertyChangeListener listener; /** * If true, then listen to the properties which are not in the propertyNames */ protected boolean excludeMode; /** * The bean to monitor. */ protected JavaBean bean; /** * Constructor of monitor with property names to monitor. * * @param propertyNames the names of properties to monitor */ public BeanMonitor(String... propertyNames) { this(false, propertyNames); } public BeanMonitor(boolean exclude, String... propertyNames) { this.excludeMode = exclude; this.propertyNames = new ArrayList<>(Arrays.asList(propertyNames)); propertyDiffs = new LinkedHashMap<>(); listener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { String propertyName = evt.getPropertyName(); if (excludeMode && BeanMonitor.this.propertyNames.contains(propertyName) || !excludeMode && !BeanMonitor.this.propertyNames.contains(propertyName)) { return; } // the property is monitored Object newValue = evt.getNewValue(); Object oldValue = evt.getOldValue(); PropertyDiff propertyDiff; if (propertyDiffs.containsKey(propertyName)) { // property was already modified propertyDiff = propertyDiffs.get(propertyName); // change the target value propertyDiff.setTargetValue(newValue); // check if value did not come back to original Object originalValue = propertyDiff.getSourceValue(); if (Objects.equals(originalValue, newValue)) { // coming back to original value // the property is no more modified propertyDiffs.remove(propertyName); } } else { // check old value and newvalue are real not equals if (!Objects.equals(newValue, oldValue)) { propertyDiff = new PropertyDiff( propertyName, oldValue, propertyName, newValue, null ); // add it to modified properties propertyDiffs.put(propertyName, propertyDiff); } } } }; } /** * Obtains the monitored {@link #bean}. * * @return the attached bean, or {@code null} if none attached. */ public Object getBean() { return bean; } /** * Tells if any of the monitored properties were modified on the attached * bean since last call to {@link #clearModified()} or * {@link #setBean(JavaBean)}. * * @return {@code true} if there were a modified monitored property on * the attached bean, {@code false} otherwise. */ public boolean wasModified() { return !propertyDiffs.isEmpty(); } /** * Obtains the names of monitored properties which has been touched for the * attached bean since last call to {@link #clearModified()} or * {@link #setBean(JavaBean)}. * * @return the array of property names to monitor. */ public String[] getModifiedProperties() { Set propertyNames = propertyDiffs.keySet(); return propertyNames.toArray(new String[0]); } /** * Obtains the original values for all modified properties. * * @return the dictionnary of original values for modified properties */ public Map getOriginalValues() { // always expose a copy of map Map map = new TreeMap<>(); for (PropertyDiff propertyDiff : propertyDiffs.values()) { map.put(propertyDiff.getSourceProperty(), propertyDiff.getSourceValue()); } return map; } /** * Obtains the property diffs since the bean is monitoried. * * @return the property diffs since the bean is monitoried. * @since 2.4 */ public PropertyDiff[] getPropertyDiffs() { Collection values = propertyDiffs.values(); return values.toArray(new PropertyDiff[0]); } /** * Sets the {@code bean} to monitor. *

* As a side effect, it will attach the {@link #listener} to new bean * (if not null) and remove it from the previous bean attached (if not null). *

* As a second side effect, it will always clean the modified states, * using the method {@link #clearModified()}. * * @param bean the new bean to monitor */ public void setBean(JavaBean bean) { JavaBean oldBean = this.bean; this.bean = bean; // while removing a bean must clean modified states clearModified(); if (oldBean != null) { // remove listener from old bean oldBean.removePropertyChangeListener(listener); } if (bean != null) { // add listener to new bean bean.addPropertyChangeListener(listener); } } /** * To clear the modified states. */ public void clearModified() { propertyDiffs.clear(); } /** * To change the list of properties to watch. * * Note: As a side-effect, we call a * {@link #clearModified()} method after having changed the list of * properties to watch. * * @param properties the list of properties to watch on the bean. * @since 3.0 */ public void setProperties(String... properties) { propertyNames.clear(); propertyNames.addAll(Arrays.asList(properties)); clearModified(); } public boolean isExcludeMode() { return excludeMode; } public void setExcludeMode(boolean excludeMode) { this.excludeMode = excludeMode; clearModified(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy