29 private static $_isInfoEnabled =
false;
30 private static $_isDebugEnabled =
false;
31 private static $_logger = null;
33 private $_persistenceFacade = null;
34 private $_eventManager = null;
37 private $_isActive =
false;
38 private $_observedObjects = array();
57 if (self::$_logger == null) {
60 $this->_persistenceFacade = $persistenceFacade;
61 $this->_eventManager = $eventManager;
65 array($this,
'stateChanged'));
66 self::$_isInfoEnabled = self::$_logger->isInfoEnabled();
67 self::$_isDebugEnabled = self::$_logger->isDebugEnabled();
75 array($this,
'stateChanged'));
83 $key = $oid->__toString();
84 if (self::$_isDebugEnabled) {
85 self::$_logger->debug(
"New Data:\n".$object->
dump());
86 self::$_logger->debug(
"Registry before:\n".$this->
dump());
90 $registeredObject = null;
91 if (isset($this->_loadedObjects[$key])) {
92 $registeredObject = $this->_loadedObjects[$key];
94 if (self::$_isDebugEnabled) {
95 self::$_logger->debug(
"Merging data of ".$key);
97 $registeredObject->mergeValues($object);
100 if (self::$_isDebugEnabled) {
101 self::$_logger->debug(
"Register loaded object: ".$key);
103 $this->_loadedObjects[$key] = $object;
105 if ($this->_isActive) {
106 if (self::$_isDebugEnabled) {
107 self::$_logger->debug(
"Start listening to: ".$key);
109 $this->_observedObjects[$key] = $object;
111 $registeredObject = $object;
113 if (self::$_isDebugEnabled) {
114 self::$_logger->debug(
"Registry after:\n".$this->
dump());
116 return $registeredObject;
123 if (!$this->_isActive) {
126 $key = $object->
getOID()->__toString();
127 if (self::$_isDebugEnabled) {
128 self::$_logger->debug(
"Register new object: ".$key);
130 $this->_newObjects[$key] = $object;
131 $this->_observedObjects[$key] = $object;
138 if (!$this->_isActive) {
141 $key = $object->
getOID()->__toString();
143 if (isset($this->_newObjects[$key]) || isset($this->_deletedObjects[$key])) {
146 if (self::$_isDebugEnabled) {
147 self::$_logger->debug(
"Register dirty object: ".$key);
149 $this->_dirtyObjects[$key] = $object;
156 if (!$this->_isActive) {
159 $key = $object->
getOID()->__toString();
162 if (isset($this->_newObjects[$key])) {
163 unset($this->_newObjects[$key]);
167 if (isset($this->_dirtyObjects[$key])) {
168 unset($this->_dirtyObjects[$key]);
170 if (self::$_isDebugEnabled) {
171 self::$_logger->debug(
"Register deleted object: ".$key);
173 $this->_deletedObjects[$key] = $object;
180 if (self::$_isInfoEnabled) {
181 self::$_logger->info(
"Starting transaction");
183 $this->_isActive =
true;
190 if (self::$_isInfoEnabled) {
191 self::$_logger->info(
"Commit transaction");
193 $changedOids = array();
194 if ($this->_isActive) {
195 $knowTypes = $this->_persistenceFacade->getKnownTypes();
198 foreach ($knowTypes as $type) {
199 $mapper = $this->_persistenceFacade->getMapper($type);
200 $mapper->beginTransaction();
206 while (!$commitDone) {
207 $changedOids = array_merge($changedOids, $this->
processInserts());
212 sizeof($this->_dirtyObjects) == 0 &&
216 if (self::$_isInfoEnabled) {
217 self::$_logger->info(
"Committing transaction");
219 foreach ($knowTypes as $type) {
220 $mapper = $this->_persistenceFacade->getMapper($type);
221 $mapper->commitTransaction();
226 self::$_logger->error(
"Rolling back transaction. Exception: ".$ex->__toString());
227 foreach ($knowTypes as $type) {
228 $mapper = $this->_persistenceFacade->getMapper($type);
229 $mapper->rollbackTransaction();
244 if (self::$_isInfoEnabled) {
245 self::$_logger->info(
"Rollback transaction");
249 $this->_isActive =
false;
256 return $this->_isActive;
263 $registeredObject = null;
265 if (isset($this->_loadedObjects[$key])) {
266 $registeredObject = $this->_loadedObjects[$key];
268 return $registeredObject;
276 if (isset($this->_newObjects[$key])) {
277 unset($this->_newObjects[$key]);
279 if (isset($this->_dirtyObjects[$key])) {
280 unset($this->_dirtyObjects[$key]);
282 if (isset($this->_deletedObjects[$key])) {
283 unset($this->_deletedObjects[$key]);
285 if (isset($this->_loadedObjects[$key])) {
286 unset($this->_loadedObjects[$key]);
288 unset($this->_observedObjects[$key]);
289 $this->_detachedObjects[$key] = $oid;
298 foreach (array_values($this->_loadedObjects) as $curObject) {
299 $str .= $curObject->dump();
308 foreach ($this->_newObjects as $object) {
309 unset($this->_observedObjects[$object->getOID()->__toString()]);
311 $this->_newObjects = array();
313 foreach ($this->_dirtyObjects as $object) {
314 unset($this->_observedObjects[$object->getOID()->__toString()]);
316 $this->_dirtyObjects = array();
318 foreach ($this->_deletedObjects as $object) {
319 unset($this->_observedObjects[$object->getOID()->__toString()]);
321 $this->_deletedObjects = array();
323 foreach ($this->_loadedObjects as $object) {
324 unset($this->_observedObjects[$object->getOID()->__toString()]);
326 $this->_loadedObjects = array();
328 $this->_detachedObjects = array();
336 $changedOids = array();
337 $pendingInserts = array();
338 $insertOids = array_keys($this->_newObjects);
339 while (
sizeof($insertOids) > 0) {
340 $key = array_shift($insertOids);
341 if (self::$_isDebugEnabled) {
342 self::$_logger->debug(
"Process insert on object: ".$key);
344 $object = $this->_newObjects[$key];
348 $requiredObjects = $object->getIndispensableObjects();
349 foreach ($requiredObjects as $requiredObject) {
351 if (self::$_isDebugEnabled) {
352 self::$_logger->debug(
"Postpone insert of object: ".$key.
". Required objects are not saved yet.");
354 $pendingInserts[] = $object;
360 $oldOid = $object->getOID();
361 $object->getMapper()->save($object);
362 $changedOids[$oldOid->__toString()] = $object->getOID()->__toString();
364 unset($this->_newObjects[$key]);
365 $insertOids = array_keys($this->_newObjects);
368 foreach ($pendingInserts as $object) {
369 $key = $object->getOID()->__toString();
370 $this->_newObjects[$key] = $object;
379 $updateOids = array_keys($this->_dirtyObjects);
380 while (
sizeof($updateOids) > 0) {
381 $key = array_shift($updateOids);
382 if (self::$_isDebugEnabled) {
383 self::$_logger->debug(
"Process update on object: ".$key);
385 $object = $this->_dirtyObjects[$key];
386 $object->getMapper()->save($object);
387 unset($this->_dirtyObjects[$key]);
388 $updateOids = array_keys($this->_dirtyObjects);
396 $deleteOids = array_keys($this->_deletedObjects);
397 while (
sizeof($deleteOids) > 0) {
398 $key = array_shift($deleteOids);
399 if (self::$_isDebugEnabled) {
400 self::$_logger->debug(
"Process delete on object: ".$key);
402 $object = $this->_deletedObjects[$key];
403 $object->getMapper()->delete($object);
404 unset($this->_deletedObjects[$key]);
405 $deleteOids = array_keys($this->_deletedObjects);
417 $key = $object->getOID()->__toString();
418 if (isset($this->_detachedObjects[$key])) {
424 if (self::$_isDebugEnabled) {
425 self::$_logger->debug(
"State changed: ".$object->getOID().
" old:".$oldState.
" new:".$newState);
447 return $this->_observedObjects;
registerDeleted(PersistentObject $object)
getOID()
Get the object id of the PersistentObject.
static getDummyId()
Get a dummy id ("wcmf" + unique 32 character string).
processUpdates()
Process the dirty objects queue.
registerDirty(PersistentObject $object)
EventManager is responsible for dispatching events to registered listeners.
registerLoaded(PersistentObject $object)
getObject()
Get the object whose state has changed.
ObjectId is the unique identifier of an object.
StateChangeEvent signals a change of the state of a PersistentObject instance.
static getLogger($name)
Get the logger with the given name.
__construct(PersistenceFacade $persistenceFacade, EventManager $eventManager)
Constructor.
Default implementation of Transaction.
Transaction implements the Unit of Work pattern as it defines the interface for maintaining a list of...
stateChanged(StateChangeEvent $event)
Listen to StateChangeEvents.
getOldValue()
Get the old value.
clear()
Clear all internal.
__toString()
Get a string representation of the object id.
getNewValue()
Get the new value.
dump()
Get a string representation of the values of the PersistentObject.
dump()
Dump the registry content into a string.
processInserts()
Process the new objects queue.
PersistenceFacade defines the interface for PersistenceFacade implementations.
$_loadedObjects
Contains all loaded objects no matter which state they have.
processDeletes()
Process the deleted objects queue.
registerNew(PersistentObject $object)
PersistentObject defines the interface of all persistent objects.