1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.wotonomy.foundation;
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 * NSKeyValueCodingSupport defines default behavior for
29 * classes implementing NSKeyValueSupport. <br><br>
30 *
31 * On an object that does not implement NSKeyValueCoding,
32 * wotonomy will call the methods on this class directly.
33 *
34 * @author michael@mpowers.net
35 * @author $Author: cgruber $
36 * @version $Revision: 892 $
37 */
38 public class NSKeyValueCodingSupport
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 NSKeyValueCoding, otherwise calls
47 * handleQueryWithUnboundKey on this class. <br><br>
48 */
49 static public Object valueForKey(
50 Object anObject, String aKey )
51 {
52
53
54
55
56
57
58
59 try
60 {
61 return Introspector.get( anObject, aKey );
62 }
63 catch ( IntrospectorException exc )
64 {
65 if ( anObject instanceof NSKeyValueCoding )
66 {
67 return ((NSKeyValueCoding)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 NSKeyValueCoding, 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 NSKeyValueCoding,
86 * otherwise calls unableToSetNullForKey on this class.
87 */
88 static public void takeValueForKey(
89 Object anObject, Object aValue, String aKey )
90 {
91
92
93
94
95 try
96 {
97 Introspector.set( anObject, aKey, aValue );
98 }
99 catch ( NullPrimitiveException exc )
100 {
101 if ( anObject instanceof NSKeyValueCoding )
102 {
103 ((NSKeyValueCoding)anObject).unableToSetNullForKey( aKey );
104 }
105 else
106 {
107 unableToSetNullForKey( anObject, aKey );
108 }
109 }
110 catch ( MissingPropertyException exc )
111 {
112 if ( anObject instanceof NSKeyValueCoding )
113 {
114 ((NSKeyValueCoding)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
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
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 NSKeyValueCoding.
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 NSKeyValueCoding.
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 NSKeyValueCoding.
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228