| /* |
| * 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.expressions; |
| |
| import java.util.*; |
| |
| import org.eclipse.persistence.internal.helper.DatabaseTable; |
| import org.eclipse.persistence.mappings.querykeys.*; |
| import org.eclipse.persistence.expressions.*; |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| |
| /** |
| * This class represents a "query key" that isn't really there |
| * in the descriptors. For example, I could use this to create |
| * an 'employee' query key from an 'address' node even if addresses |
| * don't know their employee. It's called manual, because I will |
| * have to provide the relevant join criteria myself (normally based |
| * on a reverse relationship. Motivated by batch reading. |
| */ |
| public class ManualQueryKeyExpression extends QueryKeyExpression { |
| public ManualQueryKeyExpression() { |
| super(); |
| } |
| |
| public ManualQueryKeyExpression(String impliedRelationshipName, Expression base) { |
| super(impliedRelationshipName, base); |
| } |
| |
| public ManualQueryKeyExpression(String impliedRelationshipName, Expression base, ClassDescriptor descriptor) { |
| super(impliedRelationshipName, base); |
| this.descriptor = descriptor; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return if the expression is equal to the other. |
| * This is used to allow dynamic expression's SQL to be cached. |
| */ |
| @Override |
| public boolean equals(Object object) { |
| if (this == object) { |
| return true; |
| } |
| // Equality cannot easily be determined for maunal expressions. |
| return false; |
| } |
| |
| /** |
| * INTERNAL: |
| * Used for debug printing. |
| */ |
| @Override |
| public String descriptionOfNodeType() { |
| return "Manual Query Key"; |
| } |
| |
| /** |
| * INTERNAL: |
| * If we ever get in the circumstance of a manual query key |
| * to an aggregate, then we can assume that the owner of that |
| * aggregate isn't participating (and even if it is, we can't |
| * know which node it is, so *DO* use the aggregate's parents tables |
| */ |
| @Override |
| public List<DatabaseTable> getOwnedTables() { |
| if (getDescriptor() == null) { |
| return null; |
| } else { |
| if ((getDescriptor().getHistoryPolicy() != null) && (getAsOfClause().getValue() != null)) { |
| return getDescriptor().getHistoryPolicy().getHistoricalTables(); |
| } |
| return getDescriptor().getTables(); |
| } |
| } |
| |
| @Override |
| public QueryKey getQueryKeyOrNull() { |
| return null; |
| } |
| |
| /** |
| * INTERNAL: |
| * We can never be an attribute, we're always a join |
| */ |
| @Override |
| public boolean isAttribute() { |
| return false; |
| } |
| |
| @Override |
| public Expression mappingCriteria(Expression base) { |
| return null; |
| } |
| |
| /** |
| * INTERNAL: |
| * This expression is built on a different base than the one we want. Rebuild it and |
| * return the root of the new tree |
| */ |
| @Override |
| public Expression rebuildOn(Expression newBase) { |
| ObjectExpression newLocalBase = (ObjectExpression)getBaseExpression().rebuildOn(newBase); |
| return newLocalBase.getManualQueryKey(getName(), getDescriptor()); |
| } |
| |
| /** |
| * INTERNAL: |
| * Rebuild myself against the base, with the values of parameters supplied by the context |
| * expression. This is used for transforming a standalone expression (e.g. the join criteria of a mapping) |
| * into part of some larger expression. You normally would not call this directly, instead calling twist |
| * See the comment there for more details" |
| */ |
| @Override |
| public Expression twistedForBaseAndContext(Expression newBase, Expression context, Expression oldBase) { |
| ObjectExpression twistedBase = (ObjectExpression)getBaseExpression().twistedForBaseAndContext(newBase, context, oldBase); |
| return twistedBase.getManualQueryKey(getName(), getDescriptor()); |
| |
| } |
| |
| /** |
| * Do any required validation for this node. Throw an exception if it's incorrect. |
| */ |
| @Override |
| public void validateNode() { |
| // Override super.validateNode() because those criteria don't apply to us |
| } |
| } |