summaryrefslogtreecommitdiff
path: root/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/access/EOModel.java
diff options
context:
space:
mode:
Diffstat (limited to 'projects/net.wotonomy.persistence/src/main/java/net/wotonomy/access/EOModel.java')
-rw-r--r--projects/net.wotonomy.persistence/src/main/java/net/wotonomy/access/EOModel.java396
1 files changed, 396 insertions, 0 deletions
diff --git a/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/access/EOModel.java b/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/access/EOModel.java
new file mode 100644
index 0000000..46fc8d0
--- /dev/null
+++ b/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/access/EOModel.java
@@ -0,0 +1,396 @@
+/*
+ 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.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Enumeration;
+
+import net.wotonomy.foundation.NSArray;
+import net.wotonomy.foundation.NSDictionary;
+import net.wotonomy.foundation.NSMutableArray;
+import net.wotonomy.foundation.NSMutableDictionary;
+import net.wotonomy.foundation.NSPropertyListSerialization;
+
+/**
+* An EOModel is a set of entities and stored procedures, along with a connection
+* dictionary to connect to a database.
+*
+* @author ezamudio@nasoft.com
+* @author $Author: cgruber $
+* @version $Revision: 894 $
+*/
+public class EOModel {
+
+ protected static final String IDX_NAME = "index.eomodeld";
+
+ //This array contains dictionaries with "className" and "name"
+ protected NSMutableArray _entities = new NSMutableArray();
+ protected NSMutableDictionary _entitiesByName = new NSMutableDictionary();
+ protected NSMutableDictionary _entitiesByClass = new NSMutableDictionary();
+ protected NSDictionary _connectionDictionary = NSDictionary.EmptyDictionary;
+ protected String _adaptorName = "JDBC";
+ protected NSMutableDictionary _prototypesByName = new NSMutableDictionary();
+ protected NSMutableDictionary _storedProcedures = new NSMutableDictionary();
+ protected NSMutableArray _storedProcedureNames = new NSMutableArray();
+ protected NSDictionary _userInfo = NSDictionary.EmptyDictionary;
+ protected String _name;
+ protected String _path;
+ protected NSDictionary _internalInfo = NSDictionary.EmptyDictionary;
+ protected EOModelGroup _group;
+
+ public EOModel() {
+ super();
+ }
+
+ public EOModel(NSDictionary dict, Object o) {
+ this();
+ }
+
+ public EOModel(String path) {
+ this();
+ File f = new File(path);
+ _path = f.getAbsolutePath();
+ if (!(f.exists() && f.isDirectory()))
+ throw new IllegalArgumentException("The path is invalid (" + f + ")");
+ _name = f.getName();
+ f = new File(f, "index.eomodeld");
+ if (!(f.exists() && f.isFile()))
+ throw new IllegalArgumentException("Cannot find " + f);
+ String x = null;
+ try {
+ FileInputStream in = new FileInputStream(f);
+ byte[] b = new byte[in.available()];
+ in.read(b);
+ in.close();
+ x = new String(b);
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Cannot read index.eomodeld");
+ }
+ NSDictionary d = NSPropertyListSerialization.dictionaryForString(x);
+ String version = (String)d.objectForKey("EOModelVersion");
+ if (version == null || !version.startsWith("2."))
+ throw new IllegalArgumentException("Invalid eomodel version: " + version);
+ setAdaptorName((String)d.objectForKey("adaptorName"));
+ setConnectionDictionary((NSDictionary)d.objectForKey("connectionDictionary"));
+ _entities = ((NSArray)d.objectForKey("entities")).mutableClone();
+ if (d.objectForKey("storedProcedures") != null)
+ _storedProcedureNames.addObjectsFromArray((NSArray)d.objectForKey("storedProcedures"));
+ if (d.objectForKey("internalInfo") != null)
+ _internalInfo = (NSDictionary)d.objectForKey("internalInfo");
+ if (d.objectForKey("userInfo") != null)
+ _userInfo = (NSDictionary)d.objectForKey("userInfo");
+ entityNamed("EOPrototypes");
+ }
+
+ public void setConnectionDictionary(NSDictionary dict) {
+ _connectionDictionary = dict;
+ }
+ public NSDictionary connectionDictionary() {
+ return _connectionDictionary;
+ }
+
+ public void addEntity(EOEntity ent) {
+ _entitiesByName.setObjectForKey(ent, ent.name());
+ _entitiesByClass.setObjectForKey(ent, ent.className());
+ }
+
+ public void removeEntity(EOEntity ent) {
+ _entitiesByName.removeObjectForKey(ent.name());
+ _entitiesByClass.removeObjectForKey(ent.className());
+ }
+
+ public void addStoredProcedure(EOStoredProcedure proc) {
+ if (!_storedProcedureNames.containsObject(proc))
+ _storedProcedureNames.addObject(proc);
+ _storedProcedures.setObjectForKey(proc, proc.name());
+ }
+
+ public void removeStoredProcedure(EOStoredProcedure proc) {
+ _storedProcedureNames.removeObject(proc.name());
+ _storedProcedures.removeObjectForKey(proc.name());
+ }
+
+ public EOStoredProcedure storedProcedureNamed(String name) {
+ EOStoredProcedure proc = (EOStoredProcedure)_storedProcedures.objectForKey(name);
+ //if we can't find it, check if we should load it
+ if (proc == null && _path != null && _storedProcedureNames.containsObject(name)) {
+ //try to read it from file
+ File f = new File(new File(_path), name + ".storedProcedure");
+ if (!f.exists())
+ return null;
+ String sdict = null;
+ try {
+ FileInputStream fin = new FileInputStream(f);
+ byte[] b = new byte[fin.available()];
+ fin.read(b);
+ fin.close();
+ sdict = new String(b);
+ } catch (IOException ex) {
+ return null;
+ }
+ NSDictionary plist = NSPropertyListSerialization.dictionaryForString(sdict);
+ if (plist == null)
+ throw new IllegalArgumentException("File " + f + " does not contain a valid stored procedure property list.");
+ proc = new EOStoredProcedure(plist, this);
+ //add it to our collection
+ _storedProcedures.setObjectForKey(proc, proc.name());
+ }
+ return proc;
+ }
+
+ public NSArray storedProcedures() {
+ if (_storedProcedures.count() < _storedProcedureNames.count()) {
+ for (int i=0; i<_storedProcedureNames.count(); i++)
+ storedProcedureNamed((String)_storedProcedureNames.objectAtIndex(i));
+ }
+ return _storedProcedures.allValues();
+ }
+
+ public NSArray storedProcedureNames() {
+ return _storedProcedures.allKeys();
+ }
+
+ public void setAdaptorName(String value) {
+ _adaptorName = value;
+ }
+ public String adaptorName() {
+ return _adaptorName;
+ }
+
+ public NSArray entities() {
+ if (_entitiesByName.count() >= _entities.count())
+ return _entitiesByName.allValues();
+ NSMutableArray es = new NSMutableArray();
+ for (int i = 0; i < _entities.count(); i++) {
+ NSDictionary d = (NSDictionary)_entities.objectAtIndex(i);
+ es.addObject(entityNamed((String)d.objectForKey("name")));
+ }
+ return es;
+ }
+
+ public NSArray entityNames() {
+ if (_entitiesByName.count() >= _entities.count())
+ return _entitiesByName.allKeys();
+ NSMutableArray names = new NSMutableArray();
+ for (int i = 0; i < _entities.count(); i++) {
+ NSDictionary d = (NSDictionary)_entities.objectAtIndex(i);
+ names.addObject(d.objectForKey("name"));
+ }
+ return names;
+ }
+
+ public EOEntity entityNamed(String name) {
+ EOEntity e = (EOEntity)_entitiesByName.objectForKey(name);
+ if (e == null && path() != null) {
+ boolean exists = false;
+ for (int i = 0; i < _entities.count(); i++) {
+ NSDictionary d = (NSDictionary)_entities.objectAtIndex(i);
+ if (d.objectForKey("name").equals(name))
+ exists = true;
+ }
+ if (!exists)
+ return null;
+ File f = new File(new File(path()), name + ".plist");
+ if (!(f.exists() && f.isFile()))
+ throw new IllegalArgumentException("Cannot find " + name + ".plist");
+ String s = null;
+ try {
+ FileInputStream fin = new FileInputStream(f);
+ byte[] b = new byte[fin.available()];
+ fin.read(b);
+ fin.close();
+ s = new String(b);
+ } catch (IOException ex) {
+ throw new IllegalArgumentException("Cannot read " + f);
+ }
+ NSDictionary d = NSPropertyListSerialization.dictionaryForString(s);
+ if (d == null)
+ throw new IllegalArgumentException("Cannot parse dictionary for " + f);
+ e = new EOEntity(d, this);
+ _entitiesByName.setObjectForKey(e, e.name());
+ }
+ return e;
+ }
+
+ public String name() {
+ return _name;
+ }
+
+ public String path() {
+ return _path;
+ }
+
+ public void setModelGroup(EOModelGroup group) {
+ _group = group;
+ }
+ public EOModelGroup modelGroup() {
+ return _group;
+ }
+
+ public void setUserInfo(NSDictionary dict) {
+ _userInfo = dict;
+ }
+
+ public NSDictionary userInfo() {
+ return _userInfo;
+ }
+
+ public void write() {
+ }
+
+ public void writeToFile(String path) {
+ if (!path.endsWith(".eomodeld"))
+ path += ".eomodeld";
+ File f = new File(path);
+ if (f.exists()) {
+ if (f.isDirectory()) {
+ File[] kids = f.listFiles();
+ for (int i = 0; i < kids.length; i++) {
+ String fname = kids[i].getName();
+ if (kids[i].isFile() && (fname.endsWith(".plist") || fname.endsWith(".eomodeld") || fname.endsWith(".fspec") || fname.endsWith(".storedProcedure")))
+ kids[i].delete();
+ }
+ } else
+ f.delete();
+ } else
+ f.mkdirs();
+ File kid = new File(f, "index.eomodeld");
+
+ //encode the index file
+ NSMutableDictionary d = new NSMutableDictionary();
+ d.setObjectForKey(_adaptorName, "adaptorName");
+ d.setObjectForKey("2.1", "EOModelVersion");
+ d.setObjectForKey(_connectionDictionary, "connectionDictionary");
+ if (_internalInfo != null && _internalInfo.count() > 0)
+ d.setObjectForKey(_internalInfo, "internalInfo");
+ if (_userInfo != null && _userInfo.count() > 0)
+ d.setObjectForKey(_userInfo, "userInfo");
+ if (_storedProcedureNames.count() > 0)
+ d.setObjectForKey(_storedProcedureNames, "storedProcedures");
+
+ //encode the entity list
+ entities();
+ storedProcedures();
+ NSMutableArray arr = new NSMutableArray(_entitiesByName.count());
+ Enumeration enumeration = _entitiesByName.keyEnumerator();
+ NSMutableDictionary md = new NSMutableDictionary();
+ while (enumeration.hasMoreElements()) {
+ String key = (String)enumeration.nextElement();
+ EOEntity ent = (EOEntity)_entitiesByName.objectForKey(key);
+ md.removeAllObjects();
+ ent.encodeIntoPropertyList(md);
+ File plist;
+ NSDictionary fetchSpecs = (NSDictionary)md.objectForKey("fetchSpecificationDictionary");
+ if (fetchSpecs != null) {
+ if (fetchSpecs.count() > 0) {
+ plist = new File(f, key + ".fspec");
+ String ps = NSPropertyListSerialization.stringForPropertyList(md.objectForKey("fetchSpecificationDictionary"));
+ try {
+ PrintStream stream = new PrintStream(new FileOutputStream(plist));
+ stream.println(ps);
+ stream.close();
+ } catch (IOException ex) {
+ }
+ }
+ md.removeObjectForKey("fetchSpecificationDictionary");
+ }
+ plist = new File(f, key + ".plist");
+ String ps = NSPropertyListSerialization.stringForPropertyList(md);
+ try {
+ PrintStream stream = new PrintStream(new FileOutputStream(plist));
+ stream.println(ps);
+ stream.close();
+ } catch (IOException ex) {
+ }
+ //add to the entity list for the index
+ arr.addObject(new NSDictionary(
+ new Object[]{ ent.name(), ent.className() },
+ new Object[]{ "name", "className" }));
+ }
+ d.setObjectForKey(arr, "entities");
+
+ //write the index file
+ String s = NSPropertyListSerialization.stringForPropertyList(d);
+ try {
+ PrintStream stream = new PrintStream(new FileOutputStream(kid));
+ stream.println(s);
+ stream.close();
+ } catch (IOException ex) {
+ throw new RuntimeException("Cannot write index.eomodeld");
+ }
+
+ //write the stored procedures
+ for (int i = 0; i < _storedProcedureNames.count(); i++) {
+ EOStoredProcedure proc = (EOStoredProcedure)_storedProcedures.objectForKey(_storedProcedureNames.objectAtIndex(i));
+ kid = new File(f, proc.name() + ".storedProcedure");
+ d.removeAllObjects();
+ proc.encodeIntoPropertyList(d);
+ s = NSPropertyListSerialization.stringForPropertyList(d);
+ try {
+ PrintStream stream = new PrintStream(new FileOutputStream(kid));
+ stream.println(s);
+ stream.close();
+ } catch (IOException ex) {
+ throw new RuntimeException("Cannot write " + f);
+ }
+ }
+ _path = f.getAbsolutePath();
+ }
+
+}
+/*
+ * $Log$
+ * Revision 1.2 2006/02/16 16:47:14 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.8 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.7 2003/08/13 20:46:12 chochos
+ * entityNamed() only throws if the searched entity is in the entities array and not in a file.
+ *
+ * Revision 1.6 2003/08/12 01:45:04 chochos
+ * added some code to handle prototypes
+ *
+ * Revision 1.5 2003/08/11 19:38:27 chochos
+ * Can now read from a file and re-write to another file.
+ *
+ * Revision 1.4 2003/08/11 18:20:08 chochos
+ * saving to a file seems to work now.
+ *
+ * Revision 1.3 2003/08/08 02:16:55 chochos
+ * can now read stored procedures from file.
+ *
+ * Revision 1.2 2003/08/08 00:37:00 chochos
+ * add stored procedure functionality
+ *
+ * Revision 1.1 2003/08/07 02:42:28 chochos
+ * EOModel can read an .eomodeld file. EOModelGroup doesn't do much for now.
+ *
+*/ \ No newline at end of file