/*
 * Copyright (c) 1998, 2018 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.mappings.sequenced;

import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.mappings.XMLAnyObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.mappings.XMLFragmentMapping;
import org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping;
import org.eclipse.persistence.sessions.Project;

public class EmployeeProject extends Project {

    private XMLDescriptor employeeDescriptor;
    private XMLDescriptor addressDescriptor;
    private XMLDescriptor dependentDescriptor;
    private XMLDescriptor phoneNumberDescriptor;

    public EmployeeProject() {
        super();
        this.addDescriptor(getEmployeeDescriptor());
        this.addDescriptor(getAddressDescriptor());
        this.addDescriptor(getDependentDescriptor());
        this.addDescriptor(getPhoneNumberDescriptor());
    }

    public XMLDescriptor getEmployeeDescriptor() {
        if(null == employeeDescriptor) {
            employeeDescriptor = new XMLDescriptor();
            employeeDescriptor.setJavaClass(Employee.class);
            employeeDescriptor.setDefaultRootElement("ns:employee");
            employeeDescriptor.setSequencedObject(true);

            NamespaceResolver nsResolver = new NamespaceResolver();
            nsResolver.put("ns", "urn:example");
            employeeDescriptor.setNamespaceResolver(nsResolver);

            XMLDirectMapping idMapping = new XMLDirectMapping();
            idMapping.setAttributeName("id");
            idMapping.setXPath("@id");
            employeeDescriptor.addMapping(idMapping);

            XMLDirectMapping fnMapping = new XMLDirectMapping();
            fnMapping.setAttributeName("firstName");
            fnMapping.setXPath("personal-info/ns:first-name/text()");
            employeeDescriptor.addMapping(fnMapping);

            XMLDirectMapping lnMapping = new XMLDirectMapping();
            lnMapping.setAttributeName("lastName");
            lnMapping.setXPath("personal-info/last-name/text()");
            employeeDescriptor.addMapping(lnMapping);

            XMLCompositeObjectMapping addressMapping = new XMLCompositeObjectMapping();
            addressMapping.setAttributeName("address");
            addressMapping.setXPath("address");
            addressMapping.setReferenceClass(Address.class);
            employeeDescriptor.addMapping(addressMapping);

            XMLCompositeObjectMapping dependentMapping = new XMLCompositeObjectMapping();
            dependentMapping.setAttributeName("dependent");
            dependentMapping.setXPath("dependent");
            dependentMapping.setReferenceClass(Dependent.class);
            employeeDescriptor.addMapping(dependentMapping);

            XMLAnyObjectMapping anyMapping = new XMLAnyObjectMapping();
            anyMapping.setAttributeName("any");
            anyMapping.setUseXMLRoot(true);
            employeeDescriptor.addMapping(anyMapping);

            XMLFragmentMapping nodeMapping = new XMLFragmentMapping();
            nodeMapping.setAttributeName("node");
            nodeMapping.setXPath("fragment");
            employeeDescriptor.addMapping(nodeMapping);

            /*
            XMLChoiceMapping choiceMapping = new XMLChoiceMapping();
            choiceMapping.setAttributeName("choice");
            choiceMapping.addChoiceElement("choice-address", Address.class);
            choiceMapping.addChoiceElement("choice-dependent", Dependent.class);
            choiceMapping.addChoiceElement("choice-string/text()", String.class);
            employeeDescriptor.addMapping(choiceMapping);
             */
        }
        return employeeDescriptor;
    }

    public XMLDescriptor getAddressDescriptor() {
        if(null == addressDescriptor) {
            addressDescriptor = new XMLDescriptor();
            addressDescriptor.setJavaClass(Address.class);
            addressDescriptor.setDefaultRootElement("ADDRESS-ROOT");
            addressDescriptor.addPrimaryKeyFieldName("@aid");

            XMLDirectMapping idMapping = new XMLDirectMapping();
            idMapping.setAttributeName("id");
            idMapping.setXPath("@aid");
            addressDescriptor.addMapping(idMapping);

            XMLDirectMapping streetMapping = new XMLDirectMapping();
            streetMapping.setAttributeName("street");
            streetMapping.setXPath("street/text()");
            addressDescriptor.addMapping(streetMapping);

            XMLDirectMapping cityMapping = new XMLDirectMapping();
            cityMapping.setAttributeName("city");
            cityMapping.setXPath("city/text()");
            addressDescriptor.addMapping(cityMapping);
        }
        return addressDescriptor;
    }

    public XMLDescriptor getDependentDescriptor() {
        if(null == dependentDescriptor) {
            dependentDescriptor = new XMLDescriptor();
            dependentDescriptor.setJavaClass(Dependent.class);
            dependentDescriptor.setSequencedObject(true);
            dependentDescriptor.setDefaultRootElement("BAR");

            XMLDirectMapping fnMapping = new XMLDirectMapping();
            fnMapping.setAttributeName("firstName");
            fnMapping.setXPath("first-name/text()");
            dependentDescriptor.addMapping(fnMapping);

            XMLDirectMapping lnMapping = new XMLDirectMapping();
            lnMapping.setAttributeName("lastName");
            lnMapping.setXPath("last-name/text()");
            dependentDescriptor.addMapping(lnMapping);

            XMLObjectReferenceMapping addressMapping = new XMLObjectReferenceMapping();
            addressMapping.setAttributeName("address");
            addressMapping.setReferenceClass(Address.class);
            addressMapping.addSourceToTargetKeyFieldAssociation("address-id/text()" , "@aid");
            dependentDescriptor.addMapping(addressMapping);
        }
        return dependentDescriptor;
    }

    public XMLDescriptor getPhoneNumberDescriptor() {
        if(null == phoneNumberDescriptor) {
            phoneNumberDescriptor = new XMLDescriptor();
            phoneNumberDescriptor.setJavaClass(PhoneNumber.class);
            phoneNumberDescriptor.setDefaultRootElement("phone-number");
            phoneNumberDescriptor.setSequencedObject(true);

            XMLDirectMapping areaCodeMapping = new XMLDirectMapping();
            areaCodeMapping.setAttributeName("areaCode");
            areaCodeMapping.setXPath("area-code/text()");
            phoneNumberDescriptor.addMapping(areaCodeMapping);

            XMLDirectMapping numberMapping = new XMLDirectMapping();
            numberMapping.setAttributeName("number");
            numberMapping.setXPath("text()");
            phoneNumberDescriptor.addMapping(numberMapping);

            XMLDirectMapping extensionMapping = new XMLDirectMapping();
            extensionMapping.setAttributeName("extension");
            extensionMapping.setXPath("extension/text()");
            phoneNumberDescriptor.addMapping(extensionMapping);
        }
        return phoneNumberDescriptor;
    }

}
