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.core.query.sql.model;
021
022import java.util.stream.Collectors;
023import java.util.stream.Stream;
024import java.util.stream.StreamSupport;
025
026/**
027 * Predicate builders.
028 *
029 * @since 9.3
030 */
031public class Predicates {
032
033    private Predicates() {
034        // no instantiation allowed
035    }
036
037    /** @since 10.3 */
038    public static Predicate and(Predicate left, Predicate right) {
039        return new Predicate(left, Operator.AND, right);
040    }
041
042    /** @since 10.3 */
043    public static Predicate or(Predicate left, Predicate right) {
044        return new Predicate(left, Operator.OR, right);
045    }
046
047    /** @since 10.3 */
048    public static Predicate not(Predicate predicate) {
049        return new Predicate(predicate, Operator.NOT, null);
050    }
051
052    public static Predicate eq(String name, Object value) {
053        return createPredicate(name, Operator.EQ, value);
054    }
055
056    /** @since 10.3 */
057    public static Predicate noteq(String name, Object value) {
058        return createPredicate(name, Operator.NOTEQ, value);
059    }
060
061    public static Predicate lt(String name, Object value) {
062        return createPredicate(name, Operator.LT, value);
063    }
064
065    public static Predicate lte(String name, Object value) {
066        return createPredicate(name, Operator.LTEQ, value);
067    }
068
069    public static Predicate gte(String name, Object value) {
070        return createPredicate(name, Operator.GTEQ, value);
071    }
072
073    public static Predicate gt(String name, Object value) {
074        return createPredicate(name, Operator.GT, value);
075    }
076
077    public static Predicate startsWith(String name, Object value) {
078        return createPredicate(name, Operator.STARTSWITH, value);
079    }
080
081    /** @since 10.3 */
082    public static Predicate like(String name, Object value) {
083        return createPredicate(name, Operator.LIKE, value);
084    }
085
086    /** @since 10.3 */
087    public static Predicate notlike(String name, Object value) {
088        return createPredicate(name, Operator.NOTLIKE, value);
089    }
090
091    /** @since 10.3 */
092    public static Predicate ilike(String name, Object value) {
093        return createPredicate(name, Operator.ILIKE, value);
094    }
095
096    /** @since 10.3 */
097    public static Predicate notilike(String name, Object value) {
098        return createPredicate(name, Operator.NOTILIKE, value);
099    }
100
101
102    public static Predicate in(String name, Iterable<?> values) {
103        return createPredicate(name, Operator.IN, StreamSupport.stream(values.spliterator(), false));
104    }
105
106    public static <T> Predicate in(String name, T value, T... values) {
107        return createPredicate(name, Operator.IN, Stream.concat(Stream.of(value), Stream.of(values)));
108    }
109
110    public static Predicate in(String name, Object[] values) {
111        return createPredicate(name, Operator.IN, Stream.of(values));
112    }
113
114    /** @since 10.3 */
115    public static Predicate notin(String name, Iterable<?> values) {
116        return createPredicate(name, Operator.NOTIN, StreamSupport.stream(values.spliterator(), false));
117    }
118
119    /** @since 10.3 */
120    public static <T> Predicate notin(String name, T value, T... values) {
121        return createPredicate(name, Operator.NOTIN, Stream.concat(Stream.of(value), Stream.of(values)));
122    }
123
124    /** @since 10.3 */
125    public static Predicate notin(String name, Object[] values) {
126        return createPredicate(name, Operator.NOTIN, Stream.of(values));
127    }
128
129    /** @since 10.3 */
130    public static Predicate between(String name, Object min, Object max) {
131        LiteralList range = new LiteralList();
132        range.add(Literals.toLiteral(min));
133        range.add(Literals.toLiteral(max));
134        return new Predicate(new Reference(name), Operator.BETWEEN, range);
135    }
136
137    /** @since 10.3 */
138    public static Predicate notbetween(String name, Object min, Object max) {
139        LiteralList range = new LiteralList();
140        range.add(Literals.toLiteral(min));
141        range.add(Literals.toLiteral(max));
142        return new Predicate(new Reference(name), Operator.NOTBETWEEN, range);
143    }
144
145    /** @since 10.3 */
146    public static Predicate isnull(String name) {
147        return new Predicate(new Reference(name), Operator.ISNULL, null);
148    }
149
150    /** @since 10.3 */
151    public static Predicate isnotnull(String name) {
152        return new Predicate(new Reference(name), Operator.ISNOTNULL, null);
153    }
154
155    private static Predicate createPredicate(String name, Operator operator, Object value) {
156        return new Predicate(new Reference(name), operator, Literals.toLiteral(value));
157    }
158
159    private static Predicate createPredicate(String name, Operator operator, Stream<?> values) {
160        return new Predicate(new Reference(name), operator,
161                values.map(Literals::toLiteral).collect(Collectors.toCollection(LiteralList::new)));
162    }
163
164}