blob: 4c38574d2fc509672c8461d92ecd9417c2d969a3 [file] [log] [blame]
/*
* 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:
// 07/16/2009 Andrei Ilitchev
// - Bug 282553: JPA 2.0 JoinTable support for OneToOne and ManyToOne
package org.eclipse.persistence.testing.models.onetoonejointable;
import java.util.*;
import java.io.*;
import java.math.BigDecimal;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import org.eclipse.persistence.indirection.*;
import org.eclipse.persistence.descriptors.changetracking.*;
/**
* <p><b>Purpose</b>: Represent a employee of an organization.
* <p><b>Description</b>: An Employee is a root object in the Employee Demo.
* It maintains relationships to all of the other objects in the system.
* The employee shows usage of 1-1, 1-m, m-m, aggregate and transformation mappings.
* The employee also shows usage of value holder to implement indirection for its relationships
* (note, it is strongly suggested to always use value holders for relationships).
*/
public class Employee implements Serializable, ChangeTracker {
// implements ChangeTracker for testing
/** Primary key, mapped as a direct-to-field, BigDecimal -{@literal >} NUMBER, that makes use of sequence numbers to generate the id. */
public BigDecimal id;
/** Direct-to-field mapping, String -{@literal >} VARCHAR. */
public String firstName;
/** Direct-to-field mapping, String -{@literal >} VARCHAR. */
public String lastName;
/** Object-type mapping, maps "Male" -{@literal >} "M", "Female" -{@literal >} "F". */
public String gender;
/** One-to-one mapping, employee references its address through a foreign key. */
public ValueHolderInterface address;
/** One-to-one mapping (same class relationship), employee references its manager through a foreign key. */
public ValueHolderInterface manager;
public List<Employee> managedEmployees;
/** Many-to-many mapping, employee references its projects through an intermediate join table. */
public List<Project> projects;
/** Direct-collection mapping, employee stores its collection of plain Strings in an intermediate table. */
public List<String> responsibilitiesList;
/** Direct-to-field mapping, int -{@literal >} NUMBER, salary of the employee in dollars. */
public int salary;
/** One-to-many mapping, employee references its collection of children arranged by age.
* This relationship uses transparent indirection */
public List<Child> children;
/** One-to-one mapping , inverse relationship to Project.teamLeader */
public ValueHolderInterface projectLed;
/** For performance testing, how many times primary key extracted. */
public static int getIdCallCount = 0;
public PropertyChangeListener listener;
@Override
public PropertyChangeListener _persistence_getPropertyChangeListener() {
return listener;
}
@Override
public void _persistence_setPropertyChangeListener(PropertyChangeListener listener) {
this.listener = listener;
}
public void propertyChange(String propertyName, Object oldValue, Object newValue) {
if (listener != null) {
if (oldValue != newValue) {
listener.propertyChange(new PropertyChangeEvent(this, propertyName, oldValue, newValue));
}
}
}
public void collectionChange(String propertyName, Object oldValue, Object newValue, int changeType, boolean isChangeApplied) {
if (listener != null) {
listener.propertyChange(new CollectionChangeEvent(this, propertyName, oldValue, newValue, changeType, isChangeApplied));
}
}
/**
* For fields that make use of indirection the constructor should build the value holders.
*/
public Employee() {
this.firstName = "";
this.lastName = "";
this.address = new ValueHolder();
this.manager = new ValueHolder();
this.managedEmployees = new ArrayList();
this.projects = new ArrayList();
this.responsibilitiesList = new ArrayList();
this.children = new ArrayList();
this.projectLed = new ValueHolder();
}
/**
* For bi-directional relationships, it is important to maintain both sides of the relationship when changing it.
*/
public void addManagedEmployee(Employee employee) {
getManagedEmployees().add(employee);
employee.setManager(this);
}
public void addManagedEmployee(int index, Employee employee) {
getManagedEmployees().add(index, employee);
employee.setManager(this);
}
public Employee setManagedEmployee(int index, Employee employee) {
Employee removedEmp = getManagedEmployees().set(index, employee);
removedEmp.setManager(null);
employee.setManager(this);
return removedEmp;
}
public void addChild(Child child) {
getChildren().add(child);
child.setParent(this);
}
public void addProject(Project project) {
getProjects().add(project);
project.getEmployees().add(this);
}
public void addResponsibility(String responsibility) {
getResponsibilitiesList().add(responsibility);
}
public Address getAddress() {
return (Address)address.getValue();
}
public String getFirstName() {
return firstName;
}
public String getGender() {
return gender;
}
/**
* Used for performance testing.
*/
public static int getGetIdCallCount() {
return getIdCallCount;
}
/**
* Return the persistent identifier of the receiver.
*/
public BigDecimal getId() {
getIdCallCount++;
return id;
}
public List<Child> getChildren(){
return children;
}
public String getLastName() {
return lastName;
}
public List<Employee> getManagedEmployees() {
return managedEmployees;
}
public Employee getManager() {
return (Employee)manager.getValue();
}
public Project getProjectLed() {
return (Project)projectLed.getValue();
}
public List<Project> getProjects() {
return projects;
}
public List<String> getResponsibilitiesList() {
return responsibilitiesList;
}
public int getSalary() {
return salary;
}
public void removeManagedEmployee(Employee employee) {
getManagedEmployees().remove(employee);
employee.setManager(null);
}
public void removeProject(Project project) {
getProjects().remove(project);
project.getEmployees().remove(this);
}
public void removeResponsibility(String responsibility) {
getResponsibilitiesList().remove(responsibility);
}
public void setAddress(Address address) {
propertyChange("address", this.address.getValue(), address);
this.address.setValue(address);
}
public void setChildren(Vector children){
this.children = children;
}
public void setFemale() {
propertyChange("gender", this.gender, "Female");
setGender("Female");
}
public void setFirstName(String firstName) {
propertyChange("firstName", getFirstName(), firstName);
this.firstName = firstName;
}
public void setGender(String gender) {
propertyChange("gender", this.gender, gender);
this.gender = gender;
}
/**
* For performance testing.
*/
public static void setGetIdCallCount(int value) {
Employee.getIdCallCount = value;
}
/**
* Set the persistent identifier of the receiver.
* Note this should never be changed.
* Consider making the primary key set methods protected or not having them.
* In this demo the setId is required for testing purposes.
*/
public void setId(BigDecimal id) {
propertyChange("id", this.id, id);
this.id = id;
}
public void setLastName(String lastName) {
propertyChange("lastName", this.lastName, lastName);
this.lastName = lastName;
}
public void setMale() {
propertyChange("gender", this.gender, "Male");
setGender("Male");
}
/**
* 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 setManagedEmployees(List<Employee> managedEmployees) {
propertyChange("managedEmployees", this.managedEmployees, managedEmployees);
this.managedEmployees = managedEmployees;
}
/**
* For bi-directional relationships, it is important to maintain both sides of the relationship when changing it.
* 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 setManager(Employee manager) {
propertyChange("manager", this.manager.getValue(), manager);
this.manager.setValue(manager);
}
public void setProjectLed(Project projectLed) {
propertyChange("projectLed", this.projectLed.getValue(), projectLed);
this.projectLed.setValue(projectLed);
}
public void setProjects(List<Project> projects) {
propertyChange("projects", this.projects, projects);
this.projects = projects;
}
/**
* 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 setResponsibilitiesList(Vector responsibilitiesList) {
propertyChange("responsibilitiesList", this.responsibilitiesList, responsibilitiesList);
this.responsibilitiesList = responsibilitiesList;
}
public void setSalary(int salary) {
propertyChange("salary", this.salary, salary);
this.salary = salary;
}
/**
* Print the first &amp; last name
*/
public String toString() {
StringWriter writer = new StringWriter();
writer.write("Employee: ");
writer.write(getFirstName());
writer.write(" ");
writer.write(getLastName());
return writer.toString();
}
}