com.gzj.tulip.jade.statement.SystemInterpreter.java Source code

Java tutorial

Introduction

Here is the source code for com.gzj.tulip.jade.statement.SystemInterpreter.java

Source

/*
 * Copyright 2009-2012 the original author or authors.
 *
 * 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 i 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.
 */
package com.gzj.tulip.jade.statement;

import java.sql.SQLSyntaxErrorException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.jdbc.BadSqlGrammarException;

import com.gzj.tulip.jade.statement.expression.ExqlPattern;
import com.gzj.tulip.jade.statement.expression.impl.ExqlContextImpl;
import com.gzj.tulip.jade.statement.expression.impl.ExqlPatternImpl;

/**
 * 
 * @author  [in355hz@gmail.com]
 */
public class SystemInterpreter implements Interpreter {

    private ReplacementInterpreter replacementInterpreter = new ReplacementInterpreter();
    private PreparestatmentInterpreter preparestatmentInterpreter = new PreparestatmentInterpreter();

    @Override
    public void interpret(StatementRuntime runtime) {
        replacementInterpreter.interpret(runtime);
        preparestatmentInterpreter.interpret(runtime);
    }

    /**
     * ????{xxxx}?{:xxxx}?##(:xxx)?##(xxx)?
     * <p>
     * 
     * select form ##(:table) {name} where {id}='{1}'
     * @author zlw
     *
     */
    static class ReplacementInterpreter implements Interpreter {

        final Pattern PATTERN = Pattern.compile("\\{([a-zA-Z0-9_\\.\\:]+)\\}|##\\((.+)\\)");

        final ThreadLocal<StringBuilder> stringBuilderPool = new ThreadLocal<StringBuilder>() {
            @Override
            public StringBuilder initialValue() {
                return new StringBuilder();
            };

        };

        @Override
        public void interpret(StatementRuntime runtime) {// ##(:xxx)
            StringBuilder sqlResult = stringBuilderPool.get();
            sqlResult.setLength(0);
            String sql = runtime.getSQL();
            Matcher matcher = PATTERN.matcher(sql);
            int start = 0;
            while (matcher.find(start)) {
                sqlResult.append(sql.substring(start, matcher.start()));
                String group = matcher.group();
                String key = null;
                if (group.startsWith("{")) {
                    key = matcher.group(1);
                } else if (group.startsWith("##(")) {
                    key = matcher.group(2);
                }
                // get value from parameters
                Object value = runtime.getParameters().get(key); // {paramName}?{:1}?
                if (value == null) {
                    if (key.startsWith(":") || key.startsWith("$")) {
                        value = runtime.getParameters().get(key.substring(1)); // {:paramName}
                    } else {
                        char ch = key.charAt(0);// ??key0
                        if (ch >= '0' && ch <= '9') {
                            value = runtime.getParameters().get(":" + key); // {1}?
                        }
                    }
                }
                // get value from constants
                if (value == null) {
                    value = runtime.getMetaData().getDAOMetaData().getConstants().get(key); // ?
                }
                // get value from attributes
                if (value == null) {
                    String attributeKey = group;
                    if (!attributeKey.startsWith("{")) {
                        attributeKey = "{" + key + "}";
                    }
                    value = runtime.getMetaData().getDAOMetaData().getAttribute(attributeKey); // ??
                }
                // replace it
                if (value != null) {
                    sqlResult.append(value);
                } else {
                    sqlResult.append(group);
                }
                start = matcher.end();
            }
            sqlResult.append(sql.substring(start));

            runtime.setSQL(sqlResult.toString());

        }
    }

    // ??
    static class PreparestatmentInterpreter implements Interpreter {

        static final ThreadLocal<ExqlContextImpl> exqlContextPool = new ThreadLocal<ExqlContextImpl>() {
            @Override
            public ExqlContextImpl initialValue() {
                return new ExqlContextImpl();
            };

        };

        @Override
        public void interpret(StatementRuntime runtime) {
            // ???
            ExqlContextImpl context = exqlContextPool.get();
            context.clear();

            try {
                ExqlPattern pattern = ExqlPatternImpl.compile(runtime.getSQL());
                Map<String, Object> constants = runtime.getMetaData().getDAOMetaData().getConstants();
                pattern.execute(context, runtime.getParameters(), constants);
                runtime.setArgs(context.getArgs());
                runtime.setSQL(context.flushOut());
            } catch (Exception e) {
                String daoInfo = runtime.getMetaData().toString();
                throw new BadSqlGrammarException(daoInfo, runtime.getSQL(),
                        new SQLSyntaxErrorException(daoInfo + " @SQL('" + runtime.getSQL() + "')", e));
            }
        }

    }

    // ReplacementInterpreter
    public static void main(String[] args) throws Exception {
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("table", "my_table_name");
        parameters.put("id", "my_id");
        parameters.put(":1", "first_param");

        final Pattern PATTERN = Pattern.compile("\\{([a-zA-Z0-9_\\.\\:]+)\\}|##\\((.+)\\)");

        String sql = "select form ##(:table) {name} where {id}='{1}'";

        StringBuilder sb = new StringBuilder(sql.length() + 200);
        Matcher matcher = PATTERN.matcher(sql);
        int start = 0;
        while (matcher.find(start)) {
            sb.append(sql.substring(start, matcher.start()));
            String group = matcher.group();
            String key = null;
            if (group.startsWith("{")) {
                key = matcher.group(1);
            } else if (group.startsWith("##(")) {
                key = matcher.group(2);
            }
            System.out.println(key);
            if (key == null || key.length() == 0) {
                continue;
            }
            Object value = parameters.get(key); // {paramName}?{:1}?
            if (value == null) {
                if (key.startsWith(":") || key.startsWith("$")) {
                    value = parameters.get(key.substring(1)); // {:paramName}
                } else {
                    char ch = key.charAt(0);
                    if (ch >= '0' && ch <= '9') {
                        value = parameters.get(":" + key); // {1}?
                    }
                }
            }
            if (value == null) {
                value = parameters.get(key); // ?
            }
            if (value != null) {
                sb.append(value);
            } else {
                sb.append(group);
            }
            start = matcher.end();
        }
        sb.append(sql.substring(start));
        System.out.println(sb);

    }

    // ExqlInterpreter
    public static void main0(String[] args) throws Exception {
        // ???
        String sql = "insert ignore into table_name " + "(`id`,`uid`,`favable_id`,`addtime`,`ranking`) "//
                + "values (:1,:2,now(),0)";
        ExqlPattern pattern = ExqlPatternImpl.compile(sql);
        ExqlContextImpl context = new ExqlContextImpl();

        Map<String, Object> parametersAsMap = new HashMap<String, Object>();
        parametersAsMap.put(":1", "p1");
        parametersAsMap.put(":2", "p2");

        pattern.execute(context, parametersAsMap);
        String result = context.flushOut();
        System.out.println(result);
    }

}