/* * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.data.solr.core.query; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.springframework.data.geo.Box; import org.springframework.data.geo.Distance; import org.springframework.data.geo.Point; /** * @author Christoph Strobl * @since 1.2 */ public class Crotch extends Criteria { private List<Criteria> siblings = new ArrayList<>(); private Node mostRecentSibling = null; Crotch() {} @Override public Field getField() { if (this.mostRecentSibling instanceof Criteria) { return ((Criteria) this.mostRecentSibling).getField(); } return null; } @Override public Crotch is(Object o) { mostRecentSibling.is(o); return this; } @Override public Crotch boost(float boost) { mostRecentSibling.boost(boost); return this; } @Override public Crotch not() { mostRecentSibling.not(); return this; } @Override public Crotch notOperator() { if (this.isRoot()) { this.setNegating(true); } else { super.notOperator(); } return this; } @Override public Crotch endsWith(String postfix) { mostRecentSibling.endsWith(postfix); return this; } @Override public Crotch startsWith(String prefix) { mostRecentSibling.startsWith(prefix); return this; } @Override public Crotch contains(String value) { mostRecentSibling.contains(value); return this; } @Override public Crotch is(Object... values) { mostRecentSibling.is(values); return this; } @Override public Crotch is(Iterable<?> values) { mostRecentSibling.is(values); return this; } @Override public Crotch isNull() { mostRecentSibling.isNull(); return this; } @Override public Crotch isNotNull() { mostRecentSibling.isNotNull(); return this; } @Override public Crotch contains(String... values) { mostRecentSibling.contains(values); return this; } @Override public Crotch contains(Iterable<String> values) { mostRecentSibling.contains(values); return this; } @Override public Crotch startsWith(String... values) { mostRecentSibling.startsWith(values); return this; } @Override public Crotch startsWith(Iterable<String> values) { mostRecentSibling.startsWith(values); return this; } @Override public Crotch endsWith(String... values) { mostRecentSibling.endsWith(values); return this; } @Override public Crotch endsWith(Iterable<String> values) { mostRecentSibling.endsWith(values); return this; } @Override public Crotch fuzzy(String value) { mostRecentSibling.fuzzy(value); return this; } @Override public Crotch fuzzy(String values, float levenshteinDistance) { mostRecentSibling.fuzzy(values, levenshteinDistance); return this; } @Override public Crotch sloppy(String phrase, int distance) { mostRecentSibling.sloppy(phrase, distance); return this; } @Override public Crotch expression(String nativeSolrQueryExpression) { mostRecentSibling.expression(nativeSolrQueryExpression); return this; } @Override public Crotch between(Object lowerBound, Object upperBound) { mostRecentSibling.between(lowerBound, upperBound); return this; } @Override public Crotch between(Object lowerBound, Object upperBound, boolean includeLowerBound, boolean includeUpperBound) { mostRecentSibling.between(lowerBound, upperBound, includeLowerBound, includeUpperBound); return this; } @Override public Crotch lessThan(Object upperBound) { mostRecentSibling.lessThan(upperBound); return this; } @Override public Crotch lessThanEqual(Object upperBound) { mostRecentSibling.lessThanEqual(upperBound); return this; } @Override public Crotch greaterThan(Object lowerBound) { mostRecentSibling.greaterThan(lowerBound); return this; } @Override public Crotch greaterThanEqual(Object lowerBound) { mostRecentSibling.greaterThanEqual(lowerBound); return this; } @Override public Crotch in(Object... values) { mostRecentSibling.in(values); return this; } @Override public Crotch in(Iterable<?> values) { mostRecentSibling.in(values); return this; } @Override public Crotch within(Point location, Distance distance) { mostRecentSibling.within(location, distance); return this; } @Override public Crotch near(Box box) { mostRecentSibling.near(box); return this; } @Override public Crotch near(Point location, Distance distance) { mostRecentSibling.near(location, distance); return this; } @Override public Crotch function(Function function) { mostRecentSibling.function(function); return this; } @Override public String toString() { StringBuilder sb = new StringBuilder(this.isOr() ? " OR " : " AND "); sb.append('('); boolean first = true; for (Node node : this.siblings) { String s = node.toString(); if (first) { s = s.replaceFirst("OR", "").replaceFirst("AND", ""); first = false; } sb.append(s); } sb.append(')'); return sb.toString(); } // ------- NODE STUFF -------- void add(Node node) { if (!(node instanceof Criteria)) { throw new IllegalArgumentException("Can only add instances of Criteria"); } node.setParent(this); this.siblings.add((Criteria) node); this.mostRecentSibling = node; } @Override public Collection<Criteria> getSiblings() { return Collections.unmodifiableCollection(siblings); } @Override public Crotch and(Node part) { add(part); return this; } @Override public Crotch or(Node part) { part.setPartIsOr(true); add(part); return this; } @Override public Crotch and(String fieldname) { if (this.mostRecentSibling instanceof Crotch) { ((Crotch) mostRecentSibling).add(new Criteria(fieldname)); } else { and(new Criteria(fieldname)); } return this; } @Override public Crotch or(String fieldname) { Criteria criteria = new Criteria(fieldname); criteria.setPartIsOr(true); if (this.mostRecentSibling instanceof Crotch) { ((Crotch) mostRecentSibling).add(criteria); } else { or(new Criteria(fieldname)); } return this; } }