ACS-3229: Rules v1 REST API - Get rule definition - mapping of conditions (#1252)

ACS-3229: Rules v1 REST API - Get rule definition
- adding mapping of "conditions"
- fixing trigger constants - uppercase -> lowercase
- fixing booleanMode - uppercase -> lowercase
This commit is contained in:
krdabrowski
2022-08-02 14:10:52 +02:00
committed by GitHub
parent f1c588f1da
commit 8a79d3bed1
10 changed files with 1146 additions and 7 deletions

View File

@@ -0,0 +1,230 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.model.rules;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.ActionCondition;
import org.apache.commons.collections.CollectionUtils;
@Experimental
public class CompositeCondition
{
private boolean inverted;
private ConditionOperator booleanMode = ConditionOperator.AND;
private List<CompositeCondition> compositeConditions;
private List<SimpleCondition> simpleConditions;
/**
* Converts Action conditions (service POJO) list to composite condition (REST model).
*
* @param actionConditions - list of {@link ActionCondition} service POJOs
* @return {@link CompositeCondition} REST model
*/
public static CompositeCondition from(final List<ActionCondition> actionConditions)
{
if (actionConditions == null)
{
return null;
}
final CompositeCondition conditions = new CompositeCondition();
conditions.compositeConditions = new ArrayList<>();
// group action conditions by inversion flag
actionConditions.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(ActionCondition::getInvertCondition))
// map action condition sub lists
.forEach((inverted, actionConditionsPart) -> Optional.ofNullable(CompositeCondition.ofActionConditions(actionConditionsPart, inverted, ConditionOperator.AND))
// if composite condition present add to final list
.ifPresent(compositeCondition -> conditions.compositeConditions.add(compositeCondition)));
if (conditions.compositeConditions.isEmpty()) {
conditions.compositeConditions = null;
}
return conditions;
}
private static CompositeCondition ofActionConditions(final List<ActionCondition> actionConditions, final boolean inverted, final ConditionOperator conditionOperator)
{
if (actionConditions == null)
{
return null;
}
return ofSimpleConditions(SimpleCondition.listOf(actionConditions), inverted, conditionOperator);
}
/**
* Creates a composite condition instance of simple conditions.
*
* @param simpleConditions - list of {@link SimpleCondition}
* @param inverted - determines if condition should be inverted
* @param conditionOperator - determines the operation, see {@link ConditionOperator}
* @return {@link CompositeCondition}
*/
public static CompositeCondition ofSimpleConditions(final List<SimpleCondition> simpleConditions, final boolean inverted, final ConditionOperator conditionOperator)
{
return of(simpleConditions, null, inverted, conditionOperator);
}
private static CompositeCondition of(final List<SimpleCondition> simpleConditions, final List<CompositeCondition> compositeConditions,
final boolean inverted, final ConditionOperator conditionOperator)
{
if (CollectionUtils.isEmpty(simpleConditions) && CollectionUtils.isEmpty(compositeConditions))
{
return null;
}
return builder()
.inverted(inverted)
.booleanMode(conditionOperator)
.simpleConditions(simpleConditions)
.compositeConditions(compositeConditions)
.create();
}
public boolean isInverted()
{
return inverted;
}
public void setInverted(boolean inverted)
{
this.inverted = inverted;
}
public String getBooleanMode()
{
if (booleanMode == null)
{
return null;
}
return booleanMode.name().toLowerCase();
}
public void setBooleanMode(ConditionOperator booleanMode)
{
this.booleanMode = booleanMode;
}
public List<CompositeCondition> getCompositeConditions()
{
return compositeConditions;
}
public void setCompositeConditions(List<CompositeCondition> compositeConditions)
{
this.compositeConditions = compositeConditions;
}
public List<SimpleCondition> getSimpleConditions()
{
return simpleConditions;
}
public void setSimpleConditions(List<SimpleCondition> simpleConditions)
{
this.simpleConditions = simpleConditions;
}
@Override
public String toString()
{
return "CompositeCondition{" + "inverted=" + inverted + ", booleanMode=" + booleanMode + ", compositeConditions=" + compositeConditions + ", simpleConditions="
+ simpleConditions + '}';
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
CompositeCondition that = (CompositeCondition) o;
return inverted == that.inverted && booleanMode == that.booleanMode && Objects.equals(compositeConditions, that.compositeConditions) && Objects.equals(
simpleConditions, that.simpleConditions);
}
@Override
public int hashCode()
{
return Objects.hash(inverted, booleanMode, compositeConditions, simpleConditions);
}
public static Builder builder()
{
return new Builder();
}
public static class Builder
{
private boolean inverted;
private ConditionOperator booleanMode = ConditionOperator.AND;
private List<CompositeCondition> compositeConditions;
private List<SimpleCondition> simpleConditions;
public Builder inverted(boolean inverted)
{
this.inverted = inverted;
return this;
}
public Builder booleanMode(ConditionOperator booleanMode)
{
this.booleanMode = booleanMode;
return this;
}
public Builder compositeConditions(List<CompositeCondition> compositeConditions)
{
this.compositeConditions = compositeConditions;
return this;
}
public Builder simpleConditions(List<SimpleCondition> simpleConditions)
{
this.simpleConditions = simpleConditions;
return this;
}
public CompositeCondition create()
{
final CompositeCondition condition = new CompositeCondition();
condition.setInverted(inverted);
condition.setBooleanMode(booleanMode);
condition.setCompositeConditions(compositeConditions);
condition.setSimpleConditions(simpleConditions);
return condition;
}
}
}

