/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.id;
import static com.google.common.collect.Iterables.concat;
import static java.util.Collections.singleton;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.commons.lang.StringUtils;
import com.google.common.collect.ImmutableMap;
import com.opengamma.util.ArgumentChecker;
/**
* Delegator that switches between multiple implementations based on the scheme of a unique identifier.
* <p>
* This class can be used on its own, however it is best used by creating a subclass.
* <p>
* This class is mutable and thread-safe via internal synchronization.
*
* @param <T> the type of the delegate
*/
public class UniqueIdSchemeDelegator<T> {
/**
* The default delegate.
*/
private final T _defaultDelegate;
/**
* The map of registered delegates.
*/
private final ConcurrentMap<String, T> _schemeToDelegateMap = new ConcurrentHashMap<String, T>();
/**
* Creates an instance specifying the default delegate.
*
* @param defaultDelegate the delegate to use when no scheme matches, not null
*/
public UniqueIdSchemeDelegator(final T defaultDelegate) {
ArgumentChecker.notNull(defaultDelegate, "defaultDelegate");
_defaultDelegate = defaultDelegate;
}
/**
* Creates an instance specifying the default delegate.
*
* @param defaultDelegate the delegate to use when no scheme matches, not null
* @param schemePrefixToDelegateMap the map of delegates by scheme to switch on, not null
*/
public UniqueIdSchemeDelegator(final T defaultDelegate, final Map<String, T> schemePrefixToDelegateMap) {
ArgumentChecker.notNull(defaultDelegate, "defaultDelegate");
ArgumentChecker.notNull(schemePrefixToDelegateMap, "schemePrefixToDelegateMap");
_defaultDelegate = defaultDelegate;
for (Map.Entry<String, T> delegate : schemePrefixToDelegateMap.entrySet()) {
registerDelegate(delegate.getKey(), delegate.getValue());
}
}
//-------------------------------------------------------------------------
/**
* Gets the default delegate.
*
* @return the default delegate, not null
*/
public T getDefaultDelegate() {
return _defaultDelegate;
}
/**
* Gets the map of registered delegates.
*
* @return the registered delegates, unmodifiable, not null
*/
public Map<String, T> getDelegates() {
return ImmutableMap.copyOf(_schemeToDelegateMap);
}
/**
* Returns the default delegate followed by the mapped one.
*
* @return all delegates
*/
public Iterable<T> getAllDelegates() {
return concat(singleton(_defaultDelegate), getDelegates().values());
}
//-------------------------------------------------------------------------
/**
* Chooses the delegate for a specific identifier scheme.
*
* @param scheme the identifier scheme, not null
* @return the delegate, not null
*/
public T chooseDelegate(final String scheme) {
ArgumentChecker.notNull(scheme, "scheme");
String[] schemeParts = StringUtils.split(scheme, "-", 2);
String schemePrefix = schemeParts[0];
final T delegate = _schemeToDelegateMap.get(schemePrefix);
return (delegate != null) ? delegate : _defaultDelegate;
}
//-------------------------------------------------------------------------
/**
* Registers a delegate based on a scheme.
*
* @param scheme the scheme to match, not null
* @param delegate the delegate to use, not null
* @return false if a delegate with the given scheme was previously registered, true otherwise
*/
public boolean registerDelegate(final String scheme, final T delegate) {
ArgumentChecker.notNull(scheme, "scheme");
ArgumentChecker.notNull(delegate, "delegate");
return _schemeToDelegateMap.putIfAbsent(scheme, delegate) == null;
}
/**
* Removes a delegate from those being used.
*
* @param scheme the scheme to remove, not null
*/
public void removeDelegate(final String scheme) {
ArgumentChecker.notNull(scheme, "scheme");
_schemeToDelegateMap.remove(scheme);
}
}