package it.cavallium.strangedb.java.objects.lists; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public abstract class ListQuery { public static ListQuery create(ValuePointer valuePointer, ValueOperation valueOperation) { return new ListQueryElement(valuePointer, valueOperation); } public ListQuery and(ValuePointer valuePointer, ValueOperation operation) { return new ListQueryAnd(this, create(valuePointer, operation)); } public ListQuery and(ListQuery query) { return new ListQueryAnd(this, query); } public ListQuery or(ValuePointer valuePointer, ValueOperation operation) { return new ListQueryOr(this, create(valuePointer, operation)); } public ListQuery or(ListQuery query) { return new ListQueryOr(this, query); } abstract List getQueryElementsRecursively(); static class ListQueryElement extends ListQuery { public final ValuePointer valuePointer; public final ValueOperation valueOperation; private ListQueryElement(ValuePointer valuePointer, ValueOperation valueOperation) { this.valuePointer = valuePointer; this.valueOperation = valueOperation; } @Override List getQueryElementsRecursively() { return Collections.singletonList(this); } } static class ListQueryCollection extends ListQuery { protected ListQuery[] queries; private ListQueryCollection(ListQuery... queries) { this.queries = queries; } @Override List getQueryElementsRecursively() { List elements = new ArrayList<>(); for (ListQuery query : queries) { elements.addAll(query.getQueryElementsRecursively()); } return elements; } ListQuery[] getQueryChildren() { return queries.clone(); } } static class ListQueryAnd extends ListQueryCollection { private ListQueryAnd(ListQuery... queries) { super(queries); } @Override public ListQuery and(ListQuery query) { return new ListQueryAnd(append(this.queries, query)); } @Override public ListQuery and(ValuePointer valuePointer, ValueOperation operation) { return and(create(valuePointer, operation)); } } static class ListQueryOr extends ListQueryCollection { private ListQueryOr(ListQuery... queries) { super(queries); } @Override public ListQuery or(ListQuery query) { return new ListQueryOr(append(this.queries, query)); } @Override public ListQuery or(ValuePointer valuePointer, ValueOperation operation) { return or(create(valuePointer, operation)); } } private static T[] append(T[] array, T value) { T[] newArray = Arrays.copyOf(array, array.length + 1); newArray[array.length] = value; return newArray; } }