/*
* Created on Nov 23, 2004
*
*/
package cn.org.rapid_framework.generator.util;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
/**
* @author MF1180
* Hashtable that maintains the input order of the data elements - Note
* only put, putall, clear and remove maintains the ordered list
*
*/
public class ListHashtable extends Hashtable {
protected List orderedKeys = new ArrayList();
public synchronized void clear() {
super.clear();
orderedKeys = new ArrayList();
}
public synchronized Object put(Object aKey, Object aValue) {
if (orderedKeys.contains(aKey)) {
int pos = orderedKeys.indexOf(aKey);
orderedKeys.remove(pos);
orderedKeys.add(pos,aKey);
}
else {
if (aKey instanceof Integer) {
Integer key = (Integer) aKey;
int pos = getFirstKeyGreater(key.intValue());
if (pos >= 0)
orderedKeys.add(pos,aKey);
else
orderedKeys.add(aKey);
}
else
orderedKeys.add(aKey);
}
return super.put(aKey, aValue);
}
/**
* @param aKey
* @returns
* calculate position at which the first key is greater
* otherwise return -1 if no key can be found which is greater
*
*/
private int getFirstKeyGreater(int aKey) {
int pos = 0;
int numKeys = getOrderedKeys().size();
for (int i=0;i<numKeys;i++) {
Integer key = (Integer) getOrderedKey(i);
int keyval = key.intValue();
if (keyval < aKey)
++pos;
else
break;
}
if (pos >= numKeys)
pos = -1;
return pos;
}
public synchronized Object remove(Object aKey) {
if (orderedKeys.contains(aKey)) {
int pos = orderedKeys.indexOf(aKey);
orderedKeys.remove(pos);
}
return super.remove(aKey);
}
/**
* This method reorders the ListHashtable only if the keys
* used are integer keys.
*
*/
public void reorderIntegerKeys() {
List keys = getOrderedKeys();
int numKeys = keys.size();
if (numKeys <=0 )
return;
if (!(getOrderedKey(0) instanceof Integer))
return;
List newKeys = new ArrayList();
List newValues = new ArrayList();
for (int i=0;i<numKeys;i++) {
Integer key = (Integer) getOrderedKey(i);
Object val = getOrderedValue(i);
int numNew = newKeys.size();
int pos = 0;
for (int j=0;j<numNew;j++) {
Integer newKey = (Integer) newKeys.get(j);
if (newKey.intValue() < key.intValue())
++pos;
else
break;
}
if (pos >= numKeys) {
newKeys.add(key);
newValues.add(val);
} else {
newKeys.add(pos,key);
newValues.add(pos,val);
}
}
// reset the contents
this.clear();
for (int l=0;l<numKeys;l++) {
put(newKeys.get(l),newValues.get(l));
}
}
public String toString() {
StringBuffer x = new StringBuffer();
x.append("Ordered Keys: ");
int numKeys = orderedKeys.size();
x.append("[");
for (int i=0;i<numKeys;i++) {
x.append(orderedKeys.get(i)+ " ");
}
x.append("]\n");
x.append("Ordered Values: ");
x.append("[");
for (int j=0;j<numKeys;j++) {
x.append(getOrderedValue(j)+" ");
}
x.append("]\n");
return x.toString();
}
public void merge(ListHashtable newTable) {
// This merges the newtable with the current one
int num = newTable.size();
for (int i=0;i<num;i++) {
Object aKey = newTable.getOrderedKey(i);
Object aVal = newTable.getOrderedValue(i);
this.put(aKey, aVal);
}
}
/**
* @return Returns the orderedKeys.
*/
public List getOrderedKeys() {
return orderedKeys;
}
public Object getOrderedKey(int i) {
return getOrderedKeys().get(i);
}
/**
* This method looks through the list of values and returns the key
* associated with the value.. Otherwise if not found, null is returned
* @param aValue
* @return
*/
public Object getKeyForValue(Object aValue) {
int num = getOrderedValues().size();
for (int i=0;i<num;i++) {
Object tmpVal = getOrderedValue(i);
if (tmpVal.equals(aValue)) {
return getOrderedKey(i);
}
}
return null;
}
public List getOrderedValues() {
List values = new ArrayList();
int numKeys = orderedKeys.size();
for (int i=0;i<numKeys;i++) {
values.add(get(getOrderedKey(i)));
}
return values;
}
public Object getOrderedValue(int i) {
return get(getOrderedKey(i));
}
}