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

mybatis / ibatis-2 / 761

05 Jan 2026 03:14AM UTC coverage: 65.569% (-0.004%) from 65.573%
761

push

github

web-flow
Merge pull request #350 from hazendaz/master

Further cleanup on conditional statements

1598 of 2797 branches covered (57.13%)

16 of 39 new or added lines in 3 files covered. (41.03%)

2 existing lines in 2 files now uncovered.

5016 of 7650 relevant lines covered (65.57%)

0.66 hits per line

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

72.79
/src/main/java/com/ibatis/sqlmap/engine/mapping/parameter/InlineParameterMapParser.java
1
/*
2
 * Copyright 2004-2026 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.parameter;
17

18
import com.ibatis.common.beans.Probe;
19
import com.ibatis.common.beans.ProbeFactory;
20
import com.ibatis.common.resources.Resources;
21
import com.ibatis.sqlmap.client.SqlMapException;
22
import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;
23
import com.ibatis.sqlmap.engine.mapping.sql.SqlText;
24
import com.ibatis.sqlmap.engine.type.CustomTypeHandler;
25
import com.ibatis.sqlmap.engine.type.DomTypeMarker;
26
import com.ibatis.sqlmap.engine.type.TypeHandler;
27
import com.ibatis.sqlmap.engine.type.TypeHandlerFactory;
28

29
import java.util.ArrayList;
30
import java.util.List;
31
import java.util.StringTokenizer;
32

33
/**
34
 * The Class InlineParameterMapParser.
35
 */
36
public class InlineParameterMapParser {
1✔
37

38
  /** The Constant PROBE. */
39
  private static final Probe PROBE = ProbeFactory.getProbe();
1✔
40

41
  /** The Constant PARAMETER_TOKEN. */
42
  private static final String PARAMETER_TOKEN = "#";
43

44
  /** The Constant PARAM_DELIM. */
45
  private static final String PARAM_DELIM = ":";
46

47
  /**
48
   * Parses the inline parameter map.
49
   *
50
   * @param typeHandlerFactory
51
   *          the type handler factory
52
   * @param sqlStatement
53
   *          the sql statement
54
   *
55
   * @return the sql text
56
   */
57
  public SqlText parseInlineParameterMap(TypeHandlerFactory typeHandlerFactory, String sqlStatement) {
58
    return parseInlineParameterMap(typeHandlerFactory, sqlStatement, null);
1✔
59
  }
60

61
  /**
62
   * Parses the inline parameter map.
63
   *
64
   * @param typeHandlerFactory
65
   *          the type handler factory
66
   * @param sqlStatement
67
   *          the sql statement
68
   * @param parameterClass
69
   *          the parameter class
70
   *
71
   * @return the sql text
72
   */
73
  public SqlText parseInlineParameterMap(TypeHandlerFactory typeHandlerFactory, String sqlStatement,
74
      Class parameterClass) {
75

76
    List mappingList = new ArrayList<>();
1✔
77

78
    StringTokenizer parser = new StringTokenizer(sqlStatement, PARAMETER_TOKEN, true);
1✔
79
    StringBuilder newSqlBuffer = new StringBuilder();
1✔
80

81
    String token = null;
1✔
82
    String lastToken = null;
1✔
83
    while (parser.hasMoreTokens()) {
1✔
84
      token = parser.nextToken();
1✔
85
      if (PARAMETER_TOKEN.equals(lastToken)) {
1✔
86
        if (PARAMETER_TOKEN.equals(token)) {
1!
87
          newSqlBuffer.append(PARAMETER_TOKEN);
×
88
        } else {
89
          ParameterMapping mapping = null;
1✔
90
          if (token.indexOf(PARAM_DELIM) > -1) {
1✔
91
            mapping = oldParseMapping(token, parameterClass, typeHandlerFactory);
1✔
92
          } else {
93
            mapping = newParseMapping(token, parameterClass, typeHandlerFactory);
1✔
94
          }
95

96
          mappingList.add(mapping);
1✔
97
          newSqlBuffer.append("?");
1✔
98
          boolean hasMoreTokens = parser.hasMoreTokens();
1✔
99
          if (hasMoreTokens) {
1✔
100
            token = parser.nextToken();
1✔
101
          }
102
          if (!hasMoreTokens || !PARAMETER_TOKEN.equals(token)) {
1!
103
            throw new SqlMapException(
1✔
104
                "Unterminated inline parameter in mapped statement near '" + newSqlBuffer.toString() + "'");
1✔
105
          }
106
        }
107
        token = null;
1✔
108
      } else if (!PARAMETER_TOKEN.equals(token)) {
1✔
109
        newSqlBuffer.append(token);
1✔
110
      }
111

112
      lastToken = token;
1✔
113
    }
114

115
    String newSql = newSqlBuffer.toString();
1✔
116

117
    ParameterMapping[] mappingArray = (ParameterMapping[]) mappingList
1✔
118
        .toArray(new ParameterMapping[mappingList.size()]);
1✔
119

120
    SqlText sqlText = new SqlText();
1✔
121
    sqlText.setText(newSql);
1✔
122
    sqlText.setParameterMappings(mappingArray);
1✔
123
    return sqlText;
1✔
124
  }
125

126
  /**
127
   * New parse mapping.
128
   *
129
   * @param token
130
   *          the token
131
   * @param parameterClass
132
   *          the parameter class
133
   * @param typeHandlerFactory
134
   *          the type handler factory
135
   *
136
   * @return the parameter mapping
137
   */
138
  private ParameterMapping newParseMapping(String token, Class parameterClass, TypeHandlerFactory typeHandlerFactory) {
139
    ParameterMapping mapping = new ParameterMapping();
1✔
140

141
    // #propertyName,javaType=string,jdbcType=VARCHAR,mode=IN,nullValue=N/A,handler=string,numericScale=2#
142

143
    StringTokenizer paramParser = new StringTokenizer(token, "=,", false);
1✔
144
    mapping.setPropertyName(paramParser.nextToken());
1✔
145

146
    while (paramParser.hasMoreTokens()) {
1✔
147
      String field = paramParser.nextToken();
1✔
148
      if (!paramParser.hasMoreTokens()) {
1!
149
        throw new SqlMapException("Incorrect inline parameter map format (missmatched name=value pairs): " + token);
×
150
      }
151
      String value = paramParser.nextToken();
1✔
152
      if (field == null) {
1!
NEW
153
        throw new SqlMapException("Unrecognized parameter mapping field: '" + field + "' in " + token);
×
154
      }
155
      switch (field) {
1!
156
        case "javaType":
157
          value = typeHandlerFactory.resolveAlias(value);
1✔
158
          mapping.setJavaTypeName(value);
1✔
159
          break;
1✔
160
        case "jdbcType":
161
          mapping.setJdbcTypeName(value);
1✔
162
          break;
1✔
163
        case "mode":
NEW
164
          mapping.setMode(value);
×
NEW
165
          break;
×
166
        case "nullValue":
167
          mapping.setNullValue(value);
1✔
168
          break;
1✔
169
        case "handler":
170
          try {
UNCOV
171
            value = typeHandlerFactory.resolveAlias(value);
×
NEW
172
            Object impl = Resources.instantiate(value);
×
NEW
173
            if (impl instanceof TypeHandlerCallback) {
×
NEW
174
              mapping.setTypeHandler(new CustomTypeHandler((TypeHandlerCallback) impl));
×
NEW
175
            } else if (impl instanceof TypeHandler) {
×
NEW
176
              mapping.setTypeHandler((TypeHandler) impl);
×
177
            } else {
NEW
178
              throw new SqlMapException(
×
179
                  "The class " + value + " is not a valid implementation of TypeHandler or TypeHandlerCallback");
180
            }
NEW
181
          } catch (Exception e) {
×
NEW
182
            throw new SqlMapException("Error loading class specified by handler field in " + token + ".  Cause: " + e,
×
183
                e);
NEW
184
          }
×
185
          break;
186
        case "numericScale":
187
          try {
NEW
188
            Integer numericScale = Integer.valueOf(value);
×
NEW
189
            if (numericScale.intValue() < 0) {
×
NEW
190
              throw new SqlMapException("Value specified for numericScale must be greater than or equal to zero");
×
191
            }
NEW
192
            mapping.setNumericScale(numericScale);
×
NEW
193
          } catch (NumberFormatException e) {
×
NEW
194
            throw new SqlMapException("Value specified for numericScale is not a valid Integer");
×
NEW
195
          }
×
196
          break;
197
        default:
NEW
198
          throw new SqlMapException("Unrecognized parameter mapping field: '" + field + "' in " + token);
×
199
      }
200
    }
1✔
201

202
    if (mapping.getTypeHandler() == null) {
1!
203
      TypeHandler handler;
204
      if (parameterClass == null) {
1✔
205
        handler = typeHandlerFactory.getUnkownTypeHandler();
1✔
206
      } else {
207
        handler = resolveTypeHandler(typeHandlerFactory, parameterClass, mapping.getPropertyName(),
1✔
208
            mapping.getJavaTypeName(), mapping.getJdbcTypeName());
1✔
209
      }
210
      mapping.setTypeHandler(handler);
1✔
211
    }
212

213
    return mapping;
1✔
214
  }
215

216
  /**
217
   * Old parse mapping.
218
   *
219
   * @param token
220
   *          the token
221
   * @param parameterClass
222
   *          the parameter class
223
   * @param typeHandlerFactory
224
   *          the type handler factory
225
   *
226
   * @return the parameter mapping
227
   */
228
  private ParameterMapping oldParseMapping(String token, Class parameterClass, TypeHandlerFactory typeHandlerFactory) {
229
    ParameterMapping mapping = new ParameterMapping();
1✔
230
    if (token.indexOf(PARAM_DELIM) <= -1) {
1!
231
      mapping.setPropertyName(token);
×
232
      TypeHandler handler;
233
      if (parameterClass == null) {
×
234
        handler = typeHandlerFactory.getUnkownTypeHandler();
×
235
      } else {
236
        handler = resolveTypeHandler(typeHandlerFactory, parameterClass, token, null, null);
×
237
      }
238
      mapping.setTypeHandler(handler);
×
239
      return mapping;
×
240
    }
241
    StringTokenizer paramParser = new StringTokenizer(token, PARAM_DELIM, true);
1✔
242
    int n1 = paramParser.countTokens();
1✔
243
    if (n1 == 3) {
1✔
244
      String name = paramParser.nextToken();
1✔
245
      paramParser.nextToken(); // ignore ":"
1✔
246
      String type = paramParser.nextToken();
1✔
247
      mapping.setPropertyName(name);
1✔
248
      mapping.setJdbcTypeName(type);
1✔
249
      TypeHandler handler;
250
      if (parameterClass == null) {
1✔
251
        handler = typeHandlerFactory.getUnkownTypeHandler();
1✔
252
      } else {
253
        handler = resolveTypeHandler(typeHandlerFactory, parameterClass, name, null, type);
1✔
254
      }
255
      mapping.setTypeHandler(handler);
1✔
256
    } else {
1✔
257
      if (n1 < 5) {
1!
NEW
258
        throw new SqlMapException("Incorrect inline parameter map format: " + token);
×
259
      }
260
      String name = paramParser.nextToken();
1✔
261
      paramParser.nextToken(); // ignore ":"
1✔
262
      String type = paramParser.nextToken();
1✔
263
      paramParser.nextToken(); // ignore ":"
1✔
264
      StringBuilder nullValue = new StringBuilder().append(paramParser.nextToken());
1✔
265
      while (paramParser.hasMoreTokens()) {
1!
266
        nullValue.append(paramParser.nextToken());
×
267
      }
268
      mapping.setPropertyName(name);
1✔
269
      mapping.setJdbcTypeName(type);
1✔
270
      mapping.setNullValue(nullValue.toString());
1✔
271
      TypeHandler handler;
272
      if (parameterClass == null) {
1✔
273
        handler = typeHandlerFactory.getUnkownTypeHandler();
1✔
274
      } else {
275
        handler = resolveTypeHandler(typeHandlerFactory, parameterClass, name, null, type);
1✔
276
      }
277
      mapping.setTypeHandler(handler);
1✔
278
    }
279
    return mapping;
1✔
280

281
  }
282

283
  /**
284
   * Resolve type handler.
285
   *
286
   * @param typeHandlerFactory
287
   *          the type handler factory
288
   * @param clazz
289
   *          the clazz
290
   * @param propertyName
291
   *          the property name
292
   * @param javaType
293
   *          the java type
294
   * @param jdbcType
295
   *          the jdbc type
296
   *
297
   * @return the type handler
298
   */
299
  private TypeHandler resolveTypeHandler(TypeHandlerFactory typeHandlerFactory, Class clazz, String propertyName,
300
      String javaType, String jdbcType) {
301
    TypeHandler handler = null;
1✔
302
    if (clazz == null) {
1!
303
      // Unknown
304
      handler = typeHandlerFactory.getUnkownTypeHandler();
×
305
    } else if (DomTypeMarker.class.isAssignableFrom(clazz)) {
1✔
306
      // DOM
307
      handler = typeHandlerFactory.getTypeHandler(String.class, jdbcType);
1✔
308
    } else if (java.util.Map.class.isAssignableFrom(clazz)) {
1✔
309
      // Map
310
      if (javaType == null) {
1!
311
        handler = typeHandlerFactory.getUnkownTypeHandler();
1✔
312
        // BUG 1012591 -
313
        // typeHandlerFactory.getTypeHandler(java.lang.Object.class,
314
        // jdbcType);
315
      } else {
316
        try {
317
          javaType = typeHandlerFactory.resolveAlias(javaType);
×
318
          Class javaClass = Resources.classForName(javaType);
×
319
          handler = typeHandlerFactory.getTypeHandler(javaClass, jdbcType);
×
320
        } catch (Exception e) {
×
321
          throw new SqlMapException("Error.  Could not set TypeHandler.  Cause: " + e, e);
×
322
        }
×
323
      }
324
    } else if (typeHandlerFactory.getTypeHandler(clazz, jdbcType) != null) {
1✔
325
      // Primitive
326
      handler = typeHandlerFactory.getTypeHandler(clazz, jdbcType);
1✔
327
    } else {
328
      // JavaBean
329
      if (javaType == null) {
1✔
330

331
        Class type = PROBE.getPropertyTypeForGetter(clazz, propertyName);
1✔
332
        handler = typeHandlerFactory.getTypeHandler(type, jdbcType);
1✔
333

334
      } else {
1✔
335
        try {
336
          javaType = typeHandlerFactory.resolveAlias(javaType);
1✔
337
          Class javaClass = Resources.classForName(javaType);
1✔
338
          handler = typeHandlerFactory.getTypeHandler(javaClass, jdbcType);
1✔
339
        } catch (Exception e) {
×
340
          throw new SqlMapException("Error.  Could not set TypeHandler.  Cause: " + e, e);
×
341
        }
1✔
342
      }
343
    }
344
    return handler;
1✔
345
  }
346

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