[Fix] Fixed locator finding for Activity and Action

This commit is contained in:
Robert von Burg 2016-09-23 13:29:02 +02:00
parent c4748403d8
commit d86e23b58f
9 changed files with 235 additions and 69 deletions

View File

@ -19,6 +19,7 @@ import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Set; import java.util.Set;
@ -50,6 +51,7 @@ import li.strolch.model.StrolchElement;
import li.strolch.model.StrolchRootElement; import li.strolch.model.StrolchRootElement;
import li.strolch.model.Tags; import li.strolch.model.Tags;
import li.strolch.model.activity.Activity; import li.strolch.model.activity.Activity;
import li.strolch.model.activity.IActivityElement;
import li.strolch.model.audit.AccessType; import li.strolch.model.audit.AccessType;
import li.strolch.model.audit.Audit; import li.strolch.model.audit.Audit;
import li.strolch.model.audit.AuditQuery; import li.strolch.model.audit.AuditQuery;
@ -368,8 +370,8 @@ public abstract class AbstractTransaction implements StrolchTransaction {
return (T) groupedParameterizedElement; return (T) groupedParameterizedElement;
// state or bag // state or bag
String stateOrBag = elements.get(3); String stateOrBagOrActivity = elements.get(3);
if (stateOrBag.equals(Tags.BAG)) { if (stateOrBagOrActivity.equals(Tags.BAG)) {
String parameterBagId = elements.get(4); String parameterBagId = elements.get(4);
ParameterBag bag = groupedParameterizedElement.getParameterBag(parameterBagId); ParameterBag bag = groupedParameterizedElement.getParameterBag(parameterBagId);
@ -386,7 +388,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
Parameter<?> parameter = bag.getParameter(parameterId); Parameter<?> parameter = bag.getParameter(parameterId);
return (T) parameter; return (T) parameter;
} else if (stateOrBag.equals(Tags.STATE)) { } else if (stateOrBagOrActivity.equals(Tags.STATE)) {
if (elements.size() != 5) { if (elements.size() != 5) {
String msg = "Missing state Id on locator {0}"; //$NON-NLS-1$ String msg = "Missing state Id on locator {0}"; //$NON-NLS-1$
@ -398,10 +400,29 @@ public abstract class AbstractTransaction implements StrolchTransaction {
StrolchTimedState<IValue<?>> timedState = resource.getTimedState(stateId); StrolchTimedState<IValue<?>> timedState = resource.getTimedState(stateId);
return (T) timedState; return (T) timedState;
} else if (groupedParameterizedElement instanceof Activity) {
Activity activity = (Activity) groupedParameterizedElement;
Iterator<String> iter = elements.subList(3, elements.size()).iterator();
IActivityElement element = activity;
while (iter.hasNext()) {
String next = iter.next();
if (!(element instanceof Activity)) {
String msg = "Invalid locator {0} with part {1} as not an Activity but deeper element specified"; //$NON-NLS-1$
throw new StrolchException(MessageFormat.format(msg, locator, next));
}
element = ((Activity) element).getElement(next);
}
return (T) element;
} }
String msg = "Invalid locator {0} on with part {1}"; //$NON-NLS-1$ String msg = "Invalid locator {0} with part {1}"; //$NON-NLS-1$
throw new StrolchException(MessageFormat.format(msg, locator, stateOrBag)); throw new StrolchException(MessageFormat.format(msg, locator, stateOrBagOrActivity));
} }
@Override @Override

View File

@ -15,13 +15,19 @@
*/ */
package li.strolch.policy; package li.strolch.policy;
import static li.strolch.utils.helper.StringHelper.DASH;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.ComponentContainer;
import li.strolch.agent.api.StrolchComponent; import li.strolch.agent.api.StrolchComponent;
import li.strolch.exception.StrolchException;
import li.strolch.model.Resource;
import li.strolch.model.activity.Action;
import li.strolch.persistence.api.StrolchTransaction; import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.service.api.Command; import li.strolch.service.api.Command;
import li.strolch.utils.helper.StringHelper;
/** /**
* Interface for all Strolch policies, which are instantiated by the {@link PolicyHandler} * Interface for all Strolch policies, which are instantiated by the {@link PolicyHandler}
@ -79,6 +85,31 @@ public abstract class StrolchPolicy {
return this.tx; return this.tx;
} }
/**
* Return the defined {@link Resource} on the given {@link Action}
*
* @param action
* the action for which to get the {@link Resource}
*
* @return the {@link Resource}
*
* @throws IllegalArgumentException
* if the resource is not defined on the action, i.e. fields are empty or a dash
* @throws StrolchException
* if the resource does not exist, which is referenced by the action
*/
protected Resource getResource(Action action) throws IllegalArgumentException, StrolchException {
String resourceId = action.getResourceId();
if (StringHelper.isEmpty(resourceId) || resourceId.equals(DASH))
throw new IllegalArgumentException("No resourceId defined on action " + action.getLocator());
String resourceType = action.getResourceType();
if (StringHelper.isEmpty(resourceType) || resourceType.equals(DASH))
throw new IllegalArgumentException("No resourceType defined on action " + action.getLocator());
Resource resource = this.tx.getResourceBy(resourceType, resourceId, true);
return resource;
}
/** /**
* @see Command#undo() * @see Command#undo()
*/ */

View File

@ -160,6 +160,10 @@ public class RuntimeMock implements AutoCloseable {
return this; return this;
} }
public void run(StrolchRunnable runnable) {
runnable.run(getAgent());
}
@Override @Override
public void close() throws RuntimeException { public void close() throws RuntimeException {
destroyRuntime(); destroyRuntime();
@ -180,8 +184,7 @@ public class RuntimeMock implements AutoCloseable {
try (RuntimeMock runtimeMock = new RuntimeMock(targetPath, srcPath)) { try (RuntimeMock runtimeMock = new RuntimeMock(targetPath, srcPath)) {
runtimeMock.mockRuntime(); runtimeMock.mockRuntime();
runtimeMock.startContainer(); runtimeMock.startContainer();
runtimeMock.run(runnable);
runnable.run(runtimeMock.getAgent());
} }
} }

View File

@ -15,18 +15,20 @@
*/ */
package li.strolch.runtime.query.inmemory; package li.strolch.runtime.query.inmemory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import li.strolch.RuntimeMock; import li.strolch.RuntimeMock;
import li.strolch.agent.ComponentContainerTest; import li.strolch.agent.ComponentContainerTest;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.agent.api.StrolchAgent;
import li.strolch.model.Locator; import li.strolch.model.Locator;
import li.strolch.model.Order; import li.strolch.model.Order;
import li.strolch.model.ParameterBag; import li.strolch.model.ParameterBag;
import li.strolch.model.Resource; import li.strolch.model.Resource;
import li.strolch.model.activity.Action;
import li.strolch.model.activity.Activity;
import li.strolch.model.parameter.FloatParameter; import li.strolch.model.parameter.FloatParameter;
import li.strolch.model.parameter.StringParameter; import li.strolch.model.parameter.StringParameter;
import li.strolch.model.timedstate.IntegerTimedState; import li.strolch.model.timedstate.IntegerTimedState;
@ -42,53 +44,125 @@ public class FindByLocatorTest {
private static final String PATH_FIND_BY_LOCATOR_RUNTIME = "target/FindByLocatorTest/"; private static final String PATH_FIND_BY_LOCATOR_RUNTIME = "target/FindByLocatorTest/";
@Test private static RuntimeMock runtimeMock;
public void shouldFindByLocator() { private static Certificate certificate;
RuntimeMock.runInStrolch(PATH_FIND_BY_LOCATOR_RUNTIME, ComponentContainerTest.PATH_TRANSIENT_CONTAINER,
agent -> doLocatorTest(agent)); @BeforeClass
public static void beforeClass() {
runtimeMock = new RuntimeMock(PATH_FIND_BY_LOCATOR_RUNTIME, ComponentContainerTest.PATH_TRANSIENT_CONTAINER);
runtimeMock.mockRuntime();
runtimeMock.startContainer();
certificate = runtimeMock.getPrivilegeHandler().authenticate("test", "test".getBytes());
} }
private void doLocatorTest(StrolchAgent agent) { @Test
ComponentContainer container = agent.getContainer(); public void shouldFindByResource() {
runtimeMock.run(agent -> {
try (StrolchTransaction tx = agent.getContainer().getRealm(StrolchConstants.DEFAULT_REALM)
.openTx(certificate, "test")) {
Certificate certificate = container.getPrivilegeHandler().authenticate("test", "test".getBytes()); // Resource
Locator locResource = Locator.valueOf("Resource/TestType/MyTestResource");
Resource resource = tx.findElement(locResource);
assertNotNull("Should have found a FloatParameter with the locator " + locResource, resource);
try (StrolchTransaction tx = container.getRealm(StrolchConstants.DEFAULT_REALM).openTx(certificate, "test")) { // Bag on Resource
Locator locResBag = Locator.valueOf("Resource/TestType/MyTestResource/Bag/@bag01");
ParameterBag resBag = tx.findElement(locResBag);
assertNotNull("Should have found a ParameterBag with the locator " + locResBag, resBag);
// Resource // Parameter on Resource
Locator locResource = Locator.valueOf("Resource/TestType/MyTestResource"); Locator locResStringParam = Locator.valueOf("Resource/TestType/MyTestResource/Bag/@bag01/@param5");
Resource resource = tx.findElement(locResource); StringParameter resStringParam = tx.findElement(locResStringParam);
assertNotNull("Should have found a FloatParameter with the locator " + locResource, resource); assertNotNull("Should have found a StringParameter with the locator " + locResStringParam,
resStringParam);
// Order // TimedState on Resource
Locator locOrder = Locator.valueOf("Order/TestType/MyTestOrder"); Locator locResIntegerState = Locator.valueOf("Resource/TestType/MyTestResource/State/@integerState");
Order order = tx.findElement(locOrder); IntegerTimedState integerS = tx.findElement(locResIntegerState);
assertNotNull("Should have found an Order with the locator " + locOrder, order); assertNotNull("Should have found a IntegerTimedState with the locator " + locResIntegerState, integerS);
// Bag on Resource }
Locator locResBag = Locator.valueOf("Resource/TestType/MyTestResource/Bag/@bag01"); });
ParameterBag resBag = tx.findElement(locResBag); }
assertNotNull("Should have found a ParameterBag with the locator " + locResBag, resBag);
// Bag on Order @Test
Locator locOrdBag = Locator.valueOf("Order/TestType/MyTestOrder/Bag/@bag01"); public void shouldFindByOrder() {
ParameterBag ordBag = tx.findElement(locOrdBag); runtimeMock.run(agent -> {
assertNotNull("Should have found a ParameterBag with the locator " + ordBag, locOrdBag); try (StrolchTransaction tx = agent.getContainer().getRealm(StrolchConstants.DEFAULT_REALM)
.openTx(certificate, "test")) {
// Parameter on Resource // Order
Locator locResStringParam = Locator.valueOf("Resource/TestType/MyTestResource/Bag/@bag01/@param5"); Locator locOrder = Locator.valueOf("Order/TestType/MyTestOrder");
StringParameter resStringParam = tx.findElement(locResStringParam); Order order = tx.findElement(locOrder);
assertNotNull("Should have found a StringParameter with the locator " + locResStringParam, resStringParam); assertNotNull("Should have found an Order with the locator " + locOrder, order);
// Parameter on Order // Bag on Order
Locator locOrderFloatParam = Locator.valueOf("Order/TestType/MyTestOrder/Bag/@bag01/@param2"); Locator locOrdBag = Locator.valueOf("Order/TestType/MyTestOrder/Bag/@bag01");
FloatParameter orderFloatP = tx.findElement(locOrderFloatParam); ParameterBag ordBag = tx.findElement(locOrdBag);
assertNotNull("Should have found a FloatParameter with the locator " + locOrderFloatParam, orderFloatP); assertNotNull("Should have found a ParameterBag with the locator " + ordBag, locOrdBag);
// TimedState on Resource // Parameter on Order
Locator locResIntegerState = Locator.valueOf("Resource/TestType/MyTestResource/State/@integerState"); Locator locOrderFloatParam = Locator.valueOf("Order/TestType/MyTestOrder/Bag/@bag01/@param2");
IntegerTimedState integerS = tx.findElement(locResIntegerState); FloatParameter orderFloatP = tx.findElement(locOrderFloatParam);
assertNotNull("Should have found a IntegerTimedState with the locator " + locResIntegerState, integerS); assertNotNull("Should have found a FloatParameter with the locator " + locOrderFloatParam, orderFloatP);
}
}
});
}
@Test
public void shouldFindByActivity() {
runtimeMock.run(agent -> {
try (StrolchTransaction tx = agent.getContainer().getRealm(StrolchConstants.DEFAULT_REALM)
.openTx(certificate, "test")) {
// Activity
Locator locActivity = Locator.valueOf("Activity/ActivityType/activity_1");
Activity activity = tx.findElement(locActivity);
assertNotNull("Should have found Activity with id activity_1", activity);
assertEquals("activity_1", activity.getId());
assertEquals(locActivity.toString(), activity.getLocator().toString());
// sub activity
Locator locAction = Locator.valueOf("Activity/ActivityType/activity_1/child_activity");
activity = tx.findElement(locAction);
assertNotNull("Should have found sub Activity with id child_activity", activity);
assertEquals("child_activity", activity.getId());
assertEquals(locAction.toString(), activity.getLocator().toString());
}
});
}
@Test
public void shouldFindByAction() {
runtimeMock.run(agent -> {
try (StrolchTransaction tx = agent.getContainer().getRealm(StrolchConstants.DEFAULT_REALM)
.openTx(certificate, "test")) {
// sub action
Locator locAction = Locator.valueOf("Activity/ActivityType/activity_1/action_1");
Action action = tx.findElement(locAction);
assertNotNull("Should have found Action with id action_1 on Activity activity_1", action);
assertEquals("action_1", action.getId());
assertEquals(locAction.toString(), action.getLocator().toString());
// sub sub action
locAction = Locator.valueOf("Activity/ActivityType/activity_1/child_activity/action_2");
action = tx.findElement(locAction);
assertNotNull("Should have found sub Activity with id child_activity", action);
assertEquals("action_2", action.getId());
assertEquals(locAction.toString(), action.getLocator().toString());
// sub sub action
locAction = Locator.valueOf("Activity/ActivityType/activity_1/child_activity/action_3");
action = tx.findElement(locAction);
assertNotNull("Should have found sub Activity with id child_activity", action);
assertEquals("action_3", action.getId());
assertEquals(locAction.toString(), action.getLocator().toString());
}
});
} }
} }

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<StrolchModel>
<Activity Id="activity_1" Name="Activity" Type="ActivityType" TimeOrdering="Series">
<Policies>
<Policy Type="PlanningPolicy" Value="key:SimplePlanning" />
<Policy Type="ConfirmationPolicy" Value="key:NoConfirmation" />
</Policies>
<Action Id="action_1" Name="Action 1" ResourceId="dummyId" ResourceType="dummyType" State="Created" Type="Use">
<Policies>
<Policy Type="PlanningPolicy" Value="key:SimplePlanning" />
<Policy Type="ConfirmationPolicy" Value="key:NoConfirmation" />
</Policies>
<ValueChange StateId="dummyId" Time="2012-11-30T18:12:05.628+01:00" Value="5" Type="Integer" />
</Action>
<Activity Id="child_activity" Name="Child Activity" Type="childType" TimeOrdering="Series">
<Policies>
<Policy Type="PlanningPolicy" Value="key:SimplePlanning" />
<Policy Type="ConfirmationPolicy" Value="key:NoConfirmation" />
</Policies>
<Action Id="action_2" Name="Action 2" ResourceId="dummyId" ResourceType="dummyType" State="Planned" Type="Use" />
<Action Id="action_3" Name="Action 3" ResourceId="dummyId" ResourceType="dummyType" State="Created" Type="Use" />
</Activity>
</Activity>
</StrolchModel>

View File

@ -26,5 +26,6 @@
<IncludeFile file="Enums.xml" /> <IncludeFile file="Enums.xml" />
<IncludeFile file="Resources.xml" /> <IncludeFile file="Resources.xml" />
<IncludeFile file="Orders.xml" /> <IncludeFile file="Orders.xml" />
<IncludeFile file="Activities.xml" />
</StrolchModel> </StrolchModel>

View File

@ -65,9 +65,12 @@ public class Activity extends GroupedParameterizedElement
/** /**
* Default constructor * Default constructor
* *
* @param id the id * @param id
* @param name the name * the id
* @param type the type * @param name
* the name
* @param type
* the type
*/ */
public Activity(String id, String name, String type, TimeOrdering timeOrdering) { public Activity(String id, String name, String type, TimeOrdering timeOrdering) {
super(id, name, type); super(id, name, type);
@ -261,7 +264,11 @@ public class Activity extends GroupedParameterizedElement
@Override @Override
protected void fillLocator(LocatorBuilder locatorBuilder) { protected void fillLocator(LocatorBuilder locatorBuilder) {
locatorBuilder.append(Tags.ACTIVITY).append(getType()).append(getId()); if (this.parent != null)
this.parent.fillLocator(locatorBuilder);
else
locatorBuilder.append(Tags.ACTIVITY).append(getType());
locatorBuilder.append(getId());
} }
@Override @Override

View File

@ -16,6 +16,7 @@
package li.strolch.model.policy; package li.strolch.model.policy;
import li.strolch.exception.StrolchPolicyException; import li.strolch.exception.StrolchPolicyException;
import li.strolch.utils.helper.StringHelper;
/** /**
* <p> * <p>
@ -116,6 +117,8 @@ public abstract class PolicyDef {
if (xmlValue.startsWith(JavaPolicyDef.XML_PREFIX)) { if (xmlValue.startsWith(JavaPolicyDef.XML_PREFIX)) {
String value = xmlValue.substring(JavaPolicyDef.XML_PREFIX.length()); String value = xmlValue.substring(JavaPolicyDef.XML_PREFIX.length());
if (StringHelper.isEmpty(value))
throw new StrolchPolicyException("Invalid policy configuration. Policy value is empty for " + type);
try { try {
Class.forName(value); Class.forName(value);

View File

@ -43,7 +43,7 @@ public abstract class AbstractPlanCommand extends Command {
* @param container * @param container
* @param tx * @param tx
*/ */
public AbstractPlanCommand(final ComponentContainer container, final StrolchTransaction tx) { public AbstractPlanCommand(ComponentContainer container, StrolchTransaction tx) {
super(container, tx); super(container, tx);
} }
@ -54,11 +54,11 @@ public abstract class AbstractPlanCommand extends Command {
* @param action * @param action
*/ */
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
protected void plan(final Action action) { protected void plan(Action action) {
final Locator locator = Locator.newBuilder(Tags.RESOURCE, action.getResourceType(), action.getResourceId()) Locator locator = Locator.newBuilder(Tags.RESOURCE, action.getResourceType(), action.getResourceId())
.build(); .build();
final Resource resource = tx().findElement(locator); Resource resource = tx().findElement(locator);
if (resource == null) if (resource == null)
throw new StrolchException("Resource with " + locator + " referenced by " + action.getLocator() throw new StrolchException("Resource with " + locator + " referenced by " + action.getLocator()
@ -66,9 +66,9 @@ public abstract class AbstractPlanCommand extends Command {
tx().lock(resource); tx().lock(resource);
final List<IValueChange<? extends IValue<?>>> changes = action.getChanges(); List<IValueChange<? extends IValue<?>>> changes = action.getChanges();
for (final IValueChange<?> change : changes) { for (IValueChange<?> change : changes) {
final StrolchTimedState timedState = resource.getTimedState(change.getStateId()); StrolchTimedState timedState = resource.getTimedState(change.getStateId());
timedState.applyChange(change); timedState.applyChange(change);
} }
@ -79,14 +79,14 @@ public abstract class AbstractPlanCommand extends Command {
* plan an {@link Activity} by navigating to the {#link Action} and delegating the planning depending on the * plan an {@link Activity} by navigating to the {#link Action} and delegating the planning depending on the
* {@link IActivityElement} class. * {@link IActivityElement} class.
*/ */
protected void plan(final Activity activity) { protected void plan(Activity activity) {
// TODO Martin: Use a visitor pattern so we don't start with instanceof again... // TODO Martin: Use a visitor pattern so we don't start with instanceof again...
final Iterator<Entry<String, IActivityElement>> elementIterator = activity.elementIterator(); Iterator<Entry<String, IActivityElement>> elementIterator = activity.elementIterator();
while (elementIterator.hasNext()) { while (elementIterator.hasNext()) {
final IActivityElement activityElement = elementIterator.next().getValue(); IActivityElement activityElement = elementIterator.next().getValue();
if (activityElement instanceof Activity) if (activityElement instanceof Activity)
plan((Activity) activityElement); plan((Activity) activityElement);
else if (activityElement instanceof Action) else if (activityElement instanceof Action)
@ -95,27 +95,27 @@ public abstract class AbstractPlanCommand extends Command {
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
protected void unplan(final Action action) { protected void unplan(Action action) {
final Locator locator = Locator.newBuilder(Tags.RESOURCE, action.getResourceType(), action.getResourceId()) Locator locator = Locator.newBuilder(Tags.RESOURCE, action.getResourceType(), action.getResourceId())
.build(); .build();
final Resource resource = tx().findElement(locator); Resource resource = tx().findElement(locator);
final List<IValueChange<? extends IValue<?>>> changes = action.getChanges(); List<IValueChange<? extends IValue<?>>> changes = action.getChanges();
for (final IValueChange<?> change : changes) { for (IValueChange<?> change : changes) {
final StrolchTimedState timedState = resource.getTimedState(change.getStateId()); StrolchTimedState timedState = resource.getTimedState(change.getStateId());
timedState.applyChange(change.getInverse()); timedState.applyChange(change.getInverse());
} }
action.setState(State.CREATED); action.setState(State.CREATED);
} }
protected void unplan(final Activity activity) { protected void unplan(Activity activity) {
final Iterator<Entry<String, IActivityElement>> elementIterator = activity.elementIterator(); Iterator<Entry<String, IActivityElement>> elementIterator = activity.elementIterator();
while (elementIterator.hasNext()) { while (elementIterator.hasNext()) {
final IActivityElement activityElement = elementIterator.next().getValue(); IActivityElement activityElement = elementIterator.next().getValue();
if (activityElement instanceof Activity) if (activityElement instanceof Activity)
unplan((Activity) activityElement); unplan((Activity) activityElement);