001/*
002 * (C) Copyright 2017 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *    http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Kevin Leturc <kleturc@nuxeo.com>
018 *
019 */
020package org.nuxeo.ecm.platform.audit.api;
021
022import java.util.ArrayList;
023import java.util.List;
024import java.util.stream.Collectors;
025import java.util.stream.Stream;
026
027import org.apache.commons.lang3.builder.ToStringBuilder;
028import org.nuxeo.ecm.core.query.sql.model.MultiExpression;
029import org.nuxeo.ecm.core.query.sql.model.Operand;
030import org.nuxeo.ecm.core.query.sql.model.Operator;
031import org.nuxeo.ecm.core.query.sql.model.OrderByExpr;
032import org.nuxeo.ecm.core.query.sql.model.OrderByList;
033import org.nuxeo.ecm.core.query.sql.model.Predicate;
034
035/**
036 * Query builder for querying audit.
037 *
038 * @since 9.3
039 */
040public class AuditQueryBuilder {
041
042    /**
043     * Here filter is a {@link MultiExpression} with operator AND by design.
044     */
045    protected MultiExpression filter;
046
047    protected OrderByList orders;
048
049    protected long offset = 0;
050
051    // By default retrieve all results
052    protected long limit = 0;
053
054    public AuditQueryBuilder() {
055        filter = new MultiExpression(Operator.AND, new ArrayList<>());
056        orders = new OrderByList(null); // stupid constructor
057        orders.clear();
058    }
059
060    public Predicate predicate() {
061        return filter;
062    }
063
064    /**
065     * Adds a new predicate to the list of AND predicates.
066     */
067    public AuditQueryBuilder addAndPredicate(Predicate predicate) {
068        filter.values.add(predicate);
069        return this;
070    }
071
072    /**
073     * Sets the predicates to use when querying audit. Filters are composed with an AND operator.
074     */
075    public AuditQueryBuilder predicates(Predicate filter, Predicate... filters) {
076        return predicates(Stream.concat(Stream.of(filter), Stream.of(filters)).collect(Collectors.toList()));
077    }
078
079    /**
080     * Sets the predicates to use when querying audit. Filters are composed with an AND operator.
081     */
082    @SuppressWarnings("unchecked")
083    public AuditQueryBuilder predicates(List<Predicate> filters) {
084        this.filter = new MultiExpression(Operator.AND, (List<Operand>) ((List<?>) filters));
085        return this;
086    }
087
088    /**
089     * We currently only need to handle object instantiated through {@link OrderByExprs}.
090     */
091    public OrderByList orders() {
092        return orders;
093    }
094
095    public AuditQueryBuilder defaultOrder() {
096        return orders(OrderByExprs.desc(BuiltinLogEntryData.LOG_EVENT_DATE));
097    }
098
099    /**
100     * Adds a new order to this query builder.
101     */
102    public AuditQueryBuilder order(OrderByExpr order) {
103       this.orders.add(order);
104        return this;
105    }
106
107    /**
108     * Sets the orders to use when querying audit.
109     */
110    public AuditQueryBuilder orders(OrderByExpr order, OrderByExpr... orders) {
111        return orders(Stream.concat(Stream.of(order), Stream.of(orders)).collect(Collectors.toList()));
112    }
113
114    /**
115     * Sets the orders to use when querying audit.
116     */
117    public AuditQueryBuilder orders(List<OrderByExpr> orders) {
118        this.orders.clear();
119        this.orders.addAll(orders);
120        return this;
121    }
122
123    public long offset() {
124        return offset;
125    }
126
127    public AuditQueryBuilder offset(long offset) {
128        this.offset = offset;
129        return this;
130    }
131
132    public long limit() {
133        return limit;
134    }
135
136    public AuditQueryBuilder limit(long limit) {
137        this.limit = limit;
138        return this;
139    }
140
141    @Override
142    public String toString() {
143        return ToStringBuilder.reflectionToString(this);
144    }
145
146}