| /* |
| * Copyright (c) 1998, 2019 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 |
| // dminsky - added writeFields API overriding behavior from Expression |
| package org.eclipse.persistence.internal.expressions; |
| |
| import java.io.BufferedWriter; |
| import java.io.IOException; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.persistence.expressions.Expression; |
| import org.eclipse.persistence.expressions.ExpressionBuilder; |
| import org.eclipse.persistence.internal.helper.DatabaseField; |
| import org.eclipse.persistence.internal.sessions.AbstractRecord; |
| import org.eclipse.persistence.internal.sessions.AbstractSession; |
| |
| /** |
| * Used for wrapping literal values. |
| */ |
| public class LiteralExpression extends Expression { |
| |
| protected String value; |
| protected Expression localBase; |
| |
| public LiteralExpression() { |
| super(); |
| } |
| |
| public LiteralExpression(String newValue, Expression baseExpression) { |
| super(); |
| value = newValue; |
| localBase = baseExpression; |
| } |
| |
| /** |
| * 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; |
| } |
| if (!super.equals(object)) { |
| return false; |
| } |
| LiteralExpression expression = (LiteralExpression) object; |
| return ((getValue() == expression.getValue()) || ((getValue() != null) && getValue().equals(expression.getValue()))); |
| } |
| |
| /** |
| * INTERNAL: |
| * Compute a consistent hash-code for the expression. |
| * This is used to allow dynamic expression's SQL to be cached. |
| */ |
| @Override |
| public int computeHashCode() { |
| int hashCode = super.computeHashCode(); |
| if (getValue() != null) { |
| hashCode = hashCode + getValue().hashCode(); |
| } |
| return hashCode; |
| } |
| |
| /** |
| * INTERNAL: |
| * Used for debug printing. |
| */ |
| @Override |
| public String descriptionOfNodeType() { |
| return "Literal"; |
| } |
| |
| /** |
| * Return the expression builder which is the ultimate base of this expression, or |
| * null if there isn't one (shouldn't happen if we start from a root) |
| */ |
| @Override |
| public ExpressionBuilder getBuilder() { |
| if(this.localBase != null) { |
| return this.localBase.getBuilder(); |
| } else { |
| return null; |
| } |
| } |
| |
| protected Expression getLocalBase() { |
| return localBase; |
| } |
| |
| public String getValue() { |
| return value; |
| } |
| |
| @Override |
| public boolean isLiteralExpression() { |
| return true; |
| } |
| |
| /** |
| * INTERNAL: |
| * Used for cloning. |
| */ |
| @Override |
| protected void postCopyIn(Map alreadyDone) { |
| super.postCopyIn(alreadyDone); |
| localBase = localBase.copiedVersionFrom(alreadyDone); |
| } |
| |
| /** |
| * INTERNAL: |
| * Print SQL onto the stream, using the ExpressionPrinter for context |
| */ |
| @Override |
| public void printSQL(ExpressionSQLPrinter printer) { |
| printer.printString(value); |
| } |
| |
| /** |
| * 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) { |
| Expression result = (LiteralExpression)clone(); |
| result.setLocalBase(getLocalBase().rebuildOn(newBase)); |
| return result; |
| } |
| |
| /** |
| * INTERNAL: |
| * Search the tree for any expressions (like SubSelectExpressions) that have been |
| * built using a builder that is not attached to the query. This happens in case of an Exists |
| * call using a new ExpressionBuilder(). This builder needs to be replaced with one from the query. |
| */ |
| @Override |
| public void resetPlaceHolderBuilder(ExpressionBuilder queryBuilder){ |
| return; |
| } |
| |
| |
| @Override |
| public void setLocalBase(Expression e) { |
| localBase = e; |
| } |
| |
| /** |
| * 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) { |
| return (Expression)this.clone(); |
| } |
| |
| /** |
| * INTERNAL: |
| * Return the value for in memory comparison. |
| * This is only valid for valueable expressions. |
| */ |
| @Override |
| public Object valueFromObject(Object object, AbstractSession session, AbstractRecord translationRow, int valueHolderPolicy, boolean isObjectUnregistered) { |
| return getLocalBase().getFieldValue(getValue(), session); |
| } |
| |
| /** |
| * INTERNAL: |
| * Used to print a debug form of the expression tree. |
| */ |
| @Override |
| public void writeDescriptionOn(BufferedWriter writer) throws IOException { |
| writer.write(getValue()); |
| } |
| |
| /** |
| * INTERNAL: |
| * Append the literal value into the printer, accounting for the first element |
| */ |
| @Override |
| public void writeFields(ExpressionSQLPrinter printer, List<DatabaseField> newFields, SQLSelectStatement statement) { |
| // print ", " before each selected field except the first one |
| if (printer.isFirstElementPrinted()) { |
| printer.printString(", "); |
| } else { |
| printer.setIsFirstElementPrinted(true); |
| } |
| |
| newFields.add(new DatabaseField(getValue())); |
| printSQL(printer); |
| } |
| |
| } |