/* Wotonomy: OpenStep design patterns for pure Java applications. Copyright (C) 2001 Michael Powers This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see http://www.gnu.org */ package net.wotonomy.access; import java.util.Enumeration; import net.wotonomy.control.EOEnterpriseObject; import net.wotonomy.control.EOGlobalID; import net.wotonomy.foundation.NSArray; import net.wotonomy.foundation.NSDictionary; import net.wotonomy.foundation.NSMutableArray; import net.wotonomy.foundation.NSMutableDictionary; import net.wotonomy.foundation.NSTimestamp; /** * * @author ezamudio@nasoft.com * @author $Author: cgruber $ * @version $Revision: 894 $ */ public class EODatabase { protected EOAdaptor _adaptor; protected NSMutableArray _models = new NSMutableArray(); protected NSMutableArray _contexts = new NSMutableArray(); protected NSMutableDictionary _resultCache = new NSMutableDictionary(); protected NSMutableDictionary _snapshots = new NSMutableDictionary(); protected NSTimestamp _timestamp; protected static boolean _releaseUnrefSnapshots = true; public EODatabase(EOAdaptor adaptor) { super(); if (adaptor == null) throw new IllegalArgumentException("Adaptor cannot be null."); _adaptor = adaptor; } public EODatabase(EOModel model) { super(); _adaptor = EOAdaptor.adaptorWithModel(model); addModel(model); } public EOAdaptor adaptor() { return _adaptor; } public void addModel(EOModel model) { if (!addModelIfCompatible(model)) throw new IllegalArgumentException("Model is not compatible with this database."); } public void removeMode(EOModel model) { _models.removeObject(model); } public boolean addModelIfCompatible(EOModel model) { if (_models.containsObject(model)) return false; if (model.adaptorName().equals(adaptor().name())) { if (adaptor().canServiceModel(model)) { _models.addObject(model); return true; } } return false; } public void decrementSnapshotCountForGlobalID(EOGlobalID gid) { if (_releaseUnrefSnapshots) { } } public void incrementSnapshotCountForGlobalID(EOGlobalID gid) { if (_releaseUnrefSnapshots) { } } public static void disableSnapshotRefCounting() { _releaseUnrefSnapshots = false; } public EOEntity entityForObject(EOEnterpriseObject eo) { String cname = eo.getClass().getName(); for (int i = 0; i < _models.count(); i++) { EOModel m = (EOModel) _models.objectAtIndex(i); NSArray ents = m.entities(); for (int j = 0; j < ents.count(); j++) { EOEntity e = (EOEntity) ents.objectAtIndex(i); if (e.className().equals(cname)) return e; } } return null; } public EOEntity entityNamed(String name) { for (int i = 0; i < _models.count(); i++) { EOModel m = (EOModel) _models.objectAtIndex(i); NSArray ents = m.entities(); for (int j = 0; j < ents.count(); j++) { EOEntity e = (EOEntity) ents.objectAtIndex(i); if (e.name().equals(name)) return e; } } return null; } public void forgetAllSnapshots() { _snapshots.removeAllObjects(); } public void forgetSnapshotForGlobalID(EOGlobalID gid) { _snapshots.removeObjectForKey(gid); } public void forgetSnapshotsForGlobalIDs(NSArray gids) { for (int i = 0; i < gids.count(); i++) forgetSnapshotForGlobalID((EOGlobalID) gids.objectAtIndex(i)); } public void handleDroppedConnection() { adaptor().handleDroppedConnection(); for (int i = 0; i < _contexts.count(); i++) { EODatabaseContext c = (EODatabaseContext) _contexts.objectAtIndex(i); c.handleDroppedConnection(); } } public void invalidateResultCache() { _resultCache.removeAllObjects(); } public void invalidateResultCacheForEntityNamed(String name) { _resultCache.removeObjectForKey(name); } public NSArray models() { return new NSArray(_models); } public void recordSnapshotForGlobalID(NSDictionary snap, EOGlobalID gid) { _snapshots.setObjectForKey(snap, gid); } public void recordSnapshotForSourceGlobalID(NSArray gids, EOGlobalID gid, String name) { NSMutableDictionary d = (NSMutableDictionary) _snapshots.objectForKey(gid); if (d == null) { d = new NSMutableDictionary(); _snapshots.setObjectForKey(d, gid); } d.setObjectForKey(gids, name); } public void recordSnapshots(NSDictionary snaps) { _snapshots.addEntriesFromDictionary(snaps); } public void recordToManySnapshots(NSDictionary snaps) { Enumeration enumeration = snaps.keyEnumerator(); while (enumeration.hasMoreElements()) { EOGlobalID gid = (EOGlobalID) enumeration.nextElement(); NSDictionary rels = (NSDictionary) snaps.objectForKey(gid); Enumeration relEnum = rels.keyEnumerator(); while (relEnum.hasMoreElements()) { String relName = (String) relEnum.nextElement(); NSArray gids = (NSArray) rels.objectForKey(relName); recordSnapshotForSourceGlobalID(gids, gid, relName); } } } public void registerContext(EODatabaseContext context) { if (!_contexts.contains(context)) { if (context.database() != this) throw new IllegalStateException("Cannot register context assigned to a different database."); _contexts.addObject(context); } } public void unregisterContext(EODatabaseContext context) { _contexts.removeObject(context); } public NSArray registeredContexts() { return new NSArray(_contexts); } public NSArray resultCacheForEntityNamed(String name) { return (NSArray) _resultCache.objectForKey(name); } public void setResultCache(NSArray cache, String entityName) { _resultCache.setObjectForKey(cache, entityName); } public void setTimestampToNow() { _timestamp = new NSTimestamp(); } public NSDictionary snapshotForGlobalID(EOGlobalID gid) { return (NSDictionary) _snapshots.objectForKey(gid); } public NSDictionary snapshotForGlobalID(EOGlobalID gid, long l) { return null; } public NSArray snapshotForSourceGlobalID(EOGlobalID gid, String name) { NSDictionary d = (NSDictionary) _snapshots.objectForKey(gid); if (d == null) return null; return (NSArray) d.objectForKey(name); } public NSDictionary snapshotForSourceGlobalID(EOGlobalID gid, String s, long l) { return null; } public NSDictionary snapshots() { return _snapshots; } public long timestampForGlobalID(EOGlobalID gid) { return NSTimestamp.DistantPast.timeIntervalSinceReferenceDate(); } public long timestampForSourceGlobalID(EOGlobalID gid, String s) { return 0; } } /* * $Log$ Revision 1.2 2006/02/16 16:47:13 cgruber Move some classes in to * "internal" packages and re-work imports, etc. * * Also use UnsupportedOperationExceptions where appropriate, instead of * WotonomyExceptions. * * Revision 1.1 2006/02/16 13:19:57 cgruber Check in all sources in * eclipse-friendly maven-enabled packages. * * Revision 1.2 2005/05/11 15:21:53 cgruber Change enum to enumeration, since * enum is now a keyword as of Java 5.0 * * A few other comments in the code. * * Revision 1.1 2003/08/19 01:54:43 chochos The EODatabase layer still needs a * lot of work, but it's on its way... * */