org.eclipse.persistence.internal.expressions.ClassTypeExpression Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 1998, 2024 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:
// May 21, 2009-2.0 Chris Delahunt
// - TODO Bug#: Bug Description
package org.eclipse.persistence.internal.expressions;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
* @author cdelahun
*
*/
public class ClassTypeExpression extends DataExpression {
/** Cache the aliased field. Only applies to attributes. */
protected DatabaseField field;
/** Cache the aliased field. Only applies to attributes. */
protected DatabaseField aliasedField;
/**
*
*/
public ClassTypeExpression(Expression base) {
super();
this.baseExpression = base;
}
public ClassTypeExpression() {
super();
}
/**
* INTERNAL:
* Used for debug printing.
*/
@Override
public String descriptionOfNodeType() {
return "Class For Inheritance";
}
/* (non-Javadoc)
* @see org.eclipse.persistence.expressions.Expression#rebuildOn(org.eclipse.persistence.expressions.Expression)
*/
@Override
public Expression rebuildOn(Expression newBase) {
Expression newLocalBase = getBaseExpression().rebuildOn(newBase);
Expression result = newLocalBase.type();
result.setSelectIfOrderedBy(selectIfOrderedBy());
return result;
}
/**
* INTERNAL
* This method returns the inheritance field value for an object to conform in an in-memory query.
* Similar to getFieldValue, but deals with an instance rather than a Class object directly
*/
public Object typeValueFromObject(Object object, AbstractSession session) {
// get the descriptor directly from the object, and use it to find the Java class
ClassDescriptor objectDescriptor = session.getClassDescriptor(object);
if (!objectDescriptor.hasInheritance()
|| objectDescriptor.getInheritancePolicy().shouldUseClassNameAsIndicator()
|| objectDescriptor.getInheritancePolicy().hasClassExtractor() ) {
return (objectDescriptor.getJavaClassName());
} else {
return objectDescriptor.getInheritancePolicy().getClassIndicatorMapping().get(objectDescriptor.getJavaClass());
}
}
@Override
public void validateNode() {
ClassDescriptor descriptor = getContainingDescriptor();
if (descriptor ==null){
throw QueryException.invalidTypeExpression(getBaseExpression());
}
if ( (!descriptor.hasInheritance()) || (!descriptor.getInheritancePolicy().hasClassIndicator()) ) {
throw QueryException.invalidTypeExpression(descriptor.getJavaClassName());
}
super.validateNode();
}
/**
* INTERNAL:
* Return the value for in memory comparison.
* This is only valid for value expressions.
* Pulled from QueryKeyExpression valueFromObject
*/
@Override
public Object valueFromObject(Object object, AbstractSession session, AbstractRecord translationRow, int valueHolderPolicy, boolean isObjectUnregistered) {
// The expression may be across a relationship, in which case it must be traversed.
if ((!getBaseExpression().isExpressionBuilder()) && getBaseExpression().isQueryKeyExpression()) {
object = getBaseExpression().valueFromObject(object, session, translationRow, valueHolderPolicy, isObjectUnregistered);
// toDo: Null means the join filters out the row, returning null is not correct if an inner join,
// outer/inner joins need to be fixed to filter correctly.
if (object == null) {
return null;
}
// If from an anyof the object will be a collection of values,
// A new vector must union the object values and the values extracted from it.
if (object instanceof List v) {
List