/*
 * 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.testing.oxm.classloader;

import java.lang.reflect.Method;

import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.mappings.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.testing.oxm.OXTestCase;

/**
 * Tests class loader usage in the following mappings:
 *  - XMLAnyAttributeMapping
 *  - XMLAnyCollectionMapping
 *  - XMLAnyObjectMapping
 *  - XMLBinaryDataCollectionMapping
 *  - XMLBinaryDataMapping
 *  - XMLChoiceCollectionMapping
 *  - XMLChoiceObjectMapping
 *  - XMLCollectionReferenceMapping
 *  - XMLCompositeCollectionMapping
 *  - XMLCompositeDirectCollectionMapping
 *  - XMLCompositeObjectMapping
 *  - XMLObjectReferenceMapping
 */
public class MappingTestProject extends Project {
    private Class rootObjectClass;
    private Class testObjectClass;
    private Class addressClass;
    private Class anyObjectClass;
    private Class listContainerPolicyClass;
    private Class mapContainerPolicyClass;
    private OXTestCase.Platform platform;
    private OXTestCase.Metadata metadata;

    public MappingTestProject(ClassLoader loader, OXTestCase.Platform platform, OXTestCase.Metadata metadata) {
        this.platform = platform;
        this.metadata = metadata;
        // load classes not on class path
        try {
            rootObjectClass = loader.loadClass("org.eclipse.persistence.testing.oxm.classloader.RootObject");
            testObjectClass = loader.loadClass("org.eclipse.persistence.testing.oxm.classloader.MappingTestObject");
            addressClass = loader.loadClass("org.eclipse.persistence.testing.oxm.classloader.Address");
            anyObjectClass = loader.loadClass("org.eclipse.persistence.testing.oxm.classloader.AnyObject");
            listContainerPolicyClass = loader.loadClass("org.eclipse.persistence.testing.oxm.classloader.CustomListContainerPolicy");
            mapContainerPolicyClass = loader.loadClass("org.eclipse.persistence.testing.oxm.classloader.CustomMapContainerPolicy");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // build descriptors
        this.addDescriptor(buildRootObjectDescriptor());
        this.addDescriptor(buildMappingTestObjectDescriptor());
        this.addDescriptor(buildAnyObjectDescriptor());
        this.addDescriptor(buildAddressDescriptor());
    }

    /**
     * The root descriptor contains a single mapping test object and a
     * list of address objects
     */
    public ClassDescriptor buildRootObjectDescriptor() {
        XMLDescriptor descriptor = new XMLDescriptor();
        descriptor.setJavaClass(rootObjectClass);
        descriptor.setDefaultRootElement("root-object");
        // create test object mapping
        XMLCompositeObjectMapping testObjectMapping = new XMLCompositeObjectMapping();
        testObjectMapping.setAttributeName("testObject");
        testObjectMapping.setXPath("mapping-test-object");
        testObjectMapping.setReferenceClassName(testObjectClass.getName());
        testObjectMapping.setGetMethodName("getTestObject");
        testObjectMapping.setSetMethodName("setTestObject");
        descriptor.addMapping(testObjectMapping);
        // create address mapping
        XMLCompositeCollectionMapping addMapping = new XMLCompositeCollectionMapping();
        addMapping.setAttributeName("addresses");
        addMapping.setXPath("addresses/address");
        addMapping.setReferenceClassName(addressClass.getName());
        addMapping.setGetMethodName("getAddresses");
        addMapping.setSetMethodName("setAddresses");
        ContainerPolicy listPolicy;
        try {
            listPolicy = (ContainerPolicy) listContainerPolicyClass.newInstance();
            Method meth = listContainerPolicyClass.getDeclaredMethod("setContainerClassName", new Class[] { String.class });
            meth.invoke(listPolicy, new Object[] { "java.util.ArrayList" });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        addMapping.setContainerPolicy(listPolicy);
        descriptor.addMapping(addMapping);
        return descriptor;
    }

    public ClassDescriptor buildMappingTestObjectDescriptor() {
        XMLDescriptor descriptor = new XMLDescriptor();
        descriptor.setJavaClass(testObjectClass);
        descriptor.setDefaultRootElement("mapping-test-object");
        // any attribute mapping
        XMLAnyAttributeMapping aamapping = new XMLAnyAttributeMapping();
        aamapping.setAttributeName("anyAttribute");
        aamapping.setGetMethodName("getAnyAttribute");
        aamapping.setSetMethodName("setAnyAttribute");
        ContainerPolicy mapPolicy;
        try {
            mapPolicy = (ContainerPolicy) mapContainerPolicyClass.newInstance();
            Method meth = mapContainerPolicyClass.getDeclaredMethod("setContainerClassName", new Class[] { String.class });
            meth.invoke(mapPolicy, new Object[] { "java.util.HashMap" });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        aamapping.setContainerPolicy(mapPolicy);
        descriptor.addMapping(aamapping);
        // any object mapping
        XMLAnyObjectMapping aomapping = new XMLAnyObjectMapping();
        aomapping.setAttributeName("anyObject");
        aomapping.setGetMethodName("getAnyObject");
        aomapping.setSetMethodName("setAnyObject");
        descriptor.addMapping(aomapping);
        // any collection mapping
        XMLAnyCollectionMapping acmapping = new XMLAnyCollectionMapping();
        acmapping.setXPath("any-collection");
        acmapping.setAttributeName("anyCollection");
        acmapping.setGetMethodName("getAnyCollection");
        acmapping.setSetMethodName("setAnyCollection");
        descriptor.addMapping(acmapping);

        // setup binary data and choice mapping, but only add the mappings in certain cases
        // binary data mapping
        XMLBinaryDataMapping photoMapping = new XMLBinaryDataMapping();
        photoMapping.setAttributeName("photo");
        XMLField field = new XMLField("photo");
        field.setSchemaType(XMLConstants.BASE_64_BINARY_QNAME);
        photoMapping.setField(field);
        photoMapping.setShouldInlineBinaryData(false);
        photoMapping.setSwaRef(false);
        photoMapping.setMimeType("image");
        // binary data collection mapping
        XMLBinaryDataCollectionMapping photosMapping = new XMLBinaryDataCollectionMapping();
        photosMapping.setAttributeName("photos");
        XMLField xfield = new XMLField("photos/photo");
        xfield.setSchemaType(XMLConstants.BASE_64_BINARY_QNAME);
        photosMapping.setField(xfield);
        photosMapping.setShouldInlineBinaryData(false);
        photosMapping.setSwaRef(false);
        photosMapping.setMimeType("image");
        photosMapping.setCollectionContentType(ClassConstants.APBYTE);
        // choice mapping
        XMLChoiceObjectMapping choiceMapping = new XMLChoiceObjectMapping();
        choiceMapping.setAttributeName("choice");
        choiceMapping.setGetMethodName("getChoice");
        choiceMapping.setSetMethodName("setChoice");
        choiceMapping.addChoiceElement("string-choice/text()", String.class);
        choiceMapping.addChoiceElement("int-choice/text()", Integer.class);
        // choice collection mapping
        XMLChoiceCollectionMapping choiceColMapping = new XMLChoiceCollectionMapping();
        choiceColMapping.setAttributeName("choices");
        choiceColMapping.setGetMethodName("getChoices");
        choiceColMapping.setSetMethodName("setChoices");
        choiceColMapping.addChoiceElement("street-choice/text()", String.class);
        choiceColMapping.addChoiceElement("address-choice", addressClass);
        choiceColMapping.addChoiceElement("integer-choice/text()", Integer.class);

        // 1- binary and choice are supported with SAX and Java project
        // 2- neither is supported with deployment XML
        // 3- binary is supported with DOM
        if (metadata == OXTestCase.Metadata.JAVA) {
            descriptor.addMapping(photoMapping);
            descriptor.addMapping(photosMapping);
        }
        if (platform == OXTestCase.Platform.SAX) {
            descriptor.addMapping(choiceMapping);
            descriptor.addMapping(choiceColMapping);
        }

        // object reference mapping
        XMLObjectReferenceMapping orMapping = new XMLObjectReferenceMapping();
        orMapping.setAttributeName("address");
        orMapping.setReferenceClassName(addressClass.getName());
        orMapping.addSourceToTargetKeyFieldAssociation("billing-address-ref/@address-id", "@aid");
        descriptor.addMapping(orMapping);
        // collection reference mapping
        XMLCollectionReferenceMapping addressesMapping = new XMLCollectionReferenceMapping();
        ContainerPolicy listPolicy;
        try {
            listPolicy = (ContainerPolicy) listContainerPolicyClass.newInstance();
            Method meth = listContainerPolicyClass.getDeclaredMethod("setContainerClassName", new Class[] { String.class });
            meth.invoke(listPolicy, new Object[] { "java.util.ArrayList" });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        addressesMapping.setContainerPolicy(listPolicy);
        addressesMapping.setAttributeName("addresses");
        addressesMapping.setReferenceClassName(addressClass.getName());
        addressesMapping.addSourceToTargetKeyFieldAssociation("shipping-address-ref/@address-id", "@aid");
        descriptor.addMapping(addressesMapping);
        // direct collection mapping
        XMLCompositeDirectCollectionMapping responsibilitiesMapping = new XMLCompositeDirectCollectionMapping();
        responsibilitiesMapping.setAttributeName("responsibilities");
        ContainerPolicy listPolicy1;
        try {
            listPolicy1 = (ContainerPolicy) listContainerPolicyClass.newInstance();
            Method meth = listContainerPolicyClass.getDeclaredMethod("setContainerClassName", new Class[] { String.class });
            meth.invoke(listPolicy1, new Object[] { "java.util.ArrayList" });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        responsibilitiesMapping.setContainerPolicy(listPolicy1);
        responsibilitiesMapping.setXPath("responsibilities/list/@responsibility");
        descriptor.addMapping(responsibilitiesMapping);
        return descriptor;
    }

    public ClassDescriptor buildAnyObjectDescriptor() {
        XMLDescriptor descriptor = new XMLDescriptor();
        descriptor.setJavaClass(anyObjectClass);
        descriptor.setDefaultRootElement("any-object");
        // id mapping
        XMLDirectMapping idMapping = new XMLDirectMapping();
        idMapping.setXPath("@id");
        idMapping.setAttributeName("id");
        idMapping.setGetMethodName("getId");
        idMapping.setSetMethodName("setId");
        descriptor.addMapping(idMapping);
        // name mapping
        XMLDirectMapping nameMapping = new XMLDirectMapping();
        nameMapping.setXPath("name");
        nameMapping.setAttributeName("name");
        nameMapping.setGetMethodName("getName");
        nameMapping.setSetMethodName("setName");
        descriptor.addMapping(nameMapping);
        return descriptor;
    }

    public ClassDescriptor buildAddressDescriptor() {
        XMLDescriptor descriptor = new XMLDescriptor();
        descriptor.setJavaClass(addressClass);
        // set primary key for reference mapping tests
        descriptor.addPrimaryKeyFieldName("@aid");
        // id mapping
        XMLDirectMapping idMapping = new XMLDirectMapping();
        idMapping.setAttributeName("id");
        idMapping.setXPath("@aid");
        descriptor.addMapping(idMapping);
        // street mapping
        XMLDirectMapping streetMapping = new XMLDirectMapping();
        streetMapping.setAttributeName("street");
        streetMapping.setXPath("street/text()");
        streetMapping.setGetMethodName("getStreet");
        streetMapping.setSetMethodName("setStreet");
        descriptor.addMapping(streetMapping);
        // city mapping
        XMLDirectMapping cityMapping = new XMLDirectMapping();
        cityMapping.setAttributeName("city");
        cityMapping.setXPath("city/text()");
        cityMapping.setGetMethodName("getCity");
        cityMapping.setSetMethodName("setCity");
        descriptor.addMapping(cityMapping);
        return descriptor;
    }
}
