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     */
017    package org.apache.commons.el;
018    
019    import java.util.Collection;
020    import java.util.Enumeration;
021    import java.util.HashMap;
022    import java.util.Map;
023    import 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    
040    public 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    }