org.eclipse.persistence.internal.jpa.parsing.MemberOfNode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* Copyright (c) 1998, 2020 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.internal.jpa.parsing;
/**
* INTERNAL
* Purpose: Represent the MEMBER-OF operator
*
Responsibilities:
* - MEMBER OF is not supported.
*
* @author Jon Driscoll and Joel Lucuik
* @since since July 2003
*/
import org.eclipse.persistence.expressions.*;
public class MemberOfNode extends BinaryOperatorNode {
private boolean notIndicated = false;
//If we're dealing with a NOT, we store the expression for the left.
//When we get to the one-to-many on the right, it will handle the noneOf using
//the receiver stored in the context.
//(i.e. secondLastRightExpression.noneOf(lastRightVariable, leftExpression)
private Expression leftExpression = null;
/**
* Return a new MemberOfNode
*/
public MemberOfNode() {
super();
}
/**
* INTERNAL makeNodeOneToMany:
* Traverse to the leaf on theNode and mark as one to many
*/
public void makeNodeOneToMany(Node theNode) {
Node currentNode = theNode;
do {
if (!currentNode.hasRight()) {
((AttributeNode)currentNode).setRequiresCollectionAttribute(true);
return;
}
currentNode = currentNode.getRight();
} while (true);
}
/**
* INTERNAL
* Validate node and calculates its type.
*/
@Override
public void validate(ParseTreeContext context) {
super.validate(context);
Node left = getLeft();
if (left.isVariableNode() && ((VariableNode)left).isAlias(context)) {
context.usedVariable(((VariableNode)left).getCanonicalVariableName());
}
left.validateParameter(context, right.getType());
TypeHelper typeHelper = context.getTypeHelper();
setType(typeHelper.getBooleanType());
}
@Override
public Expression generateExpression(GenerationContext context) {
// Need to make sure one of the node is marked as a one to many
if (getRight().isParameterNode()) {
makeNodeOneToMany(getLeft());
} else {
makeNodeOneToMany(getRight());
}
//Handle NOT. Store the expression for the left, let VariableNode handle it.
if (notIndicated()) {
Expression resultFromRight = null;
context.setMemberOfNode(this);
this.setLeftExpression(getLeft().generateExpression(context));
resultFromRight = getRight().generateExpression(context);
//clean up
context.setMemberOfNode(null);
this.setLeftExpression(null);
return resultFromRight;
} else {
//otherwise, handle like normal anyOf()
return getRight().generateExpression(context).equal(getLeft().generateExpression(context));
}
}
/**
* INTERNAL
* Indicate if a NOT was found in the WHERE clause.
* Examples:
* ...WHERE ... NOT MEMBER OF
*/
public void indicateNot() {
notIndicated = true;
}
public boolean notIndicated() {
return notIndicated;
}
//set and get the leftExpression. This is for NOT MEMBER OF.
public void setLeftExpression(Expression newLeftExpression) {
leftExpression = newLeftExpression;
}
public Expression getLeftExpression() {
return leftExpression;
}
}