/*
* Copyright 2004, 2005, 2006 Odysseus Software GmbH
*
* 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.
*/
import java.util.AbstractCollection;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
* List ordered map.
* The iterators returned by <code>keySet()</code>, <code>values()</code>
* and <code>entrySet()</code> methods reflect the order in which keys have
* been added to the map.
*
* @author Christoph Beck
*/
public class ListOrderedMap implements Map {
private final Map map;
private final List lst;
public static Map decorate(Map map) {
return new ListOrderedMap(map, new ArrayList());
}
protected ListOrderedMap(Map map, List lst) {
super();
this.map = map;
this.lst = lst;
lst.addAll(map.keySet());
}
public boolean containsKey(Object key) {
return map.containsKey(key);
}
public boolean containsValue(Object value) {
return map.containsValue(value);
}
public Object get(Object key) {
return map.get(key);
}
public boolean isEmpty() {
return map.isEmpty();
}
public int size() {
return map.size();
}
public boolean equals(Object object) {
return object == this ? true : map.equals(object);
}
public int hashCode() {
return map.hashCode();
}
public Object put(Object key, Object value) {
if (!map.containsKey(key)) {
lst.add(key);
}
return map.put(key, value);
}
public void putAll(Map map) {
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
put(entry.getKey(), entry.getValue());
}
}
public Object remove(Object key) {
if (map.containsKey(key)) {
lst.remove(key);
return map.remove(key);
}
return null;
}
public void clear() {
map.clear();
lst.clear();
}
public Collection values() {
return new AbstractCollection() {
public int size() {
return map.size();
}
public boolean contains(Object value) {
return map.containsValue(value);
}
public void clear() {
ListOrderedMap.this.clear();
}
public Iterator iterator() {
return new Iterator() {
Object last = null;
Iterator keys = lst.iterator();
public Object next() {
return map.get(last = keys.next());
}
public boolean hasNext() {
return keys.hasNext();
}
public void remove() {
keys.remove();
map.remove(last);
}
};
}
};
}
public Set keySet() {
return new AbstractSet() {
public int size() {
return map.size();
}
public boolean contains(Object value) {
return map.containsKey(value);
}
public void clear() {
ListOrderedMap.this.clear();
}
public Iterator iterator() {
return new Iterator() {
Object last = null;
Iterator keys = lst.iterator();
public Object next() {
return last = keys.next();
}
public boolean hasNext() {
return keys.hasNext();
}
public void remove() {
keys.remove();
map.remove(last);
}
};
}
};
}
public Set entrySet() {
return new AbstractSet() {
Set delegate = ListOrderedMap.this.map.entrySet();
public int size() {
return ListOrderedMap.this.size();
}
public boolean contains(Object obj) {
return delegate.contains(obj);
}
public boolean remove(Object obj) {
boolean result = contains(obj);
if (result) {
ListOrderedMap.this.remove(((Map.Entry)obj).getKey());
}
return result;
}
public void clear() {
ListOrderedMap.this.clear();
}
public boolean equals(Object obj) {
return obj == this ? true : delegate.equals(obj);
}
public int hashCode() {
return delegate.hashCode();
}
public String toString() {
return delegate.toString();
}
public Iterator iterator() {
return new Iterator() {
Iterator keys = lst.iterator();
Object last = null;
public Object next() {
last = keys.next();
return new Map.Entry() {
Object key = last;
public Object getKey() {
return key;
}
public Object getValue() {
return map.get(key);
}
public Object setValue(Object value) {
return map.put(key, value);
}
};
}
public boolean hasNext() {
return keys.hasNext();
}
public void remove() {
keys.remove();
map.remove(last);
}
};
}
};
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append('{');
Iterator keys = keySet().iterator();
while (keys.hasNext()) {
Object key = keys.next();
buf.append(key);
buf.append('=');
buf.append(get(key));
if (keys.hasNext()) {
buf.append(", ");
}
}
buf.append('}');
return buf.toString();
}
}