/*******************************************************************************
 * Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * 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.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
import org.eclipse.persistence.exceptions.*;

/**
* <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>.</li>
* <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>
* </ul>
* <p>
* <b>Example</b>:
* <PRE><BLOCKQUOTE>
* // 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(Object) isNull} (default) and
     * {@link org.eclipse.persistence.expressions.Expression#notNull(Object) 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(new String(""));
    }

    /**
     * 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;
    }
}
