Search in sources :

Example 6 with Symbol

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;
}
Also used : PropertySymbol(org.datanucleus.query.compiler.PropertySymbol) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) Symbol(org.datanucleus.query.compiler.Symbol) PropertySymbol(org.datanucleus.query.compiler.PropertySymbol) ClassNotResolvedException(org.datanucleus.exceptions.ClassNotResolvedException) Field(java.lang.reflect.Field)

Example 7 with 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));
    }
}
Also used : Symbol(org.datanucleus.query.compiler.Symbol)

Example 8 with Symbol

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;
}
Also used : Symbol(org.datanucleus.query.compiler.Symbol) QueryCompilation(org.datanucleus.query.compiler.QueryCompilation)

Example 9 with Symbol

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;
}
Also used : Symbol(org.datanucleus.query.compiler.Symbol)

Example 10 with Symbol

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;
}
Also used : Symbol(org.datanucleus.query.compiler.Symbol) ParameterExpression(org.datanucleus.query.expression.ParameterExpression)

Aggregations

Symbol (org.datanucleus.query.compiler.Symbol)12 HashMap (java.util.HashMap)5 QueryCompilation (org.datanucleus.query.compiler.QueryCompilation)4 SymbolTable (org.datanucleus.query.compiler.SymbolTable)4 ParameterExpression (org.datanucleus.query.expression.ParameterExpression)4 NucleusException (org.datanucleus.exceptions.NucleusException)3 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)3 JavaQueryCompiler (org.datanucleus.query.compiler.JavaQueryCompiler)3 DyadicExpression (org.datanucleus.query.expression.DyadicExpression)3 Expression (org.datanucleus.query.expression.Expression)3 InvokeExpression (org.datanucleus.query.expression.InvokeExpression)3 PrimaryExpression (org.datanucleus.query.expression.PrimaryExpression)3 VariableExpression (org.datanucleus.query.expression.VariableExpression)3 Field (java.lang.reflect.Field)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 JDOQLCompiler (org.datanucleus.query.compiler.JDOQLCompiler)2 Literal (org.datanucleus.query.expression.Literal)2 OrderExpression (org.datanucleus.query.expression.OrderExpression)2 Inventory (org.datanucleus.samples.store.Inventory)2 Product (org.datanucleus.samples.store.Product)2