1 16 package com.ibatis.sqlmap.engine.mapping.sql.dynamic; 17 18 import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate; 19 import com.ibatis.sqlmap.engine.mapping.parameter.BasicParameterMap; 20 import com.ibatis.sqlmap.engine.mapping.parameter.InlineParameterMapParser; 21 import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap; 22 import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMapping; 23 import com.ibatis.sqlmap.engine.mapping.result.ResultMap; 24 import com.ibatis.sqlmap.engine.mapping.sql.Sql; 25 import com.ibatis.sqlmap.engine.mapping.sql.SqlChild; 26 import com.ibatis.sqlmap.engine.mapping.sql.SqlText; 27 import com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.*; 28 import com.ibatis.sqlmap.engine.mapping.sql.simple.SimpleDynamicSql; 29 import com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement; 30 import com.ibatis.sqlmap.engine.scope.RequestScope; 31 32 import java.io.PrintWriter ; 33 import java.io.StringWriter ; 34 import java.util.ArrayList ; 35 import java.util.Iterator ; 36 import java.util.List ; 37 38 public class DynamicSql implements Sql, DynamicParent { 39 40 private static final InlineParameterMapParser PARAM_PARSER = new InlineParameterMapParser(); 41 42 private List children = new ArrayList (); 43 private SqlMapExecutorDelegate delegate; 44 45 public DynamicSql(SqlMapExecutorDelegate delegate) { 46 this.delegate = delegate; 47 } 48 49 public String getSql(RequestScope request, Object parameterObject) { 50 String sql = request.getDynamicSql(); 51 if (sql == null) { 52 process(request, parameterObject); 53 sql = request.getDynamicSql(); 54 } 55 return sql; 56 } 57 58 public ParameterMap getParameterMap(RequestScope request, Object parameterObject) { 59 ParameterMap map = request.getDynamicParameterMap(); 60 if (map == null) { 61 process(request, parameterObject); 62 map = request.getDynamicParameterMap(); 63 } 64 return map; 65 } 66 67 public ResultMap getResultMap(RequestScope request, Object parameterObject) { 68 return request.getResultMap(); 69 } 70 71 public void cleanup(RequestScope request) { 72 request.setDynamicSql(null); 73 request.setDynamicParameterMap(null); 74 } 75 76 private void process(RequestScope request, Object parameterObject) { 77 SqlTagContext ctx = new SqlTagContext(); 78 List localChildren = children; 79 processBodyChildren(request, ctx, parameterObject, localChildren.iterator()); 80 81 BasicParameterMap map = new BasicParameterMap(delegate); 82 map.setId(request.getStatement().getId() + "-InlineParameterMap"); 83 map.setParameterClass(((GeneralStatement) request.getStatement()).getParameterClass()); 84 map.setParameterMappingList(ctx.getParameterMappings()); 85 86 String dynSql = ctx.getBodyText(); 87 88 if (SimpleDynamicSql.isSimpleDynamicSql(dynSql)) { 90 dynSql = new SimpleDynamicSql(delegate, dynSql).getSql(request, parameterObject); 91 } 92 93 request.setDynamicSql(dynSql); 94 request.setDynamicParameterMap(map); 95 } 96 97 private void processBodyChildren(RequestScope request, SqlTagContext ctx, Object parameterObject, Iterator localChildren) { 98 PrintWriter out = ctx.getWriter(); 99 processBodyChildren(request, ctx, parameterObject, localChildren, out); 100 } 101 102 private void processBodyChildren(RequestScope request, SqlTagContext ctx, Object parameterObject, Iterator localChildren, PrintWriter out) { 103 while (localChildren.hasNext()) { 104 SqlChild child = (SqlChild) localChildren.next(); 105 if (child instanceof SqlText) { 106 SqlText sqlText = (SqlText) child; 107 String sqlStatement = sqlText.getText(); 108 if (sqlText.isWhiteSpace()) { 109 out.print(sqlStatement); 110 } else if (!sqlText.isPostParseRequired()) { 111 112 out.print(sqlStatement); 114 115 ParameterMapping[] mappings = sqlText.getParameterMappings(); 116 if (mappings != null) { 117 for (int i = 0, n = mappings.length; i < n; i++) { 118 ctx.addParameterMapping(mappings[i]); 119 } 120 } 121 } else { 122 123 IterateContext itCtx = ctx.peekIterateContext(); 124 125 if(null != itCtx && itCtx.isAllowNext()){ 126 itCtx.next(); 127 itCtx.setAllowNext(false); 128 if(!itCtx.hasNext()) { 129 itCtx.setFinal(true); 130 } 131 } 132 133 if(itCtx!=null) { 134 StringBuffer sqlStatementBuffer = new StringBuffer (sqlStatement); 135 iteratePropertyReplace(sqlStatementBuffer, itCtx); 136 sqlStatement = sqlStatementBuffer.toString(); 137 } 138 139 sqlText = PARAM_PARSER.parseInlineParameterMap(delegate.getTypeHandlerFactory(), sqlStatement); 140 141 ParameterMapping[] mappings = sqlText.getParameterMappings(); 142 out.print(sqlText.getText()); 143 if (mappings != null) { 144 for (int i = 0, n = mappings.length; i < n; i++) { 145 ctx.addParameterMapping(mappings[i]); 146 } 147 } 148 } 149 } else if (child instanceof SqlTag) { 150 SqlTag tag = (SqlTag) child; 151 SqlTagHandler handler = tag.getHandler(); 152 int response = SqlTagHandler.INCLUDE_BODY; 153 do { 154 StringWriter sw = new StringWriter (); 155 PrintWriter pw = new PrintWriter (sw); 156 157 response = handler.doStartFragment(ctx, tag, parameterObject); 158 if (response != SqlTagHandler.SKIP_BODY) { 159 160 processBodyChildren(request, ctx, parameterObject, tag.getChildren(), pw); 161 pw.flush(); 162 pw.close(); 163 StringBuffer body = sw.getBuffer(); 164 response = handler.doEndFragment(ctx, tag, parameterObject, body); 165 handler.doPrepend(ctx, tag, parameterObject, body); 166 167 if (response != SqlTagHandler.SKIP_BODY) { 168 if (body.length() > 0) { 169 out.print(body.toString()); 170 } 171 } 172 173 } 174 } while (response == SqlTagHandler.REPEAT_BODY); 175 176 ctx.popRemoveFirstPrependMarker(tag); 177 178 if(ctx.peekIterateContext()!= null && ctx.peekIterateContext().getTag() == tag) { 179 ctx.popIterateContext(); 180 } 181 182 } 183 } 184 } 185 186 190 protected void iteratePropertyReplace(StringBuffer bodyContent, IterateContext iterate) { 191 if(iterate!=null) { 192 String find = iterate.getProperty() + "[]"; 193 String replace = iterate.getProperty() + "[" + iterate.getIndex() + "]"; 194 replace(bodyContent, find, replace); 195 } 196 } 197 198 protected static void replace(StringBuffer buffer, String find, String replace) { 199 int pos = buffer.toString().indexOf(find); 200 int len = find.length(); 201 while (pos > -1) { 202 buffer.replace(pos, pos + len, replace); 203 pos = buffer.toString().indexOf(find); 204 } 205 } 206 public void addChild(SqlChild child) { 207 children.add(child); 208 } 209 210 } 211 | Popular Tags |