/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.jdo.tck.pc.companyMapWithoutJoin;

import javax.jdo.PersistenceManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/*
 * This class provides an implementation of CompanyFactory that sets all
 * of the properties of the instance and defines abstract methods to
 * construct the instance itself. It is intended to be subclassed by
 * classes that implement only the methods to construct the instance.
 */
public abstract class CompanyFactoryAbstractImpl implements CompanyFactory {
    
    protected PersistenceManager pm;
    
    /** Logger */
    protected Log logger = 
        LogFactory.getFactory().getInstance("org.apache.jdo.tck");

    /** true if debug logging is enabled. */
    protected boolean debug = logger.isDebugEnabled();
    
    /**
     * Creates a new instance of CompanyFactoryAbstractImpl
     * @param pm the PersistenceManager
     */
    public CompanyFactoryAbstractImpl(PersistenceManager pm) {
        this.pm = pm;
    }

    abstract ICompany newCompany();
    abstract IDepartment newDepartment();
    abstract IFullTimeEmployee newFullTimeEmployee();
    abstract IPartTimeEmployee newPartTimeEmployee();
    
    public ICompany newCompany(long companyid, String name,
            java.util.Date founded) {
        ICompany result = newCompany();
        result.setCompanyid(companyid);
        result.setName(name);
        result.setFounded(founded);
        if (debug) logger.debug("newCompany returned" + result);
        return result;
    }

    public IDepartment newDepartment(long deptid, String name) {
        IDepartment result = newDepartment();
        result.setDeptid(deptid);
        result.setName(name);
        if (debug) logger.debug("newDepartment returned" + result);
        return result;
    }


    public IDepartment newDepartment(long deptid, String name, ICompany company) {
        IDepartment result = newDepartment();
        result.setDeptid(deptid);
        result.setName(name);
        result.setCompany(company);
        if (debug) logger.debug("newDepartment returned" + result);
        return result;
    }

    public IFullTimeEmployee newFullTimeEmployee(long personid, String first,
            String last, String middle, java.util.Date born,
                    java.util.Date hired, String role, double sal) {
        IFullTimeEmployee result = newFullTimeEmployee();
        result.setPersonid(personid);
        result.setFirstname(first);
        result.setLastname(last);
        result.setMiddlename(middle);
        result.setBirthdate(born);
        result.setHiredate(hired);
        result.setRole(role);
        result.setSalary(sal);
        if (debug) logger.debug("newFullTimeEmployee returned" + result);
        return result;
    }

    public IPartTimeEmployee newPartTimeEmployee(long personid, String first, 
            String last, String middle, java.util.Date born,
                    java.util.Date hired, String role, double wage) {
        IPartTimeEmployee result = newPartTimeEmployee();
        result.setPersonid(personid);
        result.setFirstname(first);
        result.setLastname(last);
        result.setMiddlename(middle);
        result.setBirthdate(born);
        result.setHiredate(hired);
        result.setRole(role);
        result.setWage(wage);
        if (debug) logger.debug("newPartTimeEmployee returned" + result);
        return result;
    }

}
