Search in sources :

Example 6 with FilterBase

use of org.bedework.caldav.util.filter.FilterBase in project bw-calendar-engine by Bedework.

the class SimpleFilterParser method resolveVpath.

/**
 * A virtual path is the apparent path for a user looking at an explorer
 * view of collections.
 *
 * <p>We might have,
 * <pre>
 *    home-->Arts-->Theatre
 * </pre>
 *
 * <p>In reality the Arts collection might be an alias to another alias which
 * is an alias to a collection containing aliases including "Theatre".
 *
 * <p>So the real picture might be something like...
 * <pre>
 *    home-->Arts             (categories="ChemEng")
 *            |
 *            V
 *           Arts             (categories="Approved")
 *            |
 *            V
 *           Arts-->Theatre   (categories="Arts" AND categories="Theatre")
 *                     |
 *                     V
 *                    MainCal
 * </pre>
 * where the vertical links are aliasing. The importance of this is that
 * each alias might introduce another filtering term, the intent of which is
 * to restrict the retrieval to a specific subset. The parenthesized terms
 * represent example filters.
 *
 * <p>The desired filter is the ANDing of all the above.
 *
 * @param  vpath  a String virtual path
 * @return FilterBase object or null for bad path
 * @throws ParseFailed on error
 */
private FilterBase resolveVpath(final String vpath) throws ParseFailed {
    /* We decompose the virtual path into it's elements and then try to
     * build a sequence of collections that include the aliases and their
     * targets until we reach the last element in the path.
     *
     * We'll assume the path is already normalized and that no "/" are allowed
     * as parts of names.
     *
     * What we're doing here is resolving aliases to aliases and accumulating
     * any filtering that might be in place as a sequence of ANDed terms. For
     * example:
     *
     * /user/eng/Lectures has the filter cat=eng and is aliased to
     * /public/aliases/Lectures which has the filter cat=lectures and is aliased to
     * /public/cals/MainCal
     *
     * We want the filter (cat=eng) & (cat=Lectures) on MainCal.
     *
     * Below, we decompose the virtual path and we save the path to an actual
     * folder or calendar collection.
     */
    final Collection<BwCalendar> cols = callDecomposeVirtualPath(vpath);
    if (cols == null) {
        throw parseResult.fail("Bad virtual path: " + vpath);
    }
    FilterBase vfilter = null;
    BwCalendar vpathTarget = null;
    for (final BwCalendar col : cols) {
        if (debug) {
            debug("      vpath collection:" + col.getPath());
        }
        if (col.getFilterExpr() != null) {
            if (subParser == null) {
                subParser = callGetParser();
            }
            final ParseResult pr = subParser.parse(col.getFilterExpr(), false, col.getPath());
            if (!pr.ok) {
                throw parseResult.fromPr(pr);
            }
            if (pr.filter != null) {
                vfilter = and(null, vfilter, pr.filter);
            }
        }
        if (col.getCollectionInfo().onlyCalEntities || (col.getCalType() == BwCalendar.calTypeFolder)) {
            // reached an end point
            vpathTarget = col;
        }
    }
    if (vpathTarget == null) {
        throw parseResult.fail("Bad vpath - no calendar collection" + " vpath: " + vpath + " source: " + source);
    }
    final String name;
    if (vpathTarget.getAliasOrigin() != null) {
        name = vpathTarget.getAliasOrigin().getPath();
    } else {
        name = vpathTarget.getPath();
    }
    return and(name, vfilter, resolveColPath(vpathTarget.getPath(), false, false));
}
Also used : BwCalendar(org.bedework.calfacade.BwCalendar) ToString(org.bedework.util.misc.ToString) FilterBase(org.bedework.caldav.util.filter.FilterBase)

Example 7 with FilterBase

use of org.bedework.caldav.util.filter.FilterBase in project bw-calendar-engine by Bedework.

the class BwSysIntfImpl method getEvents.

