From 7c279747beb43c7e88633a6228a155a30e6834f7 Mon Sep 17 00:00:00 2001 From: Benjamin Culkin Date: Mon, 27 May 2024 11:38:33 -0400 Subject: Initial import --- .../foundation/valuemodel/MutableValue.java | 23 +++++ .../israfil/foundation/valuemodel/Observable.java | 37 +++++++ .../net/israfil/foundation/valuemodel/Value.java | 22 +++++ .../israfil/foundation/valuemodel/ValueHolder.java | 108 +++++++++++++++++++++ .../israfil/foundation/valuemodel/Vetoable.java | 44 +++++++++ 5 files changed, 234 insertions(+) create mode 100644 israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/MutableValue.java create mode 100644 israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/Observable.java create mode 100644 israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/Value.java create mode 100644 israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/ValueHolder.java create mode 100644 israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/Vetoable.java (limited to 'israfil-foundation-valuemodel/src/main/java') diff --git a/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/MutableValue.java b/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/MutableValue.java new file mode 100644 index 0000000..74d4dd1 --- /dev/null +++ b/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/MutableValue.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2003, Israfil Consulting Services Corporation + * + * $Id$ + * $Revision$ + * + */ +package net.israfil.foundation.valuemodel; + + +/** + * A smalltalk-style generic value accessor/mutator system, where individual + * items are accessed through a single value + * + * @author Original: Christian Edward Gruber + * @author Recent: $Author$ + * + */ +public interface MutableValue extends Value, Vetoable { + + public void set(E value); + +} diff --git a/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/Observable.java b/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/Observable.java new file mode 100644 index 0000000..574c8cf --- /dev/null +++ b/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/Observable.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2003-2007 Israfil Consulting Services Corporation + * Copyright (c) 2003-2007 Christian Edward Gruber + * All Rights Reserved + * + * $Id: Types.java 129 2006-12-31 23:20:02Z cgruber $ + */ +package net.israfil.foundation.valuemodel; + +/** + * An interface for objects that can notify observers of changes to itself. The + * changing object should call the provided callback signature, with the + * parameter being the object that was changed in its new state. + * + * Using a dynamic selector rather than a strong interface allows code + * to be notified of the change even if it was not constructed with the + * notification interface, though it does need to match the signature. + * + * @author Christian Edward Gruber + * @author Latest: $Author: cgruber $ + * @version $Revision: 129 $ + */ +public interface Observable { + + /** Add an observer to this object, with a callback method spec that will + * be invoked upon a data change. The callback method should contain three + * object parameters, one for the sender, one for the old value, and one for + * the new value. The meaning of the value (same object, copy, values, etc.) + * is left to the implementation object and the observers. + */ + public void addObservers(String callback, Object ... observers); + /** + * Remove observer from observable object. + */ + public void removeObservers(Object ... observers); + +} diff --git a/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/Value.java b/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/Value.java new file mode 100644 index 0000000..8c545bd --- /dev/null +++ b/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/Value.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2003, Israfil Consulting Services Corporation + * + * $Id$ + * $Revision$ + * + */ +package net.israfil.foundation.valuemodel; + +/** + * A smalltalk-style generic value accessor/mutator system, where individual + * items are accessed through a single value + * + * @author Original: Christian Edward Gruber + * @author Recent: $Author$ + * + */ +public interface Value extends Observable { + + public E get(); + +} diff --git a/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/ValueHolder.java b/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/ValueHolder.java new file mode 100644 index 0000000..55f23c3 --- /dev/null +++ b/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/ValueHolder.java @@ -0,0 +1,108 @@ +/* + * 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 implements MutableValue { + + private E _value = null; + private Map _observers = new HashMap(); + private Map _vetoers = new HashMap(); + + public ValueHolder(E o) { + set(o); + } + + protected ValueHolder() { } + + public E get() { + return _value; + } + + 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) + */ + 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) + */ + 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) + */ + 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) + */ + 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(); + } + } +} diff --git a/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/Vetoable.java b/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/Vetoable.java new file mode 100644 index 0000000..5369287 --- /dev/null +++ b/israfil-foundation-valuemodel/src/main/java/net/israfil/foundation/valuemodel/Vetoable.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2003-2007 Israfil Consulting Services Corporation + * Copyright (c) 2003-2007 Christian Edward Gruber + * All Rights Reserved + * + * $Id: Types.java 129 2006-12-31 23:20:02Z cgruber $ + */ +package net.israfil.foundation.valuemodel; + +/** + * An interface for objects that can notify observers of changes to itself + * before the change. The objects thus notified can veto the change. The + * specific behaviour for vetoing is undefined and is dependent upon the + * particular implementation of the vetoable object and its vetoers. + * The changing object should call the provided callback signature, with the + * parameter being the object that was changed in its new state. The vetoer + * is responsible for knowing what it needs to know in order to validate or + * veto the change. + * + * Using a dynamic selector rather than a strong interface allows code + * to be notified of the change even if it was not constructed with the + * notification interface, though it does need to match the signature. + * + * @author Christian Edward Gruber + * @author Latest: $Author: cgruber $ + * @version $Revision: 129 $ + */ +public interface Vetoable { + + /** Add one or more vetoers to this object, with a callback method spec + * that will be invoked upon a data change. The callback method should + * contain three parameters. The first is the notification source (the + * holder or whatever), the second the old value, and the third the new + * value. It also should return a boolean approving the change (or + * returning false to veto it) + */ + public void addVetoers(String callback, Object ... approvers); + + /** + * Remove one or more vetoers from vetoable object. + */ + public void removeVetoers(Object ... approvers); + +} -- cgit v1.2.3