public static void relationshipModified( final Principal user, final RelationshipInterface relationship, final PropertyKey key, final Object previousValue, final Object newValue) { TransactionCommand command = currentCommand.get(); if (command != null) { ModificationQueue modificationQueue = command.getModificationQueue(); if (modificationQueue != null) { modificationQueue.modify(user, relationship, key, previousValue, newValue); } else { logger.log(Level.SEVERE, "Got empty changeSet from command!"); } } else { logger.log(Level.SEVERE, "Relationship deleted while outside of transaction!"); } }
public Collection<ModificationEvent> getModificationEvents() { ModificationQueue modificationQueue = queues.get(); if (modificationQueue != null) { return modificationQueue.getModificationEvents(); } return null; }
public static boolean isDeleted(final Relationship rel) { if (!inTransaction()) { throw new NotInTransactionException("Not in transaction."); } final ModificationQueue queue = queues.get(); if (queue != null) { return queue.isDeleted(rel); } return false; }
public static void nodeDeleted(final Principal user, final NodeInterface node) { TransactionCommand command = currentCommand.get(); if (command != null) { ModificationQueue modificationQueue = command.getModificationQueue(); if (modificationQueue != null) { modificationQueue.delete(user, node); } else { logger.log(Level.SEVERE, "Got empty changeSet from command!"); } } else { logger.log(Level.SEVERE, "Node deleted while outside of transaction!"); } }
public static void relationshipDeleted( final Principal user, final RelationshipInterface relationship, final boolean passive) { TransactionCommand command = currentCommand.get(); if (command != null) { ModificationQueue modificationQueue = command.getModificationQueue(); if (modificationQueue != null) { modificationQueue.delete(user, relationship, passive); } else { logger.log(Level.SEVERE, "Got empty changeSet from command!"); } } else { logger.log(Level.SEVERE, "Relationship deleted while outside of transaction!"); } }
public static void postProcess(final String key, final TransactionPostProcess process) { TransactionCommand command = currentCommand.get(); if (command != null) { ModificationQueue modificationQueue = command.getModificationQueue(); if (modificationQueue != null) { modificationQueue.postProcess(key, process); } else { logger.log(Level.SEVERE, "Got empty changeSet from command!"); } } else { logger.log( Level.SEVERE, "Trying to register transaction post processing while outside of transaction!"); } }
public ModificationQueue finishTx() { final TransactionReference tx = transactions.get(); ModificationQueue modificationQueue = null; if (tx != null) { if (tx.isToplevel()) { modificationQueue = queues.get(); final Set<String> synchronizationKeys = modificationQueue.getSynchronizationKeys(); // cleanup queues.remove(); buffers.remove(); currentCommand.remove(); transactions.remove(); try { tx.close(); } catch (Throwable t) { t.printStackTrace(); } finally { // release semaphores as the transaction is now finished semaphore.release(synchronizationKeys); // careful: this can be null } } else { tx.end(); } } return modificationQueue; }
public void commitTx(final boolean doValidation) throws FrameworkException { final TransactionReference tx = transactions.get(); if (tx != null && tx.isToplevel()) { final ModificationQueue modificationQueue = queues.get(); final ErrorBuffer errorBuffer = buffers.get(); // 0.5: let transaction listeners examine (and prevent?) commit for (final StructrTransactionListener listener : listeners) { listener.beforeCommit( securityContext, modificationQueue.getModificationEvents(), tx.getSource()); } // 1. do inner callbacks (may cause transaction to fail) if (doValidation) { if (!modificationQueue.doInnerCallbacks(securityContext, errorBuffer)) { tx.failure(); throw new FrameworkException( 422, "Unable to commit transaction, validation failed", errorBuffer); } // 1.5: execute validatable post-transaction action if (!modificationQueue.doPostProcessing(securityContext, errorBuffer)) { tx.failure(); throw new FrameworkException( 422, "Unable to commit transaction, transaction post processing failed", errorBuffer); } } // 2. fetch all types of entities modified in this tx Set<String> synchronizationKeys = modificationQueue.getSynchronizationKeys(); // we need to protect the validation and indexing part of every transaction // from being entered multiple times in the presence of validators // 3. acquire semaphores for each modified type try { semaphore.acquire(synchronizationKeys); } catch (InterruptedException iex) { return; } // finally, do validation under the protection of the semaphores for each type if (!modificationQueue.doValidation(securityContext, errorBuffer, doValidation)) { tx.failure(); // create error throw new FrameworkException( 422, "Unable to commit transaction, validation failed", errorBuffer); } try { tx.success(); } catch (Throwable t) { t.printStackTrace(); } } }
/** * Call beforeModification/Creation/Deletion methods. * * @param modificationQueue * @param securityContext * @param errorBuffer * @return valid * @throws FrameworkException */ public boolean doInnerCallback( ModificationQueue modificationQueue, SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { boolean valid = true; // check for modification propagation along the relationships if ((status & STATE_PROPAGATING_MODIFICATION) == STATE_PROPAGATING_MODIFICATION && object instanceof AbstractNode) { Set<AbstractNode> nodes = ((AbstractNode) object).getNodesForModificationPropagation(); if (nodes != null) { for (AbstractNode node : nodes) { modificationQueue.propagatedModification(node); } } } // examine only the last 4 bits here switch (status & 0x000f) { case 15: case 14: case 13: case 12: case 11: case 10: case 9: case 8: // since all values >= 8 mean that the object was passively deleted, no action has to // be taken // (no callback for passive deletion!) break; case 7: // created, modified, deleted, poor guy => no callback break; case 6: // created, modified => only creation callback will be called valid &= object.onCreation(securityContext, errorBuffer); break; case 5: // created, deleted => no callback break; case 4: // created => creation callback valid &= object.onCreation(securityContext, errorBuffer); break; case 3: // modified, deleted => deletion callback valid &= object.onDeletion(securityContext, errorBuffer, removedProperties); break; case 2: // modified => modification callback valid &= object.onModification(securityContext, errorBuffer); break; case 1: // deleted => deletion callback valid &= object.onDeletion(securityContext, errorBuffer, removedProperties); break; case 0: // no action, no callback break; default: break; } // mark as finished modified = false; return valid; }