/*
 * 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:
//     mmacivor - March 10/2009 - Initial implementation
package org.eclipse.persistence.internal.jaxb;

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

import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.descriptors.InstantiationPolicy;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;

/**
 * Purpose:
 * Provide a version of Instantiation Policy that can make use of a multiple argument factory method.
 * The defaultValues specified on this policy will be passed in to the factory method for the parameter values.
 *
 * This is required for certain JAXB generated classes that have no 0 arg constructor and a factory method with multiple arguments.
 * @author mmacivor
 *
 */
public class MultiArgInstantiationPolicy extends InstantiationPolicy {
    private String[] parameterTypeNames;
    private Class[] parameterTypes;

    private Object[] defaultValues;


    public void setParameterTypeNames(String[] parameterTypeNames) {
        this.parameterTypeNames = parameterTypeNames;
    }

    public void setParameterTypes(Class[] parameterTypes) {
        this.parameterTypes = parameterTypes;
    }

    public void setDefaultValues(Object[] values) {
        defaultValues = values;
    }

    @Override
    public void convertClassNamesToClasses(ClassLoader loader) {
        super.convertClassNamesToClasses(loader);
        if(parameterTypes == null) {
            if(parameterTypeNames != null) {
                Class[] values = new Class[parameterTypeNames.length];
                for(int i = 0; i < values.length; i++) {
                    try{
                        if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                            try {
                                values[i] = AccessController.doPrivileged(new PrivilegedClassForName<>(parameterTypeNames[i], true, loader));
                            } catch (PrivilegedActionException exception) {
                                throw ValidationException.classNotFoundWhileConvertingClassNames(parameterTypeNames[i], exception.getException());
                            }
                        } else {
                            values[i] = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(parameterTypeNames[i], true, loader);
                        }
                    } catch (ClassNotFoundException exc){
                        throw ValidationException.classNotFoundWhileConvertingClassNames(factoryClassName, exc);
                    }
                }
                this.parameterTypes = values;
            }
        }

    }
    @Override
    protected void initializeMethod() throws DescriptorException {
        Class tempClass;
        if (this.getFactory() != null) {
            tempClass = this.getFactory().getClass();
        } else if (this.getFactoryClass() == null) {
            tempClass = this.getDescriptor().getJavaClass();
        } else {
            tempClass = this.getFactoryClass();
        }
        if(this.parameterTypes == null) {
            this.setMethod(this.buildMethod(tempClass, this.getMethodName(), new Class[0]));
        } else {
            this.setMethod(this.buildMethod(tempClass, this.getMethodName(), this.parameterTypes));
        }
    }

    /**
     * Build and return a new instance, using the factory.
     * The factory can be null, in which case the method is a static method defined by the descriptor class.
     */
    @Override
    protected Object buildNewInstanceUsingFactory() throws DescriptorException {
        try {
            // If the method is static, the first argument is ignored and can be null
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try {
                    return AccessController.doPrivileged(new PrivilegedMethodInvoker(getMethod(), getFactory(), this.defaultValues));
                } catch (PrivilegedActionException exception) {
                    Exception throwableException = exception.getException();
                    if (throwableException instanceof IllegalAccessException) {
                        throw DescriptorException.illegalAccessWhileMethodInstantiation(getMethod().toString(), this.getDescriptor(), throwableException);
                    } else {
                        throw DescriptorException.targetInvocationWhileMethodInstantiation(getMethod().toString(), this.getDescriptor(), throwableException);
                    }
                }
            } else {
                return PrivilegedAccessHelper.invokeMethod(getMethod(), getFactory(), this.defaultValues);
            }
        } catch (IllegalAccessException exception) {
            throw DescriptorException.illegalAccessWhileMethodInstantiation(getMethod().toString(), this.getDescriptor(), exception);
        } catch (InvocationTargetException exception) {
            throw DescriptorException.targetInvocationWhileMethodInstantiation(getMethod().toString(), this.getDescriptor(), exception);
        } catch (NullPointerException exception) {
            // Some JVMs will throw a NULL pointer exception here
            throw DescriptorException.nullPointerWhileMethodInstantiation(this.getMethod().toString(), this.getDescriptor(), exception);
        }
    }

}