View File

@@ -0,0 +1,35 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.model.rules;
import org.alfresco.service.Experimental;
@Experimental
public enum ConditionOperator
{
AND, OR
}

View File

@@ -49,6 +49,7 @@ public class Rule
private boolean shared;
private String errorScript;
private List<RuleTrigger> triggers;
private CompositeCondition conditions;
private List<Action> actions;
/**
@@ -81,6 +82,7 @@ public class Rule
}
if (ruleModel.getAction() != null)
{
builder.conditions(CompositeCondition.from(ruleModel.getAction().getActionConditions()));
if (ruleModel.getAction().getCompensatingAction() != null && ruleModel.getAction().getCompensatingAction().getParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF) != null)
{
builder.errorScript(ruleModel.getAction().getCompensatingAction().getParameterValue(ScriptActionExecuter.PARAM_SCRIPTREF).toString());
@@ -193,9 +195,13 @@ public class Rule
this.shared = shared;
}
public List<RuleTrigger> getTriggers()
public List<String> getTriggers()
{
return triggers;
if (triggers == null)
{
return null;
}
return triggers.stream().map(RuleTrigger::getValue).collect(Collectors.toList());
}
public void setTriggers(List<RuleTrigger> triggers)
@@ -203,6 +209,16 @@ public class Rule
this.triggers = triggers;
}
public CompositeCondition getConditions()
{
return conditions;
}
public void setConditions(CompositeCondition conditions)
{
this.conditions = conditions;
}
public List<Action> getActions()
{
return actions;
@@ -217,7 +233,8 @@ public class Rule
public String toString()
{
return "Rule{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", description='" + description + '\'' + ", enabled=" + enabled + ", cascade=" + cascade
+ ", asynchronous=" + asynchronous + ", shared=" + shared + ", errorScript='" + errorScript + '\'' + ", triggers=" + triggers + ", actions=" + actions + '}';
+ ", asynchronous=" + asynchronous + ", shared=" + shared + ", errorScript='" + errorScript + '\'' + ", triggers=" + triggers + ", conditions=" + conditions
+ ", actions=" + actions + '}';
}
@Override
@@ -230,13 +247,13 @@ public class Rule
Rule rule = (Rule) o;
return enabled == rule.enabled && cascade == rule.cascade && asynchronous == rule.asynchronous && shared == rule.shared && Objects.equals(id, rule.id) && Objects.equals(
name, rule.name) && Objects.equals(description, rule.description) && Objects.equals(errorScript, rule.errorScript) && Objects.equals(triggers, rule.triggers)
&& Objects.equals(actions, rule.actions);
&& Objects.equals(conditions, rule.conditions) && Objects.equals(actions, rule.actions);
}
@Override
public int hashCode()
{
return Objects.hash(id, name, description, enabled, cascade, asynchronous, shared, errorScript, triggers, actions);
return Objects.hash(id, name, description, enabled, cascade, asynchronous, shared, errorScript, triggers, conditions, actions);
}
public static Builder builder()
@@ -256,6 +273,7 @@ public class Rule
private boolean shared;
private String errorScript;
private List<RuleTrigger> triggers;
private CompositeCondition conditions;
private List<Action> actions;
public Builder id(String id)
@@ -312,6 +330,12 @@ public class Rule
return this;
}
public Builder conditions(CompositeCondition conditions)
{
this.conditions = conditions;
return this;
}
public Builder actions(List<Action> actions)
{
this.actions = actions;
@@ -330,6 +354,7 @@ public class Rule
rule.setShared(shared);
rule.setErrorScript(errorScript);
rule.setTriggers(triggers);
rule.setConditions(conditions);
rule.setActions(actions);
return rule;
}

View File

@@ -0,0 +1,277 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.model.rules;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.alfresco.repo.action.evaluator.CompareMimeTypeEvaluator;
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
import org.alfresco.repo.action.evaluator.HasAspectEvaluator;
import org.alfresco.repo.action.evaluator.HasChildEvaluator;
import org.alfresco.repo.action.evaluator.HasTagEvaluator;
import org.alfresco.repo.action.evaluator.HasVersionHistoryEvaluator;
import org.alfresco.repo.action.evaluator.InCategoryEvaluator;
import org.alfresco.repo.action.evaluator.IsSubTypeEvaluator;
import org.alfresco.repo.action.evaluator.NoConditionEvaluator;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.ActionCondition;
import org.apache.commons.collections.CollectionUtils;
@Experimental
public class SimpleCondition
{
private static final String COMPARATOR_EQUALS = "equals";
private String field;
private String comparator;
private String parameter;
/**
* Converts list of service POJO action conditions to list of REST model simple conditions.
*
* @param actionConditions - list of {@link ActionCondition} service POJOs
* @return list of {@link SimpleCondition} REST models
*/
public static List<SimpleCondition> listOf(final List<ActionCondition> actionConditions)
{
if (CollectionUtils.isEmpty(actionConditions))
{
return null;
}
return actionConditions.stream()
.map(SimpleCondition::from)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
/**
* Creates simple condition REST model instance from service POJO action condition.
*
* @param actionCondition - {@link ActionCondition} service POJO
* @return {@link SimpleCondition} REST model
*/
public static SimpleCondition from(final ActionCondition actionCondition)
{
if (actionCondition == null || actionCondition.getActionConditionDefinitionName() == null || actionCondition.getParameterValues() == null)
{
return null;
}
switch (actionCondition.getActionConditionDefinitionName())
{
case ComparePropertyValueEvaluator.NAME:
return createComparePropertyValueCondition(actionCondition);
case CompareMimeTypeEvaluator.NAME:
return createCompareMimeTypeCondition(actionCondition);
case HasAspectEvaluator.NAME:
return createHasAspectCondition(actionCondition);
case HasChildEvaluator.NAME:
return createHasChildCondition(actionCondition);
case HasTagEvaluator.NAME:
return createHasTagCondition(actionCondition);
case HasVersionHistoryEvaluator.NAME:
return createHasVersionHistoryCondition(actionCondition);
case InCategoryEvaluator.NAME:
return createInCategoryCondition(actionCondition);
case IsSubTypeEvaluator.NAME:
return createIsSubtypeCondition(actionCondition);
case NoConditionEvaluator.NAME:
default:
return null;
}
}
public String getField()
{
return field;
}
public void setField(String field)
{
this.field = field;
}
public String getComparator()
{
return comparator;
}
public void setComparator(String comparator)
{
this.comparator = comparator;
}
public String getParameter()
{
return parameter;
}
public void setParameter(String parameter)
{
this.parameter = parameter;
}
@Override
public String toString()
{
return "SimpleCondition{" + "field='" + field + '\'' + ", comparator='" + comparator + '\'' + ", parameter='" + parameter + '\'' + '}';
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
SimpleCondition that = (SimpleCondition) o;
return Objects.equals(field, that.field) && Objects.equals(comparator, that.comparator) && Objects.equals(parameter, that.parameter);
}
@Override
public int hashCode()
{
return Objects.hash(field, comparator, parameter);
}
private static SimpleCondition createComparePropertyValueCondition(final ActionCondition actionCondition) {
final SimpleCondition.Builder builder = builder();
if (actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY) != null)
{
builder.field(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY).toString().toLowerCase());
} else {
builder.field(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_PROPERTY).toString().toLowerCase());
}
return builder
.comparator(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_OPERATION).toString().toLowerCase())
.parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString())
.create();
}
private static SimpleCondition createCompareMimeTypeCondition(final ActionCondition actionCondition) {
return builder()
.field(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_PROPERTY).toString().toLowerCase())
.comparator(COMPARATOR_EQUALS)
.parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString())
.create();
}
private static SimpleCondition createHasAspectCondition(final ActionCondition actionCondition) {
return builder()
.field(HasAspectEvaluator.PARAM_ASPECT)
.comparator(COMPARATOR_EQUALS)
.parameter(actionCondition.getParameterValues().get(HasAspectEvaluator.PARAM_ASPECT).toString())
.create();
}
private static SimpleCondition createHasChildCondition(final ActionCondition actionCondition) {
final SimpleCondition.Builder builder = builder();
if (actionCondition.getParameterValues().get(HasChildEvaluator.PARAM_ASSOC_TYPE) != null)
{
builder.field(actionCondition.getParameterValues().get(HasChildEvaluator.PARAM_ASSOC_TYPE).toString().toLowerCase());
} else {
builder.field(actionCondition.getParameterValues().get(HasChildEvaluator.PARAM_ASSOC_NAME).toString().toLowerCase());
}
return builder
.comparator(COMPARATOR_EQUALS)
.parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString())
.create();
}
private static SimpleCondition createHasTagCondition(final ActionCondition actionCondition) {
return builder()
.field(HasTagEvaluator.PARAM_TAG)
.comparator(COMPARATOR_EQUALS)
.parameter(actionCondition.getParameterValues().get(HasTagEvaluator.PARAM_TAG).toString())
.create();
}
private static SimpleCondition createHasVersionHistoryCondition(final ActionCondition actionCondition) {
return builder()
.field(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_PROPERTY).toString().toLowerCase())
.comparator(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_OPERATION).toString().toLowerCase())
.parameter(actionCondition.getParameterValues().get(ComparePropertyValueEvaluator.PARAM_VALUE).toString())
.create();
}
private static SimpleCondition createInCategoryCondition(final ActionCondition actionCondition) {
return builder()
.field(actionCondition.getParameterValues().get(InCategoryEvaluator.PARAM_CATEGORY_ASPECT).toString().toLowerCase())
.comparator(COMPARATOR_EQUALS)
.parameter(actionCondition.getParameterValues().get(InCategoryEvaluator.PARAM_CATEGORY_VALUE).toString())
.create();
}
private static SimpleCondition createIsSubtypeCondition(final ActionCondition actionCondition) {
return builder()
.field(IsSubTypeEvaluator.PARAM_TYPE)
.comparator(COMPARATOR_EQUALS)
.parameter(actionCondition.getParameterValues().get(IsSubTypeEvaluator.PARAM_TYPE).toString())
.create();
}
public static Builder builder()
{
return new Builder();
}
public static class Builder
{
private String field;
private String comparator;
private String parameter;
public Builder field(String field)
{
this.field = field;
return this;
}
public Builder comparator(String comparator)
{
this.comparator = comparator;
return this;
}
public Builder parameter(String parameter)
{
this.parameter = parameter;
return this;
}
public SimpleCondition create() {
final SimpleCondition condition = new SimpleCondition();
condition.setField(field);
condition.setComparator(comparator);
condition.setParameter(parameter);
return condition;
}
}
}

