001 /**
002 * Copyright (C) 2007-2011, Jens Lehmann
003 *
004 * This file is part of DL-Learner.
005 *
006 * DL-Learner is free software; you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation; either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * DL-Learner is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program. If not, see <http://www.gnu.org/licenses/>.
018 */
019
020 package org.dllearner.core;
021
022 import java.util.HashMap;
023 import java.util.LinkedList;
024 import java.util.List;
025 import java.util.Map;
026
027 import org.apache.log4j.Logger;
028 import org.dllearner.core.options.ConfigEntry;
029 import org.dllearner.core.options.ConfigOption;
030
031 /**
032 * Stores all live components and the configuration options, which were applied
033 * to them. This allows to detect, which components are currently active, which
034 * values are assigned to specific options, and to collect statistics (e.g. in
035 * a web service scenario).
036 *
037 * @author Jens Lehmann
038 *
039 */
040 public final class ComponentPool {
041
042 private static Logger logger = Logger.getLogger(ComponentPool.class);
043
044 // stores all components, which are live (components which are
045 // no longer used have to be deregistered)
046 private List<AbstractComponent> components = new LinkedList<AbstractComponent>();
047
048 // stores the last value which was set for a particular
049 // config option
050 private Map<AbstractComponent, Map<ConfigOption<?>, Object>> lastValidConfigValue = new HashMap<AbstractComponent, Map<ConfigOption<?>, Object>>();
051 // complete history of all made config entries for a component
052 private Map<AbstractComponent, List<ConfigEntry<?>>> configEntryHistory = new HashMap<AbstractComponent, List<ConfigEntry<?>>>();
053
054 /**
055 * Registers a component instance in the pool.
056 * @param component The component to add to the pool.
057 */
058 public void registerComponent(AbstractComponent component) {
059 components.add(component);
060 Map<ConfigOption<?>, Object> emptyMap = new HashMap<ConfigOption<?>, Object>();
061 lastValidConfigValue.put(component, emptyMap);
062 configEntryHistory.put(component, new LinkedList<ConfigEntry<?>>());
063 logger.debug("Component instance " + component + " added to component pool.");
064 }
065
066 /**
067 * Unregisters a component instance. This method should be used if the
068 * component will not be used anymore. It frees the memory for
069 * storing the component and its configuration options.
070 * @param component The component to remove from the pool.
071 */
072 public void unregisterComponent(AbstractComponent component) {
073 configEntryHistory.remove(component);
074 lastValidConfigValue.remove(component);
075 components.remove(component);
076 logger.debug("Component instance " + component + " removed from component pool.");
077 }
078
079 /**
080 * Gets the last valid config value set for this component.
081 * @param <T> The type of the value of the config option (String, Integer etc.).
082 * @param component The component to query.
083 * @param option The option for which one wants to get the value.
084 * @return The last value set for this option or null if the value hasn't been
085 * set using the {@link ComponentManager}. In this case, the value is
086 * usually at the default value (or has been set internally surpassing the
087 * component architecture, which is not recommended).
088 */
089 @SuppressWarnings("unchecked")
090 protected <T> T getLastValidConfigValue(AbstractComponent component, ConfigOption<T> option) {
091 return (T) lastValidConfigValue.get(component).get(option);
092 }
093
094 /**
095 * Add a config entry change for the specified component.
096 * @param component The component, where the config entry has been set.
097 * @param entry The set config entry.
098 * @param valid A boolean value indicating whether the value was valid or not.
099 */
100 protected void addConfigEntry(AbstractComponent component, ConfigEntry<?> entry, boolean valid) {
101 configEntryHistory.get(component).add(entry);
102 if (valid) {
103 lastValidConfigValue.get(component).put(entry.getOption(), entry.getValue());
104 }
105 logger.trace("Config entry " + entry + " has been set for component " + component + " (validity: " + valid + ").");
106 }
107
108 /**
109 * Unregisters all components.
110 */
111 protected void clearComponents() {
112 components = new LinkedList<AbstractComponent>();
113 lastValidConfigValue = new HashMap<AbstractComponent, Map<ConfigOption<?>, Object>>();
114 configEntryHistory = new HashMap<AbstractComponent, List<ConfigEntry<?>>>();
115 }
116
117 /**
118 * @return The components in this pool.
119 */
120 public List<AbstractComponent> getComponents(){
121 return components;
122 }
123
124 }