001 package com.thaiopensource.util; 002 003 import java.util.Hashtable; 004 import java.util.Enumeration; 005 006 public class PropertyMapBuilder { 007 private Hashtable map; 008 private PropertyId[] keys; 009 010 private static class PropertyMapImpl implements PropertyMap { 011 private final Hashtable map; 012 private final PropertyId[] keys; 013 014 private PropertyMapImpl(Hashtable map, PropertyId[] keys) { 015 this.map = map; 016 this.keys = keys; 017 } 018 019 public Object get(PropertyId pid) { 020 return map.get(pid); 021 } 022 023 public int size() { 024 return keys.length; 025 } 026 027 public boolean contains(PropertyId pid) { 028 return map.get(pid) != null; 029 } 030 031 public PropertyId getKey(int i) { 032 return keys[i]; 033 } 034 } 035 036 public PropertyMapBuilder() { 037 this.map = new Hashtable(); 038 } 039 040 public PropertyMapBuilder(PropertyMap pm) { 041 if (pm instanceof PropertyMapImpl) { 042 PropertyMapImpl pmi = (PropertyMapImpl)pm; 043 this.map = pmi.map; 044 this.keys = pmi.keys; 045 } 046 else { 047 this.map = new Hashtable(); 048 for (int i = 0, len = pm.size(); i < len; i++) { 049 PropertyId pid = pm.getKey(i); 050 put(pid, pm.get(pid)); 051 } 052 } 053 } 054 055 private void lock() { 056 if (keys != null) 057 return; 058 keys = new PropertyId[map.size()]; 059 int i = 0; 060 for (Enumeration e = map.keys(); e.hasMoreElements();) 061 keys[i++] = (PropertyId)e.nextElement(); 062 } 063 064 private void copyIfLocked() { 065 if (keys == null) 066 return; 067 Hashtable newMap = new Hashtable(); 068 for (int i = 0; i < keys.length; i++) 069 newMap.put(keys[i], map.get(keys[i])); 070 map = newMap; 071 keys = null; 072 } 073 074 public PropertyMap toPropertyMap() { 075 lock(); 076 return new PropertyMapImpl(map, keys); 077 } 078 079 public Object put(PropertyId id, Object value) { 080 copyIfLocked(); 081 if (value == null) 082 return map.remove(id); 083 if (!id.getValueClass().isInstance(value)) 084 throw new ClassCastException(); 085 return map.put(id, value); 086 } 087 088 public Object get(PropertyId pid) { 089 return map.get(pid); 090 } 091 092 public boolean contains(PropertyId pid) { 093 return map.get(pid) != null; 094 } 095 }