• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mybatis / ibatis-2 / 730

28 Dec 2025 10:16PM UTC coverage: 65.615% (+0.5%) from 65.146%
730

push

github

web-flow
Update README.md

1602 of 2802 branches covered (57.17%)

5053 of 7701 relevant lines covered (65.61%)

0.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.59
/src/main/java/com/ibatis/sqlmap/engine/mapping/sql/dynamic/DynamicSql.java
1
/*
2
 * Copyright 2004-2025 the original author or authors.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *    https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
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.InlineParameterMapParser;
20
import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap;
21
import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMapping;
22
import com.ibatis.sqlmap.engine.mapping.result.ResultMap;
23
import com.ibatis.sqlmap.engine.mapping.sql.Sql;
24
import com.ibatis.sqlmap.engine.mapping.sql.SqlChild;
25
import com.ibatis.sqlmap.engine.mapping.sql.SqlText;
26
import com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.DynamicParent;
27
import com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.IterateContext;
28
import com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.SqlTag;
29
import com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.SqlTagContext;
30
import com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.SqlTagHandler;
31
import com.ibatis.sqlmap.engine.mapping.sql.simple.SimpleDynamicSql;
32
import com.ibatis.sqlmap.engine.scope.StatementScope;
33

34
import java.io.PrintWriter;
35
import java.io.StringWriter;
36
import java.util.ArrayList;
37
import java.util.Iterator;
38
import java.util.List;
39

40
/**
41
 * The Class DynamicSql.
42
 */