View File

@@ -28,7 +28,9 @@ package org.alfresco.rest.api;
import org.alfresco.rest.api.impl.RulesImplTest;
import org.alfresco.rest.api.model.rules.ActionTest;
import org.alfresco.rest.api.model.rules.CompositeConditionTest;
import org.alfresco.rest.api.model.rules.RuleTest;
import org.alfresco.rest.api.model.rules.SimpleConditionTest;
import org.alfresco.rest.api.nodes.NodeRulesRelationTest;
import org.alfresco.service.Experimental;
import org.junit.runner.RunWith;
@@ -40,7 +42,9 @@ import org.junit.runners.Suite;
NodeRulesRelationTest.class,
RulesImplTest.class,
RuleTest.class,
ActionTest.class
ActionTest.class,
SimpleConditionTest.class,
CompositeConditionTest.class
})
public class RulesUnitTests
{

View File

@@ -49,6 +49,7 @@ import java.util.List;
import junit.framework.TestCase;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.rules.CompositeCondition;
import org.alfresco.rest.api.model.rules.Rule;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
@@ -463,10 +464,13 @@ public class RulesImplTest extends TestCase
then(ruleServiceMock).should().saveRule(folderNodeRef, serviceRuleBody);
then(ruleServiceMock).shouldHaveNoMoreInteractions();
Rule expected = Rule.builder().id(RULE_ID)
.enabled(true)
.shared(true)
.triggers(emptyList()).create();
.triggers(emptyList())
.conditions(CompositeCondition.builder().inverted(false).create())
.create();
assertThat(updatedRule).isEqualTo(expected);
}

