/******************************************************************************* | |
* Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* 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.*; | |
import java.util.*; | |
import org.eclipse.persistence.expressions.*; | |
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. | |
*/ | |
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. | |
*/ | |
public int computeHashCode() { | |
int hashCode = super.computeHashCode(); | |
if (getValue() != null) { | |
hashCode = hashCode + getValue().hashCode(); | |
} | |
return hashCode; | |
} | |
/** | |
* INTERNAL: | |
* Used for debug printing. | |
*/ | |
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) | |
*/ | |
public ExpressionBuilder getBuilder() { | |
if(this.localBase != null) { | |
return this.localBase.getBuilder(); | |
} else { | |
return null; | |
} | |
} | |
protected Expression getLocalBase() { | |
return localBase; | |
} | |
public String getValue() { | |
return value; | |
} | |
public boolean isLiteralExpression() { | |
return true; | |
} | |
/** | |
* INTERNAL: | |
* Used for cloning. | |
*/ | |
protected void postCopyIn(Map alreadyDone) { | |
super.postCopyIn(alreadyDone); | |
localBase = localBase.copiedVersionFrom(alreadyDone); | |
} | |
/** | |
* INTERNAL: | |
* Print SQL onto the stream, using the ExpressionPrinter for context | |
*/ | |
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 | |
*/ | |
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. | |
*/ | |
public void resetPlaceHolderBuilder(ExpressionBuilder queryBuilder){ | |
return; | |
} | |
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. | |
*/ | |
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. | |
*/ | |
public void writeDescriptionOn(BufferedWriter writer) throws IOException { | |
writer.write(getValue().toString()); | |
} | |
/** | |
* INTERNAL: | |
* Append the literal value into the printer, accounting for the first element | |
*/ | |
@Override | |
public void writeFields(ExpressionSQLPrinter printer, Vector newFields, SQLSelectStatement statement) { | |
// print ", " before each selected field except the first one | |
if (printer.isFirstElementPrinted()) { | |
printer.printString(", "); | |
} else { | |
printer.setIsFirstElementPrinted(true); | |
} | |
newFields.addElement(new DatabaseField(getValue())); | |
printSQL(printer); | |
} | |
} |