/*******************************************************************************
* Copyright (c) 2007 Intel Corporation and others.
* 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:
* Intel Corporation - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.internal.tcmodification;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
public class ToolListMap implements Cloneable {
private HashMap<ITool, List<ITool>> fMap;
private CollectionEntrySet fCollectionEntrySet;
public ToolListMap(){
fMap = new HashMap<ITool, List<ITool>>();
}
// public class ValueIter {
// private Map fIterMap;
//
// public ValueIter() {
// fIterMap = new HashMap(fMap);
// for(Iterator iter = fIterMap.entrySet().iterator(); iter.hasNext();){
// Map.Entry entry = (Map.Entry)iter.next();
// Collection c = (Collection)entry.getValue();
// entry.setValue(c.iterator());
// }
// }
//
// public Iterator get(Object key){
// Iterator iter = (Iterator)fIterMap.get(key);
// if(iter != null && !iter.hasNext()){
// fIterMap.remove(key);
// return null;
// }
// return iter;
// }
// }
public class CollectionEntry {
private Map.Entry<ITool, List<ITool>> fEntry;
CollectionEntry(Map.Entry<ITool, List<ITool>> entry){
fEntry = entry;
}
public ITool getKey(){
return fEntry.getKey();
}
public List<ITool> getValue(){
return fEntry.getValue();
}
@Override
public boolean equals(Object obj) {
if(obj == this)
return true;
if(obj == null)
return false;
if(!(obj instanceof CollectionEntry))
return false;
return fEntry.equals(((CollectionEntry)obj).fEntry);
}
@Override
public int hashCode() {
return fEntry.hashCode();
}
}
private class CollectionEntrySet extends AbstractSet<CollectionEntry> {
private Set<Entry<ITool, List<ITool>>> fMapEntrySet;
private class Iter implements Iterator<CollectionEntry> {
private Iterator<Entry<ITool, List<ITool>>> fIter;
private Iter(){
fIter = fMapEntrySet.iterator();
}
public boolean hasNext() {
return fIter.hasNext();
}
public CollectionEntry next() {
return new CollectionEntry(fIter.next());
}
public void remove() {
fIter.remove();
}
}
private CollectionEntrySet(){
fMapEntrySet = fMap.entrySet();
}
@Override
public Iterator<CollectionEntry> iterator() {
return new Iter();
}
@Override
public int size() {
return fMapEntrySet.size();
}
}
public void add(ITool key, ITool value){
List<ITool> l = get(key, true);
l.add(value);
}
public List<ITool> removeAll(ITool key){
return fMap.remove(key);
}
public List<ITool> get(ITool key, boolean create){
List<ITool> l = fMap.get(key);
if(l == null && create){
l = newList(1);
fMap.put(key, l);
}
return l;
}
public List<ITool> valuesToCollection(List<ITool> c){
if(c == null)
c = newList(20);
for (List<ITool> l : fMap.values()) {
c.addAll(l);
}
return c;
}
// public List<ITool> getValues(){
// return valuesToCollection(null);
// }
// public ITool[] getValuesArray(Class clazz){
// List<ITool> list = getValues();
// ITool[] result = (ITool[])Array.newInstance(clazz, list.size());
// return list.toArray(result);
// }
protected List<ITool> newList(int size){
return new ArrayList<ITool>(size);
}
@SuppressWarnings("unchecked")
protected List<ITool> cloneList(List<ITool> l){
return (List<ITool>)((ArrayList<ITool>)l).clone();
}
public List<ITool> putValuesToCollection(List<ITool> c){
for (CollectionEntry entry : collectionEntrySet()) {
List<ITool> l = entry.getValue();
c.addAll(l);
}
return c;
}
public void remove(ITool key, ITool value){
List<ITool> c = get(key, false);
if(c != null){
if(c.remove(value) && c.size() == 0){
fMap.remove(key);
}
}
}
public ITool get(ITool key, int num){
List<ITool> l = get(key, false);
if(l != null){
return l.get(num);
}
return null;
}
public ITool remove(ITool key, int num){
List<ITool> l = get(key, false);
if(l != null){
ITool result = null;
if(l.size() > num){
result = l.remove(num);
}
return result;
}
return null;
}
public ITool removeLast(ITool key){
List<ITool> l = get(key, false);
if(l != null){
ITool result = null;
if(l.size() > 0){
result = l.remove(l.size() - 1);
}
return result;
}
return null;
}
public void removeAll(ITool key, List<ITool> values){
List<ITool> c = get(key, false);
if(c != null){
if(c.removeAll(values) && c.size() == 0){
fMap.remove(key);
}
}
}
public void clearEmptyLists(){
for(Iterator<Entry<ITool, List<ITool>>> iter = fMap.entrySet().iterator(); iter.hasNext(); ){
Map.Entry<ITool, List<ITool>> entry = iter.next();
if((entry.getValue()).size() == 0)
iter.remove();
}
}
public Set<CollectionEntry> collectionEntrySet(){
if(fCollectionEntrySet == null)
fCollectionEntrySet = new CollectionEntrySet();
return fCollectionEntrySet;
}
// public void difference(ListMap map){
// for(Iterator<Entry<ITool, List<ITool>>> iter = map.fMap.entrySet().iterator(); iter.hasNext(); ){
// Map.Entry<ITool, List<ITool>> entry = iter.next();
// List<ITool> thisC = fMap.get(entry.getKey());
// if(thisC != null){
// if(thisC.removeAll(entry.getValue()) && thisC == null){
// fMap.remove(entry.getKey());
// }
// }
// }
// }
// public ValueIter valueIter(){
// return new ValueIter();
// }
// protected Collection createCollection(Object key){
// return new ArrayList(1);
// }
@Override
public Object clone() {
try {
ToolListMap clone = (ToolListMap)super.clone();
@SuppressWarnings("unchecked")
HashMap<ITool, List<ITool>> clone2 = (HashMap<ITool, List<ITool>>)fMap.clone();
clone.fMap = clone2;
for (Entry<ITool, List<ITool>> entry : clone.fMap.entrySet()) {
entry.setValue(cloneList(entry.getValue()));
}
} catch (CloneNotSupportedException e) {
ManagedBuilderCorePlugin.log(e);
}
return null;
}
// protected Map getMap(boolean create){
// if(fMap == null && create)
// fMap = createMap();
// return fMap;
// }
//
// protected Map createMap(){
// return new HashMap();
// }
}