use of org.datanucleus.query.compiler.Symbol in project datanucleus-core by datanucleus.
the class PrimaryExpression method bind.
/**
* Method to bind the expression to the symbol table as appropriate.
* @param symtbl Symbol Table
* @return The symbol for this expression
*/
public Symbol bind(SymbolTable symtbl) {
if (left != null) {
left.bind(symtbl);
}
// TODO Cater for finding field of left expression
if (left == null && symtbl.hasSymbol(getId())) {
symbol = symtbl.getSymbol(getId());
if (symbol.getType() == Symbol.VARIABLE) {
// This is a variable, so needs converting
throw new PrimaryExpressionIsVariableException(symbol.getQualifiedName());
}
return symbol;
}
if (left != null) {
return null;
}
if (symbol == null) {
// Try with our symbol table
try {
Class symbolType = symtbl.getSymbolResolver().getType(tuples);
symbol = new PropertySymbol(getId(), symbolType);
} catch (NucleusUserException nue) {
// Thrown if a field in the primary expression doesn't exist.
}
}
if (symbol == null && symtbl.getParentSymbolTable() != null) {
// Try parent symbol table if present
try {
Class symbolType = symtbl.getParentSymbolTable().getSymbolResolver().getType(tuples);
symbol = new PropertySymbol(getId(), symbolType);
} catch (NucleusUserException nue) {
// Thrown if a field in the primary expression doesn't exist.
}
}
if (symbol == null) {
// This may be due to an entry like "org.jpox.samples.MyClass" used for "instanceof"
String className = getId();
try {
// Try to find this as a complete class name (e.g as used in "instanceof")
Class cls = symtbl.getSymbolResolver().resolveClass(className);
// Represents a valid class so throw exception to get the PrimaryExpression swapped
throw new PrimaryExpressionIsClassLiteralException(cls);
} catch (ClassNotResolvedException cnre) {
// Try to find classname.staticField
if (className.indexOf('.') < 0) {
// {candidateCls}.primary so "primary" is staticField ?
Class primaryCls = symtbl.getSymbolResolver().getPrimaryClass();
if (primaryCls == null) {
throw new NucleusUserException("Class name " + className + " could not be resolved");
}
try {
Field fld = primaryCls.getDeclaredField(className);
if (!Modifier.isStatic(fld.getModifiers())) {
throw new NucleusUserException("Identifier " + className + " is unresolved (not a static field)");
}
throw new PrimaryExpressionIsClassStaticFieldException(fld);
} catch (NoSuchFieldException nsfe) {
if (symtbl.getSymbolResolver().supportsImplicitVariables() && left == null) {
// Implicit variable assumed so swap this primary for it
throw new PrimaryExpressionIsVariableException(className);
}
throw new NucleusUserException("Class name " + className + " could not be resolved");
}
}
try {
String staticFieldName = className.substring(className.lastIndexOf('.') + 1);
className = className.substring(0, className.lastIndexOf('.'));
Class cls = symtbl.getSymbolResolver().resolveClass(className);
try {
Field fld = cls.getDeclaredField(staticFieldName);
if (!Modifier.isStatic(fld.getModifiers())) {
throw new NucleusUserException("Identifier " + className + "." + staticFieldName + " is unresolved (not a static field)");
}
throw new PrimaryExpressionIsClassStaticFieldException(fld);
} catch (NoSuchFieldException nsfe) {
throw new NucleusUserException("Identifier " + className + "." + staticFieldName + " is unresolved (not a static field)");
}
} catch (ClassNotResolvedException cnre2) {
if (getId().indexOf(".") > 0) {
Iterator<String> tupleIter = tuples.iterator();
Class cls = null;
while (tupleIter.hasNext()) {
String tuple = tupleIter.next();
if (cls == null) {
Symbol sym = symtbl.getSymbol(tuple);
if (sym == null) {
sym = symtbl.getSymbol("this");
if (sym == null) {
// TODO Need to get hold of candidate alias
break;
}
}
cls = sym.getValueType();
} else {
// Look for member of the current class
if (cls.isArray() && tuple.equals("length") && !tupleIter.hasNext()) {
// Special case of Array.length
PrimaryExpression primExpr = new PrimaryExpression(left, tuples.subList(0, tuples.size() - 1));
InvokeExpression invokeExpr = new InvokeExpression(primExpr, "size", null);
throw new PrimaryExpressionIsInvokeException(invokeExpr);
}
cls = ClassUtils.getClassForMemberOfClass(cls, tuple);
}
}
if (cls != null) {
// TODO Add symbol
}
}
}
if (symtbl.getSymbolResolver().supportsImplicitVariables() && left == null) {
// Implicit variable, so put as "left" and remove from tuples
String varName = tuples.remove(0);
VariableExpression varExpr = new VariableExpression(varName);
varExpr.bind(symtbl);
left = varExpr;
} else {
// Just throw the original exception
throw new NucleusUserException("Cannot find type of (part of) " + getId() + " since symbol has no type; implicit variable?");
}
}
}
return symbol;
}
use of org.datanucleus.query.compiler.Symbol in project datanucleus-core by datanucleus.
the class Query method applyImplicitParameterValueToCompilation.
/**
* Convenience method to apply an implicit parameter value to the compilation symbol table.
* If the (generic) compilation doesn't exist then does nothing.
* If the parameter doesn't exist in the symbol table then an exception is thrown (since no point
* providing a parameter if not in the query).
* @param name Name of the parameter
* @param value Value of the parameter
* @throws QueryInvalidParametersException if the parameter doesn't exist in the query or if the type
* of the parameter provided is inconsistent with the query
*/
protected void applyImplicitParameterValueToCompilation(String name, Object value) {
if (compilation == null) {
return;
}
// Apply to the main query
boolean symbolFound = false;
Symbol sym = compilation.getSymbolTable().getSymbol(name);
if (sym != null) {
symbolFound = true;
if (sym.getValueType() == null && value != null) {
// Update the compilation providing the type of this parameter
sym.setValueType(value.getClass());
} else if (sym.getValueType() != null && value != null) {
if (!QueryUtils.queryParameterTypesAreCompatible(sym.getValueType(), value.getClass())) {
// Parameter value supplied is not consistent with what the query compilation expects
throw new QueryInvalidParametersException("Parameter " + name + " needs to be assignable from " + sym.getValueType().getName() + " yet the value is of type " + value.getClass().getName());
}
}
}
// Apply to any subqueries
boolean subSymbolFound = applyImplicitParameterValueToSubqueries(name, value, compilation);
if (subSymbolFound) {
symbolFound = true;
}
if (!symbolFound) {
// No reference to this parameter was found in the compilation, so throw exception
throw new QueryInvalidParametersException(Localiser.msg("021116", name));
}
}
use of org.datanucleus.query.compiler.Symbol in project datanucleus-core by datanucleus.
the class Query method applyImplicitParameterValueToSubqueries.
protected boolean applyImplicitParameterValueToSubqueries(String name, Object value, QueryCompilation comp) {
boolean symbolFound = false;
Symbol sym = null;
// Apply to any subqueries
String[] subqueryNames = comp.getSubqueryAliases();
if (subqueryNames != null) {
for (int i = 0; i < subqueryNames.length; i++) {
QueryCompilation subCompilation = comp.getCompilationForSubquery(subqueryNames[i]);
sym = subCompilation.getSymbolTable().getSymbol(name);
if (sym != null) {
symbolFound = true;
if (sym.getValueType() == null && value != null) {
// Update the compilation providing the type of this parameter
sym.setValueType(value.getClass());
} else if (sym.getValueType() != null && value != null) {
if (!QueryUtils.queryParameterTypesAreCompatible(sym.getValueType(), value.getClass())) {
// Parameter value supplied is not consistent with what the query compilation expects
throw new QueryInvalidParametersException("Parameter " + name + " needs to be assignable from " + sym.getValueType().getName() + " yet the value is of type " + value.getClass().getName());
}
}
}
boolean subSymbolFound = applyImplicitParameterValueToSubqueries(name, value, subCompilation);
if (subSymbolFound) {
symbolFound = true;
}
}
}
return symbolFound;
}
use of org.datanucleus.query.compiler.Symbol in project datanucleus-core by datanucleus.
the class Query method deepFindSymbolForParameterInCompilation.
protected Symbol deepFindSymbolForParameterInCompilation(QueryCompilation compilation, Object paramKey) {
Symbol sym = null;
sym = getSymbolForParameterInCompilation(compilation, paramKey);
if (sym == null) {
String[] subqueryNames = compilation.getSubqueryAliases();
if (subqueryNames != null) {
for (int i = 0; i < subqueryNames.length; i++) {
sym = deepFindSymbolForParameterInCompilation(compilation.getCompilationForSubquery(subqueryNames[i]), paramKey);
if (sym != null) {
break;
}
}
}
}
return sym;
}
use of org.datanucleus.query.compiler.Symbol in project datanucleus-core by datanucleus.
the class Query method getSymbolForParameterInCompilation.
/**
* Convenience method to find a symbol for the specified parameter in the provided compilation.
* @param compilation The compilation
* @param paramKey The parameter name/position
* @return The symbol (if present)
*/
private Symbol getSymbolForParameterInCompilation(QueryCompilation compilation, Object paramKey) {
Symbol sym = null;
if (paramKey instanceof Integer) {
ParameterExpression expr = compilation.getParameterExpressionForPosition((Integer) paramKey);
if (expr != null) {
sym = expr.getSymbol();
}
} else {
String paramName = (String) paramKey;
sym = compilation.getSymbolTable().getSymbol(paramName);
}
return sym;
}
Aggregations