View Javadoc

1   /*
2   Wotonomy: OpenStep design patterns for pure Java applications.
3   Copyright (C) 2001 Intersect Software Corporation
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.control;
20  
21  import net.wotonomy.foundation.internal.Introspector;
22  import net.wotonomy.foundation.internal.IntrospectorException;
23  import net.wotonomy.foundation.internal.MissingPropertyException;
24  import net.wotonomy.foundation.internal.NullPrimitiveException;
25  import net.wotonomy.foundation.internal.WotonomyException;
26  
27  /***
28  * EOKeyValueCodingSupport defines default behavior for
29  * classes implementing EOKeyValueSupport.  <br><br>
30  * 
31  * On an object that does not implement EOKeyValueCoding,
32  * wotonomy will call the methods on this class directly.  
33  *
34  * @author michael@mpowers.net
35  * @author $Author: cgruber $
36  * @version $Revision: 894 $
37  */
38  public class EOKeyValueCodingSupport
39  {
40      /***
41      * Returns the value for the specified property key
42      * on the specified object. <br><br>
43      *
44      * If the property does not exist, this method calls
45      * handleQueryWithUnboundKey on the object if it 
46      * implements EOKeyValueCoding, otherwise calls
47      * handleQueryWithUnboundKey on this class. <br><br>
48      */
49      static public Object valueForKey( 
50          Object anObject, String aKey )
51      {
52          //TODO: may need to handle "." nesting here so
53          // that handleQueryWithUnboundKey gets called for 
54          // for the nested object, not the parent object
55          
56          //Correction: need to handle key paths in
57          // KeyValueCodingAdditionsSupport.
58              
59          try
60          {
61              return Introspector.get( anObject, aKey );        
62          }
63          catch ( IntrospectorException exc )
64          {
65              if ( anObject instanceof EOKeyValueCoding )
66              {
67                  return ((EOKeyValueCoding)anObject).handleQueryWithUnboundKey( aKey );
68              }
69              return handleQueryWithUnboundKey( anObject, aKey );   
70          }
71      }
72  
73      /***
74      * Sets the property to the specified value on
75      * the specified object.
76      *
77      * If the property does not exist, this method calls
78      * handleTakeValueForUnboundKey on the object if it 
79      * implements EOKeyValueCoding, otherwise calls
80      * handleTakeValueForUnboundKey on this class.
81      * 
82      * If the property is of a type that cannot allow
83      * null (e.g. primitive types) and aValue is null,
84      * this method should call unableToSetNullForKey
85      * on the object if it implements EOKeyValueCoding, 
86      * otherwise calls unableToSetNullForKey on this class.    
87      */
88      static public void takeValueForKey( 
89          Object anObject, Object aValue, String aKey )
90      {
91          //TODO: may need to handle "." nesting here so
92          // that handleTakeValueForUnboundKey gets called for 
93          // for the nested object, not the parent object
94              
95          try
96          {
97              Introspector.set( anObject, aKey, aValue );
98          }
99          catch ( NullPrimitiveException exc )
100         {
101             if ( anObject instanceof EOKeyValueCoding )
102             {
103                 ((EOKeyValueCoding)anObject).unableToSetNullForKey( aKey );
104             } 
105             else
106             {
107                 unableToSetNullForKey( anObject, aKey );   
108             }
109         }
110         catch ( MissingPropertyException exc )
111         {
112             if ( anObject instanceof EOKeyValueCoding )
113             {
114                 ((EOKeyValueCoding)anObject).handleTakeValueForUnboundKey( 
115                     aValue, aKey );
116             } 
117             else
118             {
119                 handleTakeValueForUnboundKey( anObject, aValue, aKey );   
120             }
121         }
122         
123     }
124 
125     /***
126     * Returns the value for the private field that 
127     * corresponds to the specified property on
128     * the specified object.
129     *
130     * This implementation currently calls valueForKey,
131     * because java security currently prevents us from 
132     * accessing the fields of another object.
133     */
134     static public Object storedValueForKey( 
135         Object anObject, String aKey )
136     {
137         //TODO: this currently just calls valueForKey
138         return valueForKey( anObject, aKey );
139     }
140 
141     /***
142     * Sets the the private field that corresponds to the 
143     * specified property to the specified value on the
144     * specified object.
145     *
146     * This implementation currently calls takeValueForKey,
147     * because java security currently prevents us from 
148     * accessing the fields of another object.
149     */
150     static public void takeStoredValueForKey( 
151         Object anObject, Object aValue, String aKey )
152     {
153         //TODO: this currently just calls takeValueForKey
154         takeValueForKey( anObject, aValue, aKey );
155     }
156 
157     /***
158     * Called by valueForKey when the specified key is
159     * not found on the specified object, if that object
160     * does not implement EOKeyValueCoding.
161     *
162     * This implementation throws a WotonomyException.
163     */
164     static public Object handleQueryWithUnboundKey( 
165         Object anObject, String aKey )
166     {
167         throw new WotonomyException(   
168             "Key not found for object: " 
169             + aKey + " : " + anObject );
170     }
171 
172     /***
173     * Called by takeValueForKey when the specified key
174     * is not found on the specified object, if that object
175     * does not implement EOKeyValueCoding.
176     *
177     * This implementation throws a WotonomyException.
178     */
179     static public void handleTakeValueForUnboundKey( 
180         Object anObject, Object aValue, String aKey )
181     {
182         throw new WotonomyException(   
183             "Key not found for object while setting value: " 
184             + aKey + " : " + anObject + " : " + aValue );
185     }
186 
187     /***
188     * Called by takeValueForKey when the type of the
189     * specified key is not allowed to be null, as is
190     * the case with primitive types, if the specified
191     * object does not implement EOKeyValueCoding.  
192     *
193     * This implementation throws a WotonomyException.
194     */
195     static public void unableToSetNullForKey( 
196         Object anObject, String aKey )
197     {
198         throw new WotonomyException(   
199             "Tried to key on object to null: " 
200             + aKey + " : " + anObject );
201     }
202 
203 }
204 
205 
206 /*
207  * $Log$
208  * Revision 1.2  2006/02/16 16:47:14  cgruber
209  * Move some classes in to "internal" packages and re-work imports, etc.
210  *
211  * Also use UnsupportedOperationExceptions where appropriate, instead of WotonomyExceptions.
212  *
213  * Revision 1.1  2006/02/16 13:19:57  cgruber
214  * Check in all sources in eclipse-friendly maven-enabled packages.
215  *
216  * Revision 1.5  2003/01/16 22:47:30  mpowers
217  * Compatibility changes to support compiling woextensions source.
218  * (34 out of 56 classes compile!)
219  *
220  * Revision 1.4  2001/05/18 21:04:33  mpowers
221  * Reimplemented EditingContext.initializeObject.
222  *
223  * Revision 1.3  2001/04/27 00:28:29  mpowers
224  * Fixed a return value.
225  *
226  * Revision 1.2  2001/04/03 20:36:01  mpowers
227  * Fixed refaulting/reverting/invalidating to be self-consistent.
228  *
229  * Revision 1.1  2001/03/28 17:49:33  mpowers
230  * Implemented EOKeyValueCodingSupport.
231  *
232  *
233  */
234     
235