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 net.wotonomy.control.EOFetchSpecification;
21  import net.wotonomy.control.EOQualifier;
22  import net.wotonomy.foundation.NSArray;
23  import net.wotonomy.foundation.NSDictionary;
24  import net.wotonomy.foundation.NSMutableDictionary;
25  
26  /***
27  *
28  * @author ezamudio@nasoft.com
29  * @author $Author: cgruber $
30  * @version $Revision: 894 $
31  */
32  public abstract class EOAdaptorChannel {
33  
34  	protected EOAdaptorContext _context;
35  
36  	public EOAdaptorChannel(EOAdaptorContext context) {
37  		super();
38  		_context = context;
39  	}
40  
41  	public EOAdaptorContext adaptorContext() {
42  		return _context;
43  	}
44  
45  	public void addStoredProceduresNamed(NSArray names, EOModel model) {
46  	}
47  
48  	public abstract NSArray attributesToFetch();
49  
50  	public abstract void cancelFetch();
51  
52  	public abstract void closeChannel();
53  
54  	public abstract NSArray describeResults();
55  
56  	public abstract int deleteRowsDescribedByQualifier(EOQualifier q, EOEntity entity);
57  
58  	public abstract void evaluateExpression(EOSQLExpression sql);
59  
60  	public abstract void executeStoredProcedure(EOStoredProcedure proc, NSDictionary values);
61  
62  	public abstract NSMutableDictionary fetchRow();
63  
64  	public abstract void insertRow(NSDictionary row, EOEntity entity);
65  
66  	public abstract boolean isFetchInProgress();
67  
68  	public abstract boolean isOpen();
69  
70  	public abstract void openChannel();
71  
72  	public abstract NSDictionary returnValuesForLastStoredProcedureInvocation();
73  
74  	public abstract void selectAttributes(NSArray atts, EOFetchSpecification fspec, boolean lock, EOEntity entity);
75  
76  	public abstract void setAttributesToFetch(NSArray atts);
77  
78  	public abstract int updateValuesInRowsDescribedByQualifier(NSDictionary row, EOQualifier q, EOEntity entity);
79  
80  	public void deleteRowDescribedByQualifier(EOQualifier q, EOEntity entity) {
81  		adaptorContext().beginTransaction();
82  		int count = deleteRowsDescribedByQualifier(q, entity);
83  		if (count != 1) {
84  			adaptorContext().rollbackTransaction();
85  			throw new EOGeneralAdaptorException("Qualifier deleted " + count + " rows instead of exactly one.");
86  		}
87  		adaptorContext().commitTransaction();
88  	}
89  
90  	public EOModel describeModelWithTableNames(NSArray names) {
91  		return null;
92  	}
93  
94  	public NSArray describeStoredProcedureNames() {
95  		return NSArray.EmptyArray;
96  	}
97  
98  	public NSArray describeTableNames() {
99  		return NSArray.EmptyArray;
100 	}
101 
102 	public NSMutableDictionary dictionaryWithObjectsForAttributes(Object[] values, NSArray attributes) {
103 		Object[] keys = new Object[attributes.count()];
104 		for (int i = 0; i < attributes.count(); i++)
105 			keys[i] = ((EOAttribute)attributes.objectAtIndex(i)).name();
106 		return new NSMutableDictionary(values, keys);
107 	}
108 
109 	public void lockRowComparingAttributes(NSArray atts, EOEntity entity, EOQualifier q, NSDictionary snapshot) {
110 		EOFetchSpecification fspec = new EOFetchSpecification(entity.name(), q, null);
111 		adaptorContext().beginTransaction();
112 		selectAttributes(atts, fspec, true, entity);
113 		if (isFetchInProgress()) {
114 			NSDictionary row = fetchRow();
115 			if (row == null) {
116 				cancelFetch();
117 				adaptorContext().rollbackTransaction();
118 				throw new EOGeneralAdaptorException("Cannot obtain row to lock. Probably modified from the outside.");
119 			}
120 			if (isFetchInProgress()) {
121 				if (fetchRow() != null) {
122 					cancelFetch();
123 					adaptorContext().rollbackTransaction();
124 					throw new EOGeneralAdaptorException("Qualifier returns more than one row.");
125 				}
126 			}
127 			java.util.Enumeration enumeration = snapshot.keyEnumerator();
128 			while (enumeration.hasMoreElements()) {
129 				Object key = enumeration.nextElement();
130 				Object svalue = snapshot.objectForKey(key);
131 				Object rvalue = row.objectForKey(key);
132 				if (rvalue == null) {
133 					cancelFetch();
134 					adaptorContext().rollbackTransaction();
135 					throw new EOGeneralAdaptorException("Value for key " + key + " not found in locked row.");
136 				}
137 				if (!rvalue.equals(svalue)) {
138 					cancelFetch();
139 					adaptorContext().rollbackTransaction();
140 					throw new EOGeneralAdaptorException("Value for key " + key + " differes from snapshot.");
141 				}
142 			}
143 			adaptorContext().commitTransaction();
144 			return;
145 		}
146 		adaptorContext().rollbackTransaction();
147 		throw new EOGeneralAdaptorException("A fetch was never generated.");
148 	}
149 
150 	public void performAdaptorOperation(EOAdaptorOperation operation) {
151 		int opcode = operation.adaptorOperator();
152 		switch (opcode) {
153 			case EODatabaseOperation.AdaptorLockOperator:
154 				if (operation.entity() == null)
155 					throw new EOGeneralAdaptorException("A lock operation must have an entity assigned to it.",
156 						new NSDictionary(operation, "operation"));
157 				if (operation.qualifier() == null)
158 					throw new EOGeneralAdaptorException("A lock operation must have a qualifier assigned to it.",
159 						new NSDictionary(operation, "operation"));
160 				if (operation.qualifier() == null)
161 					throw new EOGeneralAdaptorException("A lock operation must have changedValues assigned to it.",
162 						new NSDictionary(operation, "operation"));
163 				lockRowComparingAttributes(operation.attributes(), operation.entity(), operation.qualifier(), operation.changedValues());
164 				break;
165 			case EODatabaseOperation.AdaptorInsertOperator:
166 				if (operation.entity() == null)
167 					throw new EOGeneralAdaptorException("An insert operation must have an entity assigned to it.",
168 						new NSDictionary(operation, "operation"));
169 				if (operation.changedValues() == null)
170 					throw new EOGeneralAdaptorException("An insert operation must have changedValues assigned to it.",
171 						new NSDictionary(operation, "operation"));
172 				insertRow(operation.changedValues(), operation.entity());
173 				break;
174 			case EODatabaseOperation.AdaptorUpdateOperator:
175 				if (operation.entity() == null)
176 					throw new EOGeneralAdaptorException("An update operation must have an entity assigned to it.",
177 						new NSDictionary(operation, "operation"));
178 				if (operation.changedValues() == null)
179 					throw new EOGeneralAdaptorException("An update operation must have changedValues assigned to it.",
180 						new NSDictionary(operation, "operation"));
181 				updateValuesInRowsDescribedByQualifier(operation.changedValues(), operation.qualifier(), operation.entity());
182 				break;
183 			case EODatabaseOperation.AdaptorDeleteOperator:
184 				if (operation.entity() == null)
185 					throw new EOGeneralAdaptorException("A delete operation must have an entity assigned to it.",
186 						new NSDictionary(operation, "operation"));
187 				deleteRowsDescribedByQualifier(operation.qualifier(), operation.entity());
188 				break;
189 			case EODatabaseOperation.AdaptorStoredProcedureOperator:
190 				if (operation.storedProcedure() == null)
191 					throw new EOGeneralAdaptorException("A stored procedure operation must have a stored procedure assigned to it.",
192 						new NSDictionary(operation, "operation"));
193 				executeStoredProcedure(operation.storedProcedure(), operation.changedValues());
194 				break;
195 			default:
196 				throw new EOGeneralAdaptorException("I don't know how to perform an operation with code " + opcode,
197 					new NSDictionary(operation, "operation"));
198 		}
199 	}
200 
201 	public void performAdaptorOperations(NSArray ops) {
202 		for (int i = 0; i < ops.count(); i++) {
203 			EOAdaptorOperation adop = (EOAdaptorOperation)ops.objectAtIndex(i);
204 			performAdaptorOperation(adop);
205 		}
206 	}
207 
208 	public NSArray primaryKeysForNewRowsWithEntity(int count, EOEntity entity) {
209 		NSDictionary[] keys = new NSDictionary[count];
210 		for (int i = 0; i < count; i++)
211 			keys[i] = NSDictionary.EmptyDictionary;
212 		return new NSArray(keys);
213 	}
214 
215 	public void updateValuesInRowDescribedByQualifier(NSDictionary row, EOQualifier q, EOEntity entity) {
216 		adaptorContext().beginTransaction();
217 		int count = updateValuesInRowsDescribedByQualifier(row, q, entity);
218 		if (count != 1) {
219 			adaptorContext().rollbackTransaction();
220 			throw new EOGeneralAdaptorException("The qualifier should describe exactly one row (updated " + count + " rows)");
221 		}
222 		adaptorContext().commitTransaction();
223 	}
224 
225 }
226 /*
227  * $Log$
228  * Revision 1.2  2006/02/16 16:47:14  cgruber
229  * Move some classes in to "internal" packages and re-work imports, etc.
230  *
231  * Also use UnsupportedOperationExceptions where appropriate, instead of WotonomyExceptions.
232  *
233  * Revision 1.1  2006/02/16 13:19:57  cgruber
234  * Check in all sources in eclipse-friendly maven-enabled packages.
235  *
236  * Revision 1.2  2005/05/11 15:21:53  cgruber
237  * Change enum to enumeration, since enum is now a keyword as of Java 5.0
238  *
239  * A few other comments in the code.
240  *
241  * Revision 1.1  2003/08/13 00:37:45  chochos
242  * an almost complete implementation of the abstract adaptor-layer classes
243  *
244  */