diff --git a/li.strolch.agent/src/main/java/li/strolch/agent/api/LockHandler.java b/li.strolch.agent/src/main/java/li/strolch/agent/api/LockHandler.java index 794daee1f..0fb68ce8f 100644 --- a/li.strolch.agent/src/main/java/li/strolch/agent/api/LockHandler.java +++ b/li.strolch.agent/src/main/java/li/strolch/agent/api/LockHandler.java @@ -45,43 +45,45 @@ import li.strolch.model.StrolchRootElement; public interface LockHandler { /** - * Locks the given element by using the element's {@link Locator} and creating a lock on it. Calling lock multiple - * times from the same thread will not lock, it is up to the concrete implementation to define if a lock counter is - * used + * Locks the element with the given {@link Locator} and creating a lock on it. Calling lock multiple times from the + * same thread will not lock, it is up to the concrete implementation to define if a lock counter is used * - * @param element - * the element for which a {@link Lock} on its {@link Locator} is to be created and/or locked + * @param locator + * the {@link Locator} of the element for which a {@link Lock} is to be created and/or locked * * @throws StrolchLockException + * if the lock could not be acquired */ - public void lock(StrolchRootElement element) throws StrolchLockException; + public void lock(Locator locator) throws StrolchLockException; /** *

- * Unlocks the given element by finding the element's lock by its {@link Locator}. It is up to the concrete - * implementation to define if unlocking an unlocked element will fail or not. This method might not completely - * unlock the element if a lock counter is used and the object was locked multiple times. + * Unlocks the element with the given locator. It is up to the concrete implementation to define if unlocking an + * unlocked element will fail or not. This method might not completely unlock the element if a lock counter is used + * and the object was locked multiple times. *

* *

- * If the lock must be completely released, then use {@link #releaseLock(StrolchRootElement)} + * If the lock must be completely released, then use {@link #releaseLock(Locator)} *

* - * @param element - * the element for which the current/last {@link Lock} is to be unlocked + * @param locator + * the {@link Locator} of the element for which the current/last {@link Lock} is to be unlocked * * @throws StrolchLockException + * if the unlock failed */ - public void unlock(StrolchRootElement element) throws StrolchLockException; + public void unlock(Locator locator) throws StrolchLockException; /** - * Releases the lock on the given element, by unlocking all locks, i.e. after this method is called, no lock will be - * held anymore by the current thread + * Releases the lock on the element with the given {@link Locator}, by unlocking all locks, i.e. after this method + * is called, no lock will be held anymore by the current thread * - * @param element - * the element for which the {@link Lock} on the {@link Locator} is to be released + * @param locator + * the {@link Locator} of the element for which the {@link Lock} is to be released * * @throws StrolchLockException + * if the lock could not be released */ - public void releaseLock(StrolchRootElement element) throws StrolchLockException; + public void releaseLock(Locator locator) throws StrolchLockException; } diff --git a/li.strolch.agent/src/main/java/li/strolch/agent/api/StrolchRealm.java b/li.strolch.agent/src/main/java/li/strolch/agent/api/StrolchRealm.java index 4282c751c..76f241fc9 100644 --- a/li.strolch.agent/src/main/java/li/strolch/agent/api/StrolchRealm.java +++ b/li.strolch.agent/src/main/java/li/strolch/agent/api/StrolchRealm.java @@ -16,7 +16,7 @@ package li.strolch.agent.api; import li.strolch.agent.impl.DataStoreMode; -import li.strolch.model.StrolchRootElement; +import li.strolch.model.Locator; import li.strolch.persistence.api.StrolchTransaction; import li.strolch.privilege.model.Certificate; @@ -51,34 +51,34 @@ public interface StrolchRealm { public String getRealm(); /** - * Locks the given element + * Locks the element with the given {@link Locator} * * @param element - * the element to lock + * the locator of the element to lock * - * @see LockHandler#lock(StrolchRootElement) + * @see LockHandler#lock(Locator) */ - public void lock(StrolchRootElement element); + public void lock(Locator locator); /** - * Unlocks the given element (lock might still be held, if lock counter is used) + * Unlocks the element with the given {@link Locator} (lock might still be held, if lock counter is used) * - * @param lockedElement - * the element to unlock + * @param locator + * the locator of the element to unlock * - * @see LockHandler#unlock(StrolchRootElement) + * @see LockHandler#unlock(Locator) */ - public void unlock(StrolchRootElement lockedElement); + public void unlock(Locator locator); /** * Releases the lock for the given element * - * @param lockedElement - * the element for which to release the lock + * @param locator + * the locator of the element for which to release the lock * - * @see LockHandler#releaseLock(StrolchRootElement) + * @see LockHandler#releaseLock(Locator) */ - public void releaseLock(StrolchRootElement lockedElement); + public void releaseLock(Locator locator); /** * Returns the {@link DataStoreMode} diff --git a/li.strolch.agent/src/main/java/li/strolch/agent/impl/DefaultLockHandler.java b/li.strolch.agent/src/main/java/li/strolch/agent/impl/DefaultLockHandler.java index 3fd5ddd7b..9399bd429 100644 --- a/li.strolch.agent/src/main/java/li/strolch/agent/impl/DefaultLockHandler.java +++ b/li.strolch.agent/src/main/java/li/strolch/agent/impl/DefaultLockHandler.java @@ -21,15 +21,14 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import li.strolch.agent.api.LockHandler; import li.strolch.agent.api.StrolchLockException; import li.strolch.model.Locator; -import li.strolch.model.StrolchRootElement; import li.strolch.utils.dbc.DBC; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * @author Robert von Burg */ @@ -59,35 +58,36 @@ public class DefaultLockHandler implements LockHandler { } @Override - public void lock(StrolchRootElement element) throws StrolchLockException { - Locator locator = element.getLocator(); + public void lock(Locator locator) throws StrolchLockException { ReentrantLock lock = this.lockMap.get(locator); if (lock == null) { lock = new ReentrantLock(true); this.lockMap.put(locator, lock); } - lock(this.tryLockTimeUnit, this.tryLockTime, lock, element); + lock(this.tryLockTimeUnit, this.tryLockTime, lock, locator); } @Override - public void unlock(StrolchRootElement element) throws StrolchLockException { - Locator locator = element.getLocator(); + public void unlock(Locator locator) throws StrolchLockException { ReentrantLock lock = this.lockMap.get(locator); if (lock == null || !lock.isHeldByCurrentThread()) { logger.error(MessageFormat.format("Trying to unlock not locked element {0}", locator)); //$NON-NLS-1$ } else { + if (logger.isDebugEnabled()) + logger.debug("unlocking " + locator); //$NON-NLS-1$ unlock(lock); } } @Override - public void releaseLock(StrolchRootElement element) throws StrolchLockException { - Locator locator = element.getLocator(); + public void releaseLock(Locator locator) throws StrolchLockException { ReentrantLock lock = this.lockMap.get(locator); if (lock == null || !lock.isHeldByCurrentThread()) { logger.error(MessageFormat.format("Trying to unlock not locked element {0}", locator)); //$NON-NLS-1$ } else { + if (logger.isDebugEnabled()) + logger.debug("releasing lock " + locator); //$NON-NLS-1$ releaseLock(lock); } } @@ -95,17 +95,19 @@ public class DefaultLockHandler implements LockHandler { /** * @see java.util.concurrent.locks.ReentrantLock#tryLock(long, TimeUnit) */ - private void lock(TimeUnit timeUnit, long tryLockTime, ReentrantLock lock, StrolchRootElement element) + private void lock(TimeUnit timeUnit, long tryLockTime, ReentrantLock lock, Locator locator) throws StrolchLockException { try { if (!lock.tryLock(tryLockTime, timeUnit)) { String msg = "Failed to acquire lock after {0}s for {1}"; //$NON-NLS-1$ - msg = MessageFormat.format(msg, timeUnit.toSeconds(tryLockTime), element.getLocator()); + msg = MessageFormat.format(msg, timeUnit.toSeconds(tryLockTime), locator); throw new StrolchLockException(msg); } + if (logger.isDebugEnabled()) - logger.debug("locked " + toString()); //$NON-NLS-1$ + logger.debug("locked " + locator); //$NON-NLS-1$ + } catch (InterruptedException e) { throw new StrolchLockException(e.getMessage(), e); //$NON-NLS-1$ } @@ -117,8 +119,6 @@ public class DefaultLockHandler implements LockHandler { private void unlock(ReentrantLock lock) throws StrolchLockException { try { lock.unlock(); - if (logger.isDebugEnabled()) - logger.debug("unlocking " + toString()); //$NON-NLS-1$ } catch (IllegalMonitorStateException e) { throw new StrolchLockException(e.getMessage(), e); //$NON-NLS-1$ } diff --git a/li.strolch.agent/src/main/java/li/strolch/agent/impl/InternalStrolchRealm.java b/li.strolch.agent/src/main/java/li/strolch/agent/impl/InternalStrolchRealm.java index 7e613ccb2..54fcb1a79 100644 --- a/li.strolch.agent/src/main/java/li/strolch/agent/impl/InternalStrolchRealm.java +++ b/li.strolch.agent/src/main/java/li/strolch/agent/impl/InternalStrolchRealm.java @@ -34,7 +34,7 @@ import li.strolch.agent.api.ObserverHandler; import li.strolch.agent.api.OrderMap; import li.strolch.agent.api.ResourceMap; import li.strolch.agent.api.StrolchRealm; -import li.strolch.model.StrolchRootElement; +import li.strolch.model.Locator; import li.strolch.privilege.model.PrivilegeContext; import li.strolch.runtime.StrolchConstants; import li.strolch.runtime.configuration.ComponentConfiguration; @@ -67,19 +67,19 @@ public abstract class InternalStrolchRealm implements StrolchRealm { } @Override - public void lock(StrolchRootElement element) { - DBC.PRE.assertNotNull("Can not lock a null pointer =)", element); //$NON-NLS-1$ - this.lockHandler.lock(element); + public void lock(Locator locator) { + DBC.PRE.assertNotNull("Can not lock a null pointer =)", locator); //$NON-NLS-1$ + this.lockHandler.lock(locator); } @Override - public void unlock(StrolchRootElement lockedElement) { - this.lockHandler.unlock(lockedElement); + public void unlock(Locator locator) { + this.lockHandler.unlock(locator); } @Override - public void releaseLock(StrolchRootElement lockedElement) { - this.lockHandler.releaseLock(lockedElement); + public void releaseLock(Locator locator) { + this.lockHandler.releaseLock(locator); } public void initialize(ComponentContainer container, ComponentConfiguration configuration) { @@ -152,7 +152,7 @@ public abstract class InternalStrolchRealm implements StrolchRealm { } @Override - public ObserverHandler getObserverHandler() throws IllegalArgumentException{ + public ObserverHandler getObserverHandler() throws IllegalArgumentException { if (!this.updateObservers) throw new IllegalArgumentException("ObserverUpdates are not enabled!"); //$NON-NLS-1$ return this.observerHandler; diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java b/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java index 9a166f476..de069d2fe 100644 --- a/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java @@ -91,7 +91,7 @@ public abstract class AbstractTransaction implements StrolchTransaction { private List commands; private List flushedCommands; - private Set lockedElements; + private Set lockedElements; private AuditingOrderMap orderMap; private AuditingResourceMap resourceMap; @@ -255,21 +255,35 @@ public abstract class AbstractTransaction implements StrolchTransaction { return this.realm.isVersioningEnabled(); } + @Override + public void lock(Locator locator) throws StrolchLockException { + this.realm.lock(locator); + this.lockedElements.add(locator); + } + @Override public void lock(T element) throws StrolchLockException { - this.realm.lock(element); - this.lockedElements.add(element); + Locator locator = element.getLocator(); + this.realm.lock(locator); + this.lockedElements.add(locator); } @Override public void releaseLock(T element) throws StrolchLockException { - this.realm.releaseLock(element); - this.lockedElements.remove(element); + Locator locator = element.getLocator(); + this.realm.releaseLock(locator); + this.lockedElements.remove(locator); + } + + @Override + public void releaseLock(Locator locator) throws StrolchLockException { + this.realm.releaseLock(locator); + this.lockedElements.remove(locator); } private void releaseElementLocks() { - for (StrolchRootElement lockedElement : this.lockedElements) { - this.realm.releaseLock(lockedElement); + for (Locator locator : this.lockedElements) { + this.realm.releaseLock(locator); } } diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java b/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java index 06eb594c3..c86a0ff3e 100644 --- a/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java @@ -79,7 +79,7 @@ import li.strolch.service.api.Command; *

*
    *
  • Opening and closing database connections
  • - *
  • Releasing locks to strolch elements, if {@link #lock(StrolchRootElement)} is used
  • + *
  • Releasing locks to strolch elements, if {@link #lock(StrolchRootElement)} or {@link #lock(Locator)} is used
  • *
  • Performing Commands correctly
  • *
  • exception handling
  • *
  • auditing
  • @@ -333,6 +333,17 @@ public interface StrolchTransaction extends AutoCloseable { */ boolean isVersioningEnabled(); + /** + * Locks the element with the given locator and registers it on the transaction so the lock is released when the + * transaction is closed + * + * @param locator + * the {@link Locator} of the element to lock + * + * @throws StrolchLockException + */ + public void lock(Locator locator) throws StrolchLockException; + /** * Locks the given element and registers it on the transaction so the lock is released when the transaction is * closed @@ -345,8 +356,8 @@ public interface StrolchTransaction extends AutoCloseable { public void lock(T element) throws StrolchLockException; /** - * Releases the lock of the given element so that even though the transaction is still open, another - * thread/transaction can lock the element + * Releases the lock of the element so that even though the transaction is still open, another thread/transaction + * can lock the element * * @param element * the element for which the lock is to be released @@ -355,6 +366,17 @@ public interface StrolchTransaction extends AutoCloseable { */ public void releaseLock(T element) throws StrolchLockException; + /** + * Releases the lock of the element with the given {@link Locator} so that even though the transaction is still + * open, another thread/transaction can lock the element + * + * @param locator + * the {@link Locator} of the element for which the lock is to be released + * + * @throws StrolchLockException + */ + public void releaseLock(Locator locator) throws StrolchLockException; + /** * Adds the given {@link Command} to the transaction. Using this method guarantees that a {@link Command} is * executed properly: diff --git a/li.strolch.model/src/main/java/li/strolch/model/Locator.java b/li.strolch.model/src/main/java/li/strolch/model/Locator.java index 69ce6aede..941863a80 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/Locator.java +++ b/li.strolch.model/src/main/java/li/strolch/model/Locator.java @@ -186,6 +186,12 @@ public class Locator { return new Locator(this.pathElements, element); } + public Locator trim(int size) { + if (this.pathElements.size() == size) + return this; + return new Locator(this.pathElements.subList(0, size)); + } + /** * Returns the string representation of this {@link Locator} by using the {@link #PATH_SEPARATOR} to separate the * values diff --git a/li.strolch.service/src/main/java/li/strolch/execution/EventBasedExecutionHandler.java b/li.strolch.service/src/main/java/li/strolch/execution/EventBasedExecutionHandler.java index e17d5ac1a..189749a79 100644 --- a/li.strolch.service/src/main/java/li/strolch/execution/EventBasedExecutionHandler.java +++ b/li.strolch.service/src/main/java/li/strolch/execution/EventBasedExecutionHandler.java @@ -6,6 +6,7 @@ import li.strolch.execution.command.SetActionToErrorCommand; import li.strolch.execution.command.SetActionToExecutedCommand; import li.strolch.execution.command.SetActionToStoppedCommand; import li.strolch.execution.command.SetActionToWarningCommand; +import li.strolch.execution.policy.ExecutionPolicy; import li.strolch.model.Locator; import li.strolch.model.activity.Action; import li.strolch.model.activity.Activity; @@ -13,7 +14,14 @@ import li.strolch.model.activity.IActivityElement; import li.strolch.persistence.api.StrolchTransaction; import li.strolch.privilege.model.Certificate; import li.strolch.privilege.model.PrivilegeContext; +import li.strolch.utils.dbc.DBC; +/** + * The event based execution handler waits for events in that the {@link ExecutionPolicy} implementations must call the + * relevant methods when the work is complete. Afterwards the next {@link Action} in the procedure is executed + * + * @author Robert von Burg + */ public class EventBasedExecutionHandler extends ExecutionHandler { private DelayedExecutionTimer delayedExecutionTimer; @@ -76,29 +84,34 @@ public class EventBasedExecutionHandler extends ExecutionHandler { }); } - private void toExecution(String realm, Locator locator, PrivilegeContext ctx) { + private void toExecution(String realm, Locator activityLoc, PrivilegeContext ctx) { try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), ExecuteActivityCommand.class)) { - IActivityElement activityElement = tx.findElement(locator); - Activity activity = activityElement.getRootElement(); + Locator rootElemLoc = activityLoc.trim(3); + tx.lock(rootElemLoc); + + IActivityElement elem = tx.findElement(rootElemLoc); + DBC.INTERIM.assertEquals("toExecution only for Activity!", Activity.class, elem.getClass()); ExecuteActivityCommand command = new ExecuteActivityCommand(getContainer(), tx); - command.setActivity(activity); + command.setActivity((Activity) elem); tx.addCommand(command); tx.commitOnClose(); } } - private void toExecuted(String realm, Locator locator, PrivilegeContext ctx) { + private void toExecuted(String realm, Locator actionLoc, PrivilegeContext ctx) { - Locator activityLoc; + Locator activityLoc = actionLoc.trim(3); try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), SetActionToExecutedCommand.class)) { - Action action = tx.findElement(locator); - activityLoc = action.getRootElement().getLocator(); + tx.lock(activityLoc); + + IActivityElement elem = tx.findElement(actionLoc); + DBC.INTERIM.assertEquals("toExecuted only for Action!", Action.class, elem.getClass()); SetActionToExecutedCommand command = new SetActionToExecutedCommand(getContainer(), tx); - command.setAction(action); + command.setAction((Action) elem); tx.addCommand(command); tx.commitOnClose(); @@ -107,36 +120,48 @@ public class EventBasedExecutionHandler extends ExecutionHandler { toExecution(realm, activityLoc, ctx); } - private void toWarning(String realm, Locator locator, PrivilegeContext ctx) { + private void toWarning(String realm, Locator actionLoc, PrivilegeContext ctx) { try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), SetActionToExecutedCommand.class)) { - Action action = tx.findElement(locator); + Locator rootElemLoc = actionLoc.trim(3); + tx.lock(rootElemLoc); + + IActivityElement elem = tx.findElement(actionLoc); + DBC.INTERIM.assertEquals("toWarning only for Action!", Action.class, elem.getClass()); SetActionToWarningCommand command = new SetActionToWarningCommand(getContainer(), tx); - command.setAction(action); + command.setAction((Action) elem); tx.addCommand(command); tx.commitOnClose(); } } - private void toError(String realm, Locator locator, PrivilegeContext ctx) { + private void toError(String realm, Locator actionLoc, PrivilegeContext ctx) { try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), SetActionToExecutedCommand.class)) { - Action action = tx.findElement(locator); + Locator rootElemLoc = actionLoc.trim(3); + tx.lock(rootElemLoc); + + IActivityElement elem = tx.findElement(actionLoc); + DBC.INTERIM.assertEquals("toError only for Action!", Action.class, elem.getClass()); SetActionToErrorCommand command = new SetActionToErrorCommand(getContainer(), tx); - command.setAction(action); + command.setAction((Action) elem); tx.addCommand(command); tx.commitOnClose(); } } - private void toStopped(String realm, Locator locator, PrivilegeContext ctx) { + private void toStopped(String realm, Locator actionLoc, PrivilegeContext ctx) { try (StrolchTransaction tx = openTx(realm, ctx.getCertificate(), SetActionToStoppedCommand.class)) { - Action action = tx.findElement(locator); + Locator rootElemLoc = actionLoc.trim(3); + tx.lock(rootElemLoc); + + IActivityElement elem = tx.findElement(actionLoc); + DBC.INTERIM.assertEquals("toStopped only for Action!", Action.class, elem.getClass()); SetActionToStoppedCommand command = new SetActionToStoppedCommand(getContainer(), tx); - command.setAction(action); + command.setAction((Action) elem); tx.addCommand(command); tx.commitOnClose(); diff --git a/li.strolch.service/src/main/java/li/strolch/execution/ExecutionHandler.java b/li.strolch.service/src/main/java/li/strolch/execution/ExecutionHandler.java index 5735a4762..78451fede 100644 --- a/li.strolch.service/src/main/java/li/strolch/execution/ExecutionHandler.java +++ b/li.strolch.service/src/main/java/li/strolch/execution/ExecutionHandler.java @@ -2,23 +2,92 @@ package li.strolch.execution; import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.StrolchComponent; +import li.strolch.execution.policy.DurationExecution; +import li.strolch.execution.policy.ExecutionPolicy; import li.strolch.model.Locator; +import li.strolch.model.State; +import li.strolch.model.activity.Action; +import li.strolch.model.activity.Activity; +/** + *

    + * The ExecutionHandler enables the automated execution of {@link Activity} and {@link Action} elements. + *

    + * + *

    + * To start the execution of an {@link Activity} pass it to the {@link #toExecution(String, Locator)} method, and + * together with the {@link ExecutionPolicy} to execution of the element will be handled + *

    + * + * @author Robert von Burg + */ public abstract class ExecutionHandler extends StrolchComponent { public ExecutionHandler(ComponentContainer container, String componentName) { super(container, componentName); } - + + /** + *

    + * Returns the {@link DelayedExecutionTimer} + *

    + * + *

    + * The {@link DelayedExecutionTimer} allows to delay the {@link #toExecuted(String, Locator)} call by a given time. + * See the {@link DurationExecution} policy + *

    + * + * @return the {@link DelayedExecutionTimer} + */ public abstract DelayedExecutionTimer getDelayedExecutionTimer(); - public abstract void toExecution(String realm, Locator locator); + /** + * Starts the execution of the given {@link Activity} with the given {@link Locator} + * + * @param realm + * the realm where the {@link Activity} resides + * @param activityLoc + * the {@link Locator} of the {@link Activity} + */ + public abstract void toExecution(String realm, Locator activityLoc); - public abstract void toExecuted(String realm, Locator locator); + /** + * Completes the execution of the given {@link Action} with the given {@link Locator} + * + * @param realm + * the realm where the {@link Action} resides + * @param actionLoc + * the {@link Locator} of the {@link Action} + */ + public abstract void toExecuted(String realm, Locator actionLoc); - public abstract void toStopped(String realm, Locator locator); + /** + * Sets the state of the {@link Action} with the given {@link Locator} to {@link State#STOPPED} + * + * @param realm + * the realm where the {@link Action} resides + * @param actionLoc + * the {@link Locator} of the {@link Action} + */ + public abstract void toStopped(String realm, Locator actionLoc); - public abstract void toWarning(String realm, Locator locator); + /** + * Sets the state of the {@link Action} with the given {@link Locator} to {@link State#WARNING} + * + * @param realm + * the realm where the {@link Action} resides + * @param actionLoc + * the {@link Locator} of the {@link Action} + */ + public abstract void toWarning(String realm, Locator actionLoc); - public abstract void toError(String realm, Locator locator); + /** + * Sets the state of the {@link Action} with the given {@link Locator} to {@link State#ERROR} + * + * @param realm + * the realm where the {@link Action} resides + * @param actionLoc + * the {@link Locator} of the {@link Action} + */ + public abstract void toError(String realm, Locator actionLoc); } diff --git a/li.strolch.service/src/main/java/li/strolch/execution/policy/ReservationExection.java b/li.strolch.service/src/main/java/li/strolch/execution/policy/ReservationExection.java index f5a5f7082..641b4108f 100644 --- a/li.strolch.service/src/main/java/li/strolch/execution/policy/ReservationExection.java +++ b/li.strolch.service/src/main/java/li/strolch/execution/policy/ReservationExection.java @@ -52,9 +52,6 @@ public class ReservationExection extends DurationExecution { throw new StrolchModelException("Parameter " + PARAM_RESERVED + " on bag " + BAG_PARAMETERS + " missing on " + resource.getLocator()); - // immediately lock, so that when toExecution is called, we don't have a race condition - tx().lock(resource); - BooleanParameter reservedP = resource.getParameter(BAG_PARAMETERS, PARAM_RESERVED); if (action.getType().equals(TYPE_RESERVE)) return !reservedP.getValue(); diff --git a/li.strolch.service/src/main/java/li/strolch/planning/AbstractPlanCommand.java b/li.strolch.service/src/main/java/li/strolch/planning/AbstractPlanCommand.java index f75c1e2a0..51b68c699 100644 --- a/li.strolch.service/src/main/java/li/strolch/planning/AbstractPlanCommand.java +++ b/li.strolch.service/src/main/java/li/strolch/planning/AbstractPlanCommand.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Map.Entry; import li.strolch.agent.api.ComponentContainer; -import li.strolch.exception.StrolchException; import li.strolch.model.Locator; import li.strolch.model.Resource; import li.strolch.model.State; @@ -56,16 +55,12 @@ public abstract class AbstractPlanCommand extends Command { @SuppressWarnings({ "unchecked", "rawtypes" }) protected void plan(Action action) { - Locator locator = Locator.newBuilder(Tags.RESOURCE, action.getResourceType(), action.getResourceId()) - .build(); + Locator locator = Locator.newBuilder(Tags.RESOURCE, action.getResourceType(), action.getResourceId()).build(); + + tx().lock(locator); + Resource resource = tx().findElement(locator); - if (resource == null) - throw new StrolchException("Resource with " + locator + " referenced by " + action.getLocator() - + " cannot be null!"); - - tx().lock(resource); - List>> changes = action.getChanges(); for (IValueChange change : changes) { StrolchTimedState timedState = resource.getTimedState(change.getStateId()); @@ -80,7 +75,7 @@ public abstract class AbstractPlanCommand extends Command { * {@link IActivityElement} class. */ protected void plan(Activity activity) { - + // TODO Martin: Use a visitor pattern so we don't start with instanceof again... Iterator> elementIterator = activity.elementIterator(); @@ -97,8 +92,7 @@ public abstract class AbstractPlanCommand extends Command { @SuppressWarnings({ "unchecked", "rawtypes" }) protected void unplan(Action action) { - Locator locator = Locator.newBuilder(Tags.RESOURCE, action.getResourceType(), action.getResourceId()) - .build(); + Locator locator = Locator.newBuilder(Tags.RESOURCE, action.getResourceType(), action.getResourceId()).build(); Resource resource = tx().findElement(locator); List>> changes = action.getChanges(); diff --git a/li.strolch.service/src/main/java/li/strolch/planning/PlanActivityCommand.java b/li.strolch.service/src/main/java/li/strolch/planning/PlanActivityCommand.java index 939aa39d7..852e32fed 100644 --- a/li.strolch.service/src/main/java/li/strolch/planning/PlanActivityCommand.java +++ b/li.strolch.service/src/main/java/li/strolch/planning/PlanActivityCommand.java @@ -30,13 +30,11 @@ import li.strolch.service.api.Command; import li.strolch.utils.dbc.DBC; /** - * Command to plan an {@link Activity} to a {@link Resource}. This - * {@link Command} assumes that the {@link IValueChange} objects of the action - * are already constructed and {@link Action#resourceId} is set. + * Command to plan an {@link Activity} to a {@link Resource}. This {@link Command} assumes that the {@link IValueChange} + * objects of the action are already constructed and {@link Action#resourceId} is set. *

    - * It iterates the {@link IValueChange} operators and registers the resulting - * changes on the {@link StrolchTimedState} objects assigned to the - * {@link Resource}. + * It iterates the {@link IValueChange} operators and registers the resulting changes on the {@link StrolchTimedState} + * objects assigned to the {@link Resource}. * * @author Martin Smock */ @@ -76,14 +74,13 @@ public class PlanActivityCommand extends AbstractPlanCommand { @Override public void doCommand() { - validate(); tx().lock(activity); + validate(); plan(activity); } @Override public void undo() { - tx().lock(activity); unplan(activity); }