Package org.jpox.query.compiler

Source Code of org.jpox.query.compiler.Compiler

/**********************************************************************
Copyright (c) 2008 Erik Bengtson and others. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Contributors:
    ...
**********************************************************************/
package org.jpox.query.compiler;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.jpox.ClassLoaderResolver;
import org.jpox.exceptions.JPOXUserException;
import org.jpox.metadata.AbstractClassMetaData;
import org.jpox.metadata.AbstractMemberMetaData;
import org.jpox.metadata.MetaDataManager;
import org.jpox.query.expression.Expression;
import org.jpox.query.expression.ExpressionCompiler;
import org.jpox.query.node.Node;
import org.jpox.query.symbol.PropertySymbol;
import org.jpox.query.symbol.Symbol;
import org.jpox.query.symbol.SymbolResolver;
import org.jpox.query.symbol.SymbolTable;
import org.jpox.util.ClassUtils;
import org.jpox.util.Imports;

public class Compiler implements SymbolResolver
{
    JDOQLParser parser = new JDOQLParser(); // TODO Why always JDOQLParser ? SQLParser?, JPQLParser?

    final MetaDataManager metaDataManager;

    final ClassLoaderResolver clr;

    Node node;
    SymbolTable symtbl = new SymbolTable();
    Class candidateClass;
    Collection candidates;
    String filter;
    String ordering;
    String parameters;
    String variables;
    String grouping;
    String having;
    String result;
    Imports imports = new Imports();
    Expression expr;

    public Compiler(MetaDataManager metaDataManager, ClassLoaderResolver clr)
    {
        this.metaDataManager = metaDataManager;
        this.clr = clr;
    }
    public SymbolTable getSymbolTable()
    {
        return symtbl;
    }
    public void setFilter(String filter)
    {
        this.filter = filter;
    }

    public void setOrdering(String ordering)
    {
        this.ordering = ordering;
    }

    public void setResult(String result)
    {
        this.result = result;
    }

    public void setGrouping(String grouping)
    {
        this.grouping = grouping;
    }

    public void setHaving(String having)
    {
        this.having = having;
    }

    public void setCandidateClass(Class candidateClass)
    {
        this.candidateClass = candidateClass;
    }

    public void setCandidates(Collection candidates)
    {
        this.candidates = candidates;
    }

    public void compile1()
    {
        symtbl.setSymbolResolver(this);
        compileCandidates();
        compileVariables();
        compileParameters();
    }

    public void compile2()
    {
        if (filter != null)
        {
            compileFilter();
            ExpressionCompiler comp = new ExpressionCompiler();
            comp.setSymbolTable(symtbl);
            expr = comp.compileExpression(node);
            expr.bind();
        }

        // bind();
    }

    public void compileVariables()
    {
        if (variables == null)
        {
            return;
        }
        Node[][] node = parser.compileVariables(variables);
        for (int i = 0; i < node.length; i++)
        {
            symtbl.addSymbol(new PropertySymbol((String) node[i][1].getNodeValue(), imports.resolveClassDeclaration(node[i][0]
                    .getNodeChildId(), clr, null)));
        }
    }

    public void compileParameters()
    {
        if (parameters == null)
        {
            return;
        }
        Node[][] node = parser.compileVariables(parameters);
        for (int i = 0; i < node.length; i++)
        {
            symtbl.addSymbol(new PropertySymbol((String) node[i][1].getNodeValue(), imports.resolveClassDeclaration(node[i][0]
                    .getNodeChildId(), clr, null)));
        }
    }

    public Expression[] compileOrdering()
    {
        if (ordering == null)
        {
            return null;
        }
        Node[] node = parser.compileOrder(ordering);
        Expression[] expr = new Expression[node.length];
        for (int i = 0; i < node.length; i++)
        {
            ExpressionCompiler comp = new ExpressionCompiler();
            comp.setSymbolTable(symtbl);
            expr[i] = comp.compileOrderExpression(node[i]);
            expr[i].bind();
        }
        return expr;

    }

    public Expression[] compileResult()
    {
        if (result == null)
        {
            return null;
        }
        Node[] node = parser.compileTupple(result);
        Expression[] expr = new Expression[node.length];
        for (int i = 0; i < node.length; i++)
        {
            ExpressionCompiler comp = new ExpressionCompiler();
            comp.setSymbolTable(symtbl);
            expr[i] = comp.compileExpression(node[i]);
            // expr[i].bind();
        }
        return expr;
    }

