/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.core.change;
import java.io.Serializable;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.Instant;
import com.google.common.collect.Lists;
import com.opengamma.id.ObjectId;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.PublicSPI;
/**
* Manager for receiving and handling entity change events.
* <p>
* Events are sent when an entity is added, updated, removed or corrected.
* <p>
* This class is mutable and thread-safe using concurrent collections.
*/
@PublicSPI
public class BasicChangeManager implements ChangeManager, Serializable {
private static final Logger s_logger = LoggerFactory.getLogger(BasicChangeManager.class);
/**
* The listeners.
*/
private final CopyOnWriteArraySet<ChangeListener> _listeners = new CopyOnWriteArraySet<ChangeListener>();
/**
* Creates a manager.
*/
public BasicChangeManager() {
}
//-------------------------------------------------------------------------
/**
* Adds a listener to the manager.
* <p>
* The listener will receive all events.
* <p>
* This method is not intended to be overridden.
*
* @param listener the listener to add, not null
*/
@Override
public void addChangeListener(ChangeListener listener) {
ArgumentChecker.notNull(listener, "listener");
_listeners.add(listener);
}
/**
* Removed a listener from the manager.
* <p>
* The listener will cease receiving events.
* <p>
* This method is not intended to be overridden.
*
* @param listener the listener to remove, not null
*/
@Override
public void removeChangeListener(ChangeListener listener) {
ArgumentChecker.notNull(listener, "listener");
_listeners.remove(listener);
}
/**
* Gets a copy of the list of listeners.
* <p>
* This method is not intended to be overridden.
*
* @return the list of listeners, not null
*/
protected List<ChangeListener> getListeners() {
return Lists.newArrayList(_listeners);
}
//-------------------------------------------------------------------------
@Override
public void entityChanged(ChangeType type, ObjectId oid, Instant versionFrom, Instant versionTo, Instant versionInstant) {
ChangeEvent event = new ChangeEvent(type, oid, versionFrom, versionTo, versionInstant);
handleEntityChanged(event);
}
/**
* Handles an event when an entity changes.
* <p>
* This implementation calls {@link #fireEntityChanged(ChangeEvent)} directly.
* An overriding method may use a more advanced mechanism to handle the event.
*
* @param event the event that occurred, not null
*/
protected void handleEntityChanged(final ChangeEvent event) {
fireEntityChanged(event);
}
/**
* Fires an event to the local listeners when an entity changes.
* <p>
* This implementation loops around the stored listeners and calls them in
* serial on the calling thread.
*
* @param event the event that occurred, not null
*/
protected void fireEntityChanged(final ChangeEvent event) {
for (ChangeListener listener : _listeners) {
try {
listener.entityChanged(event);
} catch (Exception e) {
s_logger.error("Error while calling listener " + listener + " on entity changed", e);
}
}
}
//-------------------------------------------------------------------------
/**
* Returns a debugging string for the manager.
*
* @return the debugging string, not null
*/
@Override
public String toString() {
return getClass().getSimpleName();
}
}