/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.workbench.services.verifier.api.client.maps;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
class ChangeHandledMultiMap<V extends Comparable, T, ListType extends List<T>>
implements MultiMap<V, T, ListType> {
private final MultiMap<V, T, ListType> map;
private List<MultiMapChangeHandler<V, T>> changeHandlers = new ArrayList<>();
private MultiMapChangeHandler.ChangeSet<V, T> changeSet = new MultiMapChangeHandler.ChangeSet<>();
private int counter = 0;
public ChangeHandledMultiMap( final MultiMap<V, T, ListType> map ) {
this.map = map;
}
@Override
public boolean put( final V value,
final T t ) {
addToCounter();
final boolean put = map.put( value,
t );
addToChangeSet( value,
t );
fire();
return put;
}
@Override
public int size() {
return map.size();
}
@Override
public Set<V> keySet() {
return map.keySet();
}
@Override
public ListType get( final V key ) {
return map.get( key );
}
@Override
public boolean addAllValues( final V value,
final Collection<T> ts ) {
addToCounter();
final boolean b = map.addAllValues( value,
ts );
for ( final T t : ts ) {
addToChangeSet( value, t );
}
fire();
return b;
}
@Override
public Collection<T> remove( final V value ) {
addToCounter();
for ( final T t : get( value ) ) {
addRemovedToChangeSet( value, t );
}
final Collection<T> remove = map.remove( value );
fire();
return remove;
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
public void addChangeListener( final MultiMapChangeHandler<V, T> changeHandler ) {
changeHandlers.add( changeHandler );
}
@Override
public Collection<T> allValues() {
return map.allValues();
}
void addToCounter() {
counter++;
}
protected void fire() {
if ( counter == 1 ) {
for ( final MultiMapChangeHandler<V, T> changeHandler : changeHandlers ) {
changeHandler.onChange( changeSet );
}
changeSet = new MultiMapChangeHandler.ChangeSet<>();
}
counter--;
}
private void addToChangeSet( final V value,
final T t ) {
if ( !changeHandlers.isEmpty() ) {
changeSet.added.put( value, t );
}
}
private void addRemovedToChangeSet( final V value,
final T t ) {
if ( !changeHandlers.isEmpty() ) {
changeSet.removed.put( value,
t );
}
}
@Override
public void move( final Set<V> oldKeys,
final Set<V> newKeys,
final T t ) {
addToCounter();
for ( final V oldKey : oldKeys ) {
removeValue( oldKey,
t );
}
for ( final V newKey : newKeys ) {
put( newKey,
t );
}
fire();
}
@Override
public boolean containsKey( final V key ) {
return map.containsKey( key );
}
@Override
public V firstKey() {
return map.firstKey();
}
@Override
public V lastKey() {
return map.lastKey();
}
@Override
public MultiMap<V, T, ListType> subMap( final V fromKey,
final boolean fromInclusive,
final V toKey,
final boolean toInclusive ) {
return map.subMap( fromKey, fromInclusive,
toKey, toInclusive );
}
@Override
public void removeValue( final V value,
final T t ) {
addToCounter();
map.removeValue( value,
t );
addRemovedToChangeSet( value,
t );
fire();
}
@Override
public void clear() {
addToCounter();
for ( final V value : map.keySet() ) {
for ( final T t : map.get( value ) ) {
addRemovedToChangeSet( value,
t );
}
}
map.clear();
fire();
}
@Override
public void putAllValues( final V value,
final Collection<T> ts ) {
addToCounter();
for ( final T t : ts ) {
addToChangeSet( value,
t );
}
map.putAllValues( value,
ts );
fire();
}
}