package com.mongodb.hvdf.configuration; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; import com.mongodb.hvdf.api.ConfigurationError; import com.mongodb.hvdf.api.ServiceException; public class PluginConfiguration { public static class HVDF{ public static final String ALLOCATOR = "hvdf_allocator"; public static final String DB = "hvdf_database"; public static final String PREFIX = "hvdf_prefix"; public static final String ID_FACTORY = "id_factory"; } private static HashSet<Class<?>> registeredClasses = new HashSet<Class<?>>(); static{ registeredClasses.add(TimePeriod.class); } private final DBObject rawDocument; private final Class<?> targetClass; public PluginConfiguration(DBObject rawConfig, Class<?> target){ if(rawConfig == null){ rawConfig = new BasicDBObject(); } this.rawDocument = rawConfig; this.targetClass = target; } public <T> T get(String itemName, Class<T> expectedType, T defaultValue) { Object itemObj = rawDocument.get(itemName); // If it exists, parse the object if(itemObj != null){ return fromObject(itemName, expectedType, itemObj); } return defaultValue; } public <T> T get(String itemName, Class<T> expectedType) { // If there is a valid config value then return it T value = get(itemName, expectedType, null); if(value != null) return value; // If not, throw a service exception throw new ServiceException("Required config item missing", ConfigurationError.REQUIRED_CONFIG_MISSING). set("configuring", this.getClass()). set("requiredItem", itemName); } private <T> T fromObject(String itemName, Class<T> expectedType, Object itemObj) { try{ if(expectedType.equals(PluginConfiguration.class)){ // This is an embedded config document return expectedType.cast((new PluginConfiguration((DBObject) itemObj, this.targetClass))); } else if(registeredClasses.contains(expectedType)){ // One of the specially handled types, construct try { return (expectedType.getConstructor(Object.class).newInstance(itemObj)); } catch (Exception ex) {throw new ClassCastException();} } else{ // This must be directly convertible to target type return expectedType.cast(itemObj); } } catch(ClassCastException ccex){ throw new ServiceException("Illegal type for config item", ConfigurationError.INVALID_CONFIG_TYPE). set("configuring", targetClass). set(itemName, itemObj). set("expectedType", expectedType); } } public <T> List<T> getList(String itemName, Class<T> listOf) { List<T> list = new ArrayList<T>(); Object itemObj = rawDocument.get(itemName); if(itemObj != null){ // Must be a list if(itemObj instanceof BasicDBList){ BasicDBList rawList = (BasicDBList)itemObj; for(Object listEntry : rawList){ list.add(fromObject(itemName, listOf, listEntry)); } } else{ throw new ServiceException("Config item is not List", ConfigurationError.INVALID_CONFIG_TYPE). set("configuring", targetClass). set(itemName, itemObj). set("expectedListOf", listOf); } } // If the item doesnt exist return list; } public DBObject getRaw() { return this.rawDocument; } }