1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package net.wotonomy.access;
19
20 import net.wotonomy.foundation.NSArray;
21 import net.wotonomy.foundation.NSData;
22 import net.wotonomy.foundation.NSDictionary;
23 import net.wotonomy.foundation.NSKeyValueCoding;
24 import net.wotonomy.foundation.NSMutableArray;
25 import net.wotonomy.foundation.NSMutableDictionary;
26 import net.wotonomy.foundation.NSTimestamp;
27
28 /***
29 *
30 * @author ezamudio@nasoft.com
31 * @author $Author: cgruber $
32 * @version $Revision: 894 $
33 */
34
35 public abstract class EOAdaptor {
36
37 protected String _name;
38 protected NSDictionary _connectionDictionary = NSDictionary.EmptyDictionary;
39 protected NSMutableArray _contexts = new NSMutableArray();
40 protected Class _expressionClass;
41 private static NSMutableDictionary _expressionClassesByName = new NSMutableDictionary();
42
43 public EOAdaptor(String name) {
44 super();
45 _name = name;
46 }
47
48 /***
49 * Creates an adaptor with model's adaptorName and sets its connection
50 * dictionary to the model's connection dictionary.
51 * @param model The model to take adaptorName and connectionDictionary from.
52 * @return The adaptor specified in model.
53 */
54 public static EOAdaptor adaptorWithModel(EOModel model) {
55 if (model == null)
56 throw new IllegalArgumentException("Model must not be null.");
57 if (model.adaptorName() == null || model.adaptorName().length() == 0)
58 throw new IllegalArgumentException("Cannot create an adaptor with an empty name.");
59 EOAdaptor adaptor = adaptorWithName(model.adaptorName());
60 if (adaptor == null)
61 throw new IllegalArgumentException("Cannot create adaptor with name " + model.adaptorName());
62 adaptor.setConnectionDictionary(model.connectionDictionary());
63 return adaptor;
64 }
65
66 /***
67 * Instantiates an adaptor of a concrete EOAdaptor subclass, based on name.
68 * If name is a fully qualified class name, then it returns an instance of that class
69 * by invoking the constructor with a string argument. Otherwise, it
70 * tries to find a class called (name)Adaptor in a package called
71 * net.wotonomy.(lowercase name)adaptor; if it can't find one, an exception is raised.
72 * @param name The name of the adaptor, or a fully qualified class name.
73 * @return
74 */
75 public static EOAdaptor adaptorWithName(String name) {
76 Class adaptorClass = null;
77 String cname = null;
78 if (name.endsWith("Adaptor") && name.indexOf('.') > 0) {
79 cname = name;
80 int lastdot = name.lastIndexOf('.');
81
82 name = cname.substring(lastdot, cname.length() - 7);
83 } else {
84
85 cname = "net.wotonomy." + name.toLowerCase() + "adaptor." + name + "Adaptor";
86 }
87 try {
88 adaptorClass = Class.forName(cname);
89 } catch (ClassNotFoundException ex) {
90 throw new IllegalArgumentException("Cannot find class named " + name);
91 }
92 EOAdaptor adaptor = null;
93 java.lang.reflect.Constructor callme = null;
94 try {
95 callme = adaptorClass.getConstructor(new Class[]{ String.class });
96 adaptor = (EOAdaptor)callme.newInstance((Object[])new String[]{ name });
97 } catch (ClassCastException ex) {
98 throw new IllegalArgumentException("Class " + adaptorClass.getName() + " must inherit from net.wotonomy.access.EOAdaptor");
99 }catch (Exception ex) {
100 throw new IllegalArgumentException("Cannot find or invoke constructor with name argument in class " + adaptorClass.getName());
101 }
102 return adaptor;
103 }
104
105 public static void setExpressionClassName(String expClassName, String adaptorClassName) {
106 _expressionClassesByName.setObjectForKey(expClassName, adaptorClassName);
107 }
108 public static String expressionClassName(String adaptorClassName) {
109 return (String)_expressionClassesByName.objectForKey(adaptorClassName);
110 }
111
112 public void assignExternalInfoForAttribute(EOAttribute attribute) {
113 if (!attribute.isDerived()) {
114 attribute.setColumnName(attribute.name().toUpperCase());
115 }
116 assignExternalTypeForAttribute(attribute);
117 }
118
119 public void assignExternalTypeForAttribute(EOAttribute attribute) {
120 }
121
122 public void assignExternalInfoForEntity(EOEntity entity) {
123 entity.setExternalName(entity.name().toUpperCase());
124 }
125
126 public void assignExternalInfoForEntireModel(EOModel model) {
127 NSArray ents = model.entities();
128 for (int i = 0; i < ents.count(); i++) {
129 EOEntity e = (EOEntity)ents.objectAtIndex(i);
130
131 NSArray atts = e.attributes();
132 for (int j = 0; j < atts.count(); j++) {
133 EOAttribute a = (EOAttribute)atts.objectAtIndex(i);
134 assignExternalInfoForAttribute(a);
135 }
136 assignExternalInfoForEntity(e);
137 }
138 }
139
140 public boolean canServiceModel(EOModel model) {
141 NSDictionary mcd = model.connectionDictionary();
142 if (mcd == null && _connectionDictionary == null)
143 return true;
144 if (mcd == null || _connectionDictionary == null)
145 return false;
146 return mcd.equals(_connectionDictionary);
147 }
148
149 public void setConnectionDictionary(NSDictionary connection) {
150 _connectionDictionary = connection;
151 }
152 public NSDictionary connectionDictionary() {
153 return _connectionDictionary;
154 }
155
156 public NSArray contexts() {
157 return new NSArray(_contexts);
158 }
159
160 public abstract void assertConnectionDictionaryIsValid();
161
162 public abstract EOAdaptorContext createAdaptorContext();
163
164 public abstract Class defaultExpressionClass();
165
166 public abstract EOSQLExpressionFactory expressionFactory();
167
168 public abstract boolean isValidQualifierType(String typeName, EOModel model);
169
170 public Class expressionClass() {
171 if (_expressionClass != null)
172 return _expressionClass;
173 String cname = expressionClassName(name());
174 if (cname != null) {
175 try {
176 _expressionClass = Class.forName(cname);
177 } catch (ClassNotFoundException ex) {
178 throw new IllegalStateException("Cannot find expression class named " + cname);
179 }
180 }
181 return defaultExpressionClass();
182 }
183
184 public NSArray externalTypesWithModel(EOModel model) {
185 return NSArray.EmptyArray;
186 }
187
188 public NSData fetchedValueForDataValue(NSData value, EOAttribute attr) {
189 return value;
190 }
191
192 public NSTimestamp fetchedValueForDateValue(NSTimestamp value, EOAttribute attr) {
193 return value;
194 }
195
196 public Number fetchedValueForNumberValue(Number value, EOAttribute attr) {
197 return value;
198 }
199
200 public String fetchedValueForStringValue(String value, EOAttribute attr) {
201 return value;
202 }
203
204 public Object fetchedValueForValue(Object value, EOAttribute attr) {
205 if (value == NSKeyValueCoding.NullValue)
206 return value;
207 if (value instanceof String)
208 return fetchedValueForStringValue((String)value, attr);
209 if (value instanceof NSData)
210 return fetchedValueForDataValue((NSData)value, attr);
211 if (value instanceof Number)
212 return fetchedValueForNumberValue((Number)value, attr);
213 if (value instanceof NSTimestamp)
214 return fetchedValueForDateValue((NSTimestamp)value, attr);
215 return value;
216 }
217
218 public void handleDroppedConnection() {
219 for (int i = 0; i < _contexts.count(); i++) {
220 EOAdaptorContext c = (EOAdaptorContext)_contexts.objectAtIndex(i);
221 c.transactionDidRollback();
222 c.handleDroppedConnection();
223 }
224 _contexts.removeAllObjects();
225 }
226
227 public boolean hasOpenChannels() {
228 for (int i = 0; i < _contexts.count(); i++) {
229 EOAdaptorContext c = (EOAdaptorContext)_contexts.objectAtIndex(i);
230 if (c.hasOpenChannels())
231 return true;
232 }
233 return false;
234 }
235
236 public String internalTypeForExternalType(String extType, EOModel model) {
237 return null;
238 }
239
240 public boolean isDroppedConnectionException(Exception ex) {
241 return false;
242 }
243
244 public String name() {
245 return _name;
246 }
247
248 public NSArray prototypeAttributes() {
249 return NSArray.EmptyArray;
250 }
251
252 }
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269