/** * GRANITE DATA SERVICES * Copyright (C) 2006-2015 GRANITE DATA SERVICES S.A.S. * * This file is part of the Granite Data Services Platform. * * Granite Data Services 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 2.1 of the License, or (at your option) any later version. * * Granite Data Services 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 Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA, or see <http://www.gnu.org/licenses/>. */ package org.granite.binding; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; public class Bindings { public static ObservableValue not(ObservableValue source) { return new UniOperatorBinding<Boolean>(source) { @Override protected Boolean evaluate(Object val) { return val != null ? !(Boolean)val : null; } }; } public static ObservableValue and(ObservableValue value1, ObservableValue value2) { return new BiOperatorBinding<Boolean>(value1, value2) { @Override protected Boolean evaluate(Object val1, Object val2) { return val1 == null || val2 == null ? null : (Boolean.TRUE.equals(val1) && Boolean.TRUE.equals(val2)); } }; } public static ObservableValue or(ObservableValue value1, ObservableValue value2) { return new BiOperatorBinding<Boolean>(value1, value2) { @Override protected Boolean evaluate(Object val1, Object val2) { return val1 == null || val2 == null ? null : (Boolean.TRUE.equals(val1) || Boolean.TRUE.equals(val2)); } }; } public static ObservableValue equals(ObservableValue value1, ObservableValue value2) { return new BiOperatorBinding<Boolean>(value1, value2) { @Override protected Boolean evaluate(Object val1, Object val2) { return val1 == null || val2 == null ? false : val1.equals(val2); } }; } private static abstract class UniOperatorBinding<T> implements ObservableValue { private final ObservableValue source; private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); private T currentValue; public UniOperatorBinding(ObservableValue source) { this.source = source; this.currentValue = evaluate(source.getValue()); this.source.addChangeListener(notChangeListener); } public Object getValue() { return currentValue; } protected abstract T evaluate(Object val); public void addChangeListener(PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } public void removeChangeListener(PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } private final PropertyChangeListener notChangeListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent pce) { T oldValue = currentValue; currentValue = evaluate(pce.getNewValue()); pcs.firePropertyChange(pce.getPropertyName(), oldValue, currentValue); } }; } private static abstract class BiOperatorBinding<T> implements ObservableValue { private final ObservableValue value1; private final ObservableValue value2; private PropertyChangeSupport pcs = new PropertyChangeSupport(this); private T currentValue; public BiOperatorBinding(ObservableValue value1, ObservableValue value2) { this.value1 = value1; this.value2 = value2; currentValue = evaluate(value1.getValue(), value2.getValue()); value1.addChangeListener(value1ChangeListener); value2.addChangeListener(value2ChangeListener); } public Object getValue() { return currentValue; } protected abstract T evaluate(Object val1, Object val2); public void addChangeListener(PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } public void removeChangeListener(PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } private final PropertyChangeListener value1ChangeListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent pce) { T oldValue = currentValue; currentValue = evaluate(pce.getNewValue(), value2.getValue()); if (currentValue != oldValue) pcs.firePropertyChange(pce.getPropertyName(), oldValue, currentValue); } }; private final PropertyChangeListener value2ChangeListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent pce) { T oldValue = currentValue; currentValue = evaluate(value1.getValue(), pce.getNewValue()); if (currentValue != oldValue) pcs.firePropertyChange(pce.getPropertyName(), oldValue, currentValue); } }; } }