/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.engine.function.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.threeten.bp.Instant;
import com.opengamma.core.change.ChangeManager;
import com.opengamma.core.change.DummyChangeManager;
import com.opengamma.core.change.PassthroughChangeManager;
/**
* Combines the function configuration from two or more sources into a single configuration object.
*/
public class CombiningFunctionConfigurationSource implements FunctionConfigurationSource {
private final FunctionConfigurationSource[] _sources;
protected CombiningFunctionConfigurationSource(final FunctionConfigurationSource[] sources) {
_sources = sources;
}
private static int count(final FunctionConfigurationSource source) {
if (source == null) {
return 0;
} else if (source instanceof CombiningFunctionConfigurationSource) {
int count = 0;
for (final FunctionConfigurationSource inner : ((CombiningFunctionConfigurationSource) source).getSources()) {
count += count(inner);
}
return count;
} else {
return 1;
}
}
private static int copy(final FunctionConfigurationSource source, final FunctionConfigurationSource[] dest, int index) {
if (source != null) {
if (source instanceof CombiningFunctionConfigurationSource) {
for (final FunctionConfigurationSource inner : ((CombiningFunctionConfigurationSource) source).getSources()) {
index = copy(inner, dest, index);
}
} else {
dest[index++] = source;
}
}
return index;
}
/**
* Creates an instance that is the union of the given sources. The sources are not queried for their configuration until the composite object get queried.
* <p>
* Any nulls in the combined sources are ignored. Any sources that are themselves {@code CombinedRepositoryConfigurationSource} instances are expanded and their members used directly in the
* composite.
*
* @param sources the sources to combine, may contain nulls
* @return the composite source, not null
*/
public static FunctionConfigurationSource of(final FunctionConfigurationSource... sources) {
if ((sources == null) || (sources.length == 0)) {
return new SimpleFunctionConfigurationSource(new FunctionConfigurationBundle(Collections.<FunctionConfiguration>emptyList()));
}
int i = 0;
for (final FunctionConfigurationSource source : sources) {
i += count(source);
}
if (i == 0) {
return new SimpleFunctionConfigurationSource(new FunctionConfigurationBundle(Collections.<FunctionConfiguration>emptyList()));
} else if (i == 1) {
for (final FunctionConfigurationSource source : sources) {
if (source != null) {
return source;
}
}
throw new IllegalStateException();
} else {
final FunctionConfigurationSource[] copy = new FunctionConfigurationSource[i];
i = 0;
for (final FunctionConfigurationSource source : sources) {
i = copy(source, copy, i);
}
return new CombiningFunctionConfigurationSource(copy);
}
}
protected FunctionConfigurationSource[] getSources() {
return _sources;
}
@Override
public FunctionConfigurationBundle getFunctionConfiguration(final Instant version) {
final List<FunctionConfiguration> configs = new ArrayList<FunctionConfiguration>();
for (final FunctionConfigurationSource source : getSources()) {
configs.addAll(source.getFunctionConfiguration(version).getFunctions());
}
return new FunctionConfigurationBundle(configs);
}
@Override
public ChangeManager changeManager() {
PassthroughChangeManager changeManager = null;
for (FunctionConfigurationSource source : getSources()) {
final ChangeManager cm = source.changeManager();
if (cm != DummyChangeManager.INSTANCE) {
if (changeManager == null) {
changeManager = new PassthroughChangeManager();
}
changeManager.addChangeManager(cm);
}
}
if (changeManager == null) {
return DummyChangeManager.INSTANCE;
} else {
return changeManager;
}
}
}