001/*
002 * Copyright (c) 2012-2018 Institut National des Sciences Appliquées de Lyon (INSA Lyon) and others
003 *
004 * This program and the accompanying materials are made available under the
005 * terms of the Eclipse Public License 2.0 which is available at
006 * http://www.eclipse.org/legal/epl-2.0.
007 *
008 * SPDX-License-Identifier: EPL-2.0
009 */
010
011package org.eclipse.golo.compiler.utils;
012
013import java.util.AbstractMap;
014import java.util.Map;
015import java.util.Set;
016import java.util.Collection;
017
018public abstract class AbstractRegister<K, V> extends AbstractMap<K, Set<V>> implements Register<K, V> {
019
020  private final Map<K, Set<V>> map;
021
022  public AbstractRegister() {
023    super();
024    this.map = initMap();
025  }
026
027  protected abstract Map<K, Set<V>> initMap();
028
029  protected abstract Set<V> emptyValue();
030
031  @SuppressWarnings("unchecked")
032  private Set<V> getOrInit(Object key) {
033    Set<V> bag;
034    if (!this.map.containsKey(key)) {
035      bag = emptyValue();
036      this.map.put((K) key, bag);
037    } else {
038      bag = this.map.get(key);
039    }
040    return bag;
041  }
042
043  @Override
044  public Set<Map.Entry<K, Set<V>>> entrySet() {
045    return map.entrySet();
046  }
047
048  @Override
049  public Set<V> put(K key, Set<V> value) {
050    return this.map.put(key, value);
051  }
052
053  @Override
054  public boolean containsKey(Object key) {
055    return map.containsKey(key);
056  }
057
058  @Override
059  public Set<V> get(Object key) {
060    return getOrInit(key);
061  }
062
063  @Override
064  public void add(K key, V value) {
065    getOrInit(key).add(value);
066  }
067
068  @Override
069  public void addAll(K key, Collection<V> values) {
070    getOrInit(key).addAll(values);
071  }
072
073  @Override
074  public void updateKey(K oldKey, K newKey) {
075    if (this.map.containsKey(oldKey)) {
076      this.map.put(newKey, this.map.get(oldKey));
077      this.map.remove(oldKey);
078    }
079  }
080}