/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.config;
import com.opengamma.core.change.BasicChangeManager;
import com.opengamma.core.change.ChangeEvent;
import com.opengamma.core.change.ChangeListener;
import com.opengamma.core.change.ChangeManager;
import com.opengamma.core.change.ChangeProvider;
import com.opengamma.core.change.ChangeType;
import com.opengamma.engine.function.FunctionCompilationContext;
import com.opengamma.engine.function.FunctionDefinition;
import com.opengamma.engine.function.FunctionReinitializer;
import com.opengamma.id.ObjectId;
import com.opengamma.id.VersionCorrection;
import com.opengamma.util.ArgumentChecker;
/**
* A {@link ChangeProvider} that translates configuration changes from document identifiers to type summaries.
* <p>
* This can be used for re-initialization of functions that look up configuration items by name.
*/
public abstract class AbstractConfigChangeProvider implements ChangeProvider {
/**
* The scheme used in object identifiers that this generates change notifications for.
*/
public static final String CONFIG_TYPE_SCHEME = "ConfigItemType";
/**
* Requests the function be reinitialized whenever configurations of the given type change.
*
* @param context the compilation context, not null
* @param function the function, not null
* @param type the type to watch
*/
public static void reinitOnChanges(final FunctionCompilationContext context, final FunctionDefinition function, final Class<?> type) {
final FunctionReinitializer reinit = context.getFunctionReinitializer();
if (reinit != null) {
reinit.reinitializeFunction(function, ObjectId.of(CONFIG_TYPE_SCHEME, type.getName()));
}
}
private final ChangeListener _changeListener = new ChangeListener() {
@Override
public void entityChanged(final ChangeEvent event) {
switch (event.getType()) {
case ADDED:
configAdded(event);
break;
case CHANGED:
configChanged(event);
break;
case REMOVED:
configRemoved(event);
break;
default:
throw new UnsupportedOperationException(event.toString());
}
}
};
private final BasicChangeManager _changeManager = new BasicChangeManager() {
@Override
public synchronized void addChangeListener(final ChangeListener listener) {
ArgumentChecker.notNull(listener, "listener");
if (getListeners().isEmpty()) {
getUnderlying().changeManager().addChangeListener(_changeListener);
}
super.addChangeListener(listener);
}
@Override
public synchronized void removeChangeListener(final ChangeListener listener) {
super.removeChangeListener(listener);
if (getListeners().isEmpty()) {
getUnderlying().changeManager().removeChangeListener(_changeListener);
}
}
};
protected abstract ChangeProvider getUnderlying();
protected VersionCorrection getNewVersion(final ChangeEvent event) {
return VersionCorrection.of(event.getVersionFrom(), event.getVersionInstant());
}
protected VersionCorrection getOldVersion(final ChangeEvent event) {
return VersionCorrection.of(event.getVersionFrom().minusNanos(1L), event.getVersionInstant());
}
protected abstract void configAdded(ChangeEvent event);
protected abstract void configChanged(ChangeEvent event);
protected abstract void configRemoved(ChangeEvent event);
private void notifyListeners(final ChangeEvent event, final Class<?> clazz, final ChangeType type) {
_changeManager.entityChanged(type, ObjectId.of(CONFIG_TYPE_SCHEME, clazz.getName()), event.getVersionFrom(), event.getVersionTo(), event.getVersionInstant());
}
protected void added(final ChangeEvent event, final Class<?> type) {
notifyListeners(event, type, ChangeType.ADDED);
}
protected void changed(final ChangeEvent event, final Class<?> type) {
notifyListeners(event, type, ChangeType.CHANGED);
}
protected void removed(final ChangeEvent event, final Class<?> type) {
notifyListeners(event, type, ChangeType.REMOVED);
}
// ChangeProvider
@Override
public ChangeManager changeManager() {
return _changeManager;
}
}