/*
 * 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.mappings.transformers;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;

import org.eclipse.persistence.exceptions.DescriptorException;
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.PrivilegedGetMethodParameterTypes;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.mappings.foundation.AbstractTransformationMapping;

/**
 *  @version $Header: MethodBasedFieldTransformer.java 18-sep-2006.16:20:59 gyorke Exp $
 *  @author  mmacivor
 *  @since   10
 *  This class is used to preserve the old method of doing Field Transformations
 *  on a transformation mapping. It is used internally when the older API is used on
 *  a TransformationMapping, and handles doing invocations on the user's domain class
 */
public class MethodBasedFieldTransformer implements FieldTransformer {
    protected transient Method fieldTransformationMethod;
    protected String methodName;
    protected AbstractTransformationMapping mapping;

    public MethodBasedFieldTransformer(String methodName) {
        this.methodName = methodName;
    }

    @Override
    public void initialize(AbstractTransformationMapping mapping) {
        this.mapping = mapping;
        final Class javaClass = this.mapping.getDescriptor().getJavaClass();
        try {
            // look for the zero-argument version first
            fieldTransformationMethod = Helper.getDeclaredMethod(javaClass, methodName, new Class[0]);
        } catch (NoSuchMethodException ex) {
            try {
                // if the zero-argument version is not there, look for the one-argument version
                Class[] methodParameterTypes = new Class[1];
                methodParameterTypes[0] = ClassConstants.PublicInterfaceSession_Class;
                fieldTransformationMethod = Helper.getDeclaredMethod(javaClass, methodName, methodParameterTypes);
            } catch (NoSuchMethodException ex2) {
                try {
                    //if the one-argument version is absent, try with sessions.Session
                    Class[] methodParameterTypes = new Class[1];
                    methodParameterTypes[0] = ClassConstants.SessionsSession_Class;
                    fieldTransformationMethod = Helper.getDeclaredMethod(javaClass, methodName, methodParameterTypes);
                } catch (NoSuchMethodException exception) {
                    throw DescriptorException.noSuchMethodWhileConvertingToMethod(methodName, this.mapping, exception);
                } catch (SecurityException exception) {
                    throw DescriptorException.securityWhileConvertingToMethod(methodName, this.mapping, exception);
                }
            } catch (SecurityException exception) {
                throw DescriptorException.securityWhileConvertingToMethod(methodName, this.mapping, exception);
            }
        } catch (SecurityException exception) {
            throw DescriptorException.securityWhileConvertingToMethod(methodName, this.mapping, exception);
        }
    }

    /**
     * Return the Java class type of the field value.
     * This uses the method return type.
     */
    public Class getFieldType() {
        if (this.fieldTransformationMethod != null) {
            return this.fieldTransformationMethod.getReturnType();
        }
        return null;
    }

    @Override
    public Object buildFieldValue(Object object, String fieldName, Session session) {
        Class[] parameterTypes = null;
        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
            try{
                parameterTypes = AccessController.doPrivileged(new PrivilegedGetMethodParameterTypes(fieldTransformationMethod));
            }catch (PrivilegedActionException ex){
                throw (RuntimeException) ex.getCause();
            }
        }else{
            parameterTypes = PrivilegedAccessHelper.getMethodParameterTypes(fieldTransformationMethod);
        }

        Object[] parameters = new Object[parameterTypes.length];
        if (parameters.length == 1) {
            parameters[0] = session;
        }

        try {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try{
                    return AccessController.doPrivileged(new PrivilegedMethodInvoker(fieldTransformationMethod, object, parameters));
                }catch (PrivilegedActionException ex){
                    if (ex.getCause() instanceof IllegalAccessException){
                        throw (IllegalAccessException) ex.getCause();
                    }
                    if (ex.getCause() instanceof InvocationTargetException){
                        throw (InvocationTargetException) ex.getCause();
                    }
                    throw (RuntimeException) ex.getCause();
                }
            }else{
                return PrivilegedAccessHelper.invokeMethod(fieldTransformationMethod, object, parameters);
            }
        } catch (IllegalAccessException exception) {
            throw DescriptorException.illegalAccessWhileInvokingFieldToMethod(fieldTransformationMethod.getName(), mapping, exception);
        } catch (IllegalArgumentException exception) {
            throw DescriptorException.illegalArgumentWhileInvokingFieldToMethod(fieldTransformationMethod.getName(), mapping, exception);
        } catch (InvocationTargetException exception) {
            throw DescriptorException.targetInvocationWhileInvokingFieldToMethod(fieldTransformationMethod.getName(), mapping, exception);
        }
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String name) {
        methodName = name;
    }
}