@Override
public Collection<CalDAVEvent> getEvents(final CalDAVCollection col, final FilterBase filter, final List<String> retrieveList, final RetrievalMode recurRetrieval) throws WebdavException {
    try {
        /* Limit the results to just this collection by adding an ANDed filter */
        final SimpleFilterParser sfp = getSvci().getFilterParser();
        final String expr = "(colPath='" + SfpTokenizer.escapeQuotes(col.getPath()) + "')";
        final ParseResult pr = sfp.parse(expr, true, null);
        if (!pr.ok) {
            throw new WebdavBadRequest("Failed to reference collection " + col.getPath() + ": message was " + pr.message);
        }
        final FilterBase f = FilterBase.addAndChild(filter, pr.filter);
        final Collection<EventInfo> bwevs = // Collection
        getSvci().getEventsHandler().getEvents(// Collection
        null, f, // start
        null, // end
        null, RetrieveList.getRetrieveList(retrieveList), DeletedState.noDeleted, getRrm(recurRetrieval));
        if (bwevs == null) {
            return null;
        }
        final Collection<CalDAVEvent> evs = new ArrayList<>();
        for (final EventInfo ei : bwevs) {
            if (recurRetrieval != null) {
                ei.getEvent().setForceUTC(recurRetrieval.getExpand() != null);
            }
            evs.add(new BwCalDAVEvent(this, ei));
        }
        return evs;
    } catch (final CalFacadeAccessException cfae) {
        throw new WebdavForbidden();
    } catch (final CalFacadeException cfe) {
        if (CalFacadeException.unknownProperty.equals(cfe.getMessage())) {
            throw new WebdavBadRequest("Unknown property " + cfe.getExtra());
        }
        throw new WebdavException(cfe);
    } catch (final WebdavException wde) {
        throw wde;
    } catch (final Throwable t) {
        throw new WebdavException(t);
    }
}
Also used : WebdavBadRequest(org.bedework.webdav.servlet.shared.WebdavBadRequest) ParseResult(org.bedework.calfacade.filter.SimpleFilterParser.ParseResult) EventInfo(org.bedework.calfacade.svc.EventInfo) WebdavForbidden(org.bedework.webdav.servlet.shared.WebdavForbidden) ArrayList(java.util.ArrayList) WebdavException(org.bedework.webdav.servlet.shared.WebdavException) SimpleFilterParser(org.bedework.calfacade.filter.SimpleFilterParser) CalFacadeAccessException(org.bedework.calfacade.exc.CalFacadeAccessException) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException) CalDAVEvent(org.bedework.caldav.server.CalDAVEvent) FilterBase(org.bedework.caldav.util.filter.FilterBase)

Example 8 with FilterBase

use of org.bedework.caldav.util.filter.FilterBase in project bw-calendar-engine by Bedework.

the class ESQueryFilter method addLimits.

/**
 * This method adds extra limits to the search if they are necessary.
 * If the search is already limited to one or more collections or
 * specific href(s) then we don't need to add anything.
 *
 * <p>Otherwise we apply a default search context (if any). If the
 * result is still not limited we limit to entities owned by the
 * current principal</p>
 *
 * @param f current filter
 * @param defaultFilterContext set if we have one
 * @return augmented filter
 * @throws CalFacadeException on error
 */
public FilterBuilder addLimits(final FilterBuilder f, final FilterBase defaultFilterContext, final DeletedState delState) throws CalFacadeException {
    if (f instanceof MatchNone) {
        return f;
    }
    final List<NamedFilterBuilder> nfbs = new ArrayList<>();
    if (!queryLimited) {
        if (defaultFilterContext != null) {
            if (defaultFilterContext instanceof BwViewFilter) {
                /* Treat this specially. Create a named query for each 
             child filter. The name will be the filter name which
             itself is derived from the collection href.
          */
                final FilterBase fb = ((BwViewFilter) defaultFilterContext).getFilter();
                if ((fb != null) && (fb.getChildren() != null)) {
                    for (final FilterBase vfb : fb.getChildren()) {
                        nfbs.add(new NamedFilterBuilder(vfb.getName(), and(buildFilter(vfb), f, vfb.getName())));
                    }
                }
            } else {
                final FilterBuilder limFb = buildFilter(defaultFilterContext);
                nfbs.add(new NamedFilterBuilder(null, and(f, limFb, null)));
            }
        }
        if (!queryLimited) {
            nfbs.add(new NamedFilterBuilder(null, principalFilter(f)));
        }
    } else {
        nfbs.add(new NamedFilterBuilder(null, f));
    }
    FilterBuilder recurFb = recurTerms();
    FilterBuilder fb;
    if (nfbs.size() == 1) {
        fb = nfbs.get(0).fb;
        if (recurFb != null) {
            fb = and(fb, recurFb, null);
        }
    } else {
        fb = null;
        if (recurFb == null) {
            recurFb = new MatchAllFilterBuilder();
        }
        for (final NamedFilterBuilder nfb : nfbs) {
            fb = or(fb, and(nfb.fb, recurFb, nfb.name));
        }
    }
    if (delState == includeDeleted) {
        return fb;
    }
    return and(fb, addTerm(PropertyInfoIndex.DELETED, String.valueOf(delState == onlyDeleted)), null);
}
Also used : BwViewFilter(org.bedework.calfacade.filter.BwViewFilter) MatchAllFilterBuilder(org.elasticsearch.index.query.MatchAllFilterBuilder) AndFilterBuilder(org.elasticsearch.index.query.AndFilterBuilder) TermFilterBuilder(org.elasticsearch.index.query.TermFilterBuilder) FilterBuilder(org.elasticsearch.index.query.FilterBuilder) OrFilterBuilder(org.elasticsearch.index.query.OrFilterBuilder) RangeFilterBuilder(org.elasticsearch.index.query.RangeFilterBuilder) BoolFilterBuilder(org.elasticsearch.index.query.BoolFilterBuilder) QueryFilterBuilder(org.elasticsearch.index.query.QueryFilterBuilder) NotFilterBuilder(org.elasticsearch.index.query.NotFilterBuilder) NestedFilterBuilder(org.elasticsearch.index.query.NestedFilterBuilder) MatchAllFilterBuilder(org.elasticsearch.index.query.MatchAllFilterBuilder) TermsFilterBuilder(org.elasticsearch.index.query.TermsFilterBuilder) ArrayList(java.util.ArrayList) FilterBase(org.bedework.caldav.util.filter.FilterBase) ESQueryFilterBase(org.bedework.util.elasticsearch.ESQueryFilterBase)

Example 9 with FilterBase

use of org.bedework.caldav.util.filter.FilterBase in project bw-calendar-engine by Bedework.

the class CoreEvents method getEvents.

@Override
public Collection<CoreEventInfo> getEvents(final Collection<BwCalendar> calendars, final FilterBase filter, final BwDateTime startDate, final BwDateTime endDate, final List<BwIcalPropertyInfoEntry> retrieveList, final DeletedState delState, RecurringRetrievalMode recurRetrieval, final boolean freeBusy) throws CalFacadeException {
    /* Ensure dates are limited explicitly or implicitly */
    recurRetrieval = defaultRecurringRetrieval(recurRetrieval, startDate, endDate);
    if (debug) {
        trace("getEvents for start=" + startDate + " end=" + endDate);
    }
    FilterBase fltr = filter;
    if (!Util.isEmpty(calendars)) {
        FilterBase colfltr = null;
        for (final BwCalendar c : calendars) {
            colfltr = FilterBase.addOrChild(colfltr, new BwCollectionFilter(null, c));
        }
        fltr = FilterBase.addAndChild(fltr, colfltr);
    }
    int desiredAccess = privRead;
    if (freeBusy) {
        // DORECUR - freebusy events must have enough info for expansion
        desiredAccess = privReadFreeBusy;
    }
    final List<PropertyInfoIndex> properties = new ArrayList<>(2);
    properties.add(PropertyInfoIndex.DTSTART);
    properties.add(PropertyInfoIndex.UTC);
    final List<SortTerm> sort = new ArrayList<>(1);
    sort.add(new SortTerm(properties, true));
    String start = null;
    String end = null;
    if (startDate != null) {
        start = startDate.getDate();
    }
    if (endDate != null) {
        end = endDate.getDate();
    }
    final SearchResult sr = // query
    getIndexer(null).search(// query
    null, false, fltr, sort, // defaultFilterContext
    null, start, end, -1, delState, recurRetrieval);
    final List<SearchResultEntry> sres = sr.getIndexer().getSearchResult(sr, 0, -1, desiredAccess);
    final TreeSet<CoreEventInfo> ceis = new TreeSet<>();
    for (final SearchResultEntry sre : sres) {
        final Object o = sre.getEntity();
        if (!(o instanceof EventInfo)) {
            continue;
        }
        final EventInfo ei = (EventInfo) o;
        final BwEvent ev = ei.getEvent();
        restoreCategories(ev);
        final CoreEventInfo cei = postGetEvent(ev, null, ei.getCurrentAccess());
        if (cei == null) {
            continue;
        }
        ceis.add(cei);
    }
    return buildVavail(ceis);
}
Also used : SortTerm(org.bedework.calfacade.filter.SortTerm) CoreEventInfo(org.bedework.calcorei.CoreEventInfo) EventInfo(org.bedework.calfacade.svc.EventInfo) CoreEventInfo(org.bedework.calcorei.CoreEventInfo) ArrayList(java.util.ArrayList) SearchResult(org.bedework.calfacade.indexing.SearchResult) BwEvent(org.bedework.calfacade.BwEvent) BwCalendar(org.bedework.calfacade.BwCalendar) BwCollectionFilter(org.bedework.calfacade.filter.BwCollectionFilter) PropertyInfoIndex(org.bedework.util.calendar.PropertyIndex.PropertyInfoIndex) TreeSet(java.util.TreeSet) FilterBase(org.bedework.caldav.util.filter.FilterBase) SearchResultEntry(org.bedework.calfacade.indexing.SearchResultEntry)

Example 10 with FilterBase

use of org.bedework.caldav.util.filter.FilterBase in project bw-calendar-engine by Bedework.

the class Filters method makeWhere.

/* Generate a where clause for a query which selects the events for the
   * given filter.
   *
   * @param f         Filter element.
   */
private void makeWhere(final FilterBase f) throws CalFacadeException {
    if ((f instanceof AndFilter) || (f instanceof OrFilter)) {
        boolean itsAnd = (f instanceof AndFilter);
        qseg.append('(');
        boolean first = true;
        for (FilterBase flt : f.getChildren()) {
            if (!first) {
                if (itsAnd) {
                    qseg.append(" and ");
                } else {
                    qseg.append(" or ");
                }
            }
            makeWhere(flt);
            first = false;
        }
        qseg.append(")");
    }
    if (f instanceof BwHrefFilter) {
        // Special case this
        qseg.append('(');
        qseg.append(masterName);
        qseg.append(".");
        qseg.append("colPath");
        qseg.append("=:");
        parTerm();
        qseg.append(" and ");
        qseg.append(masterName);
        qseg.append(".");
        qseg.append("name");
        qseg.append("=:");
        parTerm();
        qseg.append(')');
        queryLimited = true;
    } else if (f instanceof PropertyFilter) {
        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 multi = pi.getMultiValued();
        boolean param = pi.getParam();
        if (param) {
            BwIcalPropertyInfoEntry parentPi = BwIcalPropertyInfo.getPinfo(pf.getParentPropertyIndex());
            fieldName = parentPi.getDbFieldName() + "." + fieldName;
        }
        if (multi) {
            if (f instanceof PresenceFilter) {
                PresenceFilter prf = (PresenceFilter) f;
                // qseg.append("(size(");
                qseg.append("((select count(*) from ");
                qseg.append(masterName);
                qseg.append(".");
                qseg.append(fieldName);
                if (pi.getPresenceField() != null) {
                    qseg.append(".");
                    qseg.append(pi.getPresenceField());
                }
                qseg.append(")");
                if (prf.getTestPresent()) {
                    qseg.append(">0)");
                } else {
                    qseg.append("=0)");
                }
            } else if (pf instanceof TimeRangeFilter) {
                String fld = "joined_" + pi.getDbFieldName();
                String subfld = "unknown";
                if (pi.getPindex() == PropertyInfoIndex.VALARM) {
                    subfld = "triggerTime";
                }
                doTimeRange((TimeRangeFilter) pf, false, fld, subfld);
            } else if (pf instanceof BwCategoryFilter) {
                BwCategory cat = ((BwCategoryFilter) pf).getEntity();
                if (cat.unsaved()) {
                    ((BwCategoryFilter) pf).setEntity(cb.getCategory(cat.getUid()));
                }
                qseg.append("(:");
                parTerm();
                if (f.getNot()) {
                    qseg.append(" not");
                }
                qseg.append(" in elements(");
                qseg.append(masterName);
                qseg.append(".");
                qseg.append(fieldName);
                qseg.append("))");
            } else if (pf instanceof BwObjectFilter) {
                // String fld = "joined_" + pi.getField();
                String subfld = "value";
                // if (pi.getPindex() == PropertyInfoIndex.CATEGORIES) {
                // subfld = "word.value";
                // }
                doObject(((BwObjectFilter) pf).getEntity(), masterName, fieldName, subfld, true);
            } else {
                qseg.append("(:");
                parTerm();
                if (f.getNot()) {
                    qseg.append(" not");
                }
                qseg.append(" in elements(");
                qseg.append(masterName);
                qseg.append(".");
                qseg.append(fieldName);
                qseg.append("))");
            }
        // not multi follow
        } else if (f instanceof PresenceFilter) {
            PresenceFilter prf = (PresenceFilter) f;
            qseg.append('(');
            qseg.append(masterName);
            qseg.append(".");
            qseg.append(fieldName);
            if (prf.getTestPresent()) {
                qseg.append(" is not null");
            } else {
                qseg.append(" is null");
            }
            qseg.append(")");
        } else if (pf instanceof EntityTimeRangeFilter) {
            doEntityTimeRange((EntityTimeRangeFilter) pf);
        } else if (pf instanceof TimeRangeFilter) {
            doTimeRange((TimeRangeFilter) pf, (pi.getFieldType().getName().equals(BwDateTime.class.getName())), masterName, fieldName);
        } else if (pf instanceof BwObjectFilter) {
            doObject(((BwObjectFilter) pf).getEntity(), masterName, fieldName, null, false);
        } else {
            /* We assume we can't handle this one as a query.
         */
            throw new CalFacadeException("org.bedework.filters.unknownfilter", String.valueOf(f));
        }
    }
}
Also used : PresenceFilter(org.bedework.caldav.util.filter.PresenceFilter) BwDateTime(org.bedework.calfacade.BwDateTime) BwHrefFilter(org.bedework.calfacade.filter.BwHrefFilter) EntityTimeRangeFilter(org.bedework.caldav.util.filter.EntityTimeRangeFilter) TimeRangeFilter(org.bedework.caldav.util.filter.TimeRangeFilter) BwCategory(org.bedework.calfacade.BwCategory) BwCategoryFilter(org.bedework.calfacade.filter.BwCategoryFilter) OrFilter(org.bedework.caldav.util.filter.OrFilter) EntityTimeRangeFilter(org.bedework.caldav.util.filter.EntityTimeRangeFilter) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException) AndFilter(org.bedework.caldav.util.filter.AndFilter) BwIcalPropertyInfoEntry(org.bedework.calfacade.ical.BwIcalPropertyInfo.BwIcalPropertyInfoEntry) PropertyFilter(org.bedework.caldav.util.filter.PropertyFilter) FilterBase(org.bedework.caldav.util.filter.FilterBase) BwObjectFilter(org.bedework.calfacade.filter.BwObjectFilter)

