package com.ericfeminella.collections
{
import flash.utils.Dictionary;
import mx.resources.IResourceBundle;
/**
*
* <code>IMap</code> implementation which dynamically creates
* a Map of key / value pairs and provides a standard API for
* working with an instance of an <code>ResourceBundle</code>.
*
* @example The following example demonstrates a typical use
* case in which a <code>ResourceMap</code> instance has keys
* and values: created, retrieved, updated and deleted (CRUD)
* via an <code>IMap</code> implementation.
*
* <listing version="3.0">
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
*
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
* // resources.properties content:
* // PROPERTY_A = value A
* // PROPERTY_B = value B
*
* var map:IMap = new ResourceMap();
* map.put("PROPERTY_A", "value A");
* map.put("PROPERTY_B", "new value...");
*
* trace( map.getKeys() );
* trace( map.getValues() );
* trace( map.size() );
*
* // outputs the following:
* // PROERTY_A, PROERTY_B
* // value A, new value...
* // 2
*
* </listing>
*
* @see http://livedocs.adobe.com/flex/3/mx/resources/IResourceBundle.html
* @see http://livedocs.adobe.com/flex/3/mx/resources/ResourceBundle.html
* @see com.ericfeminella.collections.IMap
*
*
*/
public class ResourceMap implements IMap
{
/**
*
* Defines the reference to the underlying content object
* generated by the compiler for the specified instance of
* a <code>ResourceBundle</code>
*
* <p>
* This reference is used to perform CRUD operations on
* a <code>ResourceBundle</code> instance via a concrete
* <code>IMap</code> implementation.
* </p>
*
* @see http://livedocs.adobe.com/flex/3/mx/resources/IResourceBundle.html#content
*
*/
private var resource:Object = null;
/**
*
* Creates a new <code>ResourceMap</code> instance which
* contains a map of key / value pairs initially defined
* in the specified <code>ResourceBundle</code>
*
* <p>
* By default, weak key references are used in order to
* ensure that objects are eligible for Garbage Collection
* immediatly after they are no longer being referenced.
* </p>
*
* @example The following example demonstrates how to
* create a new instance of <code>ResourceMap</code>
*
* <listing version="3.0">
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
*
* </listing>
*
* @param <code>IResourceBundle</code> instance to convert to map
*
*/
public function ResourceMap(bundle:IResourceBundle)
{
resource = bundle.content;
}
/**
*
* Adds a key and value to the <code>ResourceMap</code>
* instance.
*
* @example
* <listing version="3.0">
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* map.put( "amount", 200.32 );
*
* </listing>
*
* @param the key to add to the underlying map
* @param the value of the specified key
*
*/
public function put(key:*, value:*) : void
{
resource[key] = value;
}
/**
*
* Places all name / value pairs into the current
* <code>IMap</code> instance.
*
* @example
* <listing version="3.0">
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
*
* var table:Object = {a: "foo", b: "bar"};
* map.putAll( table );
*
* trace( map.getKeys() ); // a, b
* trace( map.getValues() ); // foo, bar
*
* </listing>
*
* @param an <code>Object</code> of name / value pairs
*
*/
public function putAll(table:Dictionary) : void
{
for (var prop:String in table)
{
put( prop, table[prop] );
}
}
/**
*
* <code>putEntry</code> is intended as a pseudo-overloaded
* <code>put</code> implementation whereby clients may call
* <code>putEntry</code> to pass an <code>IHashMapEntry</code>
* rather than a key and value.
*
* @param concrete <code>IHashMapEntry</code> implementation
*
*/
public function putEntry(entry:IHashMapEntry) : void
{
put( entry.key, entry.value );
}
/**
*
* Removes a key and value from the <code>ResourceMap</code>
* instance
*
* @example
* <listing version="3.0">
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* map.put( "admin", adminVO );
* map.remove( "admin" );
*
* </listing>
*
* @param the key to remove from the map
*
*/
public function remove(key:*) : void
{
delete resource[key];
}
/**
*
* Determines if a key exists in the <code>ResourceMap</code>
* instance
*
* @example
* <listing version="3.0">
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* map.put( "admin", adminVO );
*
* trace( map.containsKey( "admin" ) );
* //true
*
* </listing>
*
* @param key from which to determine existance in the map
* @return true if the key exists, otherwise false
*
*/
public function containsKey(key:*) : Boolean
{
return resource[key] != null;
}
/**
*
* Determines if a value exists in the <code>ResourceMap</code>
* instance
*
* @example
* <listing version="3.0">
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* map.put( "admin", adminVO );
*
* trace( map.containsValue( adminVO ) );
* //true
*
* </listing>
*
* @param value in which to determine existance in the map
* @return true if the value exisits, otherwise false
*
*/
public function containsValue(value:*) : Boolean
{
var result:Boolean;
for ( var key:* in resource )
{
if ( resource[key] == value )
{
result = true;
break;
}
}
return result;
}
/**
*
* Returns a key based on the value of the key in the
* underlying <code>ResourceMap</code> instance
*
* @example
* <listing version="3.0">
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* map.put( "admin", adminVO );
*
* trace( map.getKey( adminVO ) );
* //admin
*
* </listing>
*
* @param the key in which to retrieve the value of
* @return the value of the specified key
*
*/
public function getKey(value:*) : *
{
var id:String = null;
for ( var key:* in resource )
{
if ( resource[key] == value )
{
id = key;
break;
}
}
return id;
}
/**
*
* Returns each key added to the <code>ResourceMap</code>
* instance
*
* @example
* <listing version="3.0">
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* map.put( "admin", adminVO );
* map.put( "editor", editorVO );
*
* trace( map.getKeys() );
* //admin, editor
*
* </listing>
*
* @return Array of key identifiers
*
*/
public function getKeys() : Array
{
var keys:Array = [];
for ( var key:* in resource )
{
keys.push( key );
}
return keys;
}
/**
*
* Retrieves the value of the specified key from the
* <code>ResourceMap</code> instance
*
* @example
* <listing version="3.0">
*
* import com.ericfeminella.collections.ResourceMap;
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* map.put( "admin", adminVO );
* map.put( "editor", editorVO );
*
* trace( map.getValue( "editor" ) );
* // [object, editorVO]
*
* </listing>
*
* @param the key in which to retrieve the value of
* @return value of specified key, otherwise undefined
*
*/
public function getValue(key:*) : *
{
return resource[key];
}
/**
*
* Retrieves each value assigned to each key in the
* <code>ResourceMap</code> instance
*
* @example
* <listing version="3.0">
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* map.put( "admin", adminVO );
* map.put( "editor", editorVO );
*
* trace( map.getValues() ); //[object, adminVO],[object, editorVO]
*
* </listing>
*
* @return Array of values assigned for all keys in the map
*
*/
public function getValues() : Array
{
var values:Array = [];
for ( var key:* in resource )
{
values.push( resource[key] );
}
return values;
}
/**
*
* Determines the size of the <code>ResourceMap</code>
* instance
*
* @example
* <listing version="3.0">
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* map.put( "admin", adminVO );
* map.put( "editor", editorVO );
*
* trace( map.size() ); //2
*
* </listing>
*
* @return the current size of the map instance
*
*/
public function size() : int
{
var length:int = 0;
for ( var key:* in resource )
{
length++;
}
return length;
}
/**
*
* Determines if the current <code>ResourceMap</code>
* instance is empty
*
* @example
* <listing version="3.0">
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* trace( map.isEmpty() ); //true
*
* map.put( "admin", adminVO );
* trace( map.isEmpty() );
* // false
*
* </listing>
*
* @return true if the current map is empty, false if not
*
*/
public function isEmpty() : Boolean
{
return size() <= 0;
}
/**
*
* Resets all key value assignments in the <code>ResourceMap</code>
* instance to null
*
* @example
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* map.put( "admin", adminVO );
* map.put( "editor", editorVO );
* map.reset();
*
* trace( map.getValues() );
* // null, null
*
* </listing>
*
*/
public function reset() : void
{
for ( var key:* in resource )
{
resource[key] = null;
}
}
/**
*
* Resets all key / values defined in the <code>ResourceMap</code>
* instance to null with the exception of the specified key
*
* @example
* <listing version="3.0">
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* map.put( "admin", adminVO );
* map.put( "editor", editorVO );
*
* trace( map.getValues() );
* // [object, adminVO],[object, editorVO]
*
* map.resetAllExcept( "editor", editorVO );
* trace( map.getValues() );
* // null,[object, editorVO]
*
* </listing>
*
* @param the key which is not to be cleared from the map
*
*/
public function resetAllExcept(keyId:*) : void
{
for ( var key:* in resource )
{
if ( key != keyId )
{
resource[key] = null;
}
}
}
/**
*
* Resets all key / values in the <code>ResourceMap</code>
* instance to null
*
* @example
* <listing version="3.0">
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* map.put( "admin", adminVO );
* map.put( "editor", editorVO );
* trace( map.size() );
* //2
* map.clear();
* trace( map.size() );
* //0
*
* </listing>
*
*/
public function clear() : void
{
for ( var key:* in resource )
{
remove( key );
}
}
/**
*
* Clears all key / values defined in the <code>ResourceMap</code>
* instance with the exception of the specified key
*
* @example
* <listing version="3.0">
*
* import com.ericfeminella.collections.ResourceMap;
* import com.ericfeminella.collections.IMap;
* import mx.resources.ResourceBundle;
*
* [ResourceBundle("resources")]
* private static const rb:ResourceBundle;
*
* var map:IMap = new ResourceMap( rb, false );
* map.put( "admin", adminVO );
* map.put( "editor", editorVO );
* trace( map.size() );
* //2
*
* map.clearAllExcept( "editor", editorVO );
* trace( map.getValues() );
* //[object, editorVO]
* trace( map.size() );
* //1
*
* </listing>
*
* @param the key which is not to be cleared from the map
*
*/
public function clearAllExcept(keyId:*) : void
{
for ( var key:* in resource )
{
if ( key != keyId )
{
remove( key );
}
}
}
/**
*
* Returns an <code>Array</code> of <code>IHashMapEntry</code>
* objects based on the underlying internal map.
*
* @param <code>Array</code> of <code>IHashMapEntry</code> objects
*
*/
public function getEntries() : Array
{
var list:Array = new Array();
for ( var key:* in resource )
{
list.push( new HashMapEntry( key, resource[key] ) );
}
return list
}
}
}