    public Expression[] compileGrouping()
    {
        if (grouping == null)
        {
            return null;
        }
        Node[] node = parser.compileTupple(grouping);
        Expression[] expr = new Expression[node.length];
        for (int i = 0; i < node.length; i++)
        {
            ExpressionCompiler comp = new ExpressionCompiler();
            comp.setSymbolTable(symtbl);
            expr[i] = comp.compileExpression(node[i]);
            // expr[i].bind();
        }
        return expr;

    }

    public Expression compileHaving()
    {
        if (having == null)
        {
            return null;
        }
        Node node = parser.compile(having);
        ExpressionCompiler comp = new ExpressionCompiler();
        comp.setSymbolTable(symtbl);
        Expression expr = comp.compileExpression(node);
        // expr.bind();
        return expr;
    }
   
    public Expression getExpression()
    {
        return expr;
    }
   
    private void compileCandidates()
    {
        // TODO Remove hardcoded refs to "this". Should be an alias variable. JPQL/SQL don't have "this"
        Symbol symbol = new PropertySymbol("this", candidateClass);
        symbol.setValue(candidates);
        symtbl.addSymbol(symbol);
    }
   
    private void compileFilter()
    {
        node = parser.compile(filter);
    }
   
    public void bind()
    {
        /*
        new TreeWalkerUtil().walk(new Visitor()
        {
            public void visit(Node node,  Node parent)
            {
                node.setParent(parent);
                compileSymbol(node);
            }
       
        }, node, null);
        */
    }
   
    /**
     * Compiles a Symbol from a Node
     * @param node
     */
    /*
    void compileSymbol(Node node)
    {
        if( node.getNodeType() == Node.IDENTIFIER)
        {
            Symbol symbol = symtbl.getSymbol((String)node.getNodeValue());
            if( symbol == null )
            {
                symbol = new PropertySymbol(node.getNodeId(), (String)node.getNodeValue());
                symtbl.addSymbol(symbol);
                if( node.getParent() != null && node.getParent().getNodeType() == Node.IDENTIFIER)
                {
                    Class type = getType(node.getParent().getSymbol().getType(),(String)node.getNodeValue());
                    symbol.setType(type);
                }
                else if( node.getParent() == null )
                {
                    Class type = getType(symtbl.getSymbol("this").getType(),(String)node.getNodeValue());
                    symbol.setType(type);                   
                }
            }
            node.setSymbol(symbol);
        }
    }
   
    */
    public MetaDataManager getMetaDataManager()
    {
        return metaDataManager;
    }
   
    public ClassLoaderResolver getClassLoaderResolver()
    {
        return clr;
    }
   
    Class getType(Class cls, String fieldName)
    {
        AbstractClassMetaData acmd = getMetaDataManager().getMetaDataForClass(cls,
            getClassLoaderResolver());
        if( acmd != null )
        {
            AbstractMemberMetaData fmd =acmd.getMetaDataForMember(fieldName);
            if( fmd == null )
            {
                throw new JPOXUserException("Cannot access field "+fieldName+" on type "+cls.getName());
            }
            return fmd.getType();
        }
        else
        {
            Field field = ClassUtils.getFieldForClass(cls, fieldName);
            if( field == null )
            {
                throw new JPOXUserException("Cannot access field "+fieldName+" on type "+cls.getName());
            }
            return field.getType();
        }

    }

    public Class getType(List tuples)
    {
        Class type = null;
        Symbol symbol = symtbl.getSymbol((String)tuples.get(0));
        if( symbol != null )
        {
            type = symbol.getType();
            for( int i=1; i<tuples.size(); i++)
            {
                type = getType(type, (String)tuples.get(i));
            }
        }
        else
        {
            // TODO Remove hardcoded refs to "this". Should be an alias variable. JPQL/SQL don't have "this"
            symbol = symtbl.getSymbol("this");
            type = symbol.getType();
            for( int i=0; i<tuples.size(); i++)
            {
                type = getType(type, (String)tuples.get(i));
            }
        }
        return type;
    }
   
    public void setParameters(String parameters)
    {
        this.parameters = parameters;
    }
   
    public void bindParameters(Map parameters)
    {
        Iterator it = parameters.entrySet().iterator();
        while (it.hasNext())
        {
            Map.Entry entry = (Map.Entry)it.next();
            Symbol symbol = symtbl.getSymbol((String)entry.getKey());
            if (symbol!= null)
            {
                symbol.setValue(entry.getValue());
            }
        }
    }   
    public void setVariables(String variables)
    {
        this.variables = variables;
    }
   
    public void setImports(Imports imports)
    {
        this.imports = imports;
    }
}
TOP

Related Classes of org.jpox.query.compiler.Compiler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.