/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.queries;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;

/**
* <p><b>Purpose</b>:
* This policy defines the configuration options for a Query By Example query.
*
* <p><b>Description</b>:
* A Query By Example query is an <code>ObjectLevelReadQuery</code> where the
* selection criteria is built from an example domain object passed in via <code>setExampleObject</code>.
* <p>
* If no policy is specified the selection criteria is built from the example
* object in the following way:
* <ul>
* <li>Attributes of the example object set to <code>null</code> are ignored.
*
* <li>Attributes set to the default value for their primitive type (such as
* <code>0</code> for <code>int</code>) are ignored.
*
* <li>Unmapped attributes are ignored.
*
* <li>A domain object is returned by the query only if its values for all the
* included attributes equal those set in the example object.
* </ul><p>
* A policy can be set on the query to:
* <ul>
* <li>Always consider an attribute even if set to <code>null</code>
* or the default value for its type.  See {@link #alwaysIncludeAttribute alwaysIncludeAttribute}.
*
* <li>Ignore attributes set to some other special value.  See
* {@link #excludeValue(Object) excludeValue}.
*
* <li>Match a <code>null</code> attribute on the example object with domain objects that have
* either <code>null</code> for that attribute also, or have set a meaningful (<code>notNull</code>) value
* for that attribute.  See {@link #setShouldUseEqualityForNulls}.
*
* <li>Use specialized operations when comparing attributes set in the example object
* with those set in the domain objects.  Matching attributes can be those with
* values greater than, less than, like, or not equal to that set in the example
* object.  See {@link #addSpecialOperation}.
* </ul>
* <p>
* Note: When setting an attribute on the example object which is itself a java
* object with an ObjectReferenceMapping, the mapped components of that
* attribute will be considered, not the entire object.  There is no limit to
* how many mapped objects can be nested inside the example object.
* <p>
* Note: <code>setExampleObject</code> is different from <code>setSelectionObject</code> in
* <code>ReadObjectQuery</code> which reads a single object by first extracting
* the primary key from the selection object.
* <p>
* <b>Restrictions</b>:
* <ul>
* <li>Only attributes whose mappings are DirectToField, Aggregate (Embeddable), ObjectReference
* (OneToOne) or Collection type OneToMany/ManyToMany are considered in a Query By Example object.  The behaviour when an example object has attribute values for other mappings types is <b>undefined</b>.
* <ul><li>To ensure the example does not include any unsupported mappings the flag {@link #setValidateExample}
* should be set to true on the corresponding QueryByExamplePolicy to ensure no unsupported relationship types are used in the example.</li>
* <li> For OneToMany and ManyToMany mappings the elements within the collections and the references attribute values will be added to the expression as disjuncts (OR)</li>
* </ul>
* </li>
* </ul>
* <p>
* <b>Example</b>:
* <BLOCKQUOTE><PRE>
* // This example uses like for Strings and the salary must be greater
* // than zero.
* ReadAllQuery query = new ReadAllQuery();
* Employee employee = new Employee();
* employee.setFirstName("B%");
* employee.setLastName("S%");
* employee.setSalary(0);
* query.setExampleObject(employee);
* QueryByExamplePolicy policy = new QueryByExamplePolicy();
* policy.addSpecialOperation(String.class, "like");
* policy.addSpecialOperation(Integer.class, "greaterThan");
* policy.alwaysIncludeAttribute(Employee.class, "salary");
* query.setQueryByExamplePolicy(policy);
* Vector results = (Vector) session.executeQuery(query);
* </PRE></BLOCKQUOTE>
* @see ObjectLevelReadQuery#setExampleObject
* @see ObjectLevelReadQuery#setQueryByExamplePolicy
*
* @since TOPLink/Java 3.0
*/
public class QueryByExamplePolicy implements java.io.Serializable {
    //CR3400 Make Serializable
    public Map valuesToExclude = new HashMap();
    public Map attributesToAlwaysInclude = new HashMap();
    public Map specialOperations = new HashMap();
    public boolean shouldUseEqualityForNulls;
    protected boolean validateExample;

