public MutableSet<Entry<K, V>> entrySet() { synchronized (this.lock) { return SynchronizedMutableSet.of(this.getSortedMap().entrySet(), this.lock); } }
public MutableSet<K> keySet() { synchronized (this.lock) { return SynchronizedMutableSet.of(this.getSortedMap().keySet(), this.lock); } }
/** * Implementation of {@link reactor.data.core.state.StateMachine} that uses an {@link * reactor.core.Observable} to notify states of new values. * * @author Jon Brisbin */ public class ObservableStateMachine<T> implements StateMachine<T> { private final MutableSet<Object> states = SynchronizedMutableSet.of(UnifiedSet.newSet()); private final MutableMultimap<Object, Tuple2<?, Predicate<T>>> transitions = SynchronizedPutFastListMultimap.newMultimap(); private final boolean strict; private final Observable observable; /** * Create an new {@code ObservableStateMachine} using the given {@link reactor.core.Observable} * and denoting whether this {@link reactor.data.core.state.StateMachine} should operate in strict * mode. * * @param observable {@code Observable} to use * @param strict whether or not to operate in strict mode * @see {@link StateMachine#strict()} */ public ObservableStateMachine(Observable observable, boolean strict) { this.observable = observable; this.strict = strict; } @Override public Observable observable() { return observable; } @Override public StateMachine<T> define(Object... states) { for (Object state : states) { define(state); } return this; } @Override public <V> StateMachine<T> define(V state) { states.add(state); return this; } @Override public <V> boolean contains(V state) { return states.contains(state); } @Override public boolean strict() { return strict; } @Override public <FROM, TO> StateMachine<T> connect(FROM from, TO to) { return connect(from, to, null); } @Override public <FROM, TO> StateMachine<T> connect(FROM from, TO to, Predicate<T> predicate) { transitions.put(from, Tuple.of(to, predicate)); return this; } @Override public <FROM, TO> StateMachine<T> disconnect(FROM from, TO to) { transitions.remove(from, to); return this; } @Override public <V, X extends Throwable> StateMachine<T> when( Class<X> errorType, final Consumer<Tuple3<V, T, X>> errorConsumer) { observable.on( Selectors.type(errorType), new Consumer<Event<Throwable>>() { @SuppressWarnings("unchecked") @Override public void accept(Event<Throwable> ev) { if (null != errorConsumer && ev.getData() instanceof StateException) { V state = (V) ((StateException) ev.getData()).state; X cause = (X) ev.getData().getCause(); T data = (T) ((StateException) ev.getData()).data; errorConsumer.accept(Tuple.of(state, data, cause)); } } }); return this; } @Override public <V> StateMachine<T> on(final V state, final Function<T, T> fn) { if (strict) { Assert.isTrue(states.contains(state), "State " + state + " has not been defined"); } observable.on( (state instanceof Selector ? (Selector) state : Selectors.object(state)), new Consumer<Event<T>>() { @SuppressWarnings("unchecked") @Override public void accept(final Event<T> data) { try { data.setData(fn.apply(data.getData())); } catch (Throwable t) { observable.notify( t.getClass(), Event.wrap(new StateException(t, state, data.getData()))); } } }); return this; } @Override public <V> StateMachine<T> notify(V state) { return notify(state, null); } @SuppressWarnings("unchecked") @Override public <V> StateMachine<T> notify(final V state, final T value) { if (strict) { Assert.isTrue(states.contains(state), "State " + state + " has not been defined"); } Event<T> ev = Event.wrap(value instanceof Event ? ((Event<T>) value).getData() : value); observable.notify( state, ev, new Consumer<Event<T>>() { @Override public void accept(final Event<T> ev) { transition(state, ev.getData()); } }); return this; } private <V> void transition(V from, final T data) { MutableCollection<Tuple2<?, Predicate<T>>> ts = transitions.get(from); if (ts.isEmpty()) { return; } ts.forEach( new Procedure<Tuple2<?, Predicate<T>>>() { @SuppressWarnings("unchecked") @Override public void value(Tuple2<?, Predicate<T>> tup) { if (null == tup.getT2() || tup.getT2().test(data)) { ObservableStateMachine.this.notify(tup.getT1(), data); } } }); } private static class StateException extends Exception { private final Object state; private final Object data; private StateException(Throwable cause, Object state, Object data) { super(cause); this.state = state; this.data = data; } @Override public String toString() { return "StateException{" + "state=" + state + ", data=" + data + '}'; } } }