/*******************************************************************************
* Copyright (c) 2010-2013, Abel Hegedus, Istvan Rath and Daniel Varro
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Abel Hegedus - initial API and implementation
*******************************************************************************/
package org.eclipse.incquery.runtime.base.api;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.eclipse.incquery.runtime.base.itc.alg.incscc.Direction;
/**
* @author Abel Hegedus
*
*/
public abstract class QueryResultMap<KeyType,ValueType> extends QueryResultAssociativeStore<KeyType, ValueType> implements Map<KeyType, ValueType> {
/**
* This map contains the current key-values. Implementing classes should not modify it directly
*/
private Map<KeyType, ValueType> cache;
/**
* Constructor only visible to subclasses.
*
* @param logger
* a logger that can be used for error reporting
*/
protected QueryResultMap(Logger logger) {
cache = new HashMap<KeyType, ValueType>();
setLogger(logger);
}
/* (non-Javadoc)
* @see org.eclipse.incquery.runtime.base.api.QueryResultAssociativeStore#getCacheEntries()
*/
@Override
protected Collection<java.util.Map.Entry<KeyType, ValueType>> getCacheEntries() {
return cache.entrySet();
}
/* (non-Javadoc)
* @see org.eclipse.incquery.runtime.base.api.QueryResultAssociativeStore#internalCachePut(java.lang.Object, java.lang.Object)
*/
@Override
protected boolean internalCachePut(KeyType key, ValueType value) {
ValueType put = cache.put(key, value);
if(put == null) {
return value != null;
} else {
return !put.equals(value);
}
}
/* (non-Javadoc)
* @see org.eclipse.incquery.runtime.base.api.QueryResultAssociativeStore#internalCacheRemove(java.lang.Object, java.lang.Object)
*/
@Override
protected boolean internalCacheRemove(KeyType key, ValueType value) {
ValueType remove = cache.remove(key);
return remove != null;
}
/* (non-Javadoc)
* @see org.eclipse.incquery.runtime.base.api.QueryResultAssociativeStore#internalCacheSize()
*/
@Override
protected int internalCacheSize() {
return cache.size();
}
/* (non-Javadoc)
* @see org.eclipse.incquery.runtime.base.api.QueryResultAssociativeStore#internalCacheContainsEntry(java.lang.Object, java.lang.Object)
*/
@Override
protected boolean internalCacheContainsEntry(KeyType key, ValueType value) {
return cache.get(key).equals(value);
}
/**
* @return the cache
*/
protected Map<KeyType, ValueType> getCache() {
return cache;
}
/**
* @param cache
* the cache to set
*/
protected void setCache(Map<KeyType, ValueType> cache) {
this.cache = cache;
}
// ======================= implemented Map methods ======================
/* (non-Javadoc)
* @see java.util.Map#clear()
*/
@Override
public void clear() {
internalClear();
}
/* (non-Javadoc)
* @see java.util.Map#containsKey(java.lang.Object)
*/
@Override
public boolean containsKey(Object key) {
return cache.containsKey(key);
}
/* (non-Javadoc)
* @see java.util.Map#containsValue(java.lang.Object)
*/
@Override
public boolean containsValue(Object value) {
return cache.containsValue(value);
}
/**
* {@inheritDoc}
*
* <p>
* The returned set is immutable.
*
*/
@Override
public Set<Entry<KeyType, ValueType>> entrySet() {
return Collections.unmodifiableSet((Set<Entry<KeyType, ValueType>>) getCacheEntries());
}
/* (non-Javadoc)
* @see java.util.Map#get(java.lang.Object)
*/
@Override
public ValueType get(Object key) {
return cache.get(key);
}
/* (non-Javadoc)
* @see java.util.Map#isEmpty()
*/
@Override
public boolean isEmpty() {
return cache.isEmpty();
}
/**
* {@inheritDoc}
*
* <p>
* The returned set is immutable.
*
*/
@Override
public Set<KeyType> keySet() {
return Collections.unmodifiableSet(cache.keySet());
}
/**
* {@inheritDoc}
*
* <p>
* Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter}
*/
@Override
public ValueType put(KeyType key, ValueType value) {
if (getSetter() == null) {
throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS);
}
ValueType oldValue = cache.get(key);
boolean modified = modifyThroughQueryResultSetter(key, value, Direction.INSERT);
return modified ? oldValue : null;
}
/**
* {@inheritDoc}
*
* <p>
* Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter}
*/
@Override
public void putAll(Map<? extends KeyType, ? extends ValueType> map) {
if (getSetter() == null) {
throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS);
}
for (Entry<? extends KeyType, ? extends ValueType> entry : map.entrySet()) {
modifyThroughQueryResultSetter(entry.getKey(), entry.getValue(), Direction.INSERT);
}
return;
}
/**
* {@inheritDoc}
*
* <p>
* Throws {@link UnsupportedOperationException} if there is no {@link IQueryResultSetter}
*/
@SuppressWarnings("unchecked")
@Override
public ValueType remove(Object key) {
if (getSetter() == null) {
throw new UnsupportedOperationException(NOT_ALLOW_MODIFICATIONS);
}
// if it contains the entry, the types MUST be correct
if (cache.containsKey(key)) {
ValueType value = cache.get(key);
modifyThroughQueryResultSetter((KeyType) key, value, Direction.DELETE);
return value;
}
return null;
}
/* (non-Javadoc)
* @see java.util.Map#size()
*/
@Override
public int size() {
return internalCacheSize();
}
/**
* {@inheritDoc}
*
* <p>
* The returned collection is immutable.
*
*/
@Override
public Collection<ValueType> values() {
return Collections.unmodifiableCollection(cache.values());
}
}