    /**
     * PUBLIC:
     * Constructs a default policy equal to that used when no policy is specified.
     * <p>
     * Sets the default values to be excluded,
     * (that includes 0, false, empty String, etc).<p>
     * By default if an attribute is <code>null</code>, and yet has to be included at all times, equality (<code>isNull</code>)
     * is used for the comparison.  This is used for searching for an object with a <code>null</code> in a certain field.
     * @see #excludeDefaultPrimitiveValues
     * @see #setShouldUseEqualityForNulls setShouldUseEqualityForNulls(true)
     */
    public QueryByExamplePolicy() {
        this.valuesToExclude = new HashMap(10);
        this.attributesToAlwaysInclude = new HashMap(5);
        this.specialOperations = new HashMap(5);
        this.shouldUseEqualityForNulls = true;

        this.excludeDefaultPrimitiveValues();
    }

    /**
     * PUBLIC:
     * Allows operations other than <code>Expression.equal</code> to be used
     * for comparisons.
     * <p>
     * For example if an attribute of type <code>int</code> is
     * set to <code>x</code> in the example object, normally the query will be on all objects
     * whose attributes are also equal to <code>x</code>.  The query could however be all
     * objects whose attributes are not <code>x</code>, greater than <code>x</code>, or even less than or
     * equal to <code>x</code>.
     * <p>
     * Any comparison operation in {@link org.eclipse.persistence.expressions.Expression Expression} which takes the example attribute as a parameter
     * can be used.  A list of supported operations is provided below.
     * <p>
     * Note: A special operation can not be used for attributes set to <code>null</code>.  The only
     * options are {@link org.eclipse.persistence.expressions.Expression#isNull() isNull} (default) and
     * {@link org.eclipse.persistence.expressions.Expression#notNull() notNull}.  See
     * {@link #setShouldUseEqualityForNulls}.
     * @param attributeValueClass Attribute values of which type, for instance
     * <code>Integer</code>, to apply to.  Note for <code>int</code> attributes the
     * class is <code>Integer.class</code> not <code>int.class</code>.  This is not
     * the <code>Class</code> of the example object the attribute is an instance variable of.
     * @param operation Name of method in <code>Expression</code> used
     * @see org.eclipse.persistence.expressions.Expression#equal equal (default)
     * @see org.eclipse.persistence.expressions.Expression#notEqual notEqual
     * @see org.eclipse.persistence.expressions.Expression#equalsIgnoreCase equalsIgnoreCase
     * @see org.eclipse.persistence.expressions.Expression#lessThan lessThan
     * @see org.eclipse.persistence.expressions.Expression#lessThanEqual lessThanEqual
     * @see org.eclipse.persistence.expressions.Expression#greaterThan greaterThan
     * @see org.eclipse.persistence.expressions.Expression#greaterThanEqual greaterThanEqual
     * @see org.eclipse.persistence.expressions.Expression#like like
     * @see org.eclipse.persistence.expressions.Expression#likeIgnoreCase likeIgnoreCase
     * @see org.eclipse.persistence.expressions.Expression#containsAllKeyWords containsAllKeyWords
     * @see org.eclipse.persistence.expressions.Expression#containsAnyKeyWords containsAnyKeyWords
     * @see org.eclipse.persistence.expressions.Expression#containsSubstring(java.lang.String) containsSubstring
     * @see org.eclipse.persistence.expressions.Expression#containsSubstringIgnoringCase(java.lang.String) containsSubstringIgnoringCase
     */
    public void addSpecialOperation(Class attributeValueClass, String operation) {
        this.getSpecialOperations().put(attributeValueClass, operation);
    }

    /**
     * PUBLIC:
     * Always considers the value for a particular attribute as meaningful in a
     * query by example.
     * <p>
     * Required to override the normal behavior which is to ignore an
     * attribute of the example object if set to <code>null</code>, or an excluded value
     * like <code>0</code>.
     * <p>
     * Example: To find all projects without a budget set <code>budget</code> to 0 in the
     * example object and call <code>alwaysIncludeAttribute(Project.class, "budget")</code>
     * on the policy.
     *
     * @param exampleClass The class that the attribute belongs to, normally this is the example class unless using nested QBE.
     * @param attributeName The name of a mapped attribute.
     */
    public void alwaysIncludeAttribute(Class exampleClass, String attributeName) {
        Vector included = (Vector)getAttributesToAlwaysInclude().get(exampleClass);
        if (included == null) {
            included = new Vector(3);
        }
        included.addElement(attributeName);

        getAttributesToAlwaysInclude().put(exampleClass, included);
    }

