/*---------------------------------------------------------------------------*\
$Id: cc74c84b1e6d63a06f26e366124741db111f7320 $
---------------------------------------------------------------------------
This software is released under a BSD-style license:
Copyright (c) 2004-2007 Brian M. Clapper. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. The end-user documentation included with the redistribution, if any,
must include the following acknowlegement:
"This product includes software developed by Brian M. Clapper
(bmc@clapper.org, http://www.clapper.org/bmc/). That software is
copyright (c) 2004-2007 Brian M. Clapper."
Alternately, this acknowlegement may appear in the software itself,
if wherever such third-party acknowlegements normally appear.
3. Neither the names "clapper.org", "clapper.org Java Utility Library",
nor any of the names of the project contributors may be used to
endorse or promote products derived from this software without prior
written permission. For written permission, please contact
bmc@clapper.org.
4. Products derived from this software may not be called "clapper.org
Java Utility Library", nor may "clapper.org" appear in their names
without prior written permission of Brian M. Clapper.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
NO EVENT SHALL BRIAN M. CLAPPER BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\*---------------------------------------------------------------------------*/
package org.clapper.util.misc;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Properties;
import java.io.Serializable;
/**
* An PropertiesMap provides a thin Map<String,String>
* wrapper around a java.util.Properties object, allowing the
* Properties object to be used where a type-safe Map is
* expected. (One such place is with a
* {@link org.clapper.util.text.VariableSubstituter} class.)
*
* @see java.util.Properties
*
* @version $Revision$
*
* @author Copyright © 2004-2007 Brian M. Clapper
*/
public class PropertiesMap
extends AbstractMap
implements Serializable
{
/*----------------------------------------------------------------------*\
Public Constants
\*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*\
Inner Classes
\*----------------------------------------------------------------------*/
/**
* Entry in the internal linked list (queue) of LRU entries. Implements
* Map.Entry for convenience.
*/
private class PropertiesMapEntry implements Map.Entry
{
private String key = null;
PropertiesMapEntry (String key)
{
this.key = key;
}
public boolean equals (Object o)
{
return PropertiesMapEntry.class.isInstance (o);
}
public int hashCode()
{
return key.hashCode();
}
public String getKey()
{
return key;
}
public String getValue()
{
return PropertiesMap.this.get (key);
}
public String setValue (String value)
{
return PropertiesMap.this.put (key, value);
}
}
/**
* Set of Map.Entry objects returned by the PropertiesMap.entrySet()
* method.
*/
private class EntrySet extends AbstractSet>
{
private Set entrySetResult;
EntrySet()
{
entrySetResult = new HashSet();
// Load the entry set.
KeySet keySet = new KeySet();
for (Iterator it = keySet.iterator(); it.hasNext(); )
entrySetResult.add (new PropertiesMapEntry (it.next()));
}
public Iterator> iterator()
{
return new Iterator>()
{
Iterator it = entrySetResult.iterator();
public Map.Entry next()
{
//return (Map.Entry) it.next();
return it.next();
}
public boolean hasNext()
{
return it.hasNext();
}
public void remove()
{
it.remove();
}
};
}
public boolean contains (Object o)
{
boolean has = false;
if (o instanceof Map.Entry)
{
Map.Entry e = (Map.Entry) o;
Object key = e.getKey();
has = PropertiesMap.this.containsKey (key);
}
return has;
}
public boolean remove (Object o)
{
return (PropertiesMap.this.remove (o) != null);
}
public int size()
{
return PropertiesMap.this.size();
}
public void clear()
{
PropertiesMap.this.clear();
}
}
/**
* Set of key objects returned by the PropertiesMap.keySet() method.
*/
private class KeySet extends AbstractSet
{
private KeySet()
{
// Nothing to do
}
public Iterator iterator()
{
return new KeySetIterator();
}
public boolean contains (Object key)
{
return PropertiesMap.this.containsKey (key);
}
public boolean remove (Object key)
{
return (PropertiesMap.this.remove (key) != null);
}
public int size()
{
return PropertiesMap.this.size();
}
public void clear()
{
PropertiesMap.this.clear();
}
}
/**
* Iterator returned by KeySet.iterator()
*/
private class KeySetIterator implements Iterator
{
private Enumeration> propertyNames;
KeySetIterator()
{
propertyNames = PropertiesMap.this.properties.propertyNames();
}
public String next()
{
return (String) propertyNames.nextElement();
}
public boolean hasNext()
{
return propertyNames.hasMoreElements();
}
public void remove()
{
throw new UnsupportedOperationException();
}
}
/*----------------------------------------------------------------------*\
Private Static Variables
\*----------------------------------------------------------------------*/
/**
* See JDK 1.5 version of java.io.Serializable
*/
private static final long serialVersionUID = 1L;
/*----------------------------------------------------------------------*\
Private Variables
\*----------------------------------------------------------------------*/
private EntrySet entrySetResult = null;
private Properties properties = null;
/*----------------------------------------------------------------------*\
Constructors
\*----------------------------------------------------------------------*/
/**
* Construct a map to wrap the specified Properties object.
*
* @param properties the Properties object
*/
public PropertiesMap (Properties properties)
{
this.properties = properties;
}
/*----------------------------------------------------------------------*\
Public Methods
\*----------------------------------------------------------------------*/
/**
* Remove all mappings from this map.
*/
public void clear()
{
properties.clear();
}
/**
* Determine whether this map contains a mapping for a given key. Note
* that this implementation of containsKey() does not refresh
* the object in the cache.
*
* @param key the key to find
*
* @return true if the key is in the map, false if not
*/
public boolean containsKey (Object key)
{
return properties.containsKey (key);
}
/**
* Determine whether this map contains a given value. Note that this
* implementation of containsValue() does not refresh the
* objects in the cache.
*
* @param value the value to find
*
* @return true if the value is in the map, false if not
*/
public boolean containsValue (Object value)
{
return properties.containsValue (value);
}
/**
* Get a set view of the mappings in this map. Each element in this set
* is a Map.Entry. The collection is backed by the map, so
* changes to the map are reflected in the collection, and vice-versa.
* The collection supports element removal, which removes the
* corresponding mapping from the map, via the
* Iterator.remove, Collection.remove,
* removeAll, retainAll, and clear
* operations. It does not support the add or addAll
* operations.
*
* @return nothing
*
* @throws UnsupportedOperationException unconditionally
*/
public Set> entrySet()
{
synchronized (this)
{
if (entrySetResult == null)
entrySetResult = new EntrySet();
}
return entrySetResult;
}
/**
* Retrieve an object from the map. Retrieving an object from an
* LRU map "refreshes" the object so that it is among the most recently
* used objects.
*
* @param key the object's key in the map. Must be a string.
*
* @return the associated object, or null if not found
*
* @throws ClassCastException if key is not a string
*/
public String get (Object key)
{
return properties.getProperty ((String) key);
}
/**
* Determine whether this map is empty or not.
*
* @return true if the map has no mappings, false
* otherwise
*/
public boolean isEmpty()
{
return properties.isEmpty();
}
/**
* Return a Set view of the keys in the map. The set is
* partially backed by the map. Changes to the map are not necessarily
* reflected in the set, and vice-versa. The set does not support
* element removal.
*
* @return the set of keys in this map
*/
public Set keySet()
{
return new KeySet();
}
/**
* Associates the specified value with the specified key in this map.
* If the key already has a value in this map, the existing value is
* replaced by the new value, and the old value is replaced. If the key
* already exists in the map, it is moved to the end of the key
* insertion order list.
*
* @param key the key with which the specified value is to be associated
* @param value the value to associate with the specified key
*
* @return the previous value associated with the key, or null if (a) there
* was no previous value, or (b) the previous value was a null
*/
public String put (String key, String value)
{
String previous = (String) properties.setProperty (key, value);
entrySetResult = null;
return previous;
}
/**
* Removes the mapping for a key, if there is one. Not supported by
* this class.
*
* @param key the key to remove
*
* @return the previous value associated with the key, or null if (a) there
* was no previous value, or (b) the previous value was a null
*
* @throws UnsupportedOperationException unconditionally
*/
public String remove (Object key)
{
throw new UnsupportedOperationException();
}
/**
* Get the number of entries in the map. Note that this value can
* temporarily exceed the maximum capacity of the map. See the class
* documentation for details.
*
* @return the number of entries in the map
*/
public int size()
{
return properties.size();
}
}
Ads help maintain this website.