<?xml version="1.0" encoding="UTF-8"?>
<bm:model xmlns:s="leaf.plugin.script" xmlns:bm="http://www.leaf-framework.org/schema/bm">
    <bm:operations>
        <bm:operation name="query">
            <bm:query-sql><![CDATA[
            select * from (
            ${:@validation_sql}) vv
               #WHERE_CLAUSE#
            ]]></bm:query-sql>
        </bm:operation>
    </bm:operations>
    <bm:fields><![CDATA[
    ]]></bm:fields>
    <bm:features>
        <s:bm-script><![CDATA[
            var model = $this.getObjectContext();
            var para = $ctx.current_parameter || $ctx.parameter;
            var validation_sql;
            if (para.url) {
                var url = decodeURIComponent(para.url);
                var matches = url.match(/validation_sql=([^&]*)&?(.*$)/);
                validation_sql = matches[1];
                var para_list = {};
                if (matches[2]) {
                    var paras = matches[2].split('&');
                    for (var i = 0;i < paras.length;i++) {
                        var p = paras[i].split('=');
                        para_list[p[0]] = p[1];
                    }
                }
                validation_sql = validation_sql.replace(/\$\{@([^\}]*)\}/g, function(a, b) {
                    return "'" + (para_list[b] || '') + "'";
                });
            } else if (para.validation_sql) {
                validation_sql = para.validation_sql;
                validation_sql = validation_sql.replace(/\$\{@([^\}]*)\}/g, function(a, b) {
                    return "'" + (para[b] || '') + "'";
                });
            }
            validation_sql = validation_sql.replace(/\$\{\/session\/@([^\}]*)\}/g, function(a, b) {
                return "'" + $ctx.session[b] + "'";
            });
            // var dsf = $instance('leaf.database.service.IDatabaseServiceFactory');
            // var parsedSql = new Packages.leaf.database.ParsedSql(validation_sql);
            // var sqlServiceContext = new Packages.leaf.database.service.SqlServiceContext.createSqlServiceContext($ctx.getData());
            // var sqlRunner = new Packages.leaf.database.SqlRunner(sqlServiceContext, parsedSql);
            // var conn = dsf.getDataSource().getConnection();
            // var sql = sqlRunner.generateSQL(para.getData());
            // var ps = conn.prepareCall(sql);
            // sqlRunner.bindParameters(ps, para.getData());
            // var rs = ps.executeQuery();
            // var rsmd = rs.getMetaData();
            // var count = rsmd.getColumnCount();
            // var queryfields = new CompositeMap(model.getChild('query-fields'));
            var dsf = $instance('leaf.database.service.IDatabaseServiceFactory');
            var conn = dsf.getDataSource().getConnection();
            var stmt = conn.createStatement();
            var rs = stmt.executeQuery(validation_sql);
            var rsmd = rs.getMetaData();
            var count = rsmd.getColumnCount();
            var queryfields = new CompositeMap(model.getChild('query-fields'));
            var temp_num = 0;
            for (var i = 1;i <= count;i++) {
                var fname = rsmd.getColumnName(i);
                var dbtype = rsmd.getColumnTypeName(i)
                var f = Packages.leaf.bm.Field.createField(fname.toLowerCase());
                f.setPhysicalName(fname);
                f.setDatabaseType(dbtype);
                if (dbtype == 'NUMBER') {
                    f.setDataType('java.lang.Double');
                } else if (dbtype == 'VARCHAR2') {
                    f.setDataType('java.lang.String');
                } else if (dbtype == 'DATE') {
                    f.setDataType('java.util.Date');
                }
                if ((fname != 'VALUE_CODE' || dbtype != 'NUMBER') && temp_num < 6) {
                    f.setForDisplay(true);
                    temp_num = temp_num + 1;
                }
                var pCache = $cache('promptCache');
                var dynamic_lov_para;
                var str = validation_sql.toLowerCase();
                var source_value_code = str.match(new RegExp('[\.,\\s]([^.,\\s]*)( as)? ' + 'value_code'));
                var source_value_name = str.match(new RegExp('[\.,\\s]([^.,\\s]*)( as)? ' + 'value_name'));
                var source_value_code_display = str.match(new RegExp('[\.,\\s]([^.,\\s]*)( as)? ' + 'value_code_display'));
                var temp_prompt;
                if (fname == 'VALUE_CODE') {
                    if (dbtype != 'NUMBER') {
                        f.setForQuery(true);
                    }
                    if (source_value_code[1]) {
                        dynamic_lov_para = 'HLS_LOV_PARA.' + source_value_code[1].toUpperCase() + '.' + $session.lang;
                    }
                    temp_prompt = pCache.getValue(dynamic_lov_para);
                    if (temp_prompt) {
                        f.setPrompt(temp_prompt);
                    } else {
                        f.setPrompt('HLS.CODE');
                    }
                    f.setDisplayWidth(120);
                } else if (fname == 'VALUE_NAME') {
                    f.setForQuery(true);
                    if (source_value_name[1]) {
                        dynamic_lov_para = 'HLS_LOV_PARA.' + source_value_name[1].toUpperCase() + '.' + $session.lang;
                    }
                    temp_prompt = pCache.getValue(dynamic_lov_para);
                    if (temp_prompt) {
                        f.setPrompt(temp_prompt);
                    } else {
                        f.setPrompt('HLS.DESCRIPTION');
                    }
                    f.setDisplayWidth(250);
                } else {
                    f.setDisplayWidth(120);
                    if (fname == 'VALUE_CODE_DISPLAY') {
                        if (source_value_code_display[1]) {
                            dynamic_lov_para = 'HLS_LOV_PARA.' + source_value_code_display[1].toUpperCase() + '.' + $session.lang;
                        }
                        temp_prompt = pCache.getValue(dynamic_lov_para);
                        if (temp_prompt) {
                            f.setPrompt(temp_prompt);
                        } else {
                            f.setPrompt('HLS_LOV_PARA.' + fname);
                        }
                        f.setForQuery(true);
                    } else {
                        f.setPrompt('HLS_LOV_PARA.' + fname);
                    }
                }
                $this.addField(f);
                var qf = queryfields.createChildNS('query-field');
                qf.field = String(fname.toLowerCase());
                qf.queryoperator = (dbtype == 'NUMBER' ? '=' : 'like');
            }
            stmt.close();
            // ps.close();
            conn.close();
            model = $this.getObjectContext();
            // println(model.toXML());
        ]]></s:bm-script>
    </bm:features>
    <bm:query-fields><![CDATA[
    ]]></bm:query-fields>
</bm:model>