43
public class DynamicSql implements Sql, DynamicParent {
44

45
  /** The Constant PARAM_PARSER. */
46
  private static final InlineParameterMapParser PARAM_PARSER = new InlineParameterMapParser();
1✔
47

48
  /** The children. */
49
  private List children = new ArrayList<>();
1✔
50

51
  /** The delegate. */
52
  private SqlMapExecutorDelegate delegate;
53

54
  /**
55
   * Instantiates a new dynamic sql.
56
   *
57
   * @param delegate
58
   *          the delegate
59
   */
60
  public DynamicSql(SqlMapExecutorDelegate delegate) {
1✔
61
    this.delegate = delegate;
1✔
62
  }
1✔
63

64
  @Override
65
  public String getSql(StatementScope statementScope, Object parameterObject) {
66
    String sql = statementScope.getDynamicSql();
1✔
67
    if (sql == null) {
1!
68
      process(statementScope, parameterObject);
×
69
      sql = statementScope.getDynamicSql();
×
70
    }
71
    return sql;
1✔
72
  }
73

74
  @Override
75
  public ParameterMap getParameterMap(StatementScope statementScope, Object parameterObject) {
76
    ParameterMap map = statementScope.getDynamicParameterMap();
1✔
77
    if (map == null) {
1✔
78
      process(statementScope, parameterObject);
1✔
79
      map = statementScope.getDynamicParameterMap();
1✔
80
    }
81
    return map;
1✔
82
  }
83

84
  @Override
85
  public ResultMap getResultMap(StatementScope statementScope, Object parameterObject) {
86
    return statementScope.getResultMap();
1✔
87
  }
88

89
  @Override
90
  public void cleanup(StatementScope statementScope) {
91
    statementScope.setDynamicSql(null);
1✔
92
    statementScope.setDynamicParameterMap(null);
1✔
93
  }
1✔
94

95
  /**
96
   * Process.
97
   *
98
   * @param statementScope
99
   *          the statement scope
100
   * @param parameterObject
101
   *          the parameter object
102
   */
103
  private void process(StatementScope statementScope, Object parameterObject) {
104
    SqlTagContext ctx = new SqlTagContext();
1✔
105
    List localChildren = children;
1✔
106
    processBodyChildren(statementScope, ctx, parameterObject, localChildren.iterator());
1✔
107

108
    ParameterMap map = new ParameterMap(delegate);
1✔
109
    map.setId(statementScope.getStatement().getId() + "-InlineParameterMap");
1✔
110
    map.setParameterClass(statementScope.getStatement().getParameterClass());
1✔
111
    map.setParameterMappingList(ctx.getParameterMappings());
1✔
112

113
    String dynSql = ctx.getBodyText();
1✔
114

115
    // Processes $substitutions$ after DynamicSql
116
    if (SimpleDynamicSql.isSimpleDynamicSql(dynSql)) {
1✔
117
      dynSql = new SimpleDynamicSql(delegate, dynSql).getSql(statementScope, parameterObject);
1✔
118
    }
119

120
    statementScope.setDynamicSql(dynSql);
1✔
121
    statementScope.setDynamicParameterMap(map);
1✔
122
  }
1✔
123

124
  /**
125
   * Process body children.
126
   *
127
   * @param statementScope
128
   *          the statement scope
129
   * @param ctx
130
   *          the ctx
131
   * @param parameterObject
132
   *          the parameter object
133
   * @param localChildren
134
   *          the local children
135
   */
136
  private void processBodyChildren(StatementScope statementScope, SqlTagContext ctx, Object parameterObject,
137
      Iterator localChildren) {
138
    PrintWriter out = ctx.getWriter();
1✔
139
    processBodyChildren(statementScope, ctx, parameterObject, localChildren, out);
1✔
140
  }
1✔
141

142
  /**
143
   * Process body children.
144
   *
145
   * @param statementScope
146
   *          the statement scope
147
   * @param ctx
148
   *          the ctx
149
   * @param parameterObject
150
   *          the parameter object
151
   * @param localChildren
152
   *          the local children
153
   * @param out
154
   *          the out
155
   */
156
  private void processBodyChildren(StatementScope statementScope, SqlTagContext ctx, Object parameterObject,
157
      Iterator localChildren, PrintWriter out) {
158
    while (localChildren.hasNext()) {
1✔
159
      SqlChild child = (SqlChild) localChildren.next();
1✔
160
      if (child instanceof SqlText) {
1✔
161
        SqlText sqlText = (SqlText) child;
1✔
162
        String sqlStatement = sqlText.getText();
1✔
163
        if (sqlText.isWhiteSpace()) {
1✔
164
          out.print(sqlStatement);
1✔
165
        } else if (!sqlText.isPostParseRequired()) {
1✔
166

167
          // BODY OUT
168
          out.print(sqlStatement);
1✔
169

170
          ParameterMapping[] mappings = sqlText.getParameterMappings();
1✔
171
          if (mappings != null) {
1!
172
            for (ParameterMapping mapping : mappings) {
1✔
173
              ctx.addParameterMapping(mapping);
1✔
174
            }
175
          }
176
        } else {
1✔
177

178
          IterateContext itCtx = ctx.peekIterateContext();
1✔
179

180
          if (null != itCtx && itCtx.isAllowNext()) {
1!
181
            itCtx.next();
1✔
182
            itCtx.setAllowNext(false);
1✔
183
            if (!itCtx.hasNext()) {
1✔
184
              itCtx.setFinal(true);
1✔
185
            }
186
          }
187

188
          if (itCtx != null) {
1!
189
            StringBuilder sqlStatementBuffer = new StringBuilder(sqlStatement);
1✔
190
            iteratePropertyReplace(sqlStatementBuffer, itCtx);
1✔
191
            sqlStatement = sqlStatementBuffer.toString();
1✔
192
          }
193

194
          sqlText = PARAM_PARSER.parseInlineParameterMap(delegate.getTypeHandlerFactory(), sqlStatement);
1✔
195

196
          ParameterMapping[] mappings = sqlText.getParameterMappings();
1✔
197
          out.print(sqlText.getText());
1✔
198
          if (mappings != null) {
1!
199
            for (ParameterMapping mapping : mappings) {
1✔
200
              ctx.addParameterMapping(mapping);
1✔
201
            }
202
          }
203
        }
204
      } else if (child instanceof SqlTag) {
1!
205
        SqlTag tag = (SqlTag) child;
1✔
206
        SqlTagHandler handler = tag.getHandler();
1✔
207
        int response = SqlTagHandler.INCLUDE_BODY;
1✔
208
        do {
209
          StringWriter sw = new StringWriter();
1✔
210
          PrintWriter pw = new PrintWriter(sw);
1✔
211

212
          response = handler.doStartFragment(ctx, tag, parameterObject);
1✔
213
          if (response != SqlTagHandler.SKIP_BODY) {
1✔
214

215
            processBodyChildren(statementScope, ctx, parameterObject, tag.getChildren(), pw);
1✔
216
            pw.flush();
1✔
217
            pw.close();
1✔
218
            StringBuilder body = new StringBuilder(sw.getBuffer());
1✔
219
            response = handler.doEndFragment(ctx, tag, parameterObject, body);
1✔
220
            handler.doPrepend(ctx, tag, parameterObject, body);
1✔
221

222
            if (response != SqlTagHandler.SKIP_BODY && body.length() > 0) {
1!
223
              out.print(body.toString());
1✔
224
            }
225

226
          }
227
        } while (response == SqlTagHandler.REPEAT_BODY);
1✔
228

229
        ctx.popRemoveFirstPrependMarker(tag);
1✔
230

231
        if (ctx.peekIterateContext() != null && ctx.peekIterateContext().getTag() == tag) {
1✔
232
          ctx.setAttribute(ctx.peekIterateContext().getTag(), null);
1✔
233
          ctx.popIterateContext();
1✔
234
        }
235

236
      }
237
    }
1✔
238
  }
1✔
239

240
  /**
241
   * Iterate property replace.
242
   *
243
   * @param bodyContent
244
   *          the body content
245
   * @param iterate
246
   *          the iterate
247
   */
248
  protected void iteratePropertyReplace(StringBuilder bodyContent, IterateContext iterate) {
249
    if (iterate != null) {
1!
250
      String[] mappings = { "#", "$" };
1✔
251
      for (String mapping : mappings) {
1✔
252
        int startIndex = 0;
1✔
253
        int endIndex = -1;
1✔
254
        while (startIndex > -1 && startIndex < bodyContent.length()) {
1!
255
          startIndex = bodyContent.indexOf(mapping, endIndex + 1);
1✔
256
          endIndex = bodyContent.indexOf(mapping, startIndex + 1);
1✔
257
          if (startIndex > -1 && endIndex > -1) {
1✔
258
            bodyContent.replace(startIndex + 1, endIndex,
1✔
259
                iterate.addIndexToTagProperty(bodyContent.substring(startIndex + 1, endIndex)));
1✔
260
          }
261
        }
262
      }
263
    }
264
  }
1✔
265

266
  /**
267
   * Replace.
268
   *
269
   * @param builder
270
   *          the builder
271
   * @param find
272
   *          the find
273
   * @param replace
274
   *          the replace
275
   */
276
  protected static void replace(StringBuilder builder, String find, String replace) {
277
    int pos = builder.toString().indexOf(find);
×
278
    int len = find.length();
×
279
    while (pos > -1) {
×
280
      builder.replace(pos, pos + len, replace);
×
281
      pos = builder.toString().indexOf(find);
×
282
    }
283
  }
×
284

285
  @Override
286
  public void addChild(SqlChild child) {
287
    children.add(child);
1✔
288
  }
1✔
289

290
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc