/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.core.config.impl;
import static com.google.common.collect.Sets.newHashSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Lists;
import com.opengamma.core.AbstractSource;
import com.opengamma.core.change.AggregatingChangeManager;
import com.opengamma.core.change.ChangeManager;
import com.opengamma.core.change.PassthroughChangeManager;
import com.opengamma.core.config.ConfigSource;
import com.opengamma.id.ObjectId;
import com.opengamma.id.UniqueId;
import com.opengamma.id.UniqueIdSchemeDelegator;
import com.opengamma.id.VersionCorrection;
import com.opengamma.util.ArgumentChecker;
/**
* A source of positions that uses the scheme of the unique identifier to determine which underlying source should handle the request.
* <p>
* If no scheme-specific handler has been registered, a default is used.
* <p>
* Change events are aggregated from the different sources and presented through a single change manager.
*/
public class DelegatingConfigSource
extends UniqueIdSchemeDelegator<ConfigSource>
implements ConfigSource {
/**
* Creates an instance specifying the default delegate.
*
* @param defaultSource the source to use when no scheme matches, not null
*/
public DelegatingConfigSource(final ConfigSource defaultSource) {
super(defaultSource);
}
/**
* Creates an instance specifying the default delegate.
*
* @param defaultSource the source to use when no scheme matches, not null
* @param schemePrefixToSourceMap the map of sources by scheme to switch on, not null
*/
public DelegatingConfigSource(final ConfigSource defaultSource, final Map<String, ConfigSource> schemePrefixToSourceMap) {
super(defaultSource, schemePrefixToSourceMap);
final AggregatingChangeManager changeManager = new AggregatingChangeManager();
// REVIEW jonathan 2011-08-03 -- this assumes that the delegating source lasts for the lifetime of the engine as we
// never detach from the underlying change managers.
changeManager.addChangeManager(defaultSource.changeManager());
for (final ConfigSource source : schemePrefixToSourceMap.values()) {
changeManager.addChangeManager(source.changeManager());
}
}
//-------------------------------------------------------------------------
@Override
public ConfigItem<?> get(final UniqueId uniqueId) {
ArgumentChecker.notNull(uniqueId, "uniqueId");
return chooseDelegate(uniqueId.getScheme()).get(uniqueId);
}
@Override
public ConfigItem<?> get(final ObjectId objectId, final VersionCorrection versionCorrection) {
ArgumentChecker.notNull(objectId, "objectId");
ArgumentChecker.notNull(versionCorrection, "versionCorrection");
return chooseDelegate(objectId.getScheme()).get(objectId, versionCorrection);
}
@Override
public <R> Collection<ConfigItem<R>> get(final Class<R> clazz, final String configName, final VersionCorrection versionCorrection) {
final Map<String, ConfigSource> delegates = getDelegates();
ArgumentChecker.notNull(clazz, "clazz");
ArgumentChecker.notNull(configName, "configName");
ArgumentChecker.notNull(versionCorrection, "versionCorrection");
Collection<ConfigItem<R>> results = null;
boolean alloc = false;
for (final ConfigSource configSource : delegates.values()) {
final Collection<ConfigItem<R>> configs = configSource.get(clazz, configName, versionCorrection);
if (!configs.isEmpty()) {
if (results == null) {
results = configs;
} else if (alloc) {
results.addAll(configs);
} else {
final Collection<ConfigItem<R>> newResults = Lists.newArrayListWithCapacity(results.size() + configs.size());
newResults.addAll(results);
newResults.addAll(configs);
results = newResults;
alloc = true;
}
}
}
final Collection<ConfigItem<R>> configs = getDefaultDelegate().get(clazz, configName, versionCorrection);
if (configs.isEmpty()) {
if (results == null) {
return Collections.emptySet();
} else {
return results;
}
} else {
if (results == null) {
return configs;
} else if (alloc) {
results.addAll(configs);
return results;
} else {
final Collection<ConfigItem<R>> newResults = Lists.newArrayListWithCapacity(results.size() + configs.size());
newResults.addAll(results);
newResults.addAll(configs);
return newResults;
}
}
}
@Override
public <R> Collection<ConfigItem<R>> getAll(final Class<R> clazz, final VersionCorrection versionCorrection) {
final Map<String, ConfigSource> delegates = getDelegates();
ArgumentChecker.notNull(clazz, "clazz");
ArgumentChecker.notNull(versionCorrection, "versionCorrection");
final Set<ConfigItem<R>> combined = newHashSet();
for (final ConfigSource configSource : delegates.values()) {
final Collection<ConfigItem<R>> configs = configSource.getAll(clazz, versionCorrection);
if (configs != null) {
combined.addAll(configs);
}
}
combined.addAll(getDefaultDelegate().getAll(clazz, versionCorrection));
return combined;
}
@Override
public <R> R getConfig(final Class<R> clazz, final UniqueId uniqueId) {
ArgumentChecker.notNull(clazz, "clazz");
ArgumentChecker.notNull(uniqueId, "uniqueId");
return chooseDelegate(uniqueId.getScheme()).getConfig(clazz, uniqueId);
}
@Override
public <R> R getConfig(final Class<R> clazz, final ObjectId objectId, final VersionCorrection versionCorrection) {
ArgumentChecker.notNull(clazz, "clazz");
ArgumentChecker.notNull(objectId, "objectId");
ArgumentChecker.notNull(versionCorrection, "versionCorrection");
return chooseDelegate(objectId.getScheme()).getConfig(clazz, objectId, versionCorrection);
}
@Override
public <R> R getSingle(final Class<R> clazz, final String configName, final VersionCorrection versionCorrection) {
ArgumentChecker.notNull(clazz, "clazz");
ArgumentChecker.notNull(configName, "configName");
ArgumentChecker.notNull(versionCorrection, "versionCorrection");
final Map<String, ConfigSource> delegates = getDelegates();
for (final ConfigSource configSource : delegates.values()) {
final R config = configSource.getSingle(clazz, configName, versionCorrection);
if (config != null) {
return config;
}
}
return getDefaultDelegate().getSingle(clazz, configName, versionCorrection);
}
@Override
public <R> R getLatestByName(final Class<R> clazz, final String name) {
return getSingle(clazz, name, VersionCorrection.LATEST);
}
@Override
public ChangeManager changeManager() {
final PassthroughChangeManager cm = new PassthroughChangeManager(getDelegates().values());
cm.addChangeManager(getDefaultDelegate().changeManager());
return cm;
}
@Override
public Map<UniqueId, ConfigItem<?>> get(final Collection<UniqueId> uniqueIds) {
return AbstractSource.get(this, uniqueIds);
}
@Override
public Map<ObjectId, ConfigItem<?>> get(final Collection<ObjectId> objectIds, final VersionCorrection versionCorrection) {
return AbstractSource.get(this, objectIds, versionCorrection);
}
}