All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.l4.commons.config.internal.ConfigResolver Maven / Gradle / Ivy

The newest version!
package se.l4.commons.config.internal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import se.l4.commons.config.ConfigKey;
import se.l4.commons.serialization.SerializationException;

/**
 * Resolver for embedded references to other parts of the configuration.
 * 
 * @author Andreas Holstenson
 *
 */
public class ConfigResolver
{
	private ConfigResolver()
	{
	}
	
	/**
	 * Resolve the specified map and return the resolved map.
	 * 
	 * @param root
	 * @return
	 */
	public static Map resolve(Map root)
	{
		Map newRoot = new HashMap();
		resolve(newRoot, root, "");
		return newRoot;
	}

	/**
	 * Resolve the specified map and store it in the specified target.
	 * 
	 * @param root
	 * @param target
	 * @return
	 */
	public static Map resolveTo(Map root, Map target)
	{
		resolve(target, root, "");
		return target;
	}
	
	private static void resolve(Map newRoot, Map root, String currentKey)
	{
		for(Map.Entry e : root.entrySet())
		{
			String key = e.getKey();
			Object value = e.getValue();
			
			if(value instanceof Map)
			{
				Map map = new HashMap();
				
				String newKey = currentKey.isEmpty() ? key : currentKey + '.' + key;
				map.put(ConfigKey.NAME, newKey);
				
				resolve(map, (Map) value, newKey);
				store(newRoot, key, map, currentKey);
			}
			else if(value instanceof List)
			{
				List list = new ArrayList();
				
				String newKey = currentKey.isEmpty() ? key : currentKey + '.' + key;
				
				resolve(list, (List) value, newKey);
				store(newRoot, key, list, currentKey);
			}
			else
			{
				store(newRoot, key, value, currentKey);
			}
		}
	}
	
	private static void resolve(List newList, List oldList, String currentKey)
	{
		for(int i=0, n=oldList.size(); i map = new HashMap();
				map.put(ConfigKey.NAME, newKey);
				
				resolve(map, (Map) value, newKey);
				value = map;
			}
			else if(value instanceof List)
			{
				List list = new ArrayList();
				resolve(list, (List) value, newKey);
				value = list;
			}
			
			newList.add(value);
		}
	}

	private static void store(Map root, String key, Object value, String currentKey)
	{
		Map current = root;
		if(key.startsWith("\""))
		{
			// Quoted key, do not resolve dots
			root.put(key.substring(1, key.length()-1), value);
			return;
		}
		
		String[] path = key.split("\\.");
		StringBuilder resolvedPath = new StringBuilder(currentKey);
		for(int i=0, n=path.length-1; i newMap = new HashMap();
				if(resolvedPath.length() > 0) resolvedPath.append('.');
				resolvedPath.append(path[i]);
				
				newMap.put(ConfigKey.NAME, resolvedPath.toString());
				current.put(path[i], newMap);
				current = newMap;
			}
		}
		
		current.put(path[path.length - 1], value);
	}
}