FileDocCategorySizeDatePackage
ParseTreeContext.javaAPI DocGlassfish v2 API16504Tue May 22 16:54:38 BST 2007oracle.toplink.essentials.internal.parsing

ParseTreeContext

public class ParseTreeContext extends Object
INTERNAL

Purpose: The ParseTreeContext holds and manages context information for the parse tree for validation.

Responsibilities:

  • Associate schema names with variables
  • Associate identifier with nodes
  • Answer an alias for a variable name
  • Answer a class for a variable name
  • Answer a class loader
  • Answer true if there is a class for a variable name
  • Answer a node for a given identifier
  • Print the context on a string
see
ParseTree
author
Jon Driscoll and Joel Lucuik
since
TopLink 4.0

Fields Summary
private Map
variableDecls
private String
baseVariable
private int
currentScope
private Set
outerScopeVariables
private Map
fetchJoins
private TypeHelper
typeHelper
private Map
parameterTypes
private List
parameterNames
private NodeFactory
nodeFactory
private String
queryInfo
Constructors Summary
public ParseTreeContext(NodeFactory nodeFactory, String queryInfo)
INTERNAL Return a new initialized ParseTreeContext

        super();
        variableDecls = new HashMap();
        currentScope = 0;
        fetchJoins = new HashMap();
        typeHelper = null;
        parameterTypes = new HashMap();
        parameterNames = new ArrayList();
        this.nodeFactory = nodeFactory;
        this.queryInfo = queryInfo;
    
Methods Summary
public voidaddParameter(java.lang.String parameterName)
INTERNAL Add a parameter.

        if (!parameterNames.contains(parameterName)){
            parameterNames.add(parameterName);
        }
    
public java.lang.ClassclassForSchemaName(java.lang.String schemaName, oracle.toplink.essentials.internal.parsing.GenerationContext context)
INTERNAL Answer the class associated with the provided schema name

        ClassDescriptor descriptor = context.getSession().getDescriptorForAlias(schemaName);
        if (descriptor == null) {
            throw EJBQLException.unknownAbstractSchemaType(getQueryInfo(), schemaName);
        }
        Class theClass = descriptor.getJavaClass();
        if (theClass == null) {
            throw EJBQLException.resolutionClassNotFoundException(getQueryInfo(), schemaName);
        }
        return theClass;
    
public voiddefineParameterType(java.lang.String parameterName, java.lang.Object parameterType, int line, int column)
INTERNAL Defines the type of the parameter with the specified name.

        if (parameterTypes.containsKey(parameterName)) {
            // existing entry
            Object oldType = parameterTypes.get(parameterName);
            if (typeHelper.isAssignableFrom(oldType, parameterType)) {
                // OK
            } else if (typeHelper.isAssignableFrom(parameterType, oldType)) {
                // new parameter type is more general
                parameterTypes.put(parameterName, parameterType);
            } else {
                // error case old usage and new usage do not match type
                throw EJBQLException.invalidMultipleUseOfSameParameter(
                    getQueryInfo(), line, column, parameterName, 
                    typeHelper.getTypeName(oldType), 
                    typeHelper.getTypeName(parameterType));
            }
        } else {
            // new entry 
            parameterTypes.put(parameterName, parameterType);
        }
    
public voidenterScope()
INTERNAL Enters a new scope. This initializes the set of outer scope variables.

        currentScope++;
        resetOuterScopeVariables();
    
public java.lang.StringgetBaseVariable()

        return baseVariable;
    
public java.util.ListgetFetchJoins(java.lang.String variableName)
Returns alist of FETCH JOIN nodes for the specified attached to the specified variable.

        return (List)fetchJoins.get(variableName);
    
public oracle.toplink.essentials.internal.parsing.NodeFactorygetNodeFactory()

        return nodeFactory;
    
public java.util.SetgetOuterScopeVariables()
INTERNAL Returns the set of outer scope variables.

        return outerScopeVariables;
    
public java.util.ListgetParameterNames()
INTERNAL Return the parameter names.

        return parameterNames;
    
public java.lang.ObjectgetParameterType(java.lang.String parameter)
INTERNAL Return the type of the specified parameter.

        return parameterTypes.get(parameter);
    
public java.lang.StringgetQueryInfo()

        return queryInfo;
    
public oracle.toplink.essentials.internal.parsing.TypeHelpergetTypeHelper()
INTERNAL Returns the type helper stored in this context.

        return typeHelper;
    
public java.util.SetgetUnusedVariables()
Returns s set of variables that are declared in the current scope, but not used in the query.

        Set unused = new HashSet();
        for (Iterator i = variableDecls.entrySet().iterator(); i.hasNext();) {
            Map.Entry entry = (Map.Entry)i.next();
            String variable = (String)entry.getKey();
            VariableDecl decl = (VariableDecl)entry.getValue();
            if ((decl.scope == currentScope) && !decl.used) {
                unused.add(variable);
            }
        }
        return unused;
    
public java.lang.StringgetVariableNameForClass(java.lang.Class theClass, oracle.toplink.essentials.internal.parsing.GenerationContext context)
INTERNAL getVariableNameForClass(): Answer the name mapped to the specified class. Answer null if none found. SELECT OBJECT (emp) FROM Employee emp getVariableNameForClass(Employee.class) => "emp"

        for (Iterator i = variableDecls.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry entry = (Map.Entry)i.next();
            String nextVariable = (String)entry.getKey();
            VariableDecl decl = (VariableDecl)entry.getValue();
            if ((decl.schema != null) && 
                (theClass == this.classForSchemaName(decl.schema, context))) {
                return nextVariable;
            }
        }
        return null;
    
