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

mybatis / mybatis-3 / 2680

27 Jan 2025 11:09PM UTC coverage: 87.217% (+0.006%) from 87.211%
2680

push

github

web-flow
Merge pull request #2760 from harawata/bind-in-foreach

Handle `<bind>` correctly inside `<foreach>`

3681 of 4487 branches covered (82.04%)

143 of 153 new or added lines in 12 files covered. (93.46%)

1 existing line in 1 file now uncovered.

9668 of 11085 relevant lines covered (87.22%)

0.87 hits per line

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

96.15
/src/main/java/org/apache/ibatis/scripting/xmltags/TextSqlNode.java
1
/*
2
 *    Copyright 2009-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 org.apache.ibatis.scripting.xmltags;
17

18
import org.apache.ibatis.parsing.GenericTokenParser;
19
import org.apache.ibatis.parsing.TokenHandler;
20
import org.apache.ibatis.type.SimpleTypeRegistry;
21

22
/**
23
 * @author Clinton Begin
24
 */
25
public class TextSqlNode implements SqlNode {
26
  private final String text;
27

28
  public TextSqlNode(String text) {
1✔
29
    this.text = text;
1✔
30
  }
1✔
31

32
  public boolean isDynamic() {
33
    DynamicCheckerTokenParser checker = new DynamicCheckerTokenParser();
1✔
34
    GenericTokenParser parser = createParser(checker);
1✔
35
    parser.parse(text);
1✔
36
    return checker.isDynamic();
1✔
37
  }
38

39
  @Override
40
  public boolean apply(DynamicContext context) {
41
    GenericTokenParser parser = createParser(new BindingTokenParser(context));
1✔
42
    context.appendSql(context.parseParam(parser.parse(text)));
1✔
43
    return true;
1✔
44
  }
45

46
  private GenericTokenParser createParser(TokenHandler handler) {
47
    return new GenericTokenParser("${", "}", handler);
1✔
48
  }
49

50
  private static class BindingTokenParser implements TokenHandler {
51

52
    private final DynamicContext context;
53

54
    public BindingTokenParser(DynamicContext context) {
1✔
55
      this.context = context;
1✔
56
    }
1✔
57

58
    @Override
59
    public String handleToken(String content) {
60
      Object parameter = context.getBindings().get("_parameter");
1✔
61
      if (parameter == null) {
1!
UNCOV
62
        context.getBindings().put("value", null);
×
63
      } else if (SimpleTypeRegistry.isSimpleType(parameter.getClass())) {
1✔
64
        context.getBindings().put("value", parameter);
1✔
65
      }
66
      Object value = OgnlCache.getValue(content, context.getBindings());
1✔
67
      // issue #274 return "" instead of "null"
68
      return value == null ? "" : String.valueOf(value);
1✔
69
    }
70
  }
71

72
  private static class DynamicCheckerTokenParser implements TokenHandler {
73

74
    private boolean isDynamic;
75

76
    public DynamicCheckerTokenParser() {
1✔
77
      // Prevent Synthetic Access
78
    }
1✔
79

80
    public boolean isDynamic() {
81
      return isDynamic;
1✔
82
    }
83

84
    @Override
85
    public String handleToken(String content) {
86
      this.isDynamic = true;
1✔
87
      return null;
1✔
88
    }
89
  }
90

91
}
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

© 2026 Coveralls, Inc