package org.argeo.api.acr.search; import java.util.HashSet; import java.util.Set; import java.util.function.Consumer; import javax.xml.namespace.QName; import org.argeo.api.acr.DName; import org.argeo.api.acr.QNamed; public abstract class ContentFilter implements Constraint { private Set constraintss = new HashSet<>(); private COMPOSITION composition; boolean negateNextOperator = false; @SuppressWarnings("unchecked") ContentFilter(Class clss) { if (clss == null) this.composition = null; else if (Intersection.class.isAssignableFrom(clss)) this.composition = (COMPOSITION) new Intersection(this); else if (Union.class.isAssignableFrom(clss)) this.composition = (COMPOSITION) new Union(this); else throw new IllegalArgumentException("Unkown composition " + clss); } /* * LOGICAL OPERATORS */ public COMPOSITION all(Consumer and) { AndFilter subFilter = new AndFilter(); and.accept(subFilter); addConstraint(subFilter); return composition; } public COMPOSITION any(Consumer or) { OrFilter subFilter = new OrFilter(); or.accept(subFilter); addConstraint(subFilter); return composition; } public ContentFilter not() { negateNextOperator = !negateNextOperator; return this; } /* * NON WEBDAV */ public COMPOSITION isContentClass(QName... contentClass) { addConstraint(new IsContentClass(contentClass)); return composition; } public COMPOSITION isContentClass(QNamed... contentClass) { addConstraint(new IsContentClass(contentClass)); return composition; } /* * COMPARISON OPERATORS */ public COMPOSITION eq(QName attr, Object value) { addConstraint(new Eq(attr, value)); return composition; } public COMPOSITION eq(QNamed attr, Object value) { addConstraint(new Eq(attr.qName(), value)); return composition; } /* * UTILITIES */ protected void addConstraint(Constraint operator) { checkAddConstraint(); Constraint operatorToAdd; if (negateNextOperator) { operatorToAdd = new Not(operator); negateNextOperator = false; } else { operatorToAdd = operator; } constraintss.add(operatorToAdd); } /** Checks that the root operator is not set. */ private void checkAddConstraint() { if (composition == null && !constraintss.isEmpty()) throw new IllegalStateException("An operator is already registered (" + constraintss.iterator().next() + ") and no composition is defined"); } /* * ACCESSORs */ public Set getConstraints() { return constraintss; } public boolean isUnion() { return composition instanceof Union; } /* * CLASSES */ public static class Not implements Constraint { final Constraint negated; public Not(Constraint negated) { this.negated = negated; } public Constraint getNegated() { return negated; } } public static class Eq implements Constraint { final QName prop; final Object value; public Eq(QName prop, Object value) { super(); this.prop = prop; this.value = value; } public QName getProp() { return prop; } public Object getValue() { return value; } } public static class IsContentClass implements Constraint { final QName[] contentClasses; public IsContentClass(QName[] contentClasses) { this.contentClasses = contentClasses; } public IsContentClass(QNamed[] contentClasses) { this.contentClasses = new QName[contentClasses.length]; for (int i = 0; i < contentClasses.length; i++) this.contentClasses[i] = contentClasses[i].qName(); } public QName[] getContentClasses() { return contentClasses; } } public static void main(String[] args) { AndFilter filter = new AndFilter(); filter.eq(new QName("test"), "test").and().not().eq(new QName("type"), "integer"); OrFilter unionFilter = new OrFilter(); unionFilter.all((f) -> { f.eq(DName.displayname, "").and().eq(DName.creationdate, ""); }).or().not().any((f) -> { f.eq(DName.creationdate, "").or().eq(DName.displayname, ""); }); } }