public booleanhasMoreThanOneAliasInFrom()

        Map typeNamesToVariables = new HashMap();
        for (Iterator i = variableDecls.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry entry = (Map.Entry)i.next();
            String variable = (String)entry.getKey();
            VariableDecl decl = (VariableDecl)entry.getValue();
            if (decl.isRangeVariable) {
                typeNamesToVariables.put(decl.schema, variable);
            }
        }
        return typeNamesToVariables.size() > 1;
    
public booleanhasMoreThanOneVariablePerType()

        Map typeNamesToVariables = new HashMap();
        int nrOfRangeVariables = 0;
        //Map the Aliases to the variable names, then check the count
        for (Iterator i = variableDecls.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry entry = (Map.Entry)i.next();
            String variable = (String)entry.getKey();
            VariableDecl decl = (VariableDecl)entry.getValue();
            if (decl.isRangeVariable) {
                nrOfRangeVariables++;
                typeNamesToVariables.put(decl.schema, variable);
            }
        }
        return typeNamesToVariables.size() != nrOfRangeVariables;
    
public booleanhasParameters()
INTERNAL Returns true if the query has at least one parameter.

        return !parameterNames.isEmpty();
    
public booleanisDeclaredInOuterScope(java.lang.String variable)
INTERNAL Returns true if the specified string denotes a variable declared in an outer scope.

        VariableDecl decl = (VariableDecl)variableDecls.get(variable);
        return (decl != null) ? (decl.scope < currentScope) : false;
    
public booleanisRangeVariable(java.lang.String variable)

        VariableDecl decl = (VariableDecl)variableDecls.get(variable);
        return (decl != null) && decl.isRangeVariable;
    
public booleanisVariable(java.lang.String variable)
INTERNAL Returns true if the specified string denotes a variable.

        VariableDecl decl = (VariableDecl)variableDecls.get(variable);
        return decl != null;
    
public voidleaveScope()
INTERNAL Leaves the current scope.

        currentScope--;
    
public oracle.toplink.essentials.internal.parsing.NodepathForVariable(java.lang.String variable)
INTERNAL Returns the path if the specified string denotes a join or collection member variable.

        VariableDecl decl = (VariableDecl)variableDecls.get(variable);
        return (decl != null) ? decl.path : null;
    
public voidregisterFetchJoin(java.lang.String variableName, oracle.toplink.essentials.internal.parsing.Node node)
Associate the given variableName with the given node representating a JOIN FETCH node.

        List joins = (List)fetchJoins.get(variableName);
        if (joins == null) {
            joins = new ArrayList();
            fetchJoins.put(variableName, joins);
        }
        joins.add(node);
    
public voidregisterJoinVariable(java.lang.String variable, oracle.toplink.essentials.internal.parsing.Node path, int line, int column)
INTERNAL Associate the given path with the given variable.

        VariableDecl decl = (VariableDecl)variableDecls.get(variable);
        if (decl == null) {
            decl = new VariableDecl(variable, path);
            variableDecls.put(variable, decl);
        } else {
            String text = decl.isRangeVariable ? decl.schema : decl.path.getAsString();
            throw EJBQLException.multipleVariableDeclaration(
                getQueryInfo(), line, column, variable, text);
        }
    
public voidregisterOuterScopeVariable(java.lang.String variable)
INTERNAL Adds the specified variable to the set of outer scope variables.

        outerScopeVariables.add(variable);
    
public voidregisterSchema(java.lang.String variable, java.lang.String schema, int line, int column)
INTERNAL Associate the given schema with the given variable.

        VariableDecl decl = (VariableDecl)variableDecls.get(variable);
        if (decl == null) {
            decl = new VariableDecl(variable, schema);
            variableDecls.put(variable, decl);
        } else {
            String text = decl.isRangeVariable ? decl.schema : decl.path.getAsString();
            throw EJBQLException.multipleVariableDeclaration(
                getQueryInfo(), line, column, variable, text);
        }
    
public voidresetOuterScopeVariables()
INTERNAL Resets the set of outer scope variables.

        outerScopeVariables = new HashSet();
    
public voidresetOuterScopeVariables(java.util.Set variables)
INTERNAL Resets the set of outer scope variables.

        outerScopeVariables = variables;
    
public java.lang.StringschemaForVariable(java.lang.String variable)
INTERNAL Returns the abstract schema name if the specified string denotes a range variable.

        VariableDecl decl = (VariableDecl)variableDecls.get(variable);
        return (decl != null) ? decl.schema : null;
    
public voidsetBaseVariable(java.lang.String variable)

        this.baseVariable = variable;
    
public voidsetScopeOfVariable(java.lang.String variable)
INTERNAL Sets the scope of the specified variable to the current scope.

        VariableDecl decl = (VariableDecl)variableDecls.get(variable);
        if (decl != null) {
            decl.scope = currentScope;
        }
    
public voidsetTypeHelper(oracle.toplink.essentials.internal.parsing.TypeHelper typeHelper)
INTERNAL Stores the specified type helper in this context.

        this.typeHelper = typeHelper;
    
public voidunregisterVariable(java.lang.String variable)
INTERNAL

        variableDecls.remove(variable);
    
public voidusedVariable(java.lang.String variable)
Mark the specified variable as used if it is declared in the current scope.

        VariableDecl decl = (VariableDecl)variableDecls.get(variable);
        if ((decl != null) && (decl.scope == currentScope)) {
            decl.used = true;
        }