Aggregations

FilterBase (org.bedework.caldav.util.filter.FilterBase)25 CalFacadeException (org.bedework.calfacade.exc.CalFacadeException)9 ArrayList (java.util.ArrayList)8 OrFilter (org.bedework.caldav.util.filter.OrFilter)8 BwCalendar (org.bedework.calfacade.BwCalendar)8 AndFilter (org.bedework.caldav.util.filter.AndFilter)7 EntityTimeRangeFilter (org.bedework.caldav.util.filter.EntityTimeRangeFilter)5 PresenceFilter (org.bedework.caldav.util.filter.PresenceFilter)5 TimeRangeFilter (org.bedework.caldav.util.filter.TimeRangeFilter)5 BwObjectFilter (org.bedework.calfacade.filter.BwObjectFilter)5 ObjectFilter (org.bedework.caldav.util.filter.ObjectFilter)4 PropertyFilter (org.bedework.caldav.util.filter.PropertyFilter)4 BwCategoryFilter (org.bedework.calfacade.filter.BwCategoryFilter)4 EventInfo (org.bedework.calfacade.svc.EventInfo)4 TreeSet (java.util.TreeSet)3 BwCategory (org.bedework.calfacade.BwCategory)3 BwEvent (org.bedework.calfacade.BwEvent)3 BwHrefFilter (org.bedework.calfacade.filter.BwHrefFilter)3 BwIcalPropertyInfoEntry (org.bedework.calfacade.ical.BwIcalPropertyInfo.BwIcalPropertyInfoEntry)3 ToString (org.bedework.util.misc.ToString)3