/*
 * 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.lang.reflect.*;
import java.security.AccessController;

import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
import org.eclipse.persistence.internal.sessions.AbstractRecord;

/**
 * <p><b>Purpose</b>:</p>
 * Allows a class to be a <code>QueryRedirector</code> without implementing
 * {@link QueryRedirector QueryRedirector}.
 *
 * <p><b>Description</b>:</p>
 * Normally to define a Redirector a Class must implement <code>QueryRedirector</code> and
 * the required {@link QueryRedirector#invokeQuery QueryRedirector.invokeQuery(DatabaseQuery, Record, Session)}.
 * <p>
 * To maintain transparency it is possible to instead only define a static
 * method that takes the same arguments as <code>invokeQuery</code>.
 * </p>
 * An instance of <code>MethodBaseQueryRedirector</code> can be constructed, taking the name of that static
 * method and the <code>Class</code> in which it is defined as parameters.
 * <p>
 * Whenever <code>invokeQuery</code> is called on this instance reflection will
 * automatically be used to invoke the custom method instead.
 * </p>
 * <b>Advantages</b>:
 * <ul>
 * <li> The Redirector class and method name can be specified dynamically.
 * <li> The class containing the <code>invokeQuery</code> method does not need to implement
 * <code>QueryRedirector</code>.
 * <li> The <code>invokeQuery</code> method can have any name.
 * <li> The <code>invokeQuery</code> method can alternatively be defined to accept only
 * <code>Session session</code> and <code>Vector arguments</code> as parameters.
 * </ul>
 * <b>Disadvantages</b>:
 * <ul>
 * <li> An extra step is added as the real <code>invokeQuery</code> method is called
 * dynamically.
 * </ul>
 * <p><b>Example</b>:</p>
 * <BLOCKQUOTE><PRE>
 * // First create a named query, define a redirector for it, and add the query
 * // to the query manager.
 * ReadObjectQuery query = new ReadObjectQuery(Employee.class);
 * query.setName("findEmployeeByAnEmployee");
 * query.addArgument("employee");
 *
 * MethodBaseQueryRedirector redirector = new
 * MethodBaseQueryRedirector(QueryRedirectorTest.class, "findEmployeeByAnEmployee");
 * query.setRedirector(redirector);
 * ClassDescriptor descriptor = getSession().getDescriptor(query.getReferenceClass());
 * descriptor.getQueryManager().addQuery(query.getName(), query);
 *
 * // Now execute the query by name, passing in an Employee as an argument.
 * Vector arguments = new Vector();
 * arguments.addElement(employee);
 * objectFromDatabase =
 * getSession().executeQuery("findEmployeeByAnEmployee", Employee.class, arguments);
 *
 * // Note this Class does not implement QueryRedirector or method invokeQuery.
 * public class QueryRedirectorTest {
 * public static Object findEmployeeByAnEmployee(DatabaseQuery query, Record arguments, Session session) {
 * ((ReadObjectQuery) query).setSelectionObject(arguments.get("employee"));
 * return session.executeQuery(query);
 * }
 * }</PRE></BLOCKQUOTE>
 *
 * @see QueryRedirector
 * @author James Sutherland
 * @since TOPLink/Java 3.0
 */
public class MethodBaseQueryRedirector implements QueryRedirector {
    protected Class methodClass;
    protected String methodClassName;
    protected String methodName;
    protected transient Method method;

    /**
     * PUBLIC:
     * Returns a new query redirector.
     */
    public MethodBaseQueryRedirector() {
    }

    /**
     * PUBLIC:
     * Returns a new query redirector based on the static method in methodClass.
     */
    public MethodBaseQueryRedirector(Class methodClass, String methodName) {
        this.methodClass = methodClass;
        this.methodName = methodName;
    }

    /**
     * INTERNAL:
     * Returns the static method.
     */
    protected Method getMethod() {
        return method;
    }

    /**
     * PUBLIC:
     * Returns the class to execute the static method on.
     */
    public Class getMethodClass() {
        return methodClass;
    }

    /**
     * INTERNAL:
     * Returns the class to execute the static method on.
     */
    public String getMethodClassName() {
        if ((methodClassName == null) && (methodClass != null)) {
            methodClassName = methodClass.getName();
        }
        return methodClassName;
    }

    /**
     * PUBLIC:
     * Returns the name of the static method.
     * This method must be public, static and have argument of DatabaseQuery, Vector, Session.
     * @see #setMethodName
     */
    public String getMethodName() {
        return methodName;
    }

    /**
     * INTERNAL:
     * Set the method.
     */
    protected void initializeMethod(DatabaseQuery query) throws QueryException {
        if ((getMethodName() == null) || (getMethodClass() == null)) {
            throw QueryException.redirectionClassOrMethodNotSet(query);
        }

        // Must check 3 possible argument sets for backward compatibility.
        // The DatabaseQuery, Record, Session should be used, check last the throw correct exception.
        // Check Session, Vector.
        Class[] arguments = new Class[2];
        arguments[0] = ClassConstants.SessionsSession_Class;
        arguments[1] = ClassConstants.Vector_class;
        try {
            setMethod(Helper.getDeclaredMethod(getMethodClass(), getMethodName(), arguments));
        } catch (Exception ignore) {
            // Check DatabaseQuery, Record, Session.
            arguments = new Class[3];
            arguments[0] = ClassConstants.DatabaseQuery_Class;
            arguments[1] = ClassConstants.Record_Class;
            arguments[2] = ClassConstants.SessionsSession_Class;
            try {
                setMethod(Helper.getDeclaredMethod(getMethodClass(), getMethodName(), arguments));
            } catch (Exception ignoreAgain) {
                // Check DatabaseQuery, Record, Session.
                arguments = new Class[3];
                arguments[0] = ClassConstants.DatabaseQuery_Class;
                arguments[1] = ClassConstants.Record_Class;
                arguments[2] = ClassConstants.SessionsSession_Class;
                try {
                    setMethod(Helper.getDeclaredMethod(getMethodClass(), getMethodName(), arguments));
                } catch (Exception exception) {
                    throw QueryException.redirectionMethodNotDefinedCorrectly(getMethodClass(), getMethodName(), exception, query);
                }
            }
        }

        // Ensure the method is static.
        if (!Modifier.isStatic(getMethod().getModifiers())) {
            throw QueryException.redirectionMethodNotDefinedCorrectly(getMethodClass(), getMethodName(), null, query);
        }
    }

    /**
     * INTERNAL:
     * Call the static method to execute the query.
     */
    @Override
    public Object invokeQuery(DatabaseQuery query, DataRecord arguments, Session session) {
        if (getMethod() == null) {
            initializeMethod(query);
        }

        // To different methods type are supported for backward compatibility.
        // Check method types to call with correct arguments.
        Object result = null;
        if (getMethod().getParameterTypes().length == 3) {
            Object[] argumentArray = new Object[3];
            argumentArray[0] = query;
            argumentArray[1] = arguments;
            argumentArray[2] = session;
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    result = AccessController.doPrivileged(new PrivilegedMethodInvoker(getMethod(), null, argumentArray));
                }else{
                    result = PrivilegedAccessHelper.invokeMethod(getMethod(), null, argumentArray);
                }
            } catch (Exception exception) {
                throw QueryException.redirectionMethodError(exception, query);
            }
        } else {
            Object[] argumentArray = new Object[2];
            argumentArray[0] = session;
            argumentArray[1] = ((AbstractRecord)arguments).getValues();
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    result = AccessController.doPrivileged(new PrivilegedMethodInvoker(getMethod(), null, argumentArray));
                }else{
                    result = PrivilegedAccessHelper.invokeMethod(getMethod(), null, argumentArray);
                }
            } catch (Exception exception) {
                throw QueryException.redirectionMethodError(exception, query);
            }
        }

        return result;
    }

    /**
     * INTERNAL:
     * Sets the static method.
     */
    protected void setMethod(Method newMethod) {
        method = newMethod;
    }

    /**
     * PUBLIC:
     * Sets the class to execute the static method on.
     */
    public void setMethodClass(Class newMethodClass) {
        methodClass = newMethodClass;
    }

    /**
     * INTERNAL:
     * Sets the class to execute the static method on.
     */
    public void setMethodClassName(String newMethodClassName) {
        methodClassName = newMethodClassName;
    }

    /**
     * PUBLIC:
     * Sets the name of the static method.<p>
     * This method must be public, static and have arguments of DatabaseQuery, Record, and Session.
     * <p>
     * The DatabaseQuery argument is the query that is currently being executed.
     * <p>
     * The Record will contain the Argument names added to the Query through addArgument(Sting) or, in the case
     * of an Object query, the object attribute field names.  These names will
     * reference the argument values passed into the query, or in the case of an
     * Object Query the values from the object.
     * <p>
     * The session argument is the session that the query is currently being executed on.
     * <p>
     * Alternatively the method can take only <code>(Session session, Vector arguments)</code>
     * as parameters.
     */
    public void setMethodName(String newMethodName) {
        methodName = newMethodName;
    }
}
