com.nanyou.framework.jdbc.sql.dynamic.DynamicSql.java Source code

Java tutorial

Introduction

Here is the source code for com.nanyou.framework.jdbc.sql.dynamic.DynamicSql.java

Source

/*
 *
 *  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.
 */
package com.nanyou.framework.jdbc.sql.dynamic;

import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.commons.lang.StringUtils;

import com.nanyou.framework.jdbc.sql.Sql;
import com.nanyou.framework.jdbc.sql.SqlChild;
import com.nanyou.framework.jdbc.sql.SqlText;
import com.nanyou.framework.jdbc.sql.dynamic.elements.DynamicParent;
import com.nanyou.framework.jdbc.sql.dynamic.elements.SqlTag;
import com.nanyou.framework.jdbc.sql.dynamic.elements.SqlTagContext;
import com.nanyou.framework.jdbc.sql.dynamic.elements.SqlTagHandler;
import com.nanyou.framework.jdbc.sql.dynamic.elements.SqlTagHandlerFactory;
import com.nanyou.framework.jdbc.sql.simple.SimpleDynamicSql;

public class DynamicSql implements Sql, DynamicParent {

    private String dynamicSql;

    private String sqlStatement;

    private List children = new ArrayList();

    public DynamicSql(String dynamicSql) {
        this.dynamicSql = dynamicSql;
    }

    public String getSql(Object parameterObject) {
        if (dynamicSql != null) {
            findChildren(this, dynamicSql);
            process(parameterObject);
        }
        return sqlStatement;
    }

    private void findChildren(DynamicParent parent, String sql) {
        try {
            sql = StringUtils.remove(sql, ";");

            BufferedReader in = new BufferedReader(new StringReader(sql));
            while (true) {
                String line = in.readLine();
                if (line == null) {
                    break;
                }
                if (StringUtils.trim(line).startsWith("--<")) {
                    line = StringUtils.trim(line);
                    line = new String(line.substring(3, line.lastIndexOf('>')));
                    StringTokenizer st = new StringTokenizer(line, "= \t");
                    String tagName = st.nextToken();
                    SqlTag child = new SqlTag();
                    child.setName(tagName);
                    child.setHandler(SqlTagHandlerFactory.getSqlTagHandler(tagName));
                    while (st.hasMoreTokens()) {
                        String key = st.nextToken();
                        String value = StringUtils.remove(st.nextToken(), "\"");
                        if ("prepend".equalsIgnoreCase(key)) {
                            child.setPrependAttr(value);
                        } else if ("property".equalsIgnoreCase(key)) {
                            child.setPropertyAttr(value);
                        } else if ("open".equalsIgnoreCase(key)) {
                            child.setOpenAttr(value);
                        } else if ("close".equalsIgnoreCase(key)) {
                            child.setCloseAttr(value);
                        } else if ("conjunction".equalsIgnoreCase(key)) {
                            child.setConjunctionAttr(value);
                        } else if ("compareProperty".equalsIgnoreCase(key)) {
                            child.setComparePropertyAttr(value);
                        } else if ("compareValue".equalsIgnoreCase(key)) {
                            child.setCompareValueAttr(value);
                        }
                    }
                    String endTagName = "</" + tagName + ">";
                    StringBuffer sb = new StringBuffer();
                    while (true) {
                        line = in.readLine();
                        if (line == null) {
                            break;
                        }
                        if (line.indexOf(endTagName) > 0) {
                            break;
                        }
                        sb.append(line).append("\n");
                    }
                    findChildren(child, sb.toString());
                    parent.addChild(child);
                } else {
                    SqlText child = new SqlText();
                    ((SqlText) child).setText(line);
                    parent.addChild(child);
                }
            }
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    private void process(Object parameterObject) {

        SqlTagContext ctx = new SqlTagContext();
        List localChildren = children;
        processBodyChildren(ctx, parameterObject, localChildren.iterator());

        String dynSql = ctx.getBodyText();

        // Processes $substitutions$ after DynamicSql
        if (SimpleDynamicSql.isSimpleDynamicSql(dynSql)) {
            dynSql = new SimpleDynamicSql(dynSql).getSql(parameterObject);
        }
        this.sqlStatement = dynSql;
    }

    private void processBodyChildren(SqlTagContext ctx, Object parameterObject, Iterator localChildren) {
        PrintWriter out = ctx.getWriter();
        processBodyChildren(ctx, parameterObject, localChildren, out);
    }

    private void processBodyChildren(SqlTagContext ctx, Object parameterObject, Iterator localChildren,
            PrintWriter out) {
        while (localChildren.hasNext()) {
            SqlChild child = (SqlChild) localChildren.next();
            if (child instanceof SqlText) {
                SqlText sqlText = (SqlText) child;
                String sqlStatement = sqlText.getText();
                out.println(sqlStatement);
            } else if (child instanceof SqlTag) {
                SqlTag tag = (SqlTag) child;
                SqlTagHandler handler = tag.getHandler();
                int response = SqlTagHandler.INCLUDE_BODY;
                do {
                    StringWriter sw = new StringWriter();
                    PrintWriter pw = new PrintWriter(sw);

                    response = handler.doStartFragment(ctx, tag, parameterObject);
                    if (response != SqlTagHandler.SKIP_BODY) {

                        processBodyChildren(ctx, parameterObject, tag.getChildren(), pw);
                        pw.flush();
                        pw.close();
                        StringBuffer body = sw.getBuffer();
                        response = handler.doEndFragment(ctx, tag, parameterObject, body);
                        handler.doPrepend(ctx, tag, parameterObject, body);

                        if (response != SqlTagHandler.SKIP_BODY) {
                            if (body.length() > 0) {
                                out.println(body.toString());
                            }
                        }

                    }
                } while (response == SqlTagHandler.REPEAT_BODY);

                ctx.popRemoveFirstPrependMarker(tag);

                if (ctx.peekIterateContext() != null && ctx.peekIterateContext().getTag() == tag) {
                    ctx.setAttribute(ctx.peekIterateContext().getTag(), null);
                    ctx.popIterateContext();
                }

            }
        }
    }

    public void addChild(SqlChild child) {
        children.add(child);
    }

}