All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.molgenis.data.QueryRule Maven / Gradle / Ivy

There is a newer version: 8.4.5
Show newest version
package org.molgenis.data;

import static com.google.common.collect.Streams.stream;
import static java.lang.String.format;
import static java.util.stream.Collectors.toList;

import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/** With this class an equation model can be described for a database-field (eg a column). */
@XmlRootElement
public class QueryRule {
  /** The operator being applied to the field and value */
  @XmlElement protected Operator operator;

  /** The field-name (eq column-name) in the database */
  @XmlElement protected String field = null;

  /** The value to compare entries of the field in the database with */
  @XmlElement protected Object value = null;

  protected List nestedRules;

  public QueryRule() {}

  public QueryRule(List nestedRules) {
    this.nestedRules = nestedRules;
    operator = Operator.NESTED;
  }

  public QueryRule(QueryRule copy) {
    operator = copy.operator;
    field = copy.field;
    value = copy.value;
  }

  /** Different types of rules that can be applied. */
  public enum Operator {
    /** 'field' like 'value', searches all fields if field is not defined */
    SEARCH("search"),

    /**
     * 'field' equal to 'value'
     *
     * 

When 'field type' is 'Mref' its results are derived from the 'Contains' behavior.
* Examples:
* 1. ref1 OR ref2 can result in: * *

    *
  • re1 *
  • ref1, ref2 *
  • ref1, ref2, ref3; *
  • ref2 *
  • ref2, ref3 *
* * 2. ref1 AND ref2 can result in: * *
    *
  • ref1, ref2 *
  • ref1, ref2, ref3 *
*/ EQUALS("="), /** 'field' in 'value' (value being a list). */ IN("IN"), /** 'field' less-than 'value' */ LESS("<"), /** 'field' equal-or-less-than 'value' */ LESS_EQUAL("<="), /** 'field' greater-than 'value' */ GREATER(">"), /** 'field' equal-or-greater-than 'value' */ GREATER_EQUAL(">="), /** * 'field' equal-or-greater-than 'from value' and equal-or-less-than 'to value' (value being a * list with 'from value' as first element and 'to value' as second element */ RANGE("RANGE"), /** 'field' like 'value' (works like equals with wildcard before and after value) */ LIKE("LIKE"), /** 'field' not-equal to 'value' */ NOT("!="), /** AND operation */ AND("AND"), /** OR operation */ OR("OR"), /** indicates that 'value' is a nested array of QueryRule. The parameter 'field' is ommitted. */ NESTED(""), /** Boolean query */ SHOULD("SHOULD"), /** Disjunction max query */ DIS_MAX("DIS_MAX"), /** Fuzzy match operator */ FUZZY_MATCH("FUZZY_MATCH"), /** Fuzzy match operator */ FUZZY_MATCH_NGRAM("FUZZY_MATCH_NGRAM"); private String label; /** * Translate String label of the operator to Operator. * * @param label of the operator */ Operator(String label) { this.label = label; } /** Get the String label of the Operator. */ @Override public String toString() { return label; } } // constructor /** * Standard constructor. * *

With this constructor the field, operator and value are set in one go, so there is no need * for additional statements. * * @param field The field-name. * @param operator The operator to use for comparing entries in the field with the value. * @param value The value. */ public QueryRule(String field, Operator operator, Object value) { if (operator == Operator.AND || operator == Operator.OR) { throw new IllegalArgumentException( format("QueryRule(): Operator.%s cannot be used with two arguments", operator)); } this.field = field; this.operator = operator; setValue(value); } /** Specific constructor for rules that do not apply to a field such as LIMIT and OFFSET. */ @SuppressWarnings("unchecked") public QueryRule(Operator operator, Object value) { if (operator == Operator.SEARCH) { this.operator = operator; setValue(value); } else if (Operator.NESTED.equals(operator)) { boolean okay = true; if (value instanceof List) { for (Object o : (List) value) { if (!(o instanceof QueryRule)) okay = false; } } else { okay = false; } if (!okay) throw new IllegalArgumentException( "QueryRule(NESTED, value): value should be List"); this.nestedRules = (List) value; this.operator = operator; } else { throw new IllegalArgumentException( format("QueryRule(): Operator.%s cannot be used with one argument", operator)); } } public QueryRule(Operator operator, QueryRule nestedRules) { if (operator == Operator.NOT) { this.operator = operator; this.nestedRules = Arrays.asList(nestedRules); } else { throw new IllegalArgumentException( format("QueryRule(): Operator.%s cannot be used with one argument", operator)); } } /** Specific constructor for rules that don't have a value or field such as LAST */ public QueryRule(Operator operator) { if (operator == Operator.AND || operator == Operator.OR || operator == Operator.NOT) { this.operator = operator; } else { throw new IllegalArgumentException( format("QueryRule(): Operator.%s cannot be used without arguments", operator)); } } public QueryRule(String field, Operator equals, String value) { this(field, equals, (Object) value); } /** * Returns the field-name set for this rule. * * @return The field-name. */ public String getField() { return field; } /** * Sets a new field-name for this rule. * * @param field The new field-name. */ public void setField(String field) { this.field = field; } /** * Returns the operator set for this rule. * * @return The operator. */ public Operator getOperator() { return operator; } /** * Sets a new operator for this rule. * * @param operator The new operator. */ public void setOperator(Operator operator) { this.operator = operator; } /** * Returns the value set for this rule. * * @return The value. */ public Object getValue() { return value; } /** * Sets a new value for this rule. * * @param value The new value. */ public void setValue(Object value) { if (value instanceof Iterable) { this.value = stream((Iterable) value).map(this::toValue).collect(toList()); } else { this.value = toValue(value); } } private Object toValue(Object value) { if (value instanceof Entity) { return ((Entity) value).getIdValue(); } return value; } /** * Convenience function to return value as nested rule array. * * @return Nested rule set */ public List getNestedRules() { if (nestedRules == null) { return Collections.emptyList(); } return nestedRules; } @Override public String toString() { StringBuilder strBuilder = new StringBuilder(); fieldToString(strBuilder); operatorToString(strBuilder); valueToString(strBuilder); nestedRulesToString(strBuilder); return strBuilder.toString(); } private void fieldToString(StringBuilder strBuilder) { if (field != null) { strBuilder.append('\'').append(field).append('\''); } } private void operatorToString(StringBuilder strBuilder) { if (operator != null && operator != Operator.NESTED) { if (strBuilder.length() > 0) { strBuilder.append(' '); } strBuilder.append(operator); } } private void valueToString(StringBuilder strBuilder) { if (operator != Operator.AND && operator != Operator.OR && operator != Operator.NOT && operator != Operator.NESTED && operator != Operator.DIS_MAX && operator != Operator.SHOULD) { if (strBuilder.length() > 0) { strBuilder.append(' '); } if (operator != Operator.IN) { strBuilder.append('\'').append(value).append('\''); } else { strBuilder.append(value); } } } private void nestedRulesToString(StringBuilder strBuilder) { if (nestedRules != null && !nestedRules.isEmpty()) { if (strBuilder.length() > 0) { strBuilder.append(' '); } strBuilder.append('('); for (Iterator it = nestedRules.iterator(); it.hasNext(); ) { strBuilder.append(it.next()); if (it.hasNext()) { strBuilder.append(", "); } } strBuilder.append(')'); } } public static QueryRule eq(String name, Object value) { return new QueryRule(name, Operator.EQUALS, value); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof QueryRule)) { return false; } QueryRule queryRule = (QueryRule) o; return getOperator() == queryRule.getOperator() && Objects.equals(getField(), queryRule.getField()) && Objects.equals(getValue(), queryRule.getValue()) && Objects.equals(getNestedRules(), queryRule.getNestedRules()); } @Override public int hashCode() { return Objects.hash(getOperator(), getField(), getValue(), getNestedRules()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy