Skip to content

Commit

Permalink
MCR-3050 add "xor" support
Browse files Browse the repository at this point in the history
* fixes bug in order of child conditions
* add JUnit tests
  • Loading branch information
yagee-de committed Feb 23, 2024
1 parent ffba94a commit 31141cf
Show file tree
Hide file tree
Showing 12 changed files with 294 additions and 40 deletions.
17 changes: 10 additions & 7 deletions mycore-base/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,6 @@
</properties>
<trimStackTrace>false</trimStackTrace>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down Expand Up @@ -458,6 +451,16 @@
<artifactId>hibernate-hikaricp</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mycore</groupId>
<artifactId>mycore-classifications</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
*/
package org.mycore.access.facts.condition.combined;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;

import org.jdom2.Element;
import org.mycore.access.facts.MCRFactsAccessSystemHelper;
import org.mycore.access.facts.MCRFactsHolder;
import org.mycore.access.facts.condition.MCRAbstractCondition;
import org.mycore.access.facts.model.MCRCombinedCondition;
import org.mycore.access.facts.model.MCRCondition;
Expand All @@ -33,9 +35,10 @@
* @author Robert Stephan
*
*/
public abstract class MCRAbstractCombinedCondition extends MCRAbstractCondition implements MCRCombinedCondition {
sealed public abstract class MCRAbstractCombinedCondition extends MCRAbstractCondition implements MCRCombinedCondition
permits MCRAndCondition, MCRNotCondition, MCROrCondition, MCRXorCondition {

protected Set<MCRCondition> conditions = new HashSet<>();
protected Set<MCRCondition> conditions = new LinkedHashSet<>();

public void add(MCRCondition condition) {
conditions.add(condition);
Expand All @@ -55,6 +58,7 @@ public Set<MCRCondition> getChildConditions() {
return conditions;
}

@Deprecated
public void debugInfoForMatchingChildElement(MCRCondition c, boolean matches) {
if (isDebug()) {
Element el = c.getBoundElement();
Expand All @@ -64,4 +68,14 @@ public void debugInfoForMatchingChildElement(MCRCondition c, boolean matches) {
}
}

boolean addDebugInfoIfRequested(MCRCondition c, MCRFactsHolder facts) {
if (!isDebug()) {
return c.matches(facts);
}
boolean matches = c.matches(facts);
Objects.requireNonNull(c.getBoundElement(), "Condition is not bound to an element.")
.setAttribute("_matches", Boolean.toString(matches));
return matches;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,10 @@
* @author Robert Stephan
*
*/
public class MCRAndCondition extends MCRAbstractCombinedCondition {
public final class MCRAndCondition extends MCRAbstractCombinedCondition {

public boolean matches(MCRFactsHolder facts) {
return conditions.stream().allMatch(c -> {
boolean matches = c.matches(facts);
debugInfoForMatchingChildElement(c, matches);

return matches;
});
return conditions.stream().allMatch(c -> addDebugInfoIfRequested(c, facts));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
*/
package org.mycore.access.facts.condition.combined;

import org.jdom2.Element;
import org.mycore.access.facts.MCRFactsHolder;
import org.mycore.access.facts.model.MCRCondition;

/**
* This condition negates its child condition
Expand All @@ -31,22 +29,12 @@
* @author Robert Stephan
*
*/
public class MCRNotCondition extends MCRAbstractCombinedCondition {
public final class MCRNotCondition extends MCRAbstractCombinedCondition {

public boolean matches(MCRFactsHolder facts) {
MCRCondition negatedCondition = conditions.stream().findFirst().get();
boolean result = negatedCondition.matches(facts);
boolean negated = !result;
if (isDebug()) {
Element boundElement = negatedCondition.getBoundElement();
if (boundElement != null) {
boundElement.setAttribute("_matched", Boolean.toString(result));
}

if (this.getBoundElement() != null) {
this.getBoundElement().setAttribute("_matched", Boolean.toString(negated));
}
}
return negated;
return conditions.stream()
.limit(1)
.filter(c -> !addDebugInfoIfRequested(c, facts))
.count() == 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,9 @@
* @author Robert Stephan
*
*/
public class MCROrCondition extends MCRAbstractCombinedCondition {
public final class MCROrCondition extends MCRAbstractCombinedCondition {

public boolean matches(MCRFactsHolder facts) {
return conditions.stream().anyMatch(c -> {
boolean matches = c.matches(facts);
debugInfoForMatchingChildElement(c, matches);
return matches;
});
return conditions.stream().anyMatch(c -> addDebugInfoIfRequested(c, facts));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* This file is part of *** M y C o R e ***
* See http://www.mycore.de/ for details.
*
* MyCoRe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MyCoRe 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MyCoRe. If not, see <http://www.gnu.org/licenses/>.
*/

package org.mycore.access.facts.condition.combined;

import org.mycore.access.facts.MCRFactsHolder;

public final class MCRXorCondition extends MCRAbstractCombinedCondition {
@Override
public boolean matches(MCRFactsHolder facts) {
return conditions.stream()
.filter(c -> addDebugInfoIfRequested(c, facts))
.limit(2)
.count() == 1;
}
}
1 change: 1 addition & 0 deletions mycore-base/src/main/resources/config/mycore.properties
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ MCR.Access.Cache.Size=200

MCR.Access.Facts.Condition.and=org.mycore.access.facts.condition.combined.MCRAndCondition
MCR.Access.Facts.Condition.or=org.mycore.access.facts.condition.combined.MCROrCondition
MCR.Access.Facts.Condition.xor=org.mycore.access.facts.condition.combined.MCRXorCondition
MCR.Access.Facts.Condition.not=org.mycore.access.facts.condition.combined.MCRNotCondition
MCR.Access.Facts.Condition.id=org.mycore.access.facts.condition.fact.MCRStringCondition
MCR.Access.Facts.Condition.target=org.mycore.access.facts.condition.fact.MCRStringCondition
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* This file is part of *** M y C o R e ***
* See http://www.mycore.de/ for details.
*
* MyCoRe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MyCoRe 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MyCoRe. If not, see <http://www.gnu.org/licenses/>.
*/

package org.mycore.access.facts.condition.combined;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

class MCRAndConditionTest {

@Test
void matches() {
MCRAndCondition xor=new MCRAndCondition();
xor.add(new MCRTestCondition(()->false));
assertFalse(xor.matches(null));
xor.add(new MCRTestCondition(()->false));
assertFalse(xor.matches(null));
xor.getChildConditions().clear();
xor.add(new MCRTestCondition(()->true));
assertTrue(xor.matches(null));
xor.add(new MCRTestCondition(()->true));
assertTrue(xor.matches(null));
xor.add(new MCRTestCondition(()->false));
assertFalse(xor.matches(null));
xor.add(new MCRTestCondition(() -> {
throw new RuntimeException("Should not be checked");

Check warning on line 43 in mycore-base/src/test/java/org/mycore/access/facts/condition/combined/MCRAndConditionTest.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

mycore-base/src/test/java/org/mycore/access/facts/condition/combined/MCRAndConditionTest.java#L43

Avoid throwing raw exception types.
}));
assertFalse(xor.matches(null));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* This file is part of *** M y C o R e ***
* See http://www.mycore.de/ for details.
*
* MyCoRe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MyCoRe 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MyCoRe. If not, see <http://www.gnu.org/licenses/>.
*/

package org.mycore.access.facts.condition.combined;

import static org.junit.jupiter.api.Assertions.assertFalse;

Check notice on line 21 in mycore-base/src/test/java/org/mycore/access/facts/condition/combined/MCRNotConditionTest.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

mycore-base/src/test/java/org/mycore/access/facts/condition/combined/MCRNotConditionTest.java#L21

Unused import 'org.junit.jupiter.api.Assertions.assertFalse'

Check notice on line 21 in mycore-base/src/test/java/org/mycore/access/facts/condition/combined/MCRNotConditionTest.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

mycore-base/src/test/java/org/mycore/access/facts/condition/combined/MCRNotConditionTest.java#L21

Unused import - org.junit.jupiter.api.Assertions.assertFalse.
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

class MCRNotConditionTest {

@Test
void matches() {
MCRNotCondition xor = new MCRNotCondition();
xor.add(new MCRTestCondition(() -> false));
xor.add(new MCRTestCondition(() -> {
throw new RuntimeException("Should not be checked");

Check warning on line 33 in mycore-base/src/test/java/org/mycore/access/facts/condition/combined/MCRNotConditionTest.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

mycore-base/src/test/java/org/mycore/access/facts/condition/combined/MCRNotConditionTest.java#L33

Avoid throwing raw exception types.
}));
assertTrue(xor.matches(null));
xor.getChildConditions().clear();
xor.add(new MCRTestCondition(() -> false));
xor.add(new MCRTestCondition(() -> {
throw new RuntimeException("Should not be checked");
}));
assertTrue(xor.matches(null));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* This file is part of *** M y C o R e ***
* See http://www.mycore.de/ for details.
*
* MyCoRe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MyCoRe 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MyCoRe. If not, see <http://www.gnu.org/licenses/>.
*/

package org.mycore.access.facts.condition.combined;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

class MCROrConditionTest {

@Test
void matches() {
MCROrCondition xor = new MCROrCondition();
xor.add(new MCRTestCondition(() -> false));
assertFalse(xor.matches(null));
xor.add(new MCRTestCondition(() -> false));
assertFalse(xor.matches(null));
xor.add(new MCRTestCondition(() -> false));
assertFalse(xor.matches(null));
xor.add(new MCRTestCondition(() -> true));
assertTrue(xor.matches(null));
xor.add(new MCRTestCondition(() -> false));
assertTrue(xor.matches(null));
xor.add(new MCRTestCondition(() -> true));
assertTrue(xor.matches(null));
xor.add(new MCRTestCondition(() -> {
throw new RuntimeException("Should not be checked");

Check warning on line 44 in mycore-base/src/test/java/org/mycore/access/facts/condition/combined/MCROrConditionTest.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

mycore-base/src/test/java/org/mycore/access/facts/condition/combined/MCROrConditionTest.java#L44

Avoid throwing raw exception types.
}));
assertTrue(xor.matches(null));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* This file is part of *** M y C o R e ***
* See http://www.mycore.de/ for details.
*
* MyCoRe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MyCoRe 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MyCoRe. If not, see <http://www.gnu.org/licenses/>.
*/

package org.mycore.access.facts.condition.combined;

import org.mycore.access.facts.MCRFactsHolder;
import org.mycore.access.facts.condition.MCRAbstractCondition;

import java.util.function.Supplier;

class MCRTestCondition extends MCRAbstractCondition {
Supplier<Boolean> match;

public MCRTestCondition(Supplier<Boolean> match) {

Check notice on line 29 in mycore-base/src/test/java/org/mycore/access/facts/condition/combined/MCRTestCondition.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

mycore-base/src/test/java/org/mycore/access/facts/condition/combined/MCRTestCondition.java#L29

Redundant 'public' modifier.
this.match = match;
}

@Override
public boolean matches(MCRFactsHolder facts) {
return match.get();
}
}
Loading

0 comments on commit 31141cf

Please sign in to comment.