001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.el;
018
019import java.util.Collection;
020import java.util.Enumeration;
021import java.util.HashMap;
022import java.util.Map;
023import java.util.Set;
024
025/**
026 *
027 * <p>This is a Map implementation driven by a data source that only
028 * provides an enumeration of keys and a getValue(key) method.  This
029 * class must be subclassed to implement those methods.
030 *
031 * <p>Some of the methods may incur a performance penalty that
032 * involves enumerating the entire data source.  In these cases, the
033 * Map will try to save the results of that enumeration, but only if
034 * the underlying data source is immutable.
035 * 
036 * @author Nathan Abramson - Art Technology Group
037 * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: bayard $
038 **/
039
040public abstract class EnumeratedMap
041  implements Map
042{
043  //-------------------------------------
044  // Member variables
045  //-------------------------------------
046
047  Map mMap;
048
049  //-------------------------------------
050  public void clear ()
051  {
052    throw new UnsupportedOperationException ();
053  }
054
055  //-------------------------------------
056  public boolean containsKey (Object pKey)
057  {
058    return getValue (pKey) != null;
059  }
060
061  //-------------------------------------
062  public boolean containsValue (Object pValue)
063  {
064    return getAsMap ().containsValue (pValue);
065  }
066
067  //-------------------------------------
068  public Set entrySet ()
069  {
070    return getAsMap ().entrySet ();
071  }
072
073  //-------------------------------------
074  public Object get (Object pKey)
075  {
076    return getValue (pKey);
077  }
078
079  //-------------------------------------
080  public boolean isEmpty ()
081  {
082    return !enumerateKeys ().hasMoreElements ();
083  }
084
085  //-------------------------------------
086  public Set keySet ()
087  {
088    return getAsMap ().keySet ();
089  }
090
091  //-------------------------------------
092  public Object put (Object pKey, Object pValue)
093  {
094    throw new UnsupportedOperationException ();
095  }
096
097  //-------------------------------------
098  public void putAll (Map pMap)
099  {
100    throw new UnsupportedOperationException ();
101  }
102
103  //-------------------------------------
104  public Object remove (Object pKey)
105  {
106    throw new UnsupportedOperationException ();
107  }
108
109  //-------------------------------------
110  public int size ()
111  {
112    return getAsMap ().size ();
113  }
114
115  //-------------------------------------
116  public Collection values ()
117  {
118    return getAsMap ().values ();
119  }
120
121  //-------------------------------------
122  // Abstract methods
123  //-------------------------------------
124  /**
125   *
126   * Returns an enumeration of the keys
127   **/
128  public abstract Enumeration enumerateKeys ();
129
130  //-------------------------------------
131  /**
132   *
133   * Returns true if it is possible for this data source to change
134   **/
135  public abstract boolean isMutable ();
136
137  //-------------------------------------
138  /**
139   *
140   * Returns the value associated with the given key, or null if not
141   * found.
142   **/
143  public abstract Object getValue (Object pKey);
144
145  //-------------------------------------
146  /**
147   *
148   * Converts the MapSource to a Map.  If the map is not mutable, this
149   * is cached
150   **/
151  public Map getAsMap ()
152  {
153    if (mMap != null) {
154      return mMap;
155    }
156    else {
157      Map m = convertToMap ();
158      if (!isMutable ()) {
159        mMap = m;
160      }
161      return m;
162    }
163  }
164
165  //-------------------------------------
166  /**
167   *
168   * Converts to a Map
169   **/
170  Map convertToMap ()
171  {
172    Map ret = new HashMap ();
173    for (Enumeration e = enumerateKeys (); e.hasMoreElements (); ) {
174      Object key = e.nextElement ();
175      Object value = getValue (key);
176      ret.put (key, value);
177    }
178    return ret;
179  }
180
181  //-------------------------------------
182}