net.sf.javagimmicks.collections.mapping.AbstractValueMappings Maven / Gradle / Ivy
package net.sf.javagimmicks.collections.mapping;
import java.io.Serializable;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import net.sf.javagimmicks.collections.transformer.TransformerUtils;
import net.sf.javagimmicks.util.Function;
/**
* An abstract implementation of {@link ValueMappings} that provides default
* implementations for almost all methods.
*
* Methods to be implemented by subclasses are:
*
* - {@link #getLeftView()}
* - {@link #getRightView()}
* - {@link #put(Object, Object, Object)}
*
*/
public abstract class AbstractValueMappings implements ValueMappings, Serializable
{
private static final long serialVersionUID = 3350171311023033933L;
protected AbstractValueMappings()
{}
@Override
public Set> getMappingSet()
{
return new MappingSet(getLeftView().entrySet());
}
@Override
public Iterator> iterator()
{
return getMappingSet().iterator();
}
@Override
public ValueMappings invert()
{
return new InverseMappings(this);
}
@Override
public Map getAllForLeftKey(final L left)
{
return getLeftView().get(left);
}
@Override
public Map getAllForRightKey(final R right)
{
return getRightView().get(right);
}
@Override
public E put(final L left, final R right, final E value)
{
throw new UnsupportedOperationException();
}
@Override
public void putAllForRightKey(final R right, final Map extends L, ? extends E> c)
{
for (final Entry extends L, ? extends E> left : c.entrySet())
{
put(left.getKey(), right, left.getValue());
}
}
@Override
public void putAllForLeftKey(final L left, final Map extends R, ? extends E> c)
{
for (final Entry extends R, ? extends E> right : c.entrySet())
{
put(left, right.getKey(), right.getValue());
}
}
@Override
public E get(final L left, final R right)
{
final Map rightInnerMap = getAllForLeftKey(left);
return rightInnerMap != null ? rightInnerMap.get(right) : null;
}
@Override
public E remove(final L left, final R right)
{
final Map mappedValuesLeft = getAllForLeftKey(left);
return mappedValuesLeft != null ? mappedValuesLeft.remove(right) : null;
}
@Override
public Collection getValues()
{
return TransformerUtils.decorate(getMappingSet(), VALUE_TRANSFORMER);
}
@Override
public boolean containsLeftKey(final L left)
{
return getLeftView().containsKey(left);
}
@Override
public boolean containsRightKey(final R right)
{
return getRightView().containsKey(right);
}
@Override
public boolean containsMapping(final L left, final R right)
{
final Map rightInnerMap = getAllForLeftKey(left);
return rightInnerMap != null && rightInnerMap.containsKey(right);
}
@Override
public Map removeLeftKey(final L left)
{
return getLeftView().remove(left);
}
@Override
public Map removeRightKey(final R right)
{
return getRightView().remove(right);
}
@Override
public void clear()
{
getLeftView().clear();
}
@Override
public int size()
{
return getMappingSet().size();
}
@Override
public boolean isEmpty()
{
return getMappingSet().isEmpty();
}
@Override
public boolean equals(final Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof ValueMappings, ?, ?>))
{
return false;
}
final ValueMappings, ?, ?> other = (ValueMappings, ?, ?>) obj;
return getMappingSet().equals(other.getMappingSet());
}
@Override
public String toString()
{
return new StringBuilder()
.append(getLeftView())
.append(" | ")
.append(getRightView())
.toString();
}
protected static class MappingSet extends AbstractSet>
{
protected final Set>> _entries;
public MappingSet(final Set>> entries)
{
_entries = entries;
}
@Override
public Iterator> iterator()
{
return new MappingIterator(_entries.iterator());
}
@Override
public int size()
{
int size = 0;
for (final Entry> entry : _entries)
{
size += entry.getValue().size();
}
return size;
}
}
protected static class MappingIterator implements Iterator>
{
protected final Iterator>> _entryIterator;
protected Iterator> _valueItertor;
protected Entry> _currentEntry;
protected Entry _currentValue;
protected MappingIterator(final Iterator>> entryIterator)
{
_entryIterator = entryIterator;
}
@Override
public boolean hasNext()
{
return (_valueItertor != null && _valueItertor.hasNext()) || _entryIterator.hasNext();
}
@Override
public Mapping next()
{
moveNext();
return new DefaultValueMapping(_currentEntry.getKey(), _currentValue.getKey(),
_currentValue.getValue());
}
@Override
public void remove()
{
_valueItertor.remove();
if (_currentEntry.getValue().isEmpty())
{
_entryIterator.remove();
}
}
private void moveNext()
{
if (_valueItertor == null || !_valueItertor.hasNext())
{
_currentEntry = _entryIterator.next();
_valueItertor = _currentEntry.getValue().entrySet().iterator();
}
_currentValue = _valueItertor.next();
}
}
protected static class InverseMappings extends AbstractValueMappings
{
private static final long serialVersionUID = 6830247408926542348L;
protected final ValueMappings _partner;
public InverseMappings(final ValueMappings partner)
{
_partner = partner;
}
@Override
public ValueMappings invert()
{
return _partner;
}
@Override
public E put(final R left, final L right, final E value)
{
return _partner.put(right, left, value);
}
@Override
public void clear()
{
_partner.clear();
}
@Override
public Map> getLeftView()
{
return _partner.getRightView();
}
@Override
public Map getAllForLeftKey(final R left)
{
return _partner.getAllForRightKey(left);
}
@Override
public Map getAllForRightKey(final L right)
{
return _partner.getAllForLeftKey(right);
}
@Override
public Map> getRightView()
{
return _partner.getLeftView();
}
@Override
public E remove(final R left, final L right)
{
return _partner.remove(right, left);
}
@Override
public Map removeLeftKey(final R left)
{
return _partner.removeRightKey(left);
}
@Override
public Map removeRightKey(final L right)
{
return _partner.removeLeftKey(right);
}
}
protected final Function, E> VALUE_TRANSFORMER = new Function, E>()
{
@Override
public E apply(final Mapping source)
{
return source.getValue();
}
};
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy