Package com.alibaba.druid.mapping.spi

Source Code of com.alibaba.druid.mapping.spi.MappingVisitorUtils

package com.alibaba.druid.mapping.spi;

import java.util.Iterator;
import java.util.Map;

import com.alibaba.druid.mapping.DruidMappingException;
import com.alibaba.druid.mapping.Entity;
import com.alibaba.druid.mapping.MappingContext;
import com.alibaba.druid.mapping.MappingEngine;
import com.alibaba.druid.mapping.Property;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit;

public class MappingVisitorUtils {

    private static final String MAPPING_VAR_INDEX = "mapping.varIndex";
    private static final String MAPPING_VALUE     = "mapping.value";
    private static final String MAPPING_PROPERTY  = "mapping.property";
    private static final String MAPPING_ENTITY    = "mapping.entity";

    public static boolean visit(MappingVisitor visitor, SQLExprTableSource x) {
        SQLExpr expr = x.getExpr();

        if (expr instanceof SQLIdentifierExpr) {
            SQLIdentifierExpr tableExpr = (SQLIdentifierExpr) expr;
            String entityName = tableExpr.getName();

            Entity entity = (Entity) x.getAttribute(MAPPING_ENTITY);

            if (entity == null) {
                entity = visitor.getEntity(entityName);
            }

            if (entity == null) {
                throw new DruidMappingException("entity not found : " + entityName);
            }

            if (x.getParent() instanceof SQLSelectQueryBlock) {
                SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) x.getParent();
                if (queryBlock.getAttribute(MAPPING_ENTITY) == null) {
                    queryBlock.putAttribute(MAPPING_ENTITY, entity);
                }
            }

            x.putAttribute(MAPPING_ENTITY, entity);
            String tableName = visitor.resolveTableName(entity);
            tableExpr.setName(tableName);

            visitor.getTableSources().put(entityName, x);
        }

        if (x.getAlias() != null) {
            visitor.getTableSources().put(x.getAlias(), x);
        }

        return false;
    }

    public static boolean visit(MappingVisitor visitor, SQLTableSource x) {
        if (x.getAlias() != null) {
            visitor.getTableSources().put(x.getAlias(), x);
        }

        return true;
    }

    public static boolean fillSelectList(MappingVisitor visitor, SQLSelectQueryBlock x) {
        Entity entity = (Entity) x.getAttribute(MAPPING_ENTITY);

        if (entity == null && x.getFrom() != null) {
            entity = (Entity) x.getFrom().getAttribute(MAPPING_ENTITY);
        }

        if (entity == null) {
            return false;
        }

        x.getSelectList().clear();

        for (Property property : entity.getProperties().values()) {
            String columnName = visitor.resovleColumnName(entity, property);
            String alias = null;
            if (visitor.getContext().isGenerateAlias()) {
                alias = '"' + property.getName() + '"';
            }

            SQLExpr expr = new SQLIdentifierExpr(columnName);

            expr.putAttribute(MAPPING_ENTITY, entity);
            expr.putAttribute(MAPPING_PROPERTY, property);

            SQLSelectItem selelctItem = new SQLSelectItem(expr, alias);

            x.getSelectList().add(selelctItem);
        }

        return true;
    }

    public static boolean visit(MappingVisitor visitor, SQLPropertyExpr x) {
        SQLIdentifierExpr ownerExpr = (SQLIdentifierExpr) x.getOwner();
        String ownerName = ownerExpr.getName();

        String propertyName = x.getName();

        Property property = null;
        Entity entity = visitor.getEntity(ownerName);

        if (entity == null) {
            visitor.getUnresolveList().add(x);
            return false;
        }
        property = entity.getProperty(propertyName);

        if (property == null) {
            throw new DruidMappingException("property not found : " + propertyName);
        }

        String dbColumName = visitor.resovleColumnName(entity, property);
        x.setName(dbColumName);
        x.putAttribute(MAPPING_PROPERTY, property);
        x.putAttribute(MAPPING_ENTITY, entity);

        if (x.getParent() instanceof SQLSelectItem) {
            SQLSelectItem selectItem = (SQLSelectItem) x.getParent();
            if (visitor.getContext().isGenerateAlias() && selectItem.getAlias() == null) {
                selectItem.setAlias('"' + property.getName() + '"');
            }
        }

        return false;
    }

    public static boolean visit(MappingVisitor visitor, SQLAllColumnExpr x) {
        if (visitor.getContext().isExplainAllColumnToList()) {
            visitor.getUnresolveList().add(x);
        }

        return true;
    }

    public static boolean visit(MappingVisitor visitor, SQLIdentifierExpr x) {
        String propertyName = x.getName();

        Property property = null;
        Entity propertyEntity = null;

        for (SQLTableSource tableSource : visitor.getTableSources().values()) {
            Entity entity = (Entity) tableSource.getAttribute(MAPPING_ENTITY);
            if (entity != null) {
                property = entity.getProperty(propertyName);
                if (property != null) {
                    propertyEntity = entity;
                    break;
                }
            }
        }

        if (property == null) {
            visitor.getUnresolveList().add(x);
            return false;
        }

        String dbColumName = visitor.resovleColumnName(propertyEntity, property);
        x.setName(dbColumName);

        x.putAttribute(MAPPING_PROPERTY, property);
        x.putAttribute(MAPPING_ENTITY, propertyEntity);

        if (visitor.getContext().isGenerateAlias() && x.getParent() instanceof SQLSelectItem) {
            SQLSelectItem selectItem = (SQLSelectItem) x.getParent();
            if (visitor.getContext().isGenerateAlias() && selectItem.getAlias() == null) {
                selectItem.setAlias('"' + property.getName() + '"');
            }
        }

        return false;
    }

    public static boolean visit(MappingVisitor visitor, SQLSelectItem x) {
        x.getExpr().setParent(x);
        return true;
    }

    public static boolean visit(MappingVisitor visitor, SQLBinaryOpExpr x) {
        x.getLeft().setParent(x);
        x.getRight().setParent(x);

        if (x.getOperator() == SQLBinaryOperator.Equality) {
            if (x.getLeft() instanceof SQLIdentifierExpr && isSimpleValue(visitor, x.getRight())) {
                visit(visitor, (SQLIdentifierExpr) x.getLeft());
                x.getRight().accept(visitor);

                Entity entity = (Entity) x.getLeft().getAttribute(MAPPING_ENTITY);
                Property property = (Property) x.getLeft().getAttribute(MAPPING_PROPERTY);
                Object value = x.getRight().getAttribute(MAPPING_VALUE);

                PropertyValue propertyValue = new PropertyValue(entity, property, value);
                propertyValue.putAttribute("mapping.expr", x.getRight());
               
                visitor.getPropertyValues().add(propertyValue);

                return false;
            }

            if (x.getLeft() instanceof SQLPropertyExpr && isSimpleValue(visitor, x.getRight())) {
                visit(visitor, (SQLPropertyExpr) x.getLeft());
                x.getRight().accept(visitor);

                Entity entity = (Entity) x.getLeft().getAttribute(MAPPING_ENTITY);
                Property property = (Property) x.getLeft().getAttribute(MAPPING_PROPERTY);
                Object value = x.getRight().getAttribute(MAPPING_VALUE);

                PropertyValue propertyValue = new PropertyValue(entity, property, value);
                propertyValue.putAttribute("mapping.expr", x.getRight());
               
                visitor.getPropertyValues().add(propertyValue);

                return false;
            }
        }

        return true;
    }

    private static boolean isSimpleValue(MappingVisitor visitor, SQLExpr expr) {
        if (expr instanceof SQLNumericLiteralExpr) {
            expr.putAttribute(MAPPING_VALUE, ((SQLNumericLiteralExpr) expr).getNumber());
            return true;
        }

        if (expr instanceof SQLCharExpr) {
            expr.putAttribute(MAPPING_VALUE, ((SQLCharExpr) expr).getText());
            return true;
        }

        if (expr instanceof SQLVariantRefExpr) {
            Map<String, Object> attributes = expr.getAttributes();
            Integer varIndex = (Integer) attributes.get(MAPPING_VAR_INDEX);
            if (varIndex == null) {
                varIndex = visitor.getAndIncrementVariantIndex();
                expr.putAttribute(MAPPING_VAR_INDEX, varIndex);
            }

            if (visitor.getParameters().size() > varIndex) {
                Object parameter = visitor.getParameters().get(varIndex);
                expr.putAttribute(MAPPING_VALUE, parameter);
            }

            return true;
        }

        return false;
    }

    public static void afterResolve(MappingVisitor visitor) {
        for (Iterator<SQLExpr> iter = visitor.getUnresolveList().iterator(); iter.hasNext();) {
            SQLExpr expr = iter.next();
            if (expr instanceof SQLIdentifierExpr) {
                if (resolve(visitor, (SQLIdentifierExpr) expr)) {
                    iter.remove();
                }
            } else if (expr instanceof SQLPropertyExpr) {
                if (resolve(visitor, (SQLPropertyExpr) expr)) {
                    iter.remove();
                }
            } else if (expr instanceof SQLAllColumnExpr) {
                if (resolve(visitor, (SQLAllColumnExpr) expr)) {
                    iter.remove();
                }
            }
        }
    }

    public static boolean resolve(MappingVisitor visitor, SQLAllColumnExpr x) {
        if (!(x.getParent() instanceof SQLSelectItem)) {
            return true;
        }
        SQLSelectItem selectItem = (SQLSelectItem) x.getParent();

        if (!(selectItem.getParent() instanceof SQLSelectQueryBlock)) {
            return true;
        }

        SQLSelectQueryBlock select = (SQLSelectQueryBlock) selectItem.getParent();

        if (select.getSelectList().size() == 1) {
            if (select.getSelectList().get(0).getExpr() instanceof SQLAllColumnExpr) {
                boolean result = fillSelectList(visitor, select);
                if (!result && visitor.getContext().isExplainAllColumnToList()) {
                    visitor.getUnresolveList().add(x);
                }
            }
        }

        return false;
    }

    public static boolean resolve(MappingVisitor visitor, SQLIdentifierExpr x) {
        String propertyName = x.getName();

        for (SQLTableSource tableSource : visitor.getTableSources().values()) {
            Entity entity = (Entity) tableSource.getAttribute(MAPPING_ENTITY);
            if (entity != null) {
                Property property = entity.getProperty(propertyName);
                if (property != null) {
                    String columnName = visitor.resovleColumnName(entity, property);
                    x.setName(columnName);

                    x.putAttribute(MAPPING_ENTITY, entity);
                    x.putAttribute(MAPPING_PROPERTY, property);

                    if (visitor.getContext().isGenerateAlias() && x.getParent() instanceof SQLSelectItem) {
                        SQLSelectItem selectItem = (SQLSelectItem) x.getParent();
                        if (selectItem.getAlias() == null) {
                            selectItem.setAlias('"' + property.getName() + '"');
                        }
                    }

                    return true;
                }
            }
        }

        return false;
    }

    public static boolean resolve(MappingVisitor visitor, SQLPropertyExpr x) {
        if (x.getOwner() instanceof SQLIdentifierExpr) {
            String ownerName = ((SQLIdentifierExpr) x.getOwner()).getName();
            SQLTableSource tableSource = visitor.getTableSources().get(ownerName);
            Entity entity = (Entity) tableSource.getAttribute(MAPPING_ENTITY);

            if (entity != null) {
                Property property = entity.getProperty(x.getName());
                if (property != null) {
                    String columnName = visitor.resovleColumnName(entity, property);
                    x.setName(columnName);
                    x.putAttribute(MAPPING_ENTITY, entity);
                    x.putAttribute(MAPPING_PROPERTY, property);

                    if (visitor.getContext().isGenerateAlias() && x.getParent() instanceof SQLSelectItem) {
                        SQLSelectItem selectItem = (SQLSelectItem) x.getParent();
                        if (selectItem.getAlias() == null) {
                            selectItem.setAlias('"' + property.getName() + '"');
                        }
                    }

                    return true;
                }
            }
        }

        return false;
    }

    public static boolean visit(MappingVisitor visitor, SQLVariantRefExpr x) {
        Map<String, Object> attributes = x.getAttributes();
        Integer varIndex = (Integer) attributes.get(MAPPING_VAR_INDEX);
        if (varIndex == null) {
            varIndex = visitor.getAndIncrementVariantIndex();
            x.putAttribute(MAPPING_VAR_INDEX, varIndex);
        }
        return false;
    }
   
    public static boolean visit(MappingVisitor visitor, MySqlSelectQueryBlock x) {
        Integer maxLimit = visitor.getEngine().getMaxLimit();

        if (maxLimit != null) {
            if (x.getLimit() == null) {
                Limit limit = new Limit();
                limit.setRowCount(new SQLIntegerExpr(maxLimit));
                x.setLimit(limit);
            } else {
                SQLNumericLiteralExpr rowCountExpr = (SQLNumericLiteralExpr) x.getLimit().getRowCount();
                int rowCount = rowCountExpr.getNumber().intValue();
                if (rowCount > maxLimit.intValue()) {
                    rowCountExpr.setNumber(maxLimit);
                }
            }
        }
       
        return visit(visitor, (SQLSelectQueryBlock) x);
    }

    public static boolean visit(MappingVisitor visitor, SQLSelectQueryBlock x) {
        if (x.getSelectList().size() == 0) {
            SQLAllColumnExpr expr = new SQLAllColumnExpr();
            SQLSelectItem selectItem = new SQLSelectItem(expr);
            x.getSelectList().add(selectItem);

            expr.setParent(selectItem);
        }

        if (x.getFrom() == null) {
            Entity firstEntity = visitor.getEngine().getFirstEntity(visitor.getContext());
            SQLExprTableSource from = new SQLExprTableSource(new SQLIdentifierExpr(firstEntity.getName()));
            from.putAttribute(MAPPING_ENTITY, firstEntity);
            x.setFrom(from);
            x.putAttribute(MAPPING_ENTITY, firstEntity);
        }

        for (SQLSelectItem item : x.getSelectList()) {
            item.setParent(x);
            item.getExpr().setParent(item);
        }

        x.getFrom().setParent(x);
        if (x.getWhere() != null) {
            x.getWhere().setParent(x);
        }

        if (x.getInto() != null) {
            x.getInto().setParent(x);
        }

        return true;
    }

    public static Entity getEntity(MappingVisitor visitor, String name) {
        SQLTableSource tableSource = visitor.getTableSources().get(name);

        if (tableSource != null) {
            Entity entity = (Entity) tableSource.getAttribute(MAPPING_ENTITY);
            if (entity != null) {
                return entity;
            }

            if (tableSource instanceof SQLExprTableSource) {
                SQLExpr expr = ((SQLExprTableSource) tableSource).getExpr();

                if (expr instanceof SQLIdentifierExpr) {
                    name = ((SQLIdentifierExpr) expr).getName();
                } else {
                    return null;
                }
            } else {
                return null;
            }
        }

        Entity entity = visitor.getEntities().get(name);

        if (entity == null) {
            for (Map.Entry<String, Entity> entry : visitor.getEntities().entrySet()) {
                if (entry.getKey().equalsIgnoreCase(name)) {
                    entity = entry.getValue();
                    break;
                }
            }
        }

        return entity;
    }

    public static void setTableSource(MappingEngine engine, SQLDeleteStatement stmt, MappingContext context) {
        if (stmt.getExprTableSource() == null) {
            Entity entity = engine.getFirstEntity(context);
            stmt.setTableSource(new SQLIdentifierExpr(entity.getName()));
        }
    }

    public static void setTableSource(MappingEngine engine, SQLUpdateStatement stmt, MappingContext context) {
        if (stmt.getTableSource() == null) {
            Entity entity = engine.getFirstEntity(context);
            stmt.setTableSource(new SQLIdentifierExpr(entity.getName()));
        }
    }

    public static void setTableSource(MappingEngine engine, SQLInsertStatement stmt, MappingContext context) {
        if (stmt.getTableSource() == null) {
            Entity entity = engine.getFirstEntity(context);
            stmt.setTableSource(new SQLIdentifierExpr(entity.getName()));
        }
    }
}
TOP

Related Classes of com.alibaba.druid.mapping.spi.MappingVisitorUtils

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.