1 56 package org.objectstyle.cayenne.access; 57 58 import java.util.ArrayList ; 59 import java.util.Arrays ; 60 import java.util.Collection ; 61 import java.util.Iterator ; 62 import java.util.List ; 63 64 import org.objectstyle.cayenne.CayenneException; 65 import org.objectstyle.cayenne.CayenneRuntimeException; 66 import org.objectstyle.cayenne.DataRow; 67 import org.objectstyle.cayenne.ObjectId; 68 import org.objectstyle.cayenne.access.event.DataContextEvent; 69 import org.objectstyle.cayenne.access.event.DataContextTransactionEventListener; 70 import org.objectstyle.cayenne.access.event.DataObjectTransactionEventListener; 71 import org.objectstyle.cayenne.access.util.DefaultOperationObserver; 72 import org.objectstyle.cayenne.event.EventManager; 73 import org.objectstyle.cayenne.map.DbAttribute; 74 import org.objectstyle.cayenne.query.InsertBatchQuery; 75 import org.objectstyle.cayenne.query.Query; 76 import org.objectstyle.cayenne.util.Util; 77 78 84 class CommitObserver extends DefaultOperationObserver implements 85 DataContextTransactionEventListener { 86 87 List updObjects; 88 List delObjects; 89 List insObjects; 90 List objectsToNotify; 91 92 DataContext context; 93 94 CommitObserver(DataContext context, List insObjects, List updObjects, List delObjects) { 95 this.context = context; 96 this.insObjects = insObjects; 97 this.updObjects = updObjects; 98 this.delObjects = delObjects; 99 this.objectsToNotify = new ArrayList (); 100 101 Iterator collIter = (Arrays.asList(new List [] { 106 delObjects, updObjects, insObjects 107 })).iterator(); 108 while (collIter.hasNext()) { 109 Iterator objIter = ((Collection ) collIter.next()).iterator(); 110 while (objIter.hasNext()) { 111 Object element = objIter.next(); 112 if (element instanceof DataObjectTransactionEventListener) { 113 this.objectsToNotify.add(element); 114 } 115 } 116 } 117 } 118 119 public void nextQueryException(Query query, Exception ex) { 120 super.nextQueryException(query, ex); 121 throw new CayenneRuntimeException("Raising from query exception.", Util 122 .unwindException(ex)); 123 } 124 125 public void nextGlobalException(Exception ex) { 126 super.nextGlobalException(ex); 127 throw new CayenneRuntimeException( 128 "Raising from underlyingQueryEngine exception.", 129 Util.unwindException(ex)); 130 } 131 132 void registerForDataContextEvents() { 133 EventManager mgr = EventManager.getDefaultManager(); 134 mgr.addListener( 135 this, 136 "dataContextWillCommit", 137 DataContextEvent.class, 138 DataContext.WILL_COMMIT, 139 this.context); 140 mgr.addListener( 141 this, 142 "dataContextDidCommit", 143 DataContextEvent.class, 144 DataContext.DID_COMMIT, 145 this.context); 146 mgr.addListener( 147 this, 148 "dataContextDidRollback", 149 DataContextEvent.class, 150 DataContext.DID_ROLLBACK, 151 this.context); 152 } 153 154 void unregisterFromDataContextEvents() { 155 EventManager mgr = EventManager.getDefaultManager(); 156 mgr.removeListener(this, DataContext.WILL_COMMIT); 157 mgr.removeListener(this, DataContext.DID_COMMIT); 158 mgr.removeListener(this, DataContext.DID_ROLLBACK); 159 } 160 161 public void dataContextWillCommit(DataContextEvent event) { 162 Iterator iter = objectsToNotify.iterator(); 163 while (iter.hasNext()) { 164 ((DataObjectTransactionEventListener) iter.next()).willCommit(event); 165 } 166 } 167 168 public void dataContextDidCommit(DataContextEvent event) { 169 Iterator iter = objectsToNotify.iterator(); 170 while (iter.hasNext()) { 171 ((DataObjectTransactionEventListener) iter.next()).didCommit(event); 172 } 173 } 174 175 public void dataContextDidRollback(DataContextEvent event) { 176 } 178 179 182 public void nextGeneratedDataRows(Query query, ResultIterator keysIterator) { 183 184 List keys; 186 try { 187 keys = keysIterator.dataRows(true); 188 } 189 catch (CayenneException ex) { 190 throw new CayenneRuntimeException("Error reading primary key", Util 191 .unwindException(ex)); 192 } 193 194 if (!(query instanceof InsertBatchQuery)) { 195 throw new CayenneRuntimeException( 196 "Generated keys only supported for InsertBatchQuery, instead got " 197 + query); 198 } 199 200 InsertBatchQuery batch = (InsertBatchQuery) query; 201 202 ObjectId id = batch.getObjectId(); 203 if (id == null || !id.isTemporary()) { 204 return; 206 } 207 208 if (keys.size() != 1) { 209 throw new CayenneRuntimeException( 210 "One and only one PK row is expected, instead got " + keys.size()); 211 } 212 213 DataRow key = (DataRow) keys.get(0); 214 215 if (key.size() == 0) { 217 throw new CayenneRuntimeException("Empty key generated."); 218 } 219 220 222 if (key.size() > 1) { 227 throw new CayenneRuntimeException( 228 "Only a single column autogenerated PK is supported. " 229 + "Generated key: " 230 + key); 231 } 232 233 Iterator it = batch.getDbEntity().getGeneratedAttributes().iterator(); 234 while (it.hasNext()) { 235 DbAttribute attribute = (DbAttribute) it.next(); 236 237 if (attribute.isPrimaryKey()) { 240 Object value = key.values().iterator().next(); 241 242 id.getReplacementIdMap().put(attribute.getName(), value); 245 break; 246 } 247 } 248 } 249 } | Popular Tags |