use of org.bedework.caldav.util.filter.FilterBase in project bw-calendar-engine by Bedework.
the class ESQueryFilter method makeFilters.
private List<FilterBuilder> makeFilters(final List<FilterBase> fs, final boolean anding) throws CalFacadeException {
List<FilterBuilder> fbs = new ArrayList<>();
/* We'll try to compact the filters - if we have a whole bunch of
"term" {"category_uid": "abcd"} for example we can turn it into
"terms" {"category_uid": ["abcd", "pqrs"]}
*/
TermOrTerms lastFb = null;
for (FilterBase f : fs) {
FilterBuilder fb = makeFilter(f);
if (fb == null) {
continue;
}
if (lastFb == null) {
if (!(fb instanceof TermOrTerms)) {
fbs.add(fb);
continue;
}
lastFb = (TermOrTerms) fb;
} else if (!(fb instanceof TermOrTerms)) {
fbs.add(fb);
} else {
/* Can we combine them? */
TermOrTerms thisFb = (TermOrTerms) fb;
if (thisFb.dontMerge || !lastFb.fldName.equals(thisFb.fldName) || (lastFb.not != thisFb.not)) {
fbs.add(lastFb);
lastFb = thisFb;
} else {
lastFb = lastFb.anding(anding);
if (thisFb.isTerms) {
for (Object o : (Collection) thisFb.value) {
lastFb.addValue(o);
}
} else {
lastFb.addValue(thisFb.value);
}
}
}
}
if (lastFb != null) {
fbs.add(lastFb);
}
return fbs;
}
use of org.bedework.caldav.util.filter.FilterBase in project bw-calendar-engine by Bedework.
the class Filters method match.
private boolean match(final FilterBase f, final BwEvent ev, final String userHref) throws CalFacadeException {
if (f == null) {
return true;
}
if (debug) {
debug("match " + f);
}
if ((f instanceof AndFilter) || (f instanceof OrFilter)) {
boolean itsAnd = (f instanceof AndFilter);
for (FilterBase flt : f.getChildren()) {
if (match(flt, ev, userHref)) {
if (!itsAnd) {
// Success for OR
if (debug) {
debug("match true");
}
return true;
}
} else if (itsAnd) {
debug("match true");
return false;
}
}
// For AND all matched, for OR nothing matched
debug("match " + itsAnd);
return itsAnd;
}
if (f instanceof EntityTimeRangeFilter) {
// Matched in db query
return true;
}
if (!(f instanceof PropertyFilter)) {
/* We assume we can't handle this one as a query.
*/
throw new CalFacadeException("org.bedework.filters.unknownfilter", String.valueOf(f));
}
PropertyFilter pf = (PropertyFilter) f;
BwIcalPropertyInfoEntry pi = BwIcalPropertyInfo.getPinfo(pf.getPropertyIndex());
if (pi == null) {
throw new CalFacadeException("org.bedework.filters.unknownproperty", String.valueOf(pf.getPropertyIndex()));
}
String fieldName = pi.getDbFieldName();
boolean param = pi.getParam();
if (param) {
BwIcalPropertyInfoEntry parentPi = BwIcalPropertyInfo.getPinfo(pf.getParentPropertyIndex());
fieldName = parentPi.getDbFieldName() + "." + fieldName;
}
try {
if (pf instanceof BwCategoryFilter) {
return traceMatch(pf.match(ev, userHref));
}
if (f instanceof PresenceFilter) {
return traceMatch(matchPresence(pf.getPropertyIndex(), ev, userHref));
}
if (pf instanceof TimeRangeFilter) {
return traceMatch(match((TimeRangeFilter) pf, ev));
}
if (pf instanceof BwObjectFilter) {
return traceMatch(pf.match(ev, userHref));
}
} catch (WebdavException wde) {
throw new CalFacadeException(wde);
}
throw new CalFacadeException("org.bedework.filters.unknownfilter", String.valueOf(f));
}
use of org.bedework.caldav.util.filter.FilterBase in project bw-calendar-engine by Bedework.
the class Filters method parReplace.
/* Fill in the parameters after we generated the query.
*/
private void parReplace(final FilterBase f) throws CalFacadeException {
if (f instanceof AndFilter) {
AndFilter fb = (AndFilter) f;
for (FilterBase flt : fb.getChildren()) {
parReplace(flt);
}
return;
}
if (f instanceof BwHrefFilter) {
BwHrefFilter hf = (BwHrefFilter) f;
// Special case this
sess.setString(parPrefix + qi, hf.getPathPart());
qi++;
sess.setString(parPrefix + qi, hf.getNamePart());
qi++;
}
if (f instanceof BwCategoryFilter) {
BwCategoryFilter cf = (BwCategoryFilter) f;
BwCategory cat = cf.getEntity();
/* XXX - this is what we want to be able to do
sess.setString(parPrefix + qi, cat.getUid());
*/
sess.setEntity(parPrefix + qi, cat);
qi++;
return;
}
if (f instanceof EntityTimeRangeFilter) {
doEntityTimeRangeReplace((EntityTimeRangeFilter) f);
return;
}
if (f instanceof TimeRangeFilter) {
TimeRangeFilter trf = (TimeRangeFilter) f;
TimeRange tr = trf.getEntity();
if (tr.getStart() != null) {
sess.setParameter(parPrefix + qi, tr.getStart().toString());
qi++;
}
if (tr.getEnd() != null) {
sess.setParameter(parPrefix + qi, tr.getEnd().toString());
qi++;
}
return;
}
if (f instanceof BwObjectFilter) {
ObjectFilter of = ((BwObjectFilter) f).getEntity();
Object o = of.getEntity();
Collection c = null;
boolean isString = o instanceof String;
if (!isString) {
if (o instanceof Collection) {
c = (Collection) o;
if (c.size() > 0) {
o = c.iterator().next();
isString = o instanceof String;
}
}
}
boolean doCaseless = isString && of.getCaseless();
if (c != null) {
// TODO - Assuming String collection
for (Object co : c) {
String s = (String) co;
if (doCaseless) {
s = s.toLowerCase();
}
sess.setParameter(parPrefix + qi, s);
qi++;
}
return;
}
if (o instanceof BwCalendar) {
BwCalendar cal = unwrap((BwCalendar) o);
sess.setString(parPrefix + qi, cal.getPath());
} else if (o instanceof BwPrincipal) {
sess.setString(parPrefix + qi, ((BwPrincipal) o).getPrincipalRef());
} else if (o instanceof BwDbentity) {
sess.setEntity(parPrefix + qi, o);
} else if (of.getExact()) {
if (doCaseless) {
o = ((String) o).toLowerCase();
}
sess.setParameter(parPrefix + qi, o);
} else if (of.getEntity() instanceof String) {
String s = o.toString();
if (doCaseless) {
s = s.toLowerCase();
}
sess.setString(parPrefix + qi, "%" + s + "%");
} else {
sess.setString(parPrefix + qi, "%" + o + "%");
}
qi++;
return;
}
if (f instanceof OrFilter) {
OrFilter fb = (OrFilter) f;
for (FilterBase flt : fb.getChildren()) {
parReplace(flt);
}
return;
}
}
use of org.bedework.caldav.util.filter.FilterBase in project bw-calendar-engine by Bedework.
the class SimpleFilterParser method makePropFilter.
private FilterBase makePropFilter(final List<PropertyInfo> pis, final int oper) throws ParseFailed {
final PropertyInfo pi = pis.get(0);
FilterBase filter = null;
final List<PropertyInfoIndex> pixs = new ArrayList<>();
pis.forEach(val -> pixs.add(val.pii));
final boolean exact = (oper != like) && (oper != notLike);
if (pi.pii == PropertyInfoIndex.ENTITY_TYPE) {
checkSub(pis, 1);
return entityFilter(getMatch(oper).getValue());
}
if (oper == notDefined) {
checkSub(pis, 2);
return new PresenceFilter(null, pixs, false, pi.intKey, pi.strKey);
}
if (oper == isDefined) {
// Presence check
checkSub(pis, 2);
return new PresenceFilter(null, pixs, true, pi.intKey, pi.strKey);
}
if (oper == inTimeRange) {
checkSub(pis, 2);
return ObjectFilter.makeFilter(null, pixs, getTimeRange(), pi.intKey, pi.strKey);
}
if (pi.pii == PropertyInfoIndex.VIEW) {
checkSub(pis, 1);
// expect list of views.
final ArrayList<String> views = doWordList();
for (final String view : views) {
final FilterBase vpf = viewFilter(view);
filter = and(null, filter, vpf);
}
return filter;
}
if (pi.pii == PropertyInfoIndex.VPATH) {
checkSub(pis, 1);
// expect list of virtual paths.
final ArrayList<String> vpaths = doWordList();
for (final String vpath : vpaths) {
final FilterBase vpf = resolveVpath(vpath);
filter = and(null, filter, vpf);
}
return filter;
}
if ((pi.pii == PropertyInfoIndex.CATEGORIES) && (pis.size() == 2)) {
final PropertyInfo subPi = pis.get(1);
if (subPi.pii == PropertyInfoIndex.UID) {
// No match and category - expect list of uids.
final ArrayList<String> uids = doWordList();
for (final String uid : uids) {
final BwCategory cat = callGetCategory(uid);
if (cat == null) {
// Deleted category?
throw parseResult.fail("Category uid references missing category: " + uid + " Filter will always fail to match");
}
final ObjectFilter<String> f = new ObjectFilter<String>(null, pixs);
f.setEntity(uid);
f.setExact(exact);
f.setNot(oper == notEqual);
filter = and(null, filter, f);
}
return filter;
}
if (subPi.pii == PropertyInfoIndex.HREF) {
// No match and category - expect list of paths.
final ArrayList<String> paths = doWordList();
for (final String path : paths) {
final ObjectFilter<String> f = new ObjectFilter<String>(null, pixs);
f.setEntity(path);
f.setCaseless(false);
f.setExact(exact);
f.setNot(oper == notEqual);
filter = and(null, filter, f);
}
return filter;
}
}
if ((pi.pii == PropertyInfoIndex.COLLECTION) || (pi.pii == PropertyInfoIndex.COLPATH)) {
checkSub(pis, 1);
final ArrayList<String> paths = doWordList();
for (final String path : paths) {
final FilterBase pf = resolveColPath(path, true, true);
if (pf == null) {
continue;
}
filter = and(null, filter, pf);
}
return filter;
}
final MatchType match = getMatch(oper);
if (pi.pii == PropertyInfoIndex.CATEGORIES) {
checkSub(pis, 1);
final String val = match.getValue();
if (val.startsWith("/")) {
pixs.add(PropertyInfoIndex.HREF);
// Assume a path match
final ObjectFilter<String> f = new ObjectFilter<String>(null, pixs);
f.setEntity(val);
f.setCaseless(false);
f.setExact(exact);
f.setNot(match.getNegateCondition().equals("yes"));
return f;
}
// Try for name
final BwCategory cat = callGetCategoryByName(val);
if (cat == null) {
throw parseResult.fail("Bad property: " + "category name: " + match.getValue() + " source: " + source);
}
pixs.add(PropertyInfoIndex.UID);
final ObjectFilter<BwCategory> f = new BwCategoryFilter(null, pixs);
f.setEntity(cat);
f.setExact(exact);
f.setNot(match.getNegateCondition().equals("yes"));
return f;
}
checkSub(pis, 2);
final ObjectFilter<String> f = new ObjectFilter<>(null, pixs, pi.intKey, pi.strKey);
f.setEntity(match.getValue());
f.setCaseless(Filters.caseless(match));
f.setExact(exact);
f.setNot(match.getNegateCondition().equals("yes"));
f.setPrefixMatch(match.getPrefixMatch());
return f;
}
use of org.bedework.caldav.util.filter.FilterBase in project bw-calendar-engine by Bedework.
the class SimpleFilterParser method doTerm.
private boolean doTerm() throws ParseFailed {
if (!doFactor()) {
return false;
}
if (debug) {
debug("doTerm: " + tokenizer.toString());
}
/* If we have a logical operator next then handle that and combine the
* two filters on top of the stack.
*/
int tkn = nextToken("doTerm()");
if (tkn == StreamTokenizer.TT_EOF) {
return false;
}
tkn = checkLop(tkn);
if ((tkn != '&') && (tkn != '|')) {
tokenizer.pushBack();
if (topLOp()) {
final FilterBase filter = popFilters();
final FilterBase topFilter = popFilters();
if (anding()) {
filterStack.push(FilterBase.addAndChild(topFilter, filter));
} else {
filterStack.push(FilterBase.addOrChild(topFilter, filter));
}
// Pop it - we used it to ensure all operators at the same level are the
// same.
pop();
}
return true;
}
doLop(tkn);
doTerm();
return true;
}
Aggregations