/* * 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(); } }