View Javadoc
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.mapping.ParameterMapping;
23  import org.apache.ibatis.session.Configuration;
24  
25  public class ParameterMappingCollector {
26  
27    private final ParameterMapping[] parameterMappingSources;
28    private final List<ParameterMapping> parameterMappings = new ArrayList<>();
29    private final Map<String, Object> context;
30    private final Configuration configuration;
31  
32    private int uid = 0;
33    private String itemKey;
34  
35    public ParameterMappingCollector(ParameterMapping[] newParameterMappingSources, Map<String, Object> newContext,
36        Configuration newConfiguration) {
37      this.parameterMappingSources = newParameterMappingSources;
38      this.context = newContext;
39      this.configuration = newConfiguration;
40    }
41  
42    public void setItemKey(String value) {
43      this.itemKey = value;
44    }
45  
46    public String getItemKey() {
47      return this.itemKey;
48    }
49  
50    public String g(int mapping) {
51      ParameterMapping parameterMapping = this.parameterMappingSources[mapping];
52      PropertyInfo vi = getPropertyInfo(parameterMapping.getProperty());
53      if (vi.isIterable) {
54        parameterMapping = itemize(parameterMapping, vi);
55        this.context.put(vi.root, this.context.get(this.itemKey));
56      }
57      this.parameterMappings.add(parameterMapping);
58      return "?";
59    }
60  
61    public List<ParameterMapping> getParameterMappings() {
62      return this.parameterMappings;
63    }
64  
65    private ParameterMapping itemize(ParameterMapping source, PropertyInfo var) {
66      StringBuilder sb = new StringBuilder().append("_RPTITEM_").append(this.uid++);
67      var.root = sb.toString();
68      String propertyName = sb.append(var.path).toString();
69      ParameterMapping.Builder builder = new ParameterMapping.Builder(this.configuration, propertyName,
70          source.getJavaType());
71      builder.expression(source.getExpression()).jdbcType(source.getJdbcType()).jdbcTypeName(source.getJdbcTypeName())
72          .mode(source.getMode()).numericScale(source.getNumericScale()).resultMapId(source.getResultMapId())
73          .typeHandler(source.getTypeHandler());
74      return builder.build();
75    }
76  
77    private PropertyInfo getPropertyInfo(String name) {
78      PropertyInfo i = new PropertyInfo();
79      if (name != null) {
80        int p = name.indexOf('.');
81        if (p == -1) {
82          i.root = name;
83        } else {
84          i.root = name.substring(0, p);
85          i.path = name.substring(p);
86        }
87      }
88      i.isIterable = this.itemKey != null && this.itemKey.equals(i.root);
89      return i;
90    }
91  
92    static class PropertyInfo {
93      boolean isIterable = false;
94      String root = "";
95      String path = "";
96  
97      public PropertyInfo() {
98        // Prevent synthetic access
99      }
100   }
101 
102 }