blob: 6c3f2e6fd2bb3bc0fbb77f4c1b677c3f4d1193d3 [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:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.models.jpa.advanced;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.SerializedObjectPolicy;
import org.eclipse.persistence.descriptors.VersionLockingPolicy;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.internal.databaseaccess.DatasourceAccessor;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.mappings.querykeys.DirectCollectionQueryKey;
import org.eclipse.persistence.mappings.querykeys.ManyToManyQueryKey;
import org.eclipse.persistence.mappings.querykeys.OneToManyQueryKey;
import org.eclipse.persistence.mappings.querykeys.OneToOneQueryKey;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.SessionEvent;
import org.eclipse.persistence.sessions.SessionEventAdapter;
/**
* Session and descriptor customizer.
*/
public class Customizer implements SessionCustomizer, DescriptorCustomizer {
static HashMap sessionCalls = new HashMap();
static HashMap descriptorCalls = new HashMap();
@Override
public void customize(Session session) throws Exception {
String sessionName = session.getName();
Integer numberOfCalls = (Integer)sessionCalls.get(sessionName);
int num = 0;
if(numberOfCalls != null) {
num = numberOfCalls;
}
sessionCalls.put(sessionName, num + 1);
//**temp
session.getEventManager().addListener(new AcquireReleaseListener());
session.getEventManager().addListener(new SessionEventAdapter() {
@Override
public void postLogin(SessionEvent event) {
if (event.getSession().getPlatform().isPostgreSQL()) {
event.getSession().setQueryTimeoutDefault(0);
}
}
});
if (Boolean.parseBoolean(System.getProperty("sop"))) {
boolean isRecoverable = Boolean.parseBoolean(System.getProperty("sop.recoverable"));
Class<?> sopClass = Class.forName("oracle.toplink.exalogic.sop.SerializedObjectPolicy");
Method setIsRecoverableMethod = null;
if (isRecoverable) {
setIsRecoverableMethod = sopClass.getDeclaredMethod("setIsRecoverable", new Class[] {boolean.class});
}
Class[] sopEntities = {Employee.class, Address.class, Project.class};
for (Class sopEntity : sopEntities) {
ClassDescriptor descriptor = session.getDescriptor(sopEntity);
Object sop = sopClass.getConstructor().newInstance();
if (isRecoverable) {
setIsRecoverableMethod.invoke(sop, new Object[] {true});
}
((SerializedObjectPolicy)sop).setField(new DatabaseField("SOP"));
descriptor.setSerializedObjectPolicy((SerializedObjectPolicy)sop);
if (descriptor.usesOptimisticLocking() && (descriptor.getOptimisticLockingPolicy() instanceof VersionLockingPolicy)) {
((VersionLockingPolicy)descriptor.getOptimisticLockingPolicy()).setIsCascaded(true);
}
}
}
}
@Override
public void customize(ClassDescriptor descriptor) {
String javaClassName = descriptor.getJavaClass().getName();
Integer numberOfCalls = (Integer)descriptorCalls.get(javaClassName);
int num = 0;
if(numberOfCalls != null) {
num = numberOfCalls;
}
descriptorCalls.put(javaClassName, num + 1);
addCustomQueryKeys(descriptor);
}
public static Map getSessionCalls() {
return sessionCalls;
}
public static Map getDescriptorCalls() {
return descriptorCalls;
}
public static int getNumberOfCallsForSession(String sessionName) {
Integer numberOfCalls = (Integer)sessionCalls.get(sessionName);
if(numberOfCalls == null) {
return 0;
} else {
return numberOfCalls;
}
}
public static int getNumberOfCallsForClass(String javaClassName) {
Integer numberOfCalls = (Integer)descriptorCalls.get(javaClassName);
if(numberOfCalls == null) {
return 0;
} else {
return numberOfCalls;
}
}
protected void addCustomQueryKeys(ClassDescriptor descriptor) {
ExpressionBuilder builder;
// add QueryKeys to Employee descriptor
if(descriptor.getJavaClass().equals(Employee.class)) {
// Employee's Address (same as address attribute).
OneToOneQueryKey queryKey = new OneToOneQueryKey();
queryKey.setName("addressQK");
queryKey.setReferenceClass(Address.class);
builder = new ExpressionBuilder();
queryKey.setJoinCriteria(
builder.getField("CMP3_ADDRESS.ADDRESS_ID").equal(
builder.getParameter("CMP3_EMPLOYEE.ADDR_ID")));
descriptor.addQueryKey(queryKey);
// Projects led by Employee.
OneToManyQueryKey managedProjectsQueryKey = new OneToManyQueryKey();
managedProjectsQueryKey.setName("managedProjects");
managedProjectsQueryKey.setReferenceClass(Project.class);
builder = new ExpressionBuilder();
managedProjectsQueryKey.setJoinCriteria(
builder.getField("CMP3_PROJECT.LEADER_ID").equal(
builder.getParameter("CMP3_EMPLOYEE.EMP_ID")));
descriptor.addQueryKey(managedProjectsQueryKey);
// LargeProjects led by Employee.
OneToManyQueryKey managedLargeProjectsQueryKey = new OneToManyQueryKey();
managedLargeProjectsQueryKey.setName("managedLargeProjects");
managedLargeProjectsQueryKey.setReferenceClass(LargeProject.class);
builder = new ExpressionBuilder();
managedLargeProjectsQueryKey.setJoinCriteria(
builder.getField("CMP3_PROJECT.LEADER_ID").equal(
builder.getParameter("CMP3_EMPLOYEE.EMP_ID")));
descriptor.addQueryKey(managedLargeProjectsQueryKey);
// Employee's Projects (same as projects attribute).
ManyToManyQueryKey projectsQueryKey = new ManyToManyQueryKey();
projectsQueryKey.setName("projectsQK");
projectsQueryKey.setReferenceClass(Project.class);
builder = new ExpressionBuilder();
projectsQueryKey.setJoinCriteria(
(builder.getParameter("CMP3_EMPLOYEE.EMP_ID").equal(
builder.getTable("CMP3_EMP_PROJ").getField("EMPLOYEES_EMP_ID")).and(
builder.getTable("CMP3_EMP_PROJ").getField("projects_PROJ_ID").equal(
builder.getField("CMP3_PROJECT.PROJ_ID")))));
descriptor.addQueryKey(projectsQueryKey);
// Employee's LargeProjects.
ManyToManyQueryKey largeProjectsQueryKey = new ManyToManyQueryKey();
largeProjectsQueryKey.setName("largeProjects");
largeProjectsQueryKey.setReferenceClass(LargeProject.class);
builder = new ExpressionBuilder();
largeProjectsQueryKey.setJoinCriteria(
(builder.getParameter("CMP3_EMPLOYEE.EMP_ID").equal(
builder.getTable("CMP3_EMP_PROJ").getField("EMPLOYEES_EMP_ID")).and(
builder.getTable("CMP3_EMP_PROJ").getField("projects_PROJ_ID").equal(
builder.getField("CMP3_PROJECT.PROJ_ID")))));
descriptor.addQueryKey(largeProjectsQueryKey);
// Employee's responsibilities (same as responsibilities) - can't make this work so far.
DirectCollectionQueryKey responsibilitiesQueryKey = new DirectCollectionQueryKey();
responsibilitiesQueryKey.setName("responsibilitiesQK");
builder = new ExpressionBuilder();
responsibilitiesQueryKey.setJoinCriteria(
builder.getField("CMP3_RESPONS.DESCRIPTION").equal(
builder.getField("CMP3_RESPONS.EMP_ID").equal(
builder.getParameter("CMP3_EMPLOYEE.EMP_ID"))));
descriptor.addQueryKey(responsibilitiesQueryKey);
} else if(descriptor.getJavaClass().equals(Address.class)) {
// Employee that references Address
OneToOneQueryKey ownerQueryKey = new OneToOneQueryKey();
ownerQueryKey.setName("owner");
ownerQueryKey.setReferenceClass(Employee.class);
builder = new ExpressionBuilder();
ownerQueryKey.setJoinCriteria(
builder.getField("CMP3_EMPLOYEE.ADDR_ID").equal(
builder.getParameter("CMP3_ADDRESS.ADDRESS_ID")));
descriptor.addQueryKey(ownerQueryKey);
} else if(descriptor.getJavaClass().equals(Project.class)) {
// Project's employees.
ManyToManyQueryKey employesQueryKey = new ManyToManyQueryKey();
employesQueryKey.setName("employees");
employesQueryKey.setReferenceClass(Employee.class);
builder = new ExpressionBuilder();
employesQueryKey.setJoinCriteria(
(builder.getParameter("CMP3_PROJECT.PROJ_ID").equal(
builder.getTable("CMP3_EMP_PROJ").getField("projects_PROJ_ID")).and(
builder.getTable("CMP3_EMP_PROJ").getField("EMPLOYEES_EMP_ID").equal(
builder.getField("CMP3_EMPLOYEE.EMP_ID")))));
descriptor.addQueryKey(employesQueryKey);
}
}
//**temp
static class AcquireReleaseListener extends SessionEventAdapter {
@Override
public void postAcquireConnection(SessionEvent event) {
DatasourceAccessor accessor = (DatasourceAccessor)event.getResult();
try {
if(accessor.getLogin() == null) {
throw new RuntimeException("acquired accessor.getLogin() == null");
}
if(accessor.getDatasourceConnection() == null) {
throw new RuntimeException("AcquireReleaseListener: acquired accessor.getDatasourceConnection() == null");
}
} catch (RuntimeException ex) {
ex.printStackTrace();
throw ex;
}
}
@Override
public void preReleaseConnection(SessionEvent event) {
DatasourceAccessor accessor = (DatasourceAccessor)event.getResult();
try {
if(accessor.getLogin() == null) {
throw new RuntimeException("released accessor.getLogin() == null");
}
if(accessor.getDatasourceConnection() == null) {
throw new RuntimeException("AcquireReleaseListener: released accessor.getDatasourceConnection() == null");
}
} catch (RuntimeException ex) {
ex.printStackTrace();
throw ex;
}
}
}
}