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