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

mybatis / velocity-scripting / #375

24 Sep 2023 01:30AM CUT coverage: 82.545%. Remained the same
#375

Pull #187

github

web-flow
Merge 833f74f79 into df890ab13
Pull Request #187: Update dependency org.mybatis:mybatis-parent to v39

506 of 613 relevant lines covered (82.54%)

0.83 hits per line

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

73.91
/src/main/java/org/mybatis/scripting/velocity/ParameterMappingSourceParser.java
1
/*
2
 *    Copyright 2012-2022 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.mybatis.scripting.velocity;
17

18
import java.util.ArrayList;
19
import java.util.List;
20
import java.util.Map;
21

22
import org.apache.ibatis.builder.BaseBuilder;
23
import org.apache.ibatis.builder.BuilderException;
24
import org.apache.ibatis.builder.ParameterExpression;
25
import org.apache.ibatis.mapping.ParameterMapping;
26
import org.apache.ibatis.parsing.GenericTokenParser;
27
import org.apache.ibatis.parsing.TokenHandler;
28
import org.apache.ibatis.reflection.DefaultReflectorFactory;
29
import org.apache.ibatis.reflection.MetaClass;
30
import org.apache.ibatis.reflection.ReflectorFactory;
31
import org.apache.ibatis.session.Configuration;
32
import org.apache.ibatis.type.JdbcType;
33

34
public class ParameterMappingSourceParser {
35

36
  private static final String VALID_PROPERTIES = "javaType,jdbcType,mode,numericScale,resultMap,typeHandler,jdbcTypeName";
37

38
  private final String sql;
39

40
  private final ParameterMapping[] parameterMappingSources;
41

42
  public ParameterMappingSourceParser(Configuration configuration, String script, Class<?> parameterType) {
1✔
43
    ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(configuration, parameterType);
1✔
44
    GenericTokenParser parser = new GenericTokenParser("@{", "}", handler);
1✔
45
    this.sql = parser.parse(script);
1✔
46
    this.parameterMappingSources = handler.getParameterMappingSources();
1✔
47
  }
1✔
48

49
  public ParameterMapping[] getParameterMappingSources() {
50
    return this.parameterMappingSources;
1✔
51
  }
52

53
  public String getSql() {
54
    return this.sql;
1✔
55
  }
56

57
  private static class ParameterMappingTokenHandler extends BaseBuilder implements TokenHandler {
58

59
    private final List<ParameterMapping> parameterMappings = new ArrayList<>();
1✔
60
    private final Class<?> parameterType;
61

62
    public ParameterMappingTokenHandler(Configuration newConfiguration, Class<?> newParameterType) {
63
      super(newConfiguration);
1✔
64
      this.parameterType = newParameterType;
1✔
65
    }
1✔
66

67
    public ParameterMapping[] getParameterMappingSources() {
68
      return this.parameterMappings.toArray(new ParameterMapping[this.parameterMappings.size()]);
1✔
69
    }
70

71
    @Override
72
    public String handleToken(String content) {
73
      int index = this.parameterMappings.size();
1✔
74
      ParameterMapping pm = buildParameterMapping(content);
1✔
75
      this.parameterMappings.add(pm);
1✔
76
      return new StringBuilder().append('$').append(SQLScriptSource.MAPPING_COLLECTOR_KEY).append(".g(").append(index)
1✔
77
          .append(")").toString();
1✔
78
    }
79

80
    private ParameterMapping buildParameterMapping(String content) {
81
      Map<String, String> propertiesMap = parseParameterMapping(content);
1✔
82
      String property = propertiesMap.get("property");
1✔
83
      String jdbcType = propertiesMap.get("jdbcType");
1✔
84
      Class<?> propertyType;
85
      if (this.typeHandlerRegistry.hasTypeHandler(this.parameterType)) {
1✔
86
        propertyType = this.parameterType;
1✔
87
      } else if (JdbcType.CURSOR.name().equals(jdbcType)) {
1✔
88
        propertyType = java.sql.ResultSet.class;
×
89
      } else if (property != null) {
1✔
90
        ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
1✔
91
        MetaClass metaClass = MetaClass.forClass(this.parameterType, reflectorFactory);
1✔
92
        if (metaClass.hasGetter(property)) {
1✔
93
          propertyType = metaClass.getGetterType(property);
1✔
94
        } else {
95
          propertyType = Object.class;
×
96
        }
97
      } else {
1✔
98
        propertyType = Object.class;
×
99
      }
100
      ParameterMapping.Builder builder = new ParameterMapping.Builder(this.configuration, property, propertyType);
1✔
101
      if (jdbcType != null) {
1✔
102
        builder.jdbcType(resolveJdbcType(jdbcType));
×
103
      }
104
      Class<?> javaType = null;
1✔
105
      String typeHandlerAlias = null;
1✔
106
      for (Map.Entry<String, String> entry : propertiesMap.entrySet()) {
1✔
107
        String name = entry.getKey();
1✔
108
        String value = entry.getValue();
1✔
109
        if ("javaType".equals(name)) {
1✔
110
          javaType = resolveClass(value);
1✔
111
          builder.javaType(javaType);
1✔
112
        } else if ("jdbcType".equals(name)) {
1✔
113
          builder.jdbcType(resolveJdbcType(value));
×
114
        } else if ("mode".equals(name)) {
1✔
115
          builder.mode(resolveParameterMode(value));
×
116
        } else if ("numericScale".equals(name)) {
1✔
117
          builder.numericScale(Integer.valueOf(value));
×
118
        } else if ("resultMap".equals(name)) {
1✔
119
          builder.resultMapId(value);
×
120
        } else if ("typeHandler".equals(name)) {
1✔
121
          typeHandlerAlias = value;
×
122
        } else if ("jdbcTypeName".equals(name)) {
1✔
123
          builder.jdbcTypeName(value);
×
124
        } else if ("property".equals(name)) {
1✔
125
          // Do Nothing
126
        } else if ("expression".equals(name)) {
×
127
          throw new BuilderException("Expression based parameters are not supported yet");
×
128
        } else {
129
          throw new BuilderException("An invalid property '" + name + "' was found in mapping @{" + content
×
130
              + "}.  Valid properties are " + VALID_PROPERTIES);
131
        }
132
      }
1✔
133
      if (typeHandlerAlias != null) {
1✔
134
        builder.typeHandler(resolveTypeHandler(javaType, typeHandlerAlias));
×
135
      }
136
      return builder.build();
1✔
137
    }
138

139
    private Map<String, String> parseParameterMapping(String content) {
140
      try {
141
        return new ParameterExpression(content);
1✔
142
      } catch (BuilderException ex) {
×
143
        throw ex;
×
144
      } catch (Exception ex) {
×
145
        throw new BuilderException("Parsing error was found in mapping @{" + content
×
146
            + "}.  Check syntax #{property|(expression), var1=value1, var2=value2, ...} ", ex);
147
      }
148
    }
149

150
  }
151

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