/*
 * Copyright (c) 1998, 2020 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.
     * <p>
     * @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 = (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.
     * <p>
     * @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>.<p>
     * @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>.
     * <p>
     * @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;
    }
}
