FileDocCategorySizeDatePackage
VariableTable.javaAPI DocGlassfish v2 API11103Fri May 04 22:35:06 BST 2007com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc

VariableTable

public class VariableTable extends Object
The variable table
author
Michael Bouschen
version
0.1

Fields Summary
protected static final ResourceBundle
messages
I18N support
private ErrorMsg
errorMsg
private List
declaredVars
List of names of declared variables.
private Map
varInfos
Map of variable infos.
Constructors Summary
public VariableTable(ErrorMsg errorMsg)
Create an empty variable table

        this.errorMsg = errorMsg;
        declaredVars = new ArrayList();
        varInfos = new HashMap();
    
public VariableTable(VariableTable other)
Create a variable table initialized with the entries of the other variable table. The constructor creates copies of the values stored in the map (instances of class VarInfo).

        errorMsg = other.errorMsg;
        declaredVars = other.declaredVars;
        varInfos = new HashMap();
        for (Iterator i = other.varInfos.entrySet().iterator(); i.hasNext();)
        {
            Map.Entry entry = (Map.Entry)i.next();
            varInfos.put(entry.getKey(), new VarInfo((VarInfo)entry.getValue()));
        }
    
Methods Summary
public voidadd(java.lang.String name)
Creates a new entry in the variable table with the specified name as key and an empty value.

        declaredVars.add(name);
        // init var entry as not constraint and unused
        varInfos.put(name, new VarInfo());
    
protected voidattachConstraintToUsedAST(com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc.VariableTable$VarInfo info)

        for (Iterator i = info.used.iterator(); i.hasNext();)
        {
            JQLAST varNode = (JQLAST)i.next();
            if (varNode.getFirstChild() == null)
                varNode.setFirstChild(JQLAST.Factory.getInstance().dupTree(info.constraint));
        }
    
protected voidcheckConstraint(java.lang.String variable, com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc.VariableTable$VarInfo info)

        switch (info.status)
        {
        case VarInfo.UNCHECKED:
            // if unchecked, start checking
            info.status = VarInfo.IN_PROGRESS;
            break;
        case VarInfo.IN_PROGRESS:
            // if this VarInfo is currently processed we have a cyclic dependency
            throw new JDOUnsupportedOptionException(
                I18NHelper.getMessage(messages, "jqlc.variabletable.checkconstraint.cycle", // NOI18N
                                      variable));
        case VarInfo.CHECKED:
            // if alreday checked just return
            return;
        }
        
        if (info.dependsOn != null)
        {
            VarInfo dependendVarInfo = (VarInfo)varInfos.get(info.dependsOn);
            checkConstraint(info.dependsOn, dependendVarInfo);
        }
        
        if ((info.constraint != null) && (info.used.size() == 0))
        {
            throw new JDOUnsupportedOptionException(
                I18NHelper.getMessage(messages, "jqlc.variabletable.checkconstraint.unused", //NOI18N
                                      variable));
        }
        
        attachConstraintToUsedAST(info);
        info.status = VarInfo.CHECKED;
    
public voidcheckConstraints()

        // iterate declaredVars to check the variables in the order they are declared
        for (Iterator i = declaredVars.iterator(); i.hasNext();)
        {
            String name = (String)i.next();
            VarInfo info = (VarInfo)varInfos.get(name);
            checkConstraint(name, info);
        }
    
public voidmarkConstraint(JQLAST variable, JQLAST expr)
Mark the specified variable as constaint with the specified expr. The method sets the constraint field of the VarInfo object to true.

        String name = variable.getText();
        VarInfo entry = (VarInfo)varInfos.get(name);
        if (entry == null)
            throw new JDOFatalInternalException(I18NHelper.getMessage(
                messages,
                "jqlc.variabletable.markconstraint.varnotfound", //NOI18N
                name));
        String old = (entry.constraint==null ? null : entry.constraint.getText());
        if ((old != null) && !old.equals(expr.getText()))
        {
            errorMsg.unsupported(variable.getLine(), variable.getColumn(),
                I18NHelper.getMessage(messages, "jqlc.variabletable.markconstraint.multiple", //NOI18N
                                      name));
        }
        entry.constraint = expr;
    
public voidmarkUsed(JQLAST variable, java.lang.String dependendVar)
Mark the specified variable as used. The method sets the info field of the VarInfo object to true.

        String name = variable.getText();
        VarInfo entry = (VarInfo)varInfos.get(name);
        if (entry == null)
            throw new JDOFatalInternalException(I18NHelper.getMessage(messages,
                "jqlc.variabletable.markused.varnotfound", //NOI18N
                name));
        entry.used.add(variable);
        if (dependendVar != null)
        {
            VarInfo dependendVarInfo = (VarInfo)varInfos.get(dependendVar);
            if (dependendVarInfo.dependsOn != null)
                throw new JDOFatalInternalException(I18NHelper.getMessage(
                    messages,
                    "jqlc.variabletable.markused.multidep", //NOI18N
                    dependendVar, dependendVarInfo.dependsOn, name));
            dependendVarInfo.dependsOn = name;
        }
    
public voidmerge(com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc.VariableTable other)
Merges the specified variable table (other) into this variable table.

        for (Iterator i = declaredVars.iterator(); i.hasNext();)
        { 
            String name = (String)i.next();
            VarInfo info = (VarInfo)varInfos.get(name);
            VarInfo otherInfo = (VarInfo)other.varInfos.get(name);
            
            // copy other info if this info is empty
            if ((info.constraint == null) && (info.used.size() == 0))
            {
                info.constraint = otherInfo.constraint;
                info.used = otherInfo.used;
                info.dependsOn = otherInfo.dependsOn;
                info.status = otherInfo.status;
                continue;
            }

            // do nothing if otherInfo is empty
            if ((otherInfo.constraint == null) && (otherInfo.used.size() == 0))
            {
                continue;
            }
            
            // constraint check
            // If both variables tables include constraints they have to be the same
            if ((info.constraint != null) && (otherInfo.constraint != null))
            {
                if (!otherInfo.constraint.getText().equals(info.constraint.getText()))
                {
                    throw new JDOUnsupportedOptionException(
                        I18NHelper.getMessage(messages, "jqlc.variabletable.merge.different", name)); //NOI18N
                }
            }
            // If at least one variable table does not define constraint, 
            // nullify the constaint in this variable table
            else
            {
                info.constraint = null;
                info.dependsOn = null;
                info.status = VarInfo.UNCHECKED;
            }
            
            // copy otherInfo.used to this used list
            info.used.addAll(otherInfo.used);
        }