/*
 * 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 final PersistenceManager pm;

  /** Logger */
  protected final Log logger = LogFactory.getFactory().getInstance("org.apache.jdo.tck");

  /** true if debug logging is enabled. */
  protected final 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;
  }
}
