summaryrefslogtreecommitdiff
path: root/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/ValueHolder.java
blob: 578ee04d75519b931b3fbc9fc996ec7861d2a80e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
 * Created on Dec 8, 2003
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package net.israfil.foundation.valuemodel;

import java.util.HashMap;
import java.util.Map;

import net.israfil.foundation.dynamic.DynamicUtil;


/**
 * @author cgruber
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class ValueHolder<E> implements MutableValue<E> {

    private E _value = null;
    private Map<Integer, ObserverHolder> _observers = new HashMap<>();
    private Map<Integer, VetoerHolder> _vetoers = new HashMap<>();

	public ValueHolder(E o) {
		set(o); 
	}
        
    protected ValueHolder() { }

	@Override
	public E get() {
		return _value;
	}

    @Override
	public void set(E newValue) {
        boolean approved = true;
        E oldValue = _value;
        for (VetoerHolder vetoer : _vetoers.values()) {
        	approved &= vetoer.evaluate(this, oldValue, newValue);
        }
        
        if (!approved) return;
        else _value = newValue;
        for (ObserverHolder observer : _observers.values()) {
            observer.notify(this, oldValue, newValue);
        }
        
    }

	/**
	 * @see org.israfil.maveric.Observable#addObserver(java.lang.Object, java.lang.String)
	 */
	@Override
	public void addObservers(String callback, Object ... observers) {
    	for (Object observer : observers) {
    		_observers.put(observer.hashCode(),new ObserverHolder(observer,callback));
    	}
	}

	/**
     * @see org.israfil.maveric.Observable#removeObserver(java.lang.Object)
	 */
	@Override
	public void removeObservers(Object ... observers) {
    	for (Object observer : observers) {
    		_observers.remove(observer.hashCode());
    	}
	}
    /**
     * @see org.israfil.maveric.Vetoable#addVetoer(java.lang.Object, java.lang.String)
     */
    @Override
	public void addVetoers(String callback, Object ... vetoers) {
    	for (Object vetoer : vetoers) {
    		_vetoers.put(vetoer.hashCode(),new VetoerHolder(vetoer,callback));
    	}
    }

    /**
     * @see org.israfil.maveric.Vetoable#removeVetoer(java.lang.Object)
     */
    @Override
	public void removeVetoers(Object ... vetoers) {
    	for (Object vetoer : vetoers) {
    		_vetoers.remove(vetoer.hashCode());
    	}
    }

    protected class CallbackObjectHolder {
        public final Object receiver;
        protected final String callback; 
        public CallbackObjectHolder(Object receiver, String callback) {
            this.receiver = receiver;
            this.callback = callback;
        }
    }
    protected class ObserverHolder extends CallbackObjectHolder {
        public ObserverHolder(Object observer, String callback) { super(observer, callback); }
        public void notify(Object notifier, Object oldValue, Object newValue) {
            DynamicUtil.performOn(receiver,callback,new Object[]{notifier, oldValue , newValue});
        }
    }
    protected class VetoerHolder extends CallbackObjectHolder {
        public VetoerHolder(Object vetoer, String callback) { super(vetoer, callback); }
        public Boolean evaluate(Object notifier, Object oldValue, Object newValue) {
            Boolean result = (Boolean)DynamicUtil.performOn(receiver,callback,new Object[]{notifier,oldValue,newValue});
            return (result == null) ? true : result.booleanValue();
        }
    }
}