package org.dcache.gplazma.plugins; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; /** * Represents a map based on a somehow defined key/value source (e.g. configuration file) * depending on the given MapPredicate this may be a one to many relationship. * @author karsten * @param <TKey> type of key to access matching values * @param <TValue> type of values */ class SourceBackedPredicateMap<TKey, TValue> { private static final Logger _log = LoggerFactory.getLogger(SourceBackedPredicateMap.class); private final Map<MapPredicate<TKey>, TValue> _predicateValueMap = new LinkedHashMap<>(); private final LineSource _source; private final LineParser<? extends MapPredicate<TKey>, TValue> _parser; protected SourceBackedPredicateMap(LineSource source, LineParser<? extends MapPredicate<TKey>, TValue> parser) { _source = source; _parser = parser; } /** * Get values from the map belonging to a specific key * @param key Key to be used to find corresponding values * @return Collection of matching values */ public synchronized List<TValue> getValuesForPredicatesMatching(TKey key) { if (_source.hasChanged()) { try { _log.info("Source changed. Recreating map."); createMapFromData(_source.getContent()); } catch (IOException e) { _log.error("Error creating map.", e); return Collections.emptyList(); } } List<TValue> result = new LinkedList<>(); for (Entry<MapPredicate<TKey>, TValue> predicateEntry : _predicateValueMap.entrySet()) { if (predicateEntry.getKey().matches(key)) { result.add(predicateEntry.getValue()); } } return result; } private synchronized void createMapFromData(List<String> data) { _predicateValueMap.clear(); for (String line : data) { Map.Entry<? extends MapPredicate<TKey>, TValue> entry = _parser.accept(line); if (entry!=null) { _predicateValueMap.put(entry.getKey(), entry.getValue()); } } } }