/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.master; import java.util.Collection; import java.util.concurrent.ConcurrentHashMap; import com.opengamma.DataNotFoundException; import com.opengamma.core.AbstractSource; import com.opengamma.core.ObjectChangeListener; import com.opengamma.core.ObjectChangeListenerManager; import com.opengamma.core.Source; import com.opengamma.core.change.ChangeEvent; import com.opengamma.core.change.ChangeListener; import com.opengamma.core.change.ChangeManager; import com.opengamma.id.ObjectId; import com.opengamma.id.UniqueId; import com.opengamma.id.UniqueIdentifiable; import com.opengamma.id.VersionCorrection; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.PublicSPI; import com.opengamma.util.tuple.Pair; import com.opengamma.util.tuple.Pairs; /** * An abstract source built on top of an underlying master. * * @param <V> the type of the stored value * @param <D> the type of the document * @param <M> the type of the master */ @PublicSPI public abstract class AbstractMasterSource<V extends UniqueIdentifiable, D extends AbstractDocument, M extends AbstractChangeProvidingMaster<? extends D>> extends AbstractSource<V> implements Source<V>, ObjectChangeListenerManager { /** * The master. */ private final M _master; /** * The listeners. */ private final ConcurrentHashMap<Pair<ObjectId, ObjectChangeListener>, ChangeListener> _registeredListeners = new ConcurrentHashMap<Pair<ObjectId, ObjectChangeListener>, ChangeListener>(); /** * Creates an instance with an underlying master. * * @param master the master, not null */ public AbstractMasterSource(final M master) { ArgumentChecker.notNull(master, "master"); _master = master; } //------------------------------------------------------------------------- /** * Gets the underlying master. * * @return the master, not null */ public M getMaster() { return _master; } //------------------------------------------------------------------------- /** * Gets a document from the master by unique identifier. * <p> * This overrides the version in the unique identifier if set to do so. * * @param uniqueId the unique identifier, not null * @return the document, not null * @throws DataNotFoundException if the document could not be found */ public D getDocument(UniqueId uniqueId) { ArgumentChecker.notNull(uniqueId, "uniqueId"); return (D) getMaster().get(uniqueId); } /** * Gets a document from the master by object identifier and version-correction. * <p> * The specified version-correction may be overridden if set to do so. * * @param objectId the object identifier, not null * @param versionCorrection the version-correction, not null * @return the document, not null * @throws DataNotFoundException if the document could not be found */ public D getDocument(ObjectId objectId, VersionCorrection versionCorrection) { ArgumentChecker.notNull(objectId, "objectId"); ArgumentChecker.notNull(versionCorrection, "versionCorrection"); return (D) getMaster().get(objectId, versionCorrection); } //------------------------------------------------------------------------- @SuppressWarnings("unchecked") @Override public V get(UniqueId uniqueId) { return (V) getDocument(uniqueId).getValue(); } @SuppressWarnings("unchecked") @Override public V get(ObjectId objectId, VersionCorrection versionCorrection) { return (V) getMaster().get(objectId, versionCorrection).getValue(); } public V getFirstObject(Collection<? extends V> objects) { return objects.isEmpty() ? null : objects.iterator().next(); } //------------------------------------------------------------------------- @Override public void addChangeListener(final ObjectId oid, final ObjectChangeListener listener) { ChangeListener changeListener = new ChangeListener() { @Override public void entityChanged(ChangeEvent event) { ObjectId changedOid = event.getObjectId(); if (changedOid.equals(oid)) { listener.objectChanged(oid); } } }; _registeredListeners.put(Pairs.of(oid, listener), changeListener); changeManager().addChangeListener(changeListener); } @Override public void removeChangeListener(ObjectId oid, ObjectChangeListener listener) { ChangeListener changeListener = _registeredListeners.remove(Pairs.of(oid, listener)); changeManager().removeChangeListener(changeListener); } public ChangeManager changeManager() { return getMaster().changeManager(); } //------------------------------------------------------------------------- @Override public String toString() { return getClass().getSimpleName() + "[" + getMaster() + "]"; } }