View Javadoc

1   /*
2   Wotonomy: OpenStep design patterns for pure Java applications.
3   Copyright (C) 2000 Blacksmith, Inc.
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, see http://www.gnu.org
17  */
18  
19  package net.wotonomy.foundation;
20  
21  import java.util.Enumeration;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.Map;
25  
26  /***
27  * A pure java implementation of NSDictionary that
28  * implements Map for greater java interoperability.
29  *
30  * @author michael@mpowers.net
31  * @author cgruber@israfil.net
32  * @author $Author: cgruber $
33  * @version $Revision: 893 $
34  */
35  public class NSDictionary extends HashMap implements NSKeyValueCoding
36  {
37      public static final NSDictionary EmptyDictionary = new NSDictionary();
38  
39      /***
40      * Default constructor produces an empty dictionary.
41      */
42      public NSDictionary ()
43      {
44      	super();
45     }
46  
47      /***
48      * Constructor produces an empty dictionary with an initial capacity.
49      */
50      public NSDictionary (int initialCapacity)
51      {
52      	super(initialCapacity);
53      }
54  
55      /***
56      * Produces a dictionary that contains one key referencing one value.
57      */
58      public NSDictionary (Object key, Object value)
59      {
60      	super();
61  	    put( key, value );
62      }
63  
64      /***
65      * Produces a dictionary containing the specified keys and values.
66      * An IllegalArgumentException is thrown if the arrays are not 
67      * of the same length.
68      */
69      public NSDictionary (Object[] objects, Object[] keys)
70      {
71      	super();
72  	    if ( keys.length != objects.length )
73  	    {
74  	    	throw new IllegalArgumentException( "Array lengths do not match." );
75  	    }
76  
77  	    for ( int i = 0; i < keys.length; i++ )
78  	    {
79  	    	put( keys[i], objects[i] );
80  	    }
81      }
82  
83      /***
84      * Produces a dictionary that is a copy of the specified map (or dictionary).
85      */
86      public NSDictionary (Map aMap)
87      {
88      	super( aMap );
89      }
90  
91      /***
92      * Returns a count of the key-value pairs in this dictionary.
93      */
94      public int count ()
95      {
96      	return size();
97      }
98  
99      /***
100     * Returns an NSArray containing all keys in this dictionary.
101     */
102     public NSArray allKeys ()
103     {
104     	return new NSArray( keySet() );
105 
106     }
107 
108     /***
109     * Returns an NSArray containing all keys that reference the
110     * specified value.
111     */
112     public NSArray allKeysForObject (Object value)
113     {
114     	NSMutableArray result = new NSMutableArray();
115     	Map.Entry entry;
116 		Iterator it = entrySet().iterator();
117 
118 		while ( it.hasNext() )
119 		{
120 			entry = (Map.Entry) it.next();
121 
122 			// handle null values
123 			if ( ( value == null ) && ( entry.getValue() == null )
124 			|| ( value.equals( entry.getValue() ) ) )
125 			{
126 				// if match, add to result set
127 				result.addObject( entry.getKey() );
128 			}
129 		}
130 		
131 		return result;
132     }
133 
134     /***
135     * Returns an NSArray containing all values in this dictionary.
136     */
137     public NSArray allValues ()
138     {
139     	return new NSArray( values() );
140     }
141 
142     /***
143     * Returns whether the specified dictionary has the same or
144     * equivalent key-value pairs as this dictionary.
145     */
146     public boolean isEqualToDictionary (NSDictionary aDictionary)
147     {
148     	return equals( aDictionary );
149     }
150 
151     /***
152     * Returns an array of objects for the specified array of keys.
153     * If a key isn't found, the marker parameter will be placed 
154     * in the corresponding index(es) in the returned array.
155     */
156     public NSArray objectsForKeys (NSArray anArray, Object aMarker)
157     {
158     	NSMutableArray result = new NSMutableArray();
159     	if ( anArray == null ) return result;
160 
161 	    Object value;
162 	    Enumeration enumeration = anArray.objectEnumerator();
163 	    while ( enumeration.hasMoreElements() )
164 	    {
165 	    	value = objectForKey( enumeration.nextElement() );
166 		    if ( value == null )
167 		    {
168 		    	value = aMarker;
169 		    }
170 			result.addObject( value );
171 	    }
172 	    return result;
173     }
174 
175     /***
176     * Returns an enumeration over the keys in this dictionary.
177     */
178     public java.util.Enumeration keyEnumerator ()
179     {
180     	return new java.util.Enumeration()
181 	    {
182 	    	Iterator it = NSDictionary.this.keySet().iterator(); 
183 	    	public boolean hasMoreElements()
184 		    {
185 				return it.hasNext();
186 		    }
187 		    public Object nextElement()
188 		    {
189 		    	return it.next();
190 		    }
191 	    };
192     }
193 
194     /***
195     * Returns an enumeration over the values in this dictionary.
196     */
197     public java.util.Enumeration objectEnumerator ()
198     {
199     	return new java.util.Enumeration()
200 	    {
201 	    	Iterator it = NSDictionary.this.values().iterator(); 
202 	    	public boolean hasMoreElements()
203 		    {
204 				return it.hasNext();
205 		    }
206 		    public Object nextElement()
207 		    {
208 		    	return it.next();
209 		    }
210 	    };
211 	}
212     
213     /***
214     * Returns the value for the specified key, or null
215     * if the key is not found.
216     */
217     public Object objectForKey (Object aKey)
218     {
219     	return get( aKey );
220     }
221     
222     // interface NSKeyValueCoding
223 
224     public Object valueForKey (String aKey)
225     { // System.out.println( "valueForKey: " + aKey + "->" + this );      
226         Object result = objectForKey( aKey );
227         if ( result == null ) 
228             result = NSKeyValueCodingSupport.valueForKey( this, aKey );
229         return result;
230     }
231 
232     public void takeValueForKey (Object aValue, String aKey)
233     { // System.out.println( "takeValueForKey: " + aKey + " : " + aValue + "->" + this );      
234         put( aKey, aValue ); //FIXME: technically cheating since this is a read-only class
235     }
236 
237     public Object storedValueForKey (String aKey)
238     {
239         Object result = objectForKey( aKey );
240         if ( result == null ) 
241             result = NSKeyValueCodingSupport.storedValueForKey( this, aKey );
242         return result;
243     }
244 
245     public void takeStoredValueForKey (Object aValue, String aKey)
246     {
247         put( aKey, aValue ); //FIXME: technically cheating since this is a read-only class
248     }
249 
250     public Object handleQueryWithUnboundKey (String aKey)
251     {
252     	return NSKeyValueCodingSupport.handleQueryWithUnboundKey( this, aKey );
253     }
254 
255     public void handleTakeValueForUnboundKey (Object aValue, String aKey)
256     {
257     	NSKeyValueCodingSupport.handleTakeValueForUnboundKey( this, aValue, aKey );
258     }
259 
260     public void unableToSetNullForKey (String aKey)
261     {
262     	NSKeyValueCodingSupport.unableToSetNullForKey( this, aKey );
263     }
264 
265     public Object validateTakeValueForKeyPath (Object aValue, String aKey)
266     {
267     	throw new RuntimeException( "Not implemented yet." );
268     }
269 
270     public String toString() {
271         StringBuffer buf = new StringBuffer();
272         Enumeration enumeration = keyEnumerator();
273         boolean quote = false;
274         buf.append(NSPropertyListSerialization.TOKEN_BEGIN[NSPropertyListSerialization.PLIST_DICTIONARY]);
275         while (enumeration.hasMoreElements()) {
276             if (buf.length() == 1)
277                 buf.append(' ');
278             Object k = enumeration.nextElement();
279             buf.append(NSPropertyListSerialization.stringForPropertyList(k));
280             buf.append(" = ");
281             k = objectForKey(k);
282             buf.append(NSPropertyListSerialization.stringForPropertyList(k));
283             buf.append("; ");
284         }
285         buf.append(NSPropertyListSerialization.TOKEN_END[NSPropertyListSerialization.PLIST_DICTIONARY]);
286         return buf.toString();
287     }
288 
289 }
290 
291 /*
292  * $Log$
293  * Revision 1.2  2006/02/16 13:15:00  cgruber
294  * Check in all sources in eclipse-friendly maven-enabled packages.
295  *
296  * Revision 1.9  2005/05/11 15:21:53  cgruber
297  * Change enum to enumeration, since enum is now a keyword as of Java 5.0
298  *
299  * A few other comments in the code.
300  *
301  * Revision 1.8  2003/08/05 00:50:14  chochos
302  * use NSPropertyListSerialization to get the tokens to enclose the string description
303  *
304  * Revision 1.7  2003/08/04 20:26:10  chochos
305  * use NSPropertyListSerialization inside toString()
306  *
307  * Revision 1.6  2003/08/04 18:49:38  chochos
308  * NSDictionary(Object[], Object[]) was taking the parameters in the wrong order; for compatibility with Apple's NSDictionary, objects comes first, then keys.
309  *
310  * Revision 1.5  2003/08/04 18:26:19  chochos
311  * fixed opening '{'
312  *
313  * Revision 1.4  2003/01/28 22:11:30  mpowers
314  * Now implements NSKeyValueCoding.
315  *
316  * Revision 1.3  2002/06/30 17:58:06  mpowers
317  * Add a capacity constructor and static empty dictionary: thanks cgruber.
318  *
319  * Revision 1.2  2001/02/23 23:43:41  mpowers
320  * Removed ill-advised this.
321  *
322  * Revision 1.1.1.1  2000/12/21 15:47:31  mpowers
323  * Contributing wotonomy.
324  *
325  * Revision 1.3  2000/12/20 16:25:38  michael
326  * Added log to all files.
327  *
328  *
329  */
330 
331 
332