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

mybatis / mybatis-3 / #3245

09 Oct 2023 01:29AM UTC coverage: 86.619% (-0.01%) from 86.633%
#3245

push

github

web-flow
Merge pull request #2966 from taoyect/minor-refine

just minor refine

27 of 27 new or added lines in 4 files covered. (100.0%)

9296 of 10732 relevant lines covered (86.62%)

0.87 hits per line

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

95.45
/src/main/java/org/apache/ibatis/scripting/xmltags/TrimSqlNode.java
1
/*
2
 *    Copyright 2009-2023 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 java.util.ArrayList;
19
import java.util.Collections;
20
import java.util.List;
21
import java.util.Locale;
22
import java.util.Map;
23
import java.util.StringTokenizer;
24

25
import org.apache.ibatis.session.Configuration;
26

27
/**
28
 * @author Clinton Begin
29
 */
30
public class TrimSqlNode implements SqlNode {
31

32
  private final SqlNode contents;
33
  private final String prefix;
34
  private final String suffix;
35
  private final List<String> prefixesToOverride;
36
  private final List<String> suffixesToOverride;
37
  private final Configuration configuration;
38

39
  public TrimSqlNode(Configuration configuration, SqlNode contents, String prefix, String prefixesToOverride,
40
      String suffix, String suffixesToOverride) {
41
    this(configuration, contents, prefix, parseOverrides(prefixesToOverride), suffix,
1✔
42
        parseOverrides(suffixesToOverride));
1✔
43
  }
1✔
44

45
  protected TrimSqlNode(Configuration configuration, SqlNode contents, String prefix, List<String> prefixesToOverride,
46
      String suffix, List<String> suffixesToOverride) {
1✔
47
    this.contents = contents;
1✔
48
    this.prefix = prefix;
1✔
49
    this.prefixesToOverride = prefixesToOverride;
1✔
50
    this.suffix = suffix;
1✔
51
    this.suffixesToOverride = suffixesToOverride;
1✔
52
    this.configuration = configuration;
1✔
53
  }
1✔
54

55
  @Override
56
  public boolean apply(DynamicContext context) {
57
    FilteredDynamicContext filteredDynamicContext = new FilteredDynamicContext(context);
1✔
58
    boolean result = contents.apply(filteredDynamicContext);
1✔
59
    filteredDynamicContext.applyAll();
1✔
60
    return result;
1✔
61
  }
62

63
  private static List<String> parseOverrides(String overrides) {
64
    if (overrides != null) {
1✔
65
      final StringTokenizer parser = new StringTokenizer(overrides, "|", false);
1✔
66
      final List<String> list = new ArrayList<>(parser.countTokens());
1✔
67
      while (parser.hasMoreTokens()) {
1✔
68
        list.add(parser.nextToken().toUpperCase(Locale.ENGLISH));
1✔
69
      }
70
      return list;
1✔
71
    }
72
    return Collections.emptyList();
1✔
73
  }
74

75
  private class FilteredDynamicContext extends DynamicContext {
76
    private final DynamicContext delegate;
77
    private boolean prefixApplied;
78
    private boolean suffixApplied;
79
    private StringBuilder sqlBuffer;
80

81
    public FilteredDynamicContext(DynamicContext delegate) {
1✔
82
      super(configuration, null);
1✔
83
      this.delegate = delegate;
1✔
84
      this.prefixApplied = false;
1✔
85
      this.suffixApplied = false;
1✔
86
      this.sqlBuffer = new StringBuilder();
1✔
87
    }
1✔
88

89
    public void applyAll() {
90
      sqlBuffer = new StringBuilder(sqlBuffer.toString().trim());
1✔
91
      String trimmedUppercaseSql = sqlBuffer.toString().toUpperCase(Locale.ENGLISH);
1✔
92
      if (trimmedUppercaseSql.length() > 0) {
1✔
93
        applyPrefix(sqlBuffer, trimmedUppercaseSql);
1✔
94
        applySuffix(sqlBuffer, trimmedUppercaseSql);
1✔
95
      }
96
      delegate.appendSql(sqlBuffer.toString());
1✔
97
    }
1✔
98

99
    @Override
100
    public Map<String, Object> getBindings() {
101
      return delegate.getBindings();
1✔
102
    }
103

104
    @Override
105
    public void bind(String name, Object value) {
106
      delegate.bind(name, value);
1✔
107
    }
1✔
108

109
    @Override
110
    public int getUniqueNumber() {
111
      return delegate.getUniqueNumber();
1✔
112
    }
113

114
    @Override
115
    public void appendSql(String sql) {
116
      sqlBuffer.append(sql);
1✔
117
    }
1✔
118

119
    @Override
120
    public String getSql() {
121
      return delegate.getSql();
×
122
    }
123

124
    private void applyPrefix(StringBuilder sql, String trimmedUppercaseSql) {
125
      if (prefixApplied) {
1✔
126
        return;
×
127
      }
128
      prefixApplied = true;
1✔
129
      if (prefixesToOverride != null) {
1✔
130
        prefixesToOverride.stream().filter(trimmedUppercaseSql::startsWith).findFirst()
1✔
131
            .ifPresent(toRemove -> sql.delete(0, toRemove.trim().length()));
1✔
132
      }
133
      if (prefix != null) {
1✔
134
        sql.insert(0, " ").insert(0, prefix);
1✔
135
      }
136
    }
1✔
137

138
    private void applySuffix(StringBuilder sql, String trimmedUppercaseSql) {
139
      if (suffixApplied) {
1✔
140
        return;
×
141
      }
142
      suffixApplied = true;
1✔
143
      if (suffixesToOverride != null) {
1✔
144
        suffixesToOverride.stream()
1✔
145
            .filter(toRemove -> trimmedUppercaseSql.endsWith(toRemove) || trimmedUppercaseSql.endsWith(toRemove.trim()))
1✔
146
            .findFirst().ifPresent(toRemove -> {
1✔
147
              int start = sql.length() - toRemove.trim().length();
1✔
148
              int end = sql.length();
1✔
149
              sql.delete(start, end);
1✔
150
            });
1✔
151
      }
152
      if (suffix != null) {
1✔
153
        sql.append(" ").append(suffix);
1✔
154
      }
155
    }
1✔
156

157
  }
158

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