package com.silverforge.elasticsearchrawclient.queryDSL.queries.innerQueries; import android.text.TextUtils; import com.google.common.base.Optional; import com.silverforge.elasticsearchrawclient.exceptions.MandatoryParametersAreMissingException; import com.silverforge.elasticsearchrawclient.model.GeoPoint; import com.silverforge.elasticsearchrawclient.model.QueryTypeItem; import com.silverforge.elasticsearchrawclient.queryDSL.Constants; import com.silverforge.elasticsearchrawclient.definition.Queryable; import com.silverforge.elasticsearchrawclient.queryDSL.generator.QueryFactory; import com.silverforge.elasticsearchrawclient.queryDSL.operators.GeoShapeTypeOperator; import com.silverforge.elasticsearchrawclient.utils.QueryTypeArrayList; import com.silverforge.elasticsearchrawclient.utils.StringUtils; import java.util.ArrayList; import java.util.List; import static br.com.zbra.androidlinq.Linq.*; public class GeoShapeQuery implements Queryable { private QueryTypeArrayList<QueryTypeItem> queryBag; GeoShapeQuery(QueryTypeArrayList<QueryTypeItem> queryBag) { this.queryBag = queryBag; } @Override public String getQueryString() { return QueryFactory .geoShapeQueryGenerator() .generate(queryBag); } public static GeoShapeQueryBuilder builder() { return new GeoShapeQueryBuilder(); } public static class GeoShapeQueryBuilder extends Init<GeoShapeQueryBuilder> { @Override protected GeoShapeQueryBuilder self() { return this; } } public static abstract class Init<T extends Init<T>> { private QueryTypeArrayList<QueryTypeItem> queryBag = new QueryTypeArrayList<>(); protected abstract T self(); public T fieldName(String fieldName) { if (TextUtils.isEmpty(fieldName)) return allFields(); queryBag.addParentItem(Constants.FIELD_NAME, fieldName); return self(); } public T allFields() { queryBag.addParentItem(Constants.FIELD_NAME, "_all"); return self(); } public T type(GeoShapeTypeOperator geoShapeTypeOperator) { String value = geoShapeTypeOperator.toString(); queryBag.addItem(Constants.TYPE, value); return self(); } public T coordinates(GeoPoint geoPoint) { queryBag.addItem(Constants.COORDINATES, geoPoint); return self(); } public T coordinates(List<GeoPoint> coordinates) { Optional<List<GeoPoint>> coordinateItems = Optional.fromNullable(coordinates); List<GeoPoint> coordinateList = coordinateItems.or(new ArrayList<>()); List<String> geoPointStrings = stream(coordinateList) .select(c -> { String value = String.format("[%s,%s]", c.getLongitude(), c.getLatitude()); return value; }) .toList(); String value = "[" + StringUtils.makeCommaSeparatedList(geoPointStrings) + "]"; queryBag.addItem(Constants.COORDINATES, value); return self(); } public T multiCoordinates(List<List<GeoPoint>> coordinates) { Optional<List<List<GeoPoint>>> coordinateItems = Optional.fromNullable(coordinates); List<List<GeoPoint>> coordinateList = coordinateItems.or(new ArrayList<>(new ArrayList<>())); List<String> geoPointStrings = stream(coordinateList) .select(outerlist -> { List<String> geoList = stream(outerlist) .select(c -> { String value = String.format("[%s,%s]", c.getLongitude(), c.getLatitude()); return value; }) .toList(); String retValue = "[" + StringUtils.makeCommaSeparatedList(geoList) + "]"; return retValue; }) .toList(); String value = "[" + StringUtils.makeCommaSeparatedList(geoPointStrings) + "]"; queryBag.addItem(Constants.COORDINATES, value); return self(); } public T multiPolygonCoordinates(List<List<List<GeoPoint>>> coordinates) { Optional<List<List<List<GeoPoint>>>> coordinateItems = Optional.fromNullable(coordinates); List<List<List<GeoPoint>>> hyperCoordinateList = coordinateItems.or(new ArrayList<>(new ArrayList<>(new ArrayList()))); List<String> insaneList = stream(hyperCoordinateList) .select(hc -> { List<String> hyperList = stream(hc) .select(mc -> { List<String> multiList = stream(mc) .select(c -> { String value = String.format("[%s,%s]", c.getLongitude(), c.getLatitude()); return value; }) .toList(); String value = "[" + StringUtils.makeCommaSeparatedList(multiList) + "]"; return value; }) .toList(); String value = "[" + StringUtils.makeCommaSeparatedList(hyperList) + "]"; return value; }) .toList(); String retValue = "[" + StringUtils.makeCommaSeparatedList(insaneList) + "]"; queryBag.addItem(Constants.COORDINATES, retValue); return self(); } public T indexedShape() { queryBag.addItem(Constants.INDEXED_SHAPE, Constants.INDEXED_SHAPE); return self(); } public T id(String id) { queryBag.addItem(Constants.ID, id); return self(); } public T type(String type) { queryBag.addItem(Constants.TYPE, type); return self(); } public T index(String index) { queryBag.addItem(Constants.INDEX, index); return self(); } public T path(String path) { queryBag.addItem(Constants.PATH, path); return self(); } public GeoShapeQuery build() throws MandatoryParametersAreMissingException { if (queryBag.containsKey(Constants.INDEXED_SHAPE)) { int count = stream(queryBag) .where(q -> q.getName().equals(Constants.ID) || q.getName().equals(Constants.TYPE) || q.getName().equals(Constants.INDEX) || q.getName().equals(Constants.PATH)) .count(); if (count < 4) throw new MandatoryParametersAreMissingException( Constants.ID, Constants.TYPE, Constants.INDEX, Constants.PATH); } return new GeoShapeQuery(queryBag); } } }