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 java.io.File;
21 import java.io.FileInputStream;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.PrintStream;
25 import java.util.Enumeration;
26
27 import net.wotonomy.foundation.NSArray;
28 import net.wotonomy.foundation.NSDictionary;
29 import net.wotonomy.foundation.NSMutableArray;
30 import net.wotonomy.foundation.NSMutableDictionary;
31 import net.wotonomy.foundation.NSPropertyListSerialization;
32
33 /***
34 * An EOModel is a set of entities and stored procedures, along with a connection
35 * dictionary to connect to a database.
36 *
37 * @author ezamudio@nasoft.com
38 * @author $Author: cgruber $
39 * @version $Revision: 894 $
40 */
41 public class EOModel {
42
43 protected static final String IDX_NAME = "index.eomodeld";
44
45
46 protected NSMutableArray _entities = new NSMutableArray();
47 protected NSMutableDictionary _entitiesByName = new NSMutableDictionary();
48 protected NSMutableDictionary _entitiesByClass = new NSMutableDictionary();
49 protected NSDictionary _connectionDictionary = NSDictionary.EmptyDictionary;
50 protected String _adaptorName = "JDBC";
51 protected NSMutableDictionary _prototypesByName = new NSMutableDictionary();
52 protected NSMutableDictionary _storedProcedures = new NSMutableDictionary();
53 protected NSMutableArray _storedProcedureNames = new NSMutableArray();
54 protected NSDictionary _userInfo = NSDictionary.EmptyDictionary;
55 protected String _name;
56 protected String _path;
57 protected NSDictionary _internalInfo = NSDictionary.EmptyDictionary;
58 protected EOModelGroup _group;
59
60 public EOModel() {
61 super();
62 }
63
64 public EOModel(NSDictionary dict, Object o) {
65 this();
66 }
67
68 public EOModel(String path) {
69 this();
70 File f = new File(path);
71 _path = f.getAbsolutePath();
72 if (!(f.exists() && f.isDirectory()))
73 throw new IllegalArgumentException("The path is invalid (" + f + ")");
74 _name = f.getName();
75 f = new File(f, "index.eomodeld");
76 if (!(f.exists() && f.isFile()))
77 throw new IllegalArgumentException("Cannot find " + f);
78 String x = null;
79 try {
80 FileInputStream in = new FileInputStream(f);
81 byte[] b = new byte[in.available()];
82 in.read(b);
83 in.close();
84 x = new String(b);
85 } catch (IOException e) {
86 throw new IllegalArgumentException("Cannot read index.eomodeld");
87 }
88 NSDictionary d = NSPropertyListSerialization.dictionaryForString(x);
89 String version = (String)d.objectForKey("EOModelVersion");
90 if (version == null || !version.startsWith("2."))
91 throw new IllegalArgumentException("Invalid eomodel version: " + version);
92 setAdaptorName((String)d.objectForKey("adaptorName"));
93 setConnectionDictionary((NSDictionary)d.objectForKey("connectionDictionary"));
94 _entities = ((NSArray)d.objectForKey("entities")).mutableClone();
95 if (d.objectForKey("storedProcedures") != null)
96 _storedProcedureNames.addObjectsFromArray((NSArray)d.objectForKey("storedProcedures"));
97 if (d.objectForKey("internalInfo") != null)
98 _internalInfo = (NSDictionary)d.objectForKey("internalInfo");
99 if (d.objectForKey("userInfo") != null)
100 _userInfo = (NSDictionary)d.objectForKey("userInfo");
101 entityNamed("EOPrototypes");
102 }
103
104 public void setConnectionDictionary(NSDictionary dict) {
105 _connectionDictionary = dict;
106 }
107 public NSDictionary connectionDictionary() {
108 return _connectionDictionary;
109 }
110
111 public void addEntity(EOEntity ent) {
112 _entitiesByName.setObjectForKey(ent, ent.name());
113 _entitiesByClass.setObjectForKey(ent, ent.className());
114 }
115
116 public void removeEntity(EOEntity ent) {
117 _entitiesByName.removeObjectForKey(ent.name());
118 _entitiesByClass.removeObjectForKey(ent.className());
119 }
120
121 public void addStoredProcedure(EOStoredProcedure proc) {
122 if (!_storedProcedureNames.containsObject(proc))
123 _storedProcedureNames.addObject(proc);
124 _storedProcedures.setObjectForKey(proc, proc.name());
125 }
126
127 public void removeStoredProcedure(EOStoredProcedure proc) {
128 _storedProcedureNames.removeObject(proc.name());
129 _storedProcedures.removeObjectForKey(proc.name());
130 }
131
132 public EOStoredProcedure storedProcedureNamed(String name) {
133 EOStoredProcedure proc = (EOStoredProcedure)_storedProcedures.objectForKey(name);
134
135 if (proc == null && _path != null && _storedProcedureNames.containsObject(name)) {
136
137 File f = new File(new File(_path), name + ".storedProcedure");
138 if (!f.exists())
139 return null;
140 String sdict = null;
141 try {
142 FileInputStream fin = new FileInputStream(f);
143 byte[] b = new byte[fin.available()];
144 fin.read(b);
145 fin.close();
146 sdict = new String(b);
147 } catch (IOException ex) {
148 return null;
149 }
150 NSDictionary plist = NSPropertyListSerialization.dictionaryForString(sdict);
151 if (plist == null)
152 throw new IllegalArgumentException("File " + f + " does not contain a valid stored procedure property list.");
153 proc = new EOStoredProcedure(plist, this);
154
155 _storedProcedures.setObjectForKey(proc, proc.name());
156 }
157 return proc;
158 }
159
160 public NSArray storedProcedures() {
161 if (_storedProcedures.count() < _storedProcedureNames.count()) {
162 for (int i=0; i<_storedProcedureNames.count(); i++)
163 storedProcedureNamed((String)_storedProcedureNames.objectAtIndex(i));
164 }
165 return _storedProcedures.allValues();
166 }
167
168 public NSArray storedProcedureNames() {
169 return _storedProcedures.allKeys();
170 }
171
172 public void setAdaptorName(String value) {
173 _adaptorName = value;
174 }
175 public String adaptorName() {
176 return _adaptorName;
177 }
178
179 public NSArray entities() {
180 if (_entitiesByName.count() >= _entities.count())
181 return _entitiesByName.allValues();
182 NSMutableArray es = new NSMutableArray();
183 for (int i = 0; i < _entities.count(); i++) {
184 NSDictionary d = (NSDictionary)_entities.objectAtIndex(i);
185 es.addObject(entityNamed((String)d.objectForKey("name")));
186 }
187 return es;
188 }
189
190 public NSArray entityNames() {
191 if (_entitiesByName.count() >= _entities.count())
192 return _entitiesByName.allKeys();
193 NSMutableArray names = new NSMutableArray();
194 for (int i = 0; i < _entities.count(); i++) {
195 NSDictionary d = (NSDictionary)_entities.objectAtIndex(i);
196 names.addObject(d.objectForKey("name"));
197 }
198 return names;
199 }
200
201 public EOEntity entityNamed(String name) {
202 EOEntity e = (EOEntity)_entitiesByName.objectForKey(name);
203 if (e == null && path() != null) {
204 boolean exists = false;
205 for (int i = 0; i < _entities.count(); i++) {
206 NSDictionary d = (NSDictionary)_entities.objectAtIndex(i);
207 if (d.objectForKey("name").equals(name))
208 exists = true;
209 }
210 if (!exists)
211 return null;
212 File f = new File(new File(path()), name + ".plist");
213 if (!(f.exists() && f.isFile()))
214 throw new IllegalArgumentException("Cannot find " + name + ".plist");
215 String s = null;
216 try {
217 FileInputStream fin = new FileInputStream(f);
218 byte[] b = new byte[fin.available()];
219 fin.read(b);
220 fin.close();
221 s = new String(b);
222 } catch (IOException ex) {
223 throw new IllegalArgumentException("Cannot read " + f);
224 }
225 NSDictionary d = NSPropertyListSerialization.dictionaryForString(s);
226 if (d == null)
227 throw new IllegalArgumentException("Cannot parse dictionary for " + f);
228 e = new EOEntity(d, this);
229 _entitiesByName.setObjectForKey(e, e.name());
230 }
231 return e;
232 }
233
234 public String name() {
235 return _name;
236 }
237
238 public String path() {
239 return _path;
240 }
241
242 public void setModelGroup(EOModelGroup group) {
243 _group = group;
244 }
245 public EOModelGroup modelGroup() {
246 return _group;
247 }
248
249 public void setUserInfo(NSDictionary dict) {
250 _userInfo = dict;
251 }
252
253 public NSDictionary userInfo() {
254 return _userInfo;
255 }
256
257 public void write() {
258 }
259
260 public void writeToFile(String path) {
261 if (!path.endsWith(".eomodeld"))
262 path += ".eomodeld";
263 File f = new File(path);
264 if (f.exists()) {
265 if (f.isDirectory()) {
266 File[] kids = f.listFiles();
267 for (int i = 0; i < kids.length; i++) {
268 String fname = kids[i].getName();
269 if (kids[i].isFile() && (fname.endsWith(".plist") || fname.endsWith(".eomodeld") || fname.endsWith(".fspec") || fname.endsWith(".storedProcedure")))
270 kids[i].delete();
271 }
272 } else
273 f.delete();
274 } else
275 f.mkdirs();
276 File kid = new File(f, "index.eomodeld");
277
278
279 NSMutableDictionary d = new NSMutableDictionary();
280 d.setObjectForKey(_adaptorName, "adaptorName");
281 d.setObjectForKey("2.1", "EOModelVersion");
282 d.setObjectForKey(_connectionDictionary, "connectionDictionary");
283 if (_internalInfo != null && _internalInfo.count() > 0)
284 d.setObjectForKey(_internalInfo, "internalInfo");
285 if (_userInfo != null && _userInfo.count() > 0)
286 d.setObjectForKey(_userInfo, "userInfo");
287 if (_storedProcedureNames.count() > 0)
288 d.setObjectForKey(_storedProcedureNames, "storedProcedures");
289
290
291 entities();
292 storedProcedures();
293 NSMutableArray arr = new NSMutableArray(_entitiesByName.count());
294 Enumeration enumeration = _entitiesByName.keyEnumerator();
295 NSMutableDictionary md = new NSMutableDictionary();
296 while (enumeration.hasMoreElements()) {
297 String key = (String)enumeration.nextElement();
298 EOEntity ent = (EOEntity)_entitiesByName.objectForKey(key);
299 md.removeAllObjects();
300 ent.encodeIntoPropertyList(md);
301 File plist;
302 NSDictionary fetchSpecs = (NSDictionary)md.objectForKey("fetchSpecificationDictionary");
303 if (fetchSpecs != null) {
304 if (fetchSpecs.count() > 0) {
305 plist = new File(f, key + ".fspec");
306 String ps = NSPropertyListSerialization.stringForPropertyList(md.objectForKey("fetchSpecificationDictionary"));
307 try {
308 PrintStream stream = new PrintStream(new FileOutputStream(plist));
309 stream.println(ps);
310 stream.close();
311 } catch (IOException ex) {
312 }
313 }
314 md.removeObjectForKey("fetchSpecificationDictionary");
315 }
316 plist = new File(f, key + ".plist");
317 String ps = NSPropertyListSerialization.stringForPropertyList(md);
318 try {
319 PrintStream stream = new PrintStream(new FileOutputStream(plist));
320 stream.println(ps);
321 stream.close();
322 } catch (IOException ex) {
323 }
324
325 arr.addObject(new NSDictionary(
326 new Object[]{ ent.name(), ent.className() },
327 new Object[]{ "name", "className" }));
328 }
329 d.setObjectForKey(arr, "entities");
330
331
332 String s = NSPropertyListSerialization.stringForPropertyList(d);
333 try {
334 PrintStream stream = new PrintStream(new FileOutputStream(kid));
335 stream.println(s);
336 stream.close();
337 } catch (IOException ex) {
338 throw new RuntimeException("Cannot write index.eomodeld");
339 }
340
341
342 for (int i = 0; i < _storedProcedureNames.count(); i++) {
343 EOStoredProcedure proc = (EOStoredProcedure)_storedProcedures.objectForKey(_storedProcedureNames.objectAtIndex(i));
344 kid = new File(f, proc.name() + ".storedProcedure");
345 d.removeAllObjects();
346 proc.encodeIntoPropertyList(d);
347 s = NSPropertyListSerialization.stringForPropertyList(d);
348 try {
349 PrintStream stream = new PrintStream(new FileOutputStream(kid));
350 stream.println(s);
351 stream.close();
352 } catch (IOException ex) {
353 throw new RuntimeException("Cannot write " + f);
354 }
355 }
356 _path = f.getAbsolutePath();
357 }
358
359 }
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396