/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.livedata; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import com.opengamma.livedata.msg.LiveDataSubscriptionResponse; import com.opengamma.util.ArgumentChecker; /** * {@link LiveDataClient} that tracks subscriptions and can resubscribe. * This allows subscriptions to be refreshed in the event of the underlying data source going up and down. The * subscription operations are handed off to a delegate {@link LiveDataClient}. */ public class ResubscribingLiveDataClient implements LiveDataClient { private final LiveDataClient _delegate; private final Set<Subscription> _subscriptions = Collections.newSetFromMap(new ConcurrentHashMap<Subscription, Boolean>()); public ResubscribingLiveDataClient(LiveDataClient delegate) { _delegate = ArgumentChecker.notNull(delegate, "delegate"); } @Override public void subscribe(UserPrincipal user, LiveDataSpecification spec, LiveDataListener listener) { _subscriptions.add(new Subscription(user, spec, listener)); _delegate.subscribe(user, spec, listener); } @Override public void subscribe(UserPrincipal user, Collection<LiveDataSpecification> specs, LiveDataListener listener) { for (LiveDataSpecification spec : specs) { _subscriptions.add(new Subscription(user, spec, listener)); } _delegate.subscribe(user, specs, listener); } @Override public void unsubscribe(UserPrincipal user, LiveDataSpecification spec, LiveDataListener listener) { _subscriptions.remove(new Subscription(user, spec, listener)); _delegate.unsubscribe(user, spec, listener); } @Override public void unsubscribe(UserPrincipal user, Collection<LiveDataSpecification> specs, LiveDataListener listener) { for (LiveDataSpecification spec : specs) { _subscriptions.remove(new Subscription(user, spec, listener)); } _delegate.unsubscribe(user, specs, listener); } @Override public LiveDataSubscriptionResponse snapshot(UserPrincipal user, LiveDataSpecification spec, long timeout) { return _delegate.snapshot(user, spec, timeout); } @Override public Collection<LiveDataSubscriptionResponse> snapshot(UserPrincipal user, Collection<LiveDataSpecification> specs, long timeout) { return _delegate.snapshot(user, specs, timeout); } @Override public String getDefaultNormalizationRuleSetId() { return _delegate.getDefaultNormalizationRuleSetId(); } @Override public void close() { _delegate.close(); } @Override public boolean isEntitled(UserPrincipal user, LiveDataSpecification spec) { return _delegate.isEntitled(user, spec); } @Override public Map<LiveDataSpecification, Boolean> isEntitled(UserPrincipal user, Collection<LiveDataSpecification> specs) { return _delegate.isEntitled(user, specs); } public void resubscribe() { for (Subscription subscription : _subscriptions) { _delegate.subscribe(subscription._user, subscription._spec, subscription._listener); } } private static final class Subscription { private final UserPrincipal _user; private final LiveDataSpecification _spec; private final LiveDataListener _listener; private Subscription(UserPrincipal user, LiveDataSpecification spec, LiveDataListener listener) { _user = user; _spec = spec; _listener = listener; } @Override public int hashCode() { return Objects.hash(_user, _spec, _listener); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } final Subscription other = (Subscription) obj; return Objects.equals(this._user, other._user) && Objects.equals(this._spec, other._spec) && Objects.equals(this._listener, other._listener); } } }