
package javax.script;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * SimpleNamespace is an implementation of Namespace using an 
 * instance of java.util.HashMap or another Map passed in a 
 * constructor to store and expose key-pair values.
 * 
 * @author Nandika Jayawardana <nandika@opensource.lk>
 * @author Sanka Samaranayake  <sanka@opensoruce.lk>
 */
public class SimpleNamespace implements Namespace {
	
	/**
     * In which the key-value pairs are stored.
	 */
    protected Map map;
	
    /**
     * Constructs a SimpleNamespace.
     */
	public SimpleNamespace(){
        map = new HashMap();
	}
    
    /**
     * Constructs a SimpleNamespace and initializes it using a 
     * specified map. 
     * 
     * @param map a map which is used to initialize the 
     *            SimpleNamespace
     */
	public SimpleNamespace(Map map){
		this.map = map;
	}

    /**
     * Associates the specified value with the specified key in a 
     * java.util.Map. If the map previously contained a mapping for 
     * this key, the old value is replaced.
     * 
     * @param key the String value which uniquely identifies the 
     *            object
     * @param value the object to be stored.
     * @throws IllegalArgumentException if the key is null or is not
     *         java.lang.String type
     */
    public Object put(Object key, Object value) 
            throws IllegalArgumentException{
      
    	if ((key == null) || !(key instanceof java.lang.String) ) {
            throw new IllegalArgumentException("key is null or not a String");
        }       
		
    	return map.put(key,value);
	}
	
    /**
     * Copies all of the mappings from the specified map to this map.
     * These mappings will replace any mappings that this map had for
     * any of the keys currently in the specified map.
     * 
     * @param toMerge mappings to be stored in the map.
     * @throws IllegalArgumentException if a key is null or is not 
     *         java.lang.String type in the specified map
     */
	public void putAll(Map toMerge) throws IllegalArgumentException {
        
        Set keySet= toMerge.keySet();
		Iterator keys= keySet.iterator();
		
        while (keys.hasNext()) {
			if (keys.next() instanceof String) {
				throw new IllegalArgumentException("a key is not a String");
            }
        }
            
		map.putAll(toMerge);	
	}
    
    public int size() {
        return map.size();
    }
    
    public void clear() {
        map.clear();    
    }
    
    public boolean isEmpty() {
        return map.isEmpty();
    }
    
	public boolean containsKey(Object key) {
		return map.containsKey(key);
	}
	public boolean containsValue(Object value) {
		return map.containsValue(value);
	}
    
    public Collection values() {
        return map.values();
    }
    
	public Set entrySet() {
		return map.entrySet();
	}
	
    public Object get(Object key) {
		return map.get(key);
	}

	public Set keySet() {
		return map.keySet();
	}

    public Object remove(Object key) {
		return map.remove(key);
	}
}
