/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.web.convention;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.Set;
import org.fudgemsg.AnnotationReflector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Maps;
import com.opengamma.core.convention.ConventionType;
import com.opengamma.master.convention.ManageableConvention;
import com.opengamma.util.ClassUtils;
/**
* Provides all supported convention types
*/
public final class ConventionTypesProvider {
/** Logger. */
private static final Logger s_logger = LoggerFactory.getLogger(ConventionTypesProvider.class);
/**
* Singleton instance.
*/
private static final ConventionTypesProvider s_instance = new ConventionTypesProvider();
/**
* Map of config types.
*/
private final ImmutableSortedMap<String, Class<? extends ManageableConvention>> _conventionTypeMap;
/**
* Map of config descriptions.
*/
private final ImmutableSortedMap<String, String> _conventionDescriptionMap;
//-------------------------------------------------------------------------
/**
* Gets the singleton instance.
*
* @return the provider, not null
*/
public static ConventionTypesProvider getInstance() {
return s_instance;
}
//-------------------------------------------------------------------------
/**
* Restricted constructor
*/
private ConventionTypesProvider() {
Map<String, Class<? extends ManageableConvention>> result = Maps.newHashMap();
ImmutableSortedMap.Builder<String, String> descriptions = ImmutableSortedMap.naturalOrder();
AnnotationReflector reflector = AnnotationReflector.getDefaultReflector();
Set<Class<? extends ManageableConvention>> conventionClasses = reflector.getReflector().getSubTypesOf(ManageableConvention.class);
for (Class<? extends ManageableConvention> conventionClass : conventionClasses) {
// ensure this class is fully loaded, to force static initialization
ClassUtils.initClass(conventionClass);
// find type
if (Modifier.isAbstract(conventionClass.getModifiers())) {
continue;
}
ConventionType type;
try {
type = (ConventionType) conventionClass.getDeclaredField("TYPE").get(null);
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ex) {
s_logger.warn("Convention class must declare a static variable 'TYPE' but none found: " + conventionClass.getName());
continue;
}
// extract description
String description = type.getName().replaceAll(
String.format("%s|%s|%s", "(?<=[A-Z])(?=[A-Z][a-z])", "(?<=[^A-Z])(?=[A-Z])", "(?<=[A-Za-z])(?=[^A-Za-z])"), " ");
// store
Class<?> old = result.put(type.getName(), conventionClass);
if (old != null) {
s_logger.warn("Two classes exist with the same name: " + conventionClass.getSimpleName());
}
descriptions.put(type.getName(), description);
}
_conventionTypeMap = ImmutableSortedMap.copyOf(result);
_conventionDescriptionMap = descriptions.build();
}
//-------------------------------------------------------------------------
/**
* Gets the set of convention keys.
*
* @return the types, not null
*/
public ImmutableSortedSet<String> getTypeSet() {
return ImmutableSortedSet.copyOf(_conventionTypeMap.keySet());
}
/**
* Gets the map of convention types by short key.
*
* @return the map, not null
*/
public ImmutableSortedMap<String, Class<? extends ManageableConvention>> getTypeMap() {
return _conventionTypeMap;
}
/**
* Gets the map of convention descriptions by short key.
*
* @return the map, not null
*/
public ImmutableSortedMap<String, String> getDescriptionMap() {
return _conventionDescriptionMap;
}
/**
* Gets the description for a type.
*
* @param clazz the convention class, not null
* @return the description, not null
*/
public String getDescription(Class<?> clazz) {
String key = HashBiMap.create(_conventionTypeMap).inverse().get(clazz);
String description = null;
if (key != null) {
description = _conventionDescriptionMap.get(key);
}
return (description != null ? description : clazz.getSimpleName());
}
}