/*
 * 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:
//     dminsky - initial API and implementation
package org.eclipse.persistence.testing.tests.unitofwork;

import java.util.Vector;

import org.eclipse.persistence.descriptors.*;
import org.eclipse.persistence.mappings.foundation.*;
import org.eclipse.persistence.tools.schemaframework.TableDefinition;

public class MutableAttributeObject {

    protected int id;

    // supported byte[] type
    protected byte[] byteArray;

    // java.util types
    protected java.util.Calendar utilCalendar;
    protected java.util.Date utilDate;

    // java.sql types
    protected java.sql.Date sqlDate;
    protected java.sql.Time sqlTime;
    protected java.sql.Timestamp sqlTimestamp;

    // custom java.util.Date subclass
    protected DateSubclass dateSubclass;

    public MutableAttributeObject() {
        super();
    }

    public static MutableAttributeObject example1() {
        MutableAttributeObject container = new MutableAttributeObject();

        long timeNow = System.currentTimeMillis();

        // byte[] with all values set to 1
        byte[] someBytes = new byte[128];
        java.util.Arrays.fill(someBytes, (byte)1);
        container.setByteArray(someBytes);

        // java.util types
        container.setUtilDate(new java.util.Date(timeNow));
        java.util.Calendar cal = java.util.Calendar.getInstance();
        cal.setTimeInMillis(timeNow);
        container.setUtilCalendar(cal);

        // java.sql types
        container.setSqlTime(new java.sql.Time(timeNow));
        container.setSqlDate(new java.sql.Date(timeNow));
        container.setSqlTimestamp(new java.sql.Timestamp(timeNow));

        // custom date subclass
        container.setDateSubclass(new DateSubclass());
        return container;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public byte[] getByteArray() {
        return byteArray;
    }

    public void setByteArray(byte[] byteArray) {
        this.byteArray = byteArray;
    }

    public java.util.Calendar getUtilCalendar() {
        return utilCalendar;
    }

    public void setUtilCalendar(java.util.Calendar utilCalendar) {
        this.utilCalendar = utilCalendar;
    }

    public java.util.Date getUtilDate() {
        return utilDate;
    }

    public void setUtilDate(java.util.Date utilDate) {
        this.utilDate = utilDate;
    }

    public java.sql.Time getSqlTime() {
        return sqlTime;
    }

    public void setSqlTime(java.sql.Time sqlTime) {
        this.sqlTime = sqlTime;
    }

    public java.sql.Timestamp getSqlTimestamp() {
        return sqlTimestamp;
    }

    public void setSqlTimestamp(java.sql.Timestamp sqlTimestamp) {
        this.sqlTimestamp = sqlTimestamp;
    }

    public java.sql.Date getSqlDate() {
        return sqlDate;
    }

    public void setSqlDate(java.sql.Date sqlDate) {
        this.sqlDate = sqlDate;
    }

    public DateSubclass getDateSubclass() {
        return dateSubclass;
    }

    public void setDateSubclass(DateSubclass dateSubclass) {
        this.dateSubclass = dateSubclass;
    }

    public static RelationalDescriptor descriptor() {
        RelationalDescriptor descriptor = new RelationalDescriptor();

        /* define the class, table and descriptor properties. */
        descriptor.setJavaClass(MutableAttributeObject.class);
        descriptor.setTableName("MUTABLE_TYPE");
        descriptor.setPrimaryKeyFieldName("ID");
        descriptor.setSequenceNumberFieldName("ID");
        descriptor.setSequenceNumberName("SEQ");

        /* Next define the direct mappings. */
        descriptor.addDirectMapping("id", "ID");
        descriptor.addDirectMapping("byteArray", "BYTE_ARRAY");
        descriptor.addDirectMapping("dateSubclass", "DATE_SUBCLASS");
        descriptor.addDirectMapping("sqlDate", "SQL_DATE");
        descriptor.addDirectMapping("sqlTime", "SQL_TIME");
        descriptor.addDirectMapping("sqlTimestamp", "SQL_TIMESTAMP");
        descriptor.addDirectMapping("utilCalendar", "UTIL_CALENDAR");
        descriptor.addDirectMapping("utilDate", "UTIL_DATE");

        /* Configure all of the mappings as mutable, except the id mapping */
        Vector mappings = descriptor.getMappings();
        for (int i = 0; i < mappings.size(); i++) {
            AbstractDirectMapping mapping = (AbstractDirectMapping)mappings.get(i);
            if (!mapping.getAttributeName().equalsIgnoreCase("id")) {
                mapping.setIsMutable(true);
            }
        }

        return descriptor;
    }

    public static TableDefinition tableDefinition() {
        TableDefinition definition = new TableDefinition();

        definition.setName("MUTABLE_TYPE");

        // identity field
        definition.addIdentityField("ID", java.lang.Integer.class);

        // regular direct mapping fields
        definition.addField("BYTE_ARRAY", java.sql.Blob.class); // byte[] mapping to BLOB
        definition.addField("DATE_SUBCLASS", java.sql.Date.class);
        definition.addField("SQL_DATE", java.sql.Date.class);
        definition.addField("SQL_TIME", java.sql.Time.class);
        definition.addField("SQL_TIMESTAMP", java.sql.Timestamp.class);
        definition.addField("UTIL_CALENDAR", java.sql.Timestamp.class);
        definition.addField("UTIL_DATE", java.sql.Date.class);

        return definition;
    }

}