    /**
     * INTERNAL:
     * This method is used to determine which operation to use for comparison (equal, or a special operation).
     */
    public Expression completeExpression(Expression expression, Object attributeValue, Class attributeValueClass) {
        String operation = this.getOperation(attributeValue.getClass());

        if (operation == null) {
            //it means no special operation used. Use equal.
            return expression.equal(attributeValue);
        }

        Class[] argTypes = { attributeValueClass };
        Object[] args = { attributeValue };
        try {
            java.lang.reflect.Method anOperator = Helper.getDeclaredMethod(ClassConstants.Expression_Class, operation, argTypes);
            if (anOperator == null) {
                throw QueryException.methodDoesNotExistOnExpression(operation, argTypes);
            }
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try{
                    expression = (Expression)AccessController.doPrivileged(new PrivilegedMethodInvoker(anOperator, expression, args));
                }catch (PrivilegedActionException ex){
                    throw (RuntimeException) ex.getCause();
                }
            }else{
                expression = PrivilegedAccessHelper.invokeMethod(anOperator, expression, args);
            }
        } catch (NoSuchMethodException nsme) {
            Class superClass = attributeValueClass.getSuperclass();
            if (superClass != null) {
                return completeExpression(expression, attributeValue, superClass);
            } else {
                throw QueryException.methodDoesNotExistOnExpression(operation, argTypes);
            }
        } catch (IllegalAccessException iae) {
            throw QueryException.methodDoesNotExistOnExpression(operation, argTypes);
        } catch (java.lang.reflect.InvocationTargetException ite) {
            throw QueryException.methodDoesNotExistOnExpression(operation, argTypes);
        }
        return expression;
    }

    /**
     * INTERNAL:
     * This method is used when the attribute value is null, but it has
     * to be included at all times. It determines whether to use isNull, or notNull.
     */
    public Expression completeExpressionForNull(Expression expression) {
        if (shouldUseEqualityForNulls()) {
            return expression.isNull();
        } else {
            return expression.notNull();
        }
    }

    /**
     * PUBLIC:
     * Ignores attributes set to the default value for their primitive type.
     * <p>
     * For instance <code>0</code> is used as <code>null</code> for deciding
     * which <code>int</code> attributes of the example object can be ignored in a
     * query by example.
     * <p>
     * Called by the constructor.
     */
    public void excludeDefaultPrimitiveValues() {
        excludeValue(0);
        excludeValue(0.0);
        excludeValue(false);
        excludeValue((short)0);
        excludeValue('\u0000');
        excludeValue((long)0);
        excludeValue((byte)0);
        excludeValue(0.0f);
        excludeValue("");
    }

    /**
     * PUBLIC:
     * An attribute in the example object set to an excluded value will be
     * ignored in a Query By Example.<p>
     * The default excluded value for <code>byte</code> is <code>0</code>.
     */
    public void excludeValue(byte value) {
        excludeValue(Byte.valueOf(value));
    }

    /**
     * PUBLIC:
     * An attribute in the example object set to an excluded value will be
     * ignored in a Query By Example.<p>
     * The default excluded value for <code>char</code> is <code>'\u0000'</code>.
     */
    public void excludeValue(char value) {
        excludeValue(Character.valueOf(value));
    }

    /**
     * PUBLIC:
     * An attribute in the example object set to an excluded value will be
     * ignored in a Query By Example.<p>
     * The default excluded value for <code>double</code> is <code>0.0</code>.
     */
    public void excludeValue(double value) {
        excludeValue(Double.valueOf(value));
    }

    /**
     * PUBLIC:
     * An attribute in the example object set to an excluded value will be
     * ignored in a Query By Example.<p>
     * The default excluded value for <code>float</code> is <code>0.0f</code>.
     */
    public void excludeValue(float value) {
        excludeValue(Float.valueOf(value));
    }

    /**
     * PUBLIC:
     * An attribute in the example object set to be an excluded value will be
     * ignored in a Query By Example.<p>
     * The default excluded value for <code>int</code> is <code>0</code>.
     */
    public void excludeValue(int value) {
        excludeValue(Integer.valueOf(value));
    }

    /**
     * PUBLIC:
     * An attribute in the example object set to an excluded value will be
     * ignored in a Query By Example.<p>
     * The default excluded value for <code>long</code> is <code>0</code>.
     */
    public void excludeValue(long value) {
        excludeValue(Long.valueOf(value));
    }

    /**
     * PUBLIC:
     * An attribute in the example object set to an excluded value will be
     * ignored in a Query By Example.<p>
     * The default excluded value for <code>String</code> is <code>""</code>.<p>
     * Note: <code>null</code> is special and always considered an excluded value.
     */
    public void excludeValue(Object value) {
        this.valuesToExclude.put(value, value);
    }

    /**
     * PUBLIC:
     * An attribute in the example object set to an excluded value will be
     * ignored in a Query By Example.<p>
     * The default excluded value for <code>short</code> is <code>0</code>.
     */
    public void excludeValue(short value) {
        excludeValue(Short.valueOf(value));
    }

    /**
     * PUBLIC:
     * An attribute in the example object set to an excluded value will be
     * ignored in a Query By Example.<p>
     * The default excluded value for <code>boolean</code> is <code>false</code>.
     */
    public void excludeValue(boolean value) {
        excludeValue(Boolean.valueOf(value));
    }

    /**
     * PUBLIC:
     * Attributes to always consider even if set to <code>null</code> or an excluded
     * value like <code>0</code> or <code>false</code>.
     * @see #alwaysIncludeAttribute
     */
    public Map getAttributesToAlwaysInclude() {
        return attributesToAlwaysInclude;
    }

    /**
     * INTERNAL:
     * determines which operation to use for comparison.
     */
    public String getOperation(Class aClass) {
        String operation = (String)this.getSpecialOperations().get(aClass);
        if (operation != null) {
            if (!operation.equals("equal")) {
                return operation;
            }
        }
        return null;

    }

    /**
     * PUBLIC:
     * The special operations to use in place of <code>equal</code>.
     * @return A hashtable where the keys are <code>Class</code> objects and the values
     * are the names of operations to use for attributes of that <code>Class</code>.
     * @see #addSpecialOperation
     */
    public Map getSpecialOperations() {
        return specialOperations;
    }

    /**
     * PUBLIC:
     * Decides which attributes to ignore based on the values they are set to.
     * <p>
     * If an attribute of the example domain object is set to one of these values it will
     * be ignored, and not considered in the query.
     * <p>
     * Attributes set to excluded values are not always ignored.
     * See {@link #alwaysIncludeAttribute alwaysIncludeAttribute}.
     * @return valuesToExclude The keys and values are values to exclude (key == value).  Primitives are
     * wrapped, so <code>int 0</code> will be stored as <code>Integer(0)</code>.
     * @see #excludeValue
     * @see #excludeDefaultPrimitiveValues
     * @see #includeAllValues
     */
    public Map getValuesToExclude() {
        return valuesToExclude;
    }

    /**
     * PUBLIC:
     * Considers all mapped attributes in the example object as meaningful in a
     * Query By Example.<p>
     * Note: Even attributes of the example object that are
     * not set, and therefore zero or empty by default, will be included.<p>
     * Reverses a previous call to {@link #excludeDefaultPrimitiveValues}.
     */
    public void includeAllValues() {
        setValuesToExclude(new HashMap(5));
    }

    /**
     * INTERNAL:
     * returns whether the attributeName is to be always included.
     */
    public boolean isAlwaysIncluded(Class theClass, String attributeName) {
        Vector values = (Vector)this.getAttributesToAlwaysInclude().get(theClass);
        if (values != null) {
            return (values.contains(attributeName));
        }
        return false;

    }

    /**
     * INTERNAL:
     * returns if the value is in the values to be excluded automatically.
     */
    public boolean isExcludedValue(Object value) {
        return this.getValuesToExclude().containsKey(value);

    }

    /**
     * PUBLIC:
     * Considers all attributes set to a previously excluded value on the example object.
     * <p>
     * Primitive values to be removed must first be wrapped inside an Object.
     *
     * @param value No attributes set to <code>value</code> will be excluded from a Query By Example.
     * <code>value.getClass()</code> is a key of the Hashtable returned by {@link #getValuesToExclude}.
     * <p>Note: There is a distinction between an attribute and the value
     * it is set to.  An attribute can be included independently of its value with
     * {@link #alwaysIncludeAttribute alwaysIncludeAttribute} (recommended).  It can also be included
     * by making the value it is set to no longer excluded.
     * <p>Note: <code>null</code> values are special and will always be excluded.
     * @see #excludeDefaultPrimitiveValues
     * @see #includeAllValues
     * @see #excludeValue(Object)
     */
    public void removeFromValuesToExclude(Object value) {
        getValuesToExclude().remove(value);
    }

    /**
     * INTERNAL:
     * It is possible to generate a Hashtable (keys are the Class, and values the attribute names)
     * of the attributes to be included at all times (even if the value is null, or the value
     * belongs to the values to be excluced automatically).
     */
    public void setAttributesToAlwaysInclude(Map newAttributesToAlwaysInclude) {
        attributesToAlwaysInclude = newAttributesToAlwaysInclude;
    }

    /**
     * PUBLIC:
     * Matches an included <code>null</code> attribute in the example object
     * either to objects with that attribute also set to <code>null</code> or to any
     * value other than <code>null</code>.
     * <p>
     * Set to <code>false</code> to only select objects where certain attributes have been set.
     * <p>
     * Example: to find all Employees with an assigned <code>address</code>, set
     * attribute <code>address</code> to <code>null</code> in the example object,
     * call <code>alwaysIncludeAttribute(Employee.class, "address")</code> and then
     * call <code>setShouldUseEqualityForNulls(false)</code>.
     * <p>
     * Note: Unless an attribute set to <code>null</code> is specifically included, it
     * will not be considered at all in the Query By Example.
     * @param shouldUseEqualityForNulls If true (by default) uses <code>isNull</code> else <code>notNull</code>.
     * @see #addSpecialOperation addSpecialOperation
     * @see #alwaysIncludeAttribute alwaysIncludeAttribute
     */
    public void setShouldUseEqualityForNulls(boolean shouldUseEqualityForNulls) {
        this.shouldUseEqualityForNulls = shouldUseEqualityForNulls;
    }

    /**
     * PUBLIC:
     * The special operations to use in place of <code>equal</code>.
     * @param newOperations A hashtable where the keys are <code>Class</code> objects and the values
     * are the names of operations to use for attributes of that <code>Class</code>.
     * @see #addSpecialOperation
     */
    public void setSpecialOperations(Map newOperations) {
        specialOperations = newOperations;
    }

    /**
     * PUBLIC:
     * When set to <code>true</code> the example object will be validated for unsupported mapping types.
     * If you wish these mapping types to be ignored either set this flag to <code>false</code> or add the attribute
     * to the list of ignored attributes in this policy
     */
    public void setValidateExample(boolean validate){
        this.validateExample = validate;
    }

    /**
     * PUBLIC:
     * Decides which attributes to ignore based on the values they are set to.
     * <p>
     * An attribute of the example domain object set to one of these values will
     * be ignored, and not considered in the query.
     * <p>
     * Attributes set to excluded values are not always ignored.
     * See {@link #alwaysIncludeAttribute alwaysIncludeAttribute}.
     * @param newValuesToExclude The keys and values are values to exclude (key == value).  Primitives are
     * wrapped, so <code>int 0</code> will be stored as <code>Integer(0)</code>.
     * @see #excludeValue
     * @see #excludeDefaultPrimitiveValues
     * @see #includeAllValues
     */
    public void setValuesToExclude(Map newValuesToExclude) {
        valuesToExclude = newValuesToExclude;
    }

    /**
     * INTERNAL:
     * This method determines whether an attribute pair is be included in the query.
     */
    public boolean shouldIncludeInQuery(Class aClass, String attributeName, Object attributeValue) {
        if (attributeValue == null) {
            if (this.isAlwaysIncluded(aClass, attributeName)) {
                //this attribute is to be included always, even if its value is null.
                return true;
            } else {
                return false;
            }
        }

        if (this.isExcludedValue(attributeValue)) {
            if (this.isAlwaysIncluded(aClass, attributeName)) {
                //this attribute is to be included always, even if its value belongs to the list of values to be excluded.
                return true;
            } else {
                return false;
            }
        }

        return true;
    }

    /**
     * PUBLIC:
     * Matches an included <code>null</code> attribute in the example object
     * either to objects with that attribute also set to <code>null</code> or to any
     * value other than <code>null</code>.
     * <p>
     * Set to <code>false</code> to only select objects where certain attributes have been set.
     * <p>
     * Example: to find all Employees with an assigned <code>address</code>, set
     * attribute <code>address</code> to <code>null</code> in the example object,
     * call <code>alwaysIncludeAttribute(Employee.class, "address")</code> and then
     * call <code>setShouldUseEqualityForNulls(false)</code>.
     *
     * @return If true (by default) uses <code>isNull</code> else <code>notNull</code>.
     * @see #addSpecialOperation addSpecialOperation
     * @see #alwaysIncludeAttribute alwaysIncludeAttribute
     */
    public boolean shouldUseEqualityForNulls() {
        return shouldUseEqualityForNulls;
    }

    /**
     * PUBLIC:
     * Returns true if the example object used with this policy should be validated for attributes
     * with unsupported mappings.
     */
    public boolean shouldValidateExample(){
        return this.validateExample;
    }
}