View File

@@ -0,0 +1,180 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.model.rules;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.action.ActionConditionImpl;
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.ActionCondition;
import org.junit.Test;
@Experimental
public class CompositeConditionTest
{
@Test
public void testFrom()
{
final List<ActionCondition> actionConditions = List.of(
createActionCondition("value1"),
createActionCondition("value2", true),
createActionCondition("value3")
);
final CompositeCondition expectedCompositeCondition = createCompositeCondition(List.of(
createCompositeCondition(false, List.of(
createSimpleCondition("value1"),
createSimpleCondition("value3")
)),
createCompositeCondition(true, List.of(
createSimpleCondition("value2")
))
));
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions);
assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCompositeCondition);
}
@Test
public void testFromEmptyList()
{
final List<ActionCondition> actionConditions = Collections.emptyList();
final CompositeCondition expectedCompositeCondition = CompositeCondition.builder().create();
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions);
assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCompositeCondition);
}
@Test
public void testFromNullValue()
{
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.from(null);
assertThat(actualCompositeCondition).isNull();
}
@Test
public void testFromListContainingNull()
{
final List<ActionCondition> actionConditions = new ArrayList<>();
actionConditions.add(null);
final CompositeCondition expectedCompositeCondition = CompositeCondition.builder().create();
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.from(actionConditions);
assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCompositeCondition);
}
@Test
public void testOfSimpleConditions()
{
final List<SimpleCondition> simpleConditions = List.of(SimpleCondition.builder().field("field").comparator("comparator").parameter("param").create());
final boolean inverted = true;
final ConditionOperator conditionOperator = ConditionOperator.OR;
final CompositeCondition expectedCondition = createCompositeCondition(inverted, conditionOperator, null, simpleConditions);
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.ofSimpleConditions(simpleConditions, inverted, conditionOperator);
assertThat(actualCompositeCondition).isNotNull().usingRecursiveComparison().isEqualTo(expectedCondition);
}
@Test
public void testOfEmptySimpleConditions()
{
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.ofSimpleConditions(Collections.emptyList(), false, ConditionOperator.AND);
assertThat(actualCompositeCondition).isNull();
}
@Test
public void testOfNullSimpleConditions()
{
// when
final CompositeCondition actualCompositeCondition = CompositeCondition.ofSimpleConditions(null, false, ConditionOperator.AND);
assertThat(actualCompositeCondition).isNull();
}
private static ActionCondition createActionCondition(final String value)
{
return createActionCondition(value, false);
}
private static ActionCondition createActionCondition(final String value, final boolean inverted)
{
final ActionCondition actionCondition = new ActionConditionImpl("fake-id", ComparePropertyValueEvaluator.NAME);
actionCondition.setInvertCondition(inverted);
final Map<String, Serializable> parameterValues = new HashMap<>();
parameterValues.put(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY, "content-property");
parameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, "operation");
parameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, value);
actionCondition.setParameterValues(parameterValues);
return actionCondition;
}
private static SimpleCondition createSimpleCondition(final String value) {
return SimpleCondition.builder()
.field("content-property")
.comparator("operation")
.parameter(value)
.create();
}
private static CompositeCondition createCompositeCondition(final List<CompositeCondition> compositeConditions) {
return createCompositeCondition(false, ConditionOperator.AND, compositeConditions, null);
}
private static CompositeCondition createCompositeCondition(final boolean inverted, final List<SimpleCondition> simpleConditions) {
return createCompositeCondition(inverted, ConditionOperator.AND, null, simpleConditions);
}
private static CompositeCondition createCompositeCondition(final boolean inverted, final ConditionOperator conditionOperator,
final List<CompositeCondition> compositeConditions, final List<SimpleCondition> simpleConditions) {
return CompositeCondition.builder()
.inverted(inverted)
.booleanMode(conditionOperator)
.compositeConditions(compositeConditions)
.simpleConditions(simpleConditions)
.create();
}
}

View File

@@ -28,6 +28,7 @@ package org.alfresco.rest.api.model.rules;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Collections;
import java.util.List;
import org.alfresco.repo.action.ActionConditionImpl;
@@ -110,6 +111,7 @@ public class RuleTest
.shared(RULE_SHARED)
.triggers(List.of(RuleTrigger.INBOUND, RuleTrigger.UPDATE))
.errorScript(ERROR_SCRIPT)
.conditions(CompositeCondition.from(Collections.emptyList()))
.create();
}
}

View File

@@ -0,0 +1,213 @@
/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2022 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.model.rules;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.alfresco.repo.action.ActionConditionImpl;
import org.alfresco.repo.action.evaluator.CompareMimeTypeEvaluator;
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
import org.alfresco.repo.action.evaluator.HasAspectEvaluator;
import org.alfresco.repo.action.evaluator.HasChildEvaluator;
import org.alfresco.repo.action.evaluator.HasTagEvaluator;
import org.alfresco.repo.action.evaluator.HasVersionHistoryEvaluator;
import org.alfresco.repo.action.evaluator.InCategoryEvaluator;
import org.alfresco.repo.action.evaluator.IsSubTypeEvaluator;
import org.alfresco.repo.action.evaluator.NoConditionEvaluator;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.action.ActionCondition;
import org.junit.Test;
@Experimental
public class SimpleConditionTest
{
private static List<TestData> getTestData() {
return List.of(
TestData.of(ComparePropertyValueEvaluator.NAME),
TestData.of(CompareMimeTypeEvaluator.NAME),
TestData.of(HasAspectEvaluator.NAME),
TestData.of(HasChildEvaluator.NAME),
TestData.of(HasTagEvaluator.NAME),
TestData.of(HasVersionHistoryEvaluator.NAME),
TestData.of(InCategoryEvaluator.NAME),
TestData.of(IsSubTypeEvaluator.NAME),
TestData.of(NoConditionEvaluator.NAME, true),
TestData.of("fake-definition-name", true),
TestData.of("", true),
TestData.of(null, true)
);
}
@Test
public void testFrom()
{
for (TestData testData : getTestData())
{
final ActionCondition actionCondition = createActionCondition(testData.actionDefinitionName);
// when
final SimpleCondition actualSimpleCondition = SimpleCondition.from(actionCondition);
assertThat(Objects.isNull(actualSimpleCondition)).isEqualTo(testData.isNullResult);
if (!testData.isNullResult)
{
assertThat(actualSimpleCondition.getField()).isNotEmpty();
assertThat(actualSimpleCondition.getComparator()).isNotEmpty();
assertThat(actualSimpleCondition.getParameter()).isNotEmpty();
}
}
}
@Test
public void testFromNullValue()
{
// when
final SimpleCondition actualSimpleCondition = SimpleCondition.from(null);
assertThat(actualSimpleCondition).isNull();
}
@Test
public void testFromActionConditionWithoutDefinitionName()
{
final ActionCondition actionCondition = new ActionConditionImpl("fake-id", null, createParameterValues());
// when
final SimpleCondition actualSimpleCondition = SimpleCondition.from(actionCondition);
assertThat(actualSimpleCondition).isNull();
}
@Test
public void testFromActionConditionWithoutParameterValues()
{
final ActionCondition actionCondition = new ActionConditionImpl("fake-id", "fake-def-name", null);
// when
final SimpleCondition actualSimpleCondition = SimpleCondition.from(actionCondition);
assertThat(actualSimpleCondition).isNull();
}
@Test
public void testListOf()
{
final List<ActionCondition> actionConditions = List.of(
createActionCondition(ComparePropertyValueEvaluator.NAME),
createActionCondition(CompareMimeTypeEvaluator.NAME)
);
final List<SimpleCondition> expectedSimpleConditions = List.of(
SimpleCondition.builder().field("content-property").comparator("operation").parameter("value").create(),
SimpleCondition.builder().field("property").comparator("equals").parameter("value").create()
);
// when
final List<SimpleCondition> actualSimpleConditions = SimpleCondition.listOf(actionConditions);
assertThat(actualSimpleConditions)
.isNotNull()
.containsExactlyElementsOf(expectedSimpleConditions);
}
@Test
public void testListOfEmptyActionConditions()
{
final List<SimpleCondition> actualSimpleConditions = SimpleCondition.listOf(Collections.emptyList());
assertThat(actualSimpleConditions).isNull();
}
@Test
public void testListOfNullActionConditions()
{
final List<SimpleCondition> actualSimpleConditions = SimpleCondition.listOf(null);
assertThat(actualSimpleConditions).isNull();
}
@Test
public void testListOfActionConditionsContainingNull()
{
final List<ActionCondition> actionConditions = new ArrayList<>();
actionConditions.add(null);
final List<SimpleCondition> actualSimpleConditions = SimpleCondition.listOf(actionConditions);
assertThat(actualSimpleConditions).isNotNull().isEmpty();
}
private static ActionCondition createActionCondition(final String actionDefinitionName)
{
return new ActionConditionImpl("fake-id", actionDefinitionName, createParameterValues());
}
private static Map<String, Serializable> createParameterValues() {
final Map<String, Serializable> parameterValues = new HashMap<>();
parameterValues.put(ComparePropertyValueEvaluator.PARAM_CONTENT_PROPERTY, "content-property");
parameterValues.put(HasChildEvaluator.PARAM_ASSOC_TYPE, "assoc-type");
parameterValues.put(ComparePropertyValueEvaluator.PARAM_PROPERTY, "property");
parameterValues.put(ComparePropertyValueEvaluator.PARAM_OPERATION, "operation");
parameterValues.put(ComparePropertyValueEvaluator.PARAM_VALUE, "value");
parameterValues.put(HasAspectEvaluator.PARAM_ASPECT, "aspect");
parameterValues.put(HasChildEvaluator.PARAM_ASSOC_NAME, "assoc-name");
parameterValues.put(HasTagEvaluator.PARAM_TAG, "tag");
parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_ASPECT, "category-aspect");
parameterValues.put(InCategoryEvaluator.PARAM_CATEGORY_VALUE, "category-value");
parameterValues.put(IsSubTypeEvaluator.PARAM_TYPE, "type");
return parameterValues;
}
private static class TestData
{
String actionDefinitionName;
boolean isNullResult;
public TestData(String actionDefinitionName, boolean isNullResult)
{
this.actionDefinitionName = actionDefinitionName;
this.isNullResult = isNullResult;
}
public static TestData of(String actionDefinitionName) {
return new TestData(actionDefinitionName, false);
}
public static TestData of(String actionDefinitionName, boolean isNullResult) {
return new TestData(actionDefinitionName, isNullResult);
}
}
}