packagede.unihd.dbs.uima.annotator.heideltime.resources;importjava.util.Collection;importjava.util.HashMap;importjava.util.HashSet;importjava.util.Iterator;importjava.util.Map;importjava.util.Set;importjava.util.regex.Pattern;/*** Implements a HashMap extended with regular expression keys and caching functionality.
*
*@authorJulian Zell
**/
public class RegexHashMap implements Map{private HashMap container = new HashMap();private HashMap cache = new HashMap();/*** clears both the container and the cache hashmaps*/
public voidclear() {
container.clear();
cache.clear();
}/*** checks whether the cache or container contain a specific key, then evaluates the
* container's keys as regexes and checks whether they match the specific key.*/
public booleancontainsKey(Object key) {//the key is a direct hit from our cache
if(cache.containsKey(key))return true;//the key is a direct hit from our hashmap
if(container.containsKey(key))return true;//check if the requested key is a matching string of a regex key from our container
Iterator regexKeys =container.keySet().iterator();while(regexKeys.hasNext()) {if(Pattern.matches(regexKeys.next(), (String) key))return true;
}//if the three previous tests yield no result, the key does not exist
return false;
}/*** checks whether a specific value is container within either container or cache*/
public booleancontainsValue(Object value) {//the value is a direct hit from our cache
if(cache.containsValue(value))return true;//the value is a direct hit from our hashmap
if(container.containsValue(value))return true;//otherwise, the value isn't within this object
return false;
}/*** returns a merged entryset containing within both the container and cache entrysets*/
public Set>entrySet() {//prepare the container
HashSet> set = new HashSet>();//add the set from our container
set.addAll(container.entrySet());//add the set from our cache
set.addAll(cache.entrySet());returnset;
}/*** checks whether the requested key has a direct match in either cache or container, and if it
* doesn't, also evaluates the container's keyset as regexes to match against the input key and
* if any of those methods yield a value, returns that value
* if a value is found doing regex evaluation, use that regex-key's match as a non-regex
* key with the regex's value to form a new entry in the cache.*/
publicT get(Object key) {//output for requested key null is the value null; normal Map behavior
if(key == null) return null;
T result= null;if((result = cache.get(key)) != null) {//if the requested key maps to a value in the cache
returnresult;
}else if((result = container.get(key)) != null) {//if the requested key maps to a value in the container
returnresult;
}else{//check if the requested key is a matching string of a regex key from our container
Iterator> regexKeys =container.entrySet().iterator();while(regexKeys.hasNext()) {//prepare current entry
Entry entry =regexKeys.next();//check if the key is a regex matching the input key
if(Pattern.matches(entry.getKey(), (String) key)) {
putCache((String) key, entry.getValue());returnentry.getValue();
}
}
}//no value for the given key was found in any of container/cache/regexkey-container
return null;
}/*** checks whether both container and cache are empty*/
public booleanisEmpty() {return container.isEmpty() &&cache.isEmpty();
}/*** returns the keysets of both the container and cache hashmaps*/
public SetkeySet() {//prepare container
HashSet set = new HashSet();//add container keys
set.addAll(container.keySet());//add cache keys
set.addAll(cache.keySet());returnset;
}/*** associates a key with a value in the container hashmap*/
publicT put(String key, T value) {returncontainer.put(key, value);
}/*** associates a key with a value in the cache hashmap.
*@paramkey Key to map from
*@paramvalue Value to map to
*@returnprevious value associated with the key, or null if unassociated before*/
publicT putCache(String key, T value) {returncache.put(key, value);
}/*** adds a map to the container*/
public void putAll(Map extends String, ? extends T>m) {
container.putAll(m);
}/*** removes a specific key's association from the container*/
publicT remove(Object key) {returncontainer.remove(key);
}/*** returns the combined size of container and cache*/
public intsize() {return container.size() +cache.size();
}/*** returns the combined collection of both the values of the container as well as
* the cache.*/
public Collectionvalues() {//prepare set
HashSet set = new HashSet();//add all container values
set.addAll(container.values());//add all cache values
set.addAll(cache.values());returnset;
}
}