/*
 * 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, org.eclipse.persistence.sessions.Record 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;
    }
}
