]> git.argeo.org Git - lgpl/argeo-commons.git/blob - ContentFilter.java
c5f5fc607b634a9b10447da8303aede30f3f3f60
[lgpl/argeo-commons.git] / ContentFilter.java
1 package org.argeo.api.acr.search;
2
3 import java.util.HashSet;
4 import java.util.Set;
5 import java.util.function.Consumer;
6
7 import javax.xml.namespace.QName;
8
9 import org.argeo.api.acr.DName;
10 import org.argeo.api.acr.QNamed;
11
12 public abstract class ContentFilter<COMPOSITION extends Composition> implements Constraint {
13 private Set<Constraint> constraintss = new HashSet<>();
14
15 private COMPOSITION composition;
16
17 boolean negateNextOperator = false;
18
19 @SuppressWarnings("unchecked")
20 ContentFilter(Class<COMPOSITION> clss) {
21 if (clss == null)
22 this.composition = null;
23 else if (Intersection.class.isAssignableFrom(clss))
24 this.composition = (COMPOSITION) new Intersection(this);
25 else if (Union.class.isAssignableFrom(clss))
26 this.composition = (COMPOSITION) new Union(this);
27 else
28 throw new IllegalArgumentException("Unkown composition " + clss);
29 }
30
31 /*
32 * LOGICAL OPERATORS
33 */
34
35 public COMPOSITION all(Consumer<AndFilter> and) {
36 AndFilter subFilter = new AndFilter();
37 and.accept(subFilter);
38 addConstraint(subFilter);
39 return composition;
40 }
41
42 public COMPOSITION any(Consumer<OrFilter> or) {
43 OrFilter subFilter = new OrFilter();
44 or.accept(subFilter);
45 addConstraint(subFilter);
46 return composition;
47 }
48
49 public ContentFilter<COMPOSITION> not() {
50 negateNextOperator = !negateNextOperator;
51 return this;
52 }
53
54 /*
55 * NON WEBDAV
56 */
57 public COMPOSITION isContentClass(QName... contentClass) {
58 addConstraint(new IsContentClass(contentClass));
59 return composition;
60 }
61
62 public COMPOSITION isContentClass(QNamed... contentClass) {
63 addConstraint(new IsContentClass(contentClass));
64 return composition;
65 }
66
67 /*
68 * COMPARISON OPERATORS
69 */
70
71 public COMPOSITION eq(QName attr, Object value) {
72 addConstraint(new Eq(attr, value));
73 return composition;
74 }
75
76 public COMPOSITION eq(QNamed attr, Object value) {
77 addConstraint(new Eq(attr.qName(), value));
78 return composition;
79 }
80
81 /*
82 * UTILITIES
83 */
84 protected void addConstraint(Constraint operator) {
85 checkAddConstraint();
86 Constraint operatorToAdd;
87 if (negateNextOperator) {
88 operatorToAdd = new Not(operator);
89 negateNextOperator = false;
90 } else {
91 operatorToAdd = operator;
92 }
93 constraintss.add(operatorToAdd);
94 }
95
96 /** Checks that the root operator is not set. */
97 private void checkAddConstraint() {
98 if (composition == null && !constraintss.isEmpty())
99 throw new IllegalStateException("An operator is already registered (" + constraintss.iterator().next()
100 + ") and no composition is defined");
101 }
102
103 /*
104 * ACCESSORs
105 */
106 public Set<Constraint> getConstraints() {
107 return constraintss;
108 }
109
110 public boolean isUnion() {
111 return composition instanceof Union;
112 }
113
114 /*
115 * CLASSES
116 */
117
118 public static class Not implements Constraint {
119 final Constraint negated;
120
121 public Not(Constraint negated) {
122 this.negated = negated;
123 }
124
125 public Constraint getNegated() {
126 return negated;
127 }
128
129 }
130
131 public static class Eq implements Constraint {
132 final QName prop;
133 final Object value;
134
135 public Eq(QName prop, Object value) {
136 super();
137 this.prop = prop;
138 this.value = value;
139 }
140
141 public QName getProp() {
142 return prop;
143 }
144
145 public Object getValue() {
146 return value;
147 }
148
149 }
150
151 public static class IsContentClass implements Constraint {
152 final QName[] contentClasses;
153
154 public IsContentClass(QName[] contentClasses) {
155 this.contentClasses = contentClasses;
156 }
157
158 public IsContentClass(QNamed[] contentClasses) {
159 this.contentClasses = new QName[contentClasses.length];
160 for (int i = 0; i < contentClasses.length; i++)
161 this.contentClasses[i] = contentClasses[i].qName();
162 }
163
164 public QName[] getContentClasses() {
165 return contentClasses;
166 }
167
168 }
169
170 public static void main(String[] args) {
171 AndFilter filter = new AndFilter();
172 filter.eq(new QName("test"), "test").and().not().eq(new QName("type"), "integer");
173
174 OrFilter unionFilter = new OrFilter();
175 unionFilter.all((f) -> {
176 f.eq(DName.displayname, "").and().eq(DName.creationdate, "");
177 }).or().not().any((f) -> {
178 f.eq(DName.creationdate, "").or().eq(DName.displayname, "");
179 });
180
181 }
182
183 }