/*
 * 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.testing.tests.validation;

import org.eclipse.persistence.sessions.DataRecord;

import java.sql.Time;

import java.util.Vector;


//Created by Ian Reid
//Date: Feb 6, 2k3
//used for testing (TL-ERROR 81) called from class org.eclipse.persistence.testing.tests.validation.ReturnTypeInGetAttributeAccessorTest

public class EmployeeWithProblems extends org.eclipse.persistence.testing.models.employee.domain.Employee {
    /** One-to-one mapping, employee references its address through a foreign key. */
    public
    //    public ValueHolderInterface addressWithProblems;//used to test TL-125
    org.eclipse.persistence.testing.models.employee.domain.Address addressWithProblems; //used to test TL-125

    /** One-to-many mapping (same class relationship), inverse relationship to manager, uses manager foreign key in the target. */
    public String managedEmployeesWithProblems; //used to test TL-133

    /** One-to-one mapping (same class relationship), employee references its manager through a foreign key. */
    public EmployeeWithProblems managerWithProblems; //used to test TL-144

    /** Aggregate-collection mapping. */
    public Vector addressesWithProblems; //used to test TL-153

    public String notMapped; //used to test TL-45

    private String illegalAccess; //used in tests which require an in-accessable attribute

    /* Varray Testing added
  */
    private Vector courses; //used to test TL-157

    public Vector getCourses() {
        return courses;
    }

    public void setCourses(Vector input) {
        courses = input;
    }

    public void addCourse(String input) {
        getCourses().add(new String(input));
    }

    public String getIllegalAccess() throws java.lang.IllegalAccessException {
        throw new IllegalAccessException();
    }

    public void setIllegalAccess(String input) throws java.lang.IllegalAccessException {
        throw new IllegalAccessException();
    }

    public EmployeeWithProblems() {
        super();
        //     this.addressWithProblems = new org.eclipse.persistence.testing.models.employee.domain.Address();//new ValueHolder();//initilized to null to cause error
        //      this.managedEmployeesWithProblems = new Vector();
        //    this.managerWithProblems = null;
        this.addressesWithProblems = new Vector();
        this.courses = new Vector();
    }
    //this method returns void (instead of Time[]) to produce the error (TL-ERROR 81)

    public void buildNormalHours2(DataRecord row, org.eclipse.persistence.sessions.Session session) { //used in test class org.eclipse.persistence.testing.tests.validation.ReturnTypeInGetAttributeAccessorTest
        Time[] hours = new Time[2];

        /** This conversion allows for the database type not to match, i.e. may be a Timestamp or String. */
        hours[0] = session.getPlatform().convertObject(row.get("START_TIME"), Time.class);
        hours[1] = session.getPlatform().convertObject(row.get("END_TIME"), Time.class);
        //    return hours;
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    public

    org.eclipse.persistence.testing.models.employee.domain.Address getAddressWithProblems() {
        return addressWithProblems; //.getValue();
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    public

    void setAddressWithProblems(org.eclipse.persistence.testing.models.employee.domain.Address address) {
        this.addressWithProblems = address; //.setValue(address);
    }

    public String getManagedEmployeesWithProblems() {
        return managedEmployeesWithProblems;
    }

    public void setManagedEmployeesWithProblems(String input) {
        managedEmployeesWithProblems = input;
    }

    public EmployeeWithProblems getManagerWithProblems() {
        return managerWithProblems;
    }

    public void setManagerWithProblems(EmployeeWithProblems input) {
        managerWithProblems = input;
    }


}
