package org.jactr.core.module.procedural.map.template; /* * default logging */ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import javolution.util.FastList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jactr.core.module.procedural.map.instance.IInstaniationMap; import org.jactr.core.production.IProduction; public abstract class AbstractInstantiationMapTemplate<T, K, M extends IInstantiationMapTemplate<K>> implements IInstantiationMapTemplate<T> { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(AbstractInstantiationMapTemplate.class); final private T _root; final private Map<K, M> _subMaps; final private Set<IProduction> _relevant; protected AbstractInstantiationMapTemplate(T root) { _root = root; _subMaps = new HashMap<K, M>(); _relevant = new HashSet<IProduction>(); installInitialMaps(_root); } public T getRoot() { return _root; } public int getSize() { synchronized (_subMaps) { return _subMaps.size(); } } public boolean add(IProduction production) { FastList<M> subMaps = getSubMaps(); boolean added = false; for (M subMap : subMaps) added |= subMap.add(production); if (added) synchronized (_relevant) { _relevant.add(production); } FastList.recycle(subMaps); return added; } public void remove(IProduction production) { FastList<M> subMaps = getSubMaps(); for (M subMap : subMaps) { subMap.remove(production); if (subMap.getSize() == 0) removeSubMap(getRoot(), subMap.getRoot()); } synchronized (_relevant) { _relevant.remove(production); } FastList.recycle(subMaps); } public Set<IProduction> get(Set<IProduction> container) { if (container == null) container = new HashSet<IProduction>(); synchronized(_relevant) { container.addAll(_relevant); } return container; } abstract public IInstaniationMap<T> instantiate(Object... params); /** * return all the possible current sub map keys for the given root * * @param root * @return */ abstract protected Set<K> getSubMapKeys(T root); /** * initialize with the current properties * * @param root */ protected void installInitialMaps(T root) { for (K key : getSubMapKeys(root)) addSubMap(root, key); } protected M addSubMap(T root, K key) { M subMap = instantiateSubMap(root, key); if (subMap != null) synchronized (_subMaps) { if (_subMaps.containsKey(key)) if (LOGGER.isWarnEnabled()) LOGGER.warn("Replacing previous content at " + key); _subMaps.put(key, subMap); } return subMap; } protected void removeSubMap(T root, K key) { synchronized (_subMaps) { _subMaps.remove(key); } } /** * instantiate the actual submap * * @param root * @param key * @return */ abstract protected M instantiateSubMap(T root, K key); protected FastList<M> getSubMaps() { FastList<M> maps = FastList.newInstance(); synchronized (_subMaps) { maps.addAll(_subMaps.values()); } return maps; } protected M getSubMap(K key, boolean createIfMissing) { synchronized (_subMaps) { M subMap = _subMaps.get(key); if (subMap == null && createIfMissing) subMap = addSubMap(getRoot(), key); return subMap; } } }