View Javadoc

1   /*
2    Wotonomy: OpenStep design patterns for pure Java applications.
3    Copyright (C) 2001 Michael Powers
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  package net.wotonomy.access;
19  
20  import java.util.Enumeration;
21  import java.util.List;
22  import java.util.Map;
23  
24  import net.wotonomy.control.EOAndQualifier;
25  import net.wotonomy.control.EOCooperatingObjectStore;
26  import net.wotonomy.control.EOEditingContext;
27  import net.wotonomy.control.EOEnterpriseObject;
28  import net.wotonomy.control.EOFaultHandler;
29  import net.wotonomy.control.EOFaulting;
30  import net.wotonomy.control.EOFetchSpecification;
31  import net.wotonomy.control.EOGlobalID;
32  import net.wotonomy.control.EOKeyGlobalID;
33  import net.wotonomy.control.EOKeyValueCoding;
34  import net.wotonomy.control.EOKeyValueCodingSupport;
35  import net.wotonomy.control.EOKeyValueQualifier;
36  import net.wotonomy.control.EOObjectStoreCoordinator;
37  import net.wotonomy.control.EOQualifier;
38  import net.wotonomy.foundation.NSArray;
39  import net.wotonomy.foundation.NSDictionary;
40  import net.wotonomy.foundation.NSLocking;
41  import net.wotonomy.foundation.NSMutableArray;
42  import net.wotonomy.foundation.NSMutableDictionary;
43  
44  /***
45  *
46  * @author ezamudio@nasoft.com
47  * @author $Author: cgruber $
48  * @version $Revision: 894 $
49  */
50  public class EODatabaseContext
51  	extends EOCooperatingObjectStore implements NSLocking {
52  
53  	private static Class _contextClass;
54  	protected EODatabase _database;
55  	protected EOAdaptorContext _context;
56  	protected NSMutableArray _channels = new NSMutableArray();
57  	protected NSMutableArray _lockedObjects = new NSMutableArray();
58  
59  	protected NSMutableDictionary _simpleSnaps;
60  	protected NSMutableDictionary _manySnaps;
61  
62  	protected EOObjectStoreCoordinator _coordinator;
63  	protected EOEditingContext _currEC;
64  	protected int _updateStrategy;
65  
66  	public EODatabaseContext(EODatabase database) {
67  		super();
68  		_database = database;
69  		_context = _database.adaptor().createAdaptorContext();
70  	}
71  
72  	public EOAdaptorContext adaptorContext() {
73  		return _context;
74  	}
75  
76  	public EODatabase database() {
77  		return _database;
78  	}
79  
80  	public EODatabaseChannel availableChannel() {
81  		for (int i = 0; i < _channels.count(); i++) {
82  			EODatabaseChannel c = (EODatabaseChannel)_channels.objectAtIndex(i);
83  			if (!c.isFetchInProgress())
84  				return c;
85  		}
86  		EODatabaseChannel c = new EODatabaseChannel(this);
87  		registerChannel(c);
88  		return c;
89  	}
90  
91  	public void batchFetchRelationship(EORelationship rel, NSArray arr, EOEditingContext ec) {
92  	}
93  
94  	public static void setContextClassToRegister(Class contextClass) {
95  		_contextClass = contextClass;
96  	}
97  	public static Class contextClassToRegister() {
98  		if (_contextClass == null)
99  			_contextClass = EODatabaseContext.class;
100 		return _contextClass;
101 	}
102 
103 	public EOObjectStoreCoordinator coordinator() {
104 		return _coordinator;
105 	}
106 
107 	public void editingContextDidForgetObjectWithGlobalID(EOEditingContext ec, EOGlobalID gid) {
108 		database().decrementSnapshotCountForGlobalID(gid);
109 	}
110 
111 	public void handleDroppedConnection() {
112 		//TODO: unregister channels
113 		adaptorContext().handleDroppedConnection();
114 	}
115 
116 	/* (non-Javadoc)
117 	 * @see net.wotonomy.control.EOCooperatingObjectStore#ownsGlobalID(net.wotonomy.control.EOGlobalID)
118 	 */
119 	public boolean ownsGlobalID(EOGlobalID gid) {
120 		if (!(gid instanceof EOKeyGlobalID))
121 			return false;
122 		return (database().entityNamed(((EOKeyGlobalID)gid).entityName()) != null);
123 	}
124 
125 	/* (non-Javadoc)
126 	 * @see net.wotonomy.control.EOCooperatingObjectStore#ownsObject(net.wotonomy.control.EOEnterpriseObject)
127 	 */
128 	public boolean ownsObject(EOEnterpriseObject eo) {
129 		if (eo.entityName() == null)
130 			return false;
131 		return (database().entityNamed(eo.entityName()) != null);
132 	}
133 
134 	/* (non-Javadoc)
135 	 * @see net.wotonomy.control.EOCooperatingObjectStore#handlesFetchSpecification(net.wotonomy.control.EOFetchSpecification)
136 	 */
137 	public boolean handlesFetchSpecification(EOFetchSpecification fspec) {
138 		String ename = fspec.entityName();
139 		return (database().entityNamed(ename) != null);
140 	}
141 
142 	public boolean hasBusyChannels() {
143 		return adaptorContext().hasBusyChannels();
144 	}
145 
146 	/* (non-Javadoc)
147 	 * @see net.wotonomy.control.EOCooperatingObjectStore#prepareForSaveWithCoordinator(net.wotonomy.control.EOObjectStoreCoordinator, net.wotonomy.control.EOEditingContext)
148 	 */
149 	public void prepareForSaveWithCoordinator(EOObjectStoreCoordinator coord, EOEditingContext ec) {
150 		// TODO Auto-generated method stub
151 		_coordinator = coord;
152 		_currEC = ec;
153 	}
154 
155 	/* (non-Javadoc)
156 	 * @see net.wotonomy.control.EOCooperatingObjectStore#recordChangesInEditingContext()
157 	 */
158 	public void recordChangesInEditingContext() {
159 		// TODO insert, delete, update
160 	}
161 
162 	/* (non-Javadoc)
163 	 * @see net.wotonomy.control.EOCooperatingObjectStore#recordUpdateForObject(net.wotonomy.control.EOEnterpriseObject, net.wotonomy.foundation.NSDictionary)
164 	 */
165 	public void recordUpdateForObject(EOEnterpriseObject eo, NSDictionary changes) {
166 		// TODO Auto-generated method stub
167 	}
168 
169 	public void recordSnapshotForGlobalID(NSDictionary snap, EOGlobalID gid) {
170 		if (_simpleSnaps == null)
171 			throw new IllegalArgumentException("Attempt to record a snapshot without a transaction in progress");
172 		_simpleSnaps.setObjectForKey(snap, gid);
173 	}
174 
175 	public void recordSnapshotForSourceGlobalID(NSArray gids, EOGlobalID gid, String relationName) {
176 		if (_manySnaps == null)
177 			throw new IllegalArgumentException("Attempt to record a snapshot without a transaction in progress");
178 		NSMutableDictionary d = (NSMutableDictionary)_manySnaps.objectForKey(gid);
179 		if (d == null) {
180 			d = new NSMutableDictionary();
181 			_manySnaps.setObjectForKey(d, gid);
182 		}
183 		d.setObjectForKey(gids, relationName);
184 	}
185 
186 	public void recordSnapshots(NSDictionary snaps) {
187 		if (_simpleSnaps == null)
188 			throw new IllegalArgumentException("Attempt to record snapshots without a transaction in progress.");
189 		_simpleSnaps.addEntriesFromDictionary(snaps);
190 		/* Make sure we don't need to do this instead
191 		Enumeration enumeration = snaps.keyEnumerator();
192 		while (enumeration.hasMoreElements()) {
193 			EOGlobalID g = (EOGlobalID)enumeration.nextElement();
194 			NSDictionary d = (NSDictionary)snaps.objectForKey(g);
195 			recordSnapshotForGlobalID(d, g);
196 		}*/
197 	}
198 
199 	public void recordToManySnapshots(NSDictionary snaps) {
200 		if (_manySnaps == null)
201 			throw new IllegalArgumentException("Attempt to record snapshots without a transaction in progress.");
202 		Enumeration enumeration = snaps.keyEnumerator();
203 		while (enumeration.hasMoreElements()) {
204 			Object key = enumeration.nextElement();
205 			NSDictionary d = (NSDictionary)snaps.objectForKey(key);
206 			NSMutableDictionary d2 = (NSMutableDictionary)_manySnaps.objectForKey(key);
207 			if (d2 == null) {
208 				d2 = new NSMutableDictionary();
209 				_manySnaps.setObjectForKey(d2, key);
210 			}
211 			//this could also be done with many calls to recordSnapshotForSourceGID
212 			d2.addEntriesFromDictionary(d);
213 		}
214 	}
215 
216 	/* (non-Javadoc)
217 	 * @see net.wotonomy.control.EOCooperatingObjectStore#performChanges()
218 	 */
219 	public void performChanges() {
220 		// TODO Auto-generated method stub
221 
222 	}
223 
224 	/* (non-Javadoc)
225 	 * @see net.wotonomy.control.EOCooperatingObjectStore#commitChanges()
226 	 */
227 	public void commitChanges() {
228 		adaptorContext().commitTransaction();
229 	}
230 
231 	/* (non-Javadoc)
232 	 * @see net.wotonomy.control.EOCooperatingObjectStore#rollbackChanges()
233 	 */
234 	public void rollbackChanges() {
235 		adaptorContext().rollbackTransaction();
236 	}
237 
238 	/* (non-Javadoc)
239 	 * @see net.wotonomy.control.EOCooperatingObjectStore#valuesForKeys(net.wotonomy.foundation.NSArray, net.wotonomy.control.EOEnterpriseObject)
240 	 */
241 	public NSDictionary valuesForKeys(NSArray keys, EOEnterpriseObject eo) {
242 		// TODO check snapshots; eo could be a fault
243 		return eo.valuesForKeys(keys);
244 	}
245 
246 	/* (non-Javadoc)
247 	 * @see net.wotonomy.foundation.NSLocking#lock()
248 	 */
249 	public void lock() {
250 		EOAccessLock.lock();
251 	}
252 
253 	/* (non-Javadoc)
254 	 * @see net.wotonomy.foundation.NSLocking#unlock()
255 	 */
256 	public void unlock() {
257 		EOAccessLock.unlock();
258 	}
259 
260 	/* (non-Javadoc)
261 	 * @see net.wotonomy.control.EOObjectStore#arrayFaultWithSourceGlobalID(net.wotonomy.control.EOGlobalID, java.lang.String, net.wotonomy.control.EOEditingContext)
262 	 */
263 	public NSArray arrayFaultWithSourceGlobalID(
264 			EOGlobalID gid, String relName, EOEditingContext ec) {
265 		if (!(gid instanceof EOKeyGlobalID))
266 			throw new IllegalArgumentException("an EOKeyGlobalID is needed.");
267 		EOAccessArrayFaultHandler handler = new EOAccessArrayFaultHandler((EOKeyGlobalID)gid, relName, this, ec);
268 		return new NSArray(handler);
269 	}
270 
271 	/* (non-Javadoc)
272 	 * @see net.wotonomy.control.EOObjectStore#faultForGlobalID(net.wotonomy.control.EOGlobalID, net.wotonomy.control.EOEditingContext)
273 	 */
274 	public /*EOEnterpriseObject*/Object faultForGlobalID(EOGlobalID gid, EOEditingContext ec) {
275 		if (!(gid instanceof EOKeyGlobalID))
276 			throw new IllegalArgumentException("Cannot fault an object that doesn't have a key global ID.");
277 		EOAccessFaultHandler handler = new EOAccessFaultHandler((EOKeyGlobalID)gid, this, ec);
278 		EOEntity e = database().entityNamed(((EOKeyGlobalID)gid).entityName());
279 		Object o = e.classDescriptionForInstances().createInstanceWithEditingContext(ec, gid);
280 		EOFaultHandler.makeObjectIntoFault(o, handler);
281 		return o;
282 	}
283 
284 	/* (non-Javadoc)
285 	 * @see net.wotonomy.control.EOObjectStore#faultForRawRow(java.util.Map, java.lang.String, net.wotonomy.control.EOEditingContext)
286 	 */
287 	public /*EOEnterpriseObject*/ Object faultForRawRow(Map row, String entityName, EOEditingContext ec) {
288 		EOEntity e = database().entityNamed(entityName);
289 		EOGlobalID gid = e.globalIDForRow(row);
290 		return faultForGlobalID(gid, ec);
291 	}
292 
293 	public void forgetSnapshotForGlobalID(EOGlobalID gid) {
294 		if (_simpleSnaps == null)
295 			throw new IllegalArgumentException("Attempt to forget snapshot with no transaction in progress.");
296 		_simpleSnaps.removeObjectForKey(gid);
297 		_manySnaps.removeObjectForKey(gid);
298 	}
299 
300 	public void forgetSnapshotsForGlobalIDs(List gids) {
301 		for (int i = 0; i < gids.size(); i++) {
302 			EOGlobalID g = (EOGlobalID)gids.get(i);
303 			forgetSnapshotForGlobalID(g);
304 			database().forgetSnapshotForGlobalID(g);
305 		}
306 	}
307 
308 	/* (non-Javadoc)
309 	 * @see net.wotonomy.control.EOObjectStore#initializeObject(java.lang.Object, net.wotonomy.control.EOGlobalID, net.wotonomy.control.EOEditingContext)
310 	 */
311 	public void initializeObject(/*EOEnterpriseObject*/Object eo, EOGlobalID gid, EOEditingContext ec) {
312 		if (gid.isTemporary())
313 			return;
314 		NSDictionary snap = snapshotForGlobalID(gid);
315 		Object obj = ec.objectForGlobalID(gid);
316 		EOEntity e = database().entityNamed(((EOKeyGlobalID)gid).entityName());
317 		NSArray props = e.classProperties();
318 		for (int i = 0; i < props.count(); i++) {
319 			EOProperty p = (EOProperty)props.objectAtIndex(i);
320 			Object val = snap.objectForKey(p.name());
321 			if (p instanceof EOAttribute) {
322                 if ( eo instanceof EOKeyValueCoding )
323                 {
324                     ((EOKeyValueCoding)eo).takeValueForKey(val, p.name());
325                 } 
326                 else
327                 {
328                     EOKeyValueCodingSupport.takeValueForKey( eo, val, p.name() );   
329                 }
330 			} else if (p instanceof EORelationship) {
331 				if (((EORelationship)p).isToMany()) {
332 					val = arrayFaultWithSourceGlobalID(gid, p.name(), ec);
333 				} else {
334 					EOEntity dest = ((EORelationship)p).destinationEntity();
335 					EOKeyGlobalID kgid = (EOKeyGlobalID)dest.globalIDForRow(snap);
336 					val = ec.objectForGlobalID(kgid);
337 					if (val == null)
338 						val = new EOAccessFaultHandler(kgid, this, ec);
339 				}
340 				if (val == EOKeyValueCoding.NullValue)
341 					val = null;
342                 if ( eo instanceof EOKeyValueCoding )
343                 {
344                     ((EOKeyValueCoding)eo).takeValueForKey(val, p.name());
345                 } 
346                 else
347                 {
348                     EOKeyValueCodingSupport.takeValueForKey( eo, val, p.name() );   
349                 }
350 			}
351 		}
352 	}
353 
354 	/* (non-Javadoc)
355 	 * @see net.wotonomy.control.EOObjectStore#invalidateAllObjects()
356 	 */
357 	public void invalidateAllObjects() {
358 		invalidateObjectsWithGlobalIDs(database().snapshots().allKeys());
359 	}
360 
361 	/* (non-Javadoc)
362 	 * @see net.wotonomy.control.EOObjectStore#invalidateObjectsWithGlobalIDs(java.util.List)
363 	 */
364 	public void invalidateObjectsWithGlobalIDs(List aList) {
365 		forgetSnapshotsForGlobalIDs(aList);
366 	}
367 
368 	/* (non-Javadoc)
369 	 * @see net.wotonomy.control.EOObjectStore#isObjectLockedWithGlobalID(net.wotonomy.control.EOGlobalID, net.wotonomy.control.EOEditingContext)
370 	 */
371 	public boolean isObjectLockedWithGlobalID(EOGlobalID gid, EOEditingContext ec) {
372 		return isObjectLockedWithGlobalID(gid);
373 	}
374 
375 	public boolean isObjectLockedWithGlobalID(EOGlobalID gid) {
376 		return _lockedObjects.containsObject(gid);
377 	}
378 
379 	/* (non-Javadoc)
380 	 * @see net.wotonomy.control.EOObjectStore#lockObjectWithGlobalID(net.wotonomy.control.EOGlobalID, net.wotonomy.control.EOEditingContext)
381 	 */
382 	public void lockObjectWithGlobalID(EOGlobalID gid, EOEditingContext ec) {
383 		NSDictionary snap = snapshotForGlobalID(gid);
384 		if (snap == null)
385 			return;
386 		if (!(gid instanceof EOKeyGlobalID))
387 			return;
388 		EOEntity e = database().entityNamed(((EOKeyGlobalID)gid).entityName());
389 		EOQualifier q = e.qualifierForPrimaryKey(snap);
390 		EOFetchSpecification fspec = new EOFetchSpecification(e.name(), q, null);
391 		fspec.setLocksObjects(true);
392 		NSArray arr = ec.objectsWithFetchSpecification(fspec);
393 		if (arr.count() != 1)
394 			throw new IllegalStateException("Cannot lock object with Global ID " + gid);
395 	}
396 
397 	/* (non-Javadoc)
398 	 * @see net.wotonomy.control.EOObjectStore#objectsForSourceGlobalID(net.wotonomy.control.EOGlobalID, java.lang.String, net.wotonomy.control.EOEditingContext)
399 	 */
400 	public NSArray objectsForSourceGlobalID(
401 			EOGlobalID gid, String relationName, EOEditingContext ec) {
402 		EOEnterpriseObject eo = (EOEnterpriseObject)ec.objectForGlobalID(gid);
403 		if (eo == null)
404 			throw new IllegalStateException("Cannot find object for global ID " + gid + " in specified editing context.");
405 		//Get the source object
406 		EOEnterpriseObject source = (EOEnterpriseObject) faultForGlobalID(gid, ec);
407 		if (source == null)
408 			throw new IllegalStateException("There is no snapshot for source global ID " + gid);
409 
410 		//Check if there is already a value here
411 		NSArray value = (NSArray)source.valueForKey(relationName);
412 		EOAccessArrayFaultHandler handler = null;
413 		if (value != null) {
414 			if (EOFaultHandler.isFault(value)) {
415 				handler = new EOAccessArrayFaultHandler((EOKeyGlobalID)gid, relationName, this, ec);
416 				//TODO: fire the fault an return the value
417 			} else
418 				return value;
419 		}
420 
421 		//Get the relationship
422 		EOEntity entity = database().entityNamed(eo.entityName());
423 		EORelationship rel = entity.relationshipNamed(relationName);
424 		if (rel == null)
425 			throw new IllegalStateException("Cannot find relationship named " + relationName + " in entity " + entity.name());
426 
427 		//create a fetch specification for this
428 		EOQualifier q = null;
429 		NSArray joins = rel.joins();
430 		NSMutableArray subq = new NSMutableArray(joins.count());
431 		for (int i = 0; i < joins.count(); i++) {
432 			EOJoin j = (EOJoin)joins.objectAtIndex(i);
433 			String key = j.destinationAttribute().name();
434 			Object val = eo.valueForKey(j.sourceAttribute().name());
435 			subq.addObject(new EOKeyValueQualifier(key, EOQualifier.QualifierOperatorEqual, val));
436 		}
437 		if (subq.count() == 1) {
438 			q = (EOQualifier)subq.objectAtIndex(0);
439 		} else {
440 			q = new EOAndQualifier(subq);
441 		}
442 		EOFetchSpecification fspec = new EOFetchSpecification(rel.destinationEntity().name(), q, null);
443 		NSArray res = ec.objectsWithFetchSpecification(fspec, ec);
444 		NSMutableArray gids = new NSMutableArray(res.count());
445 		for (int i = 0; i < res.count(); i++)
446 			gids.addObject(ec.globalIDForObject(res.objectAtIndex(i)));
447 		recordSnapshotForSourceGlobalID(gids, gid, relationName);
448 		return res;
449 	}
450 
451 	/* (non-Javadoc)
452 	 * @see net.wotonomy.control.EOObjectStore#objectsWithFetchSpecification(net.wotonomy.control.EOFetchSpecification, net.wotonomy.control.EOEditingContext)
453 	 */
454 	public NSArray objectsWithFetchSpecification(EOFetchSpecification fspec, EOEditingContext ec) {
455 		EODatabaseChannel channel = availableChannel();
456 		channel.selectObjectsWithFetchSpecification(fspec, ec);
457 		NSMutableArray arr = new NSMutableArray();
458 		while (channel.isFetchInProgress()) {
459 			Object o = channel.fetchObject();
460 			if (o != null) {
461 				arr.addObject(o);
462 			}
463 		}
464 		return arr;
465 	}
466 
467 	/* (non-Javadoc)
468 	 * @see net.wotonomy.control.EOObjectStore#refaultObject(java.lang.Object, net.wotonomy.control.EOGlobalID, net.wotonomy.control.EOEditingContext)
469 	 */
470 	public void refaultObject(Object obj, EOGlobalID gid, EOEditingContext ec) {
471 		if (!(gid instanceof EOKeyGlobalID))
472 			throw new IllegalArgumentException("GlobalID must be an EOKeyGlobalID");
473 		if (obj instanceof EOFaulting)
474 		//check if it's already a fault
475 		if (!EOFaultHandler.isFault(obj)) {
476 			((EOFaulting)obj).turnIntoFault(EOFaultHandler.handlerForFault(obj));
477 		}
478 	}
479 
480 	/* (non-Javadoc)
481 	 * @see net.wotonomy.control.EOObjectStore#saveChangesInEditingContext(net.wotonomy.control.EOEditingContext)
482 	 */
483 	public void saveChangesInEditingContext(EOEditingContext ec) {
484 		prepareForSaveWithCoordinator(null, ec);
485 		recordChangesInEditingContext();
486 		performChanges();
487 		commitChanges();
488 	}
489 
490 	public void registerChannel(EODatabaseChannel channel) {
491 		if (channel.databaseContext() != this)
492 			throw new IllegalArgumentException("Cannot register a channel on a context other than its own.");
493 		if (_channels.containsObject(channel))
494 			throw new IllegalArgumentException("Attempt to register a channel more than once.");
495 		_channels.addObject(channel);
496 	}
497 
498 	public void unregisterChannel(EODatabaseChannel channel) {
499 		if (channel.databaseContext() != this)
500 			throw new IllegalArgumentException("Attempt to unregister a channel from a context other than its own.");
501 		_channels.removeObject(channel);
502 	}
503 
504 	public NSArray registeredChannels() {
505 		return new NSArray(_channels);
506 	}
507 
508 	public NSDictionary snapshotForGlobalID(EOGlobalID gid) {
509 		NSDictionary d = null;
510 		if (_simpleSnaps != null) {
511 			d = (NSDictionary)_simpleSnaps.objectForKey(gid);
512 		}
513 		if (d == null)
514 			d = database().snapshotForGlobalID(gid);
515 		return d;
516 	}
517 
518 	public NSArray snapshotForSourceGlobalID(EOGlobalID gid, String name) {
519 		NSArray a = null;
520 		if (_manySnaps != null) {
521 			NSDictionary d = (NSDictionary)_manySnaps.objectForKey(gid);
522 			a = (NSArray)d.objectForKey(name);
523 		}
524 		if (a == null)
525 			a = database().snapshotForSourceGlobalID(gid, name);
526 		return a;
527 	}
528 
529 	public void setUpdateStrategy(int strategy) {
530 		_updateStrategy = strategy;
531 	}
532 
533 	public int updateStrategy() {
534 		return _updateStrategy;
535 	}
536 
537 }
538 /*
539  * $Log$
540  * Revision 1.2  2006/02/16 16:47:13  cgruber
541  * Move some classes in to "internal" packages and re-work imports, etc.
542  *
543  * Also use UnsupportedOperationExceptions where appropriate, instead of WotonomyExceptions.
544  *
545  * Revision 1.1  2006/02/16 13:19:57  cgruber
546  * Check in all sources in eclipse-friendly maven-enabled packages.
547  *
548  * Revision 1.5  2005/05/11 15:21:53  cgruber
549  * Change enum to enumeration, since enum is now a keyword as of Java 5.0
550  *
551  * A few other comments in the code.
552  *
553  * Revision 1.4  2003/12/18 15:37:38  mpowers
554  * Changes to retain ability to work with objects that don't necessarily
555  * implement EOEnterpriseObject.  I would still like to preserve this case
556  * for general usage, however the access package is free to assume that
557  * those objects will be EOs and cast appropriately.
558  *
559  * Revision 1.3  2003/08/29 21:14:44  chochos
560  * implement a couple more methods.
561  *
562  * Revision 1.2  2003/08/20 01:16:22  chochos
563  * more methods have code now, but there's no way to test this yet. The core is still pending.
564  *
565  * Revision 1.1  2003/08/19 01:54:43  chochos
566  * The EODatabase layer still needs a lot of work, but it's on its way...
567  *
568  */