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

mybatis / freemarker-scripting / #281

pending completion
#281

Pull #150

github

web-flow
Merge 3411c6de0 into 9185d6a44
Pull Request #150: Update dependency org.mybatis:mybatis-parent to v38

243 of 260 relevant lines covered (93.46%)

0.93 hits per line

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

75.86
/src/main/java/org/mybatis/scripting/freemarker/MyBatisParamDirective.java
1
/*
2
 *    Copyright 2015-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.freemarker;
17

18
import java.io.IOException;
19
import java.util.List;
20
import java.util.Map;
21

22
import freemarker.core.Environment;
23
import freemarker.ext.util.WrapperTemplateModel;
24
import freemarker.template.DefaultListAdapter;
25
import freemarker.template.SimpleScalar;
26
import freemarker.template.TemplateBooleanModel;
27
import freemarker.template.TemplateDateModel;
28
import freemarker.template.TemplateDirectiveBody;
29
import freemarker.template.TemplateDirectiveModel;
30
import freemarker.template.TemplateException;
31
import freemarker.template.TemplateModel;
32
import freemarker.template.TemplateNumberModel;
33
import freemarker.template.TemplateScalarModel;
34

35
/**
36
 * Custom FreeMarker directive for generating "#{paramName}" declarations in convenient way. Problem is FreeMarker
37
 * supports this syntax natively and there are no chance to disable this (although it is deprecated). And to get
38
 * "#{paramName}" we should write ${r"#{paramName}"}. With this directive you can write more simple:
39
 * <p>
40
 * <blockquote>
41
 *
42
 * <pre>
43
 *     &lt;@p name="paramName"/&gt;
44
 * </pre>
45
 *
46
 * </blockquote>
47
 * <p>
48
 * Also directive supports `value` attribute. If it is specified, param will take passed value and create the
49
 * corresponding #{}-parameter. This is useful in loops:
50
 * </p>
51
 * <blockquote>
52
 *
53
 * <pre>
54
 *     &lt;#list ids as id&gt;
55
 *       &lt;@p value=id/&gt;
56
 *       &lt;#if id_has_next&gt;,&lt;/#if&gt;
57
 *     &lt;/#list&gt;
58
 * </pre>
59
 *
60
 * </blockquote>
61
 * <p>
62
 * will be translated into
63
 * </p>
64
 * <blockquote>
65
 *
66
 * <pre>
67
 *     #{_p0},#{_p1},#{_p2}
68
 * </pre>
69
 *
70
 * </blockquote>
71
 * <p>
72
 * And MyBatis engine will convert it to `?`-params finally.
73
 * </p>
74
 *
75
 * @author elwood
76
 */
77
public class MyBatisParamDirective implements TemplateDirectiveModel {
78
  public static String DEFAULT_KEY = "p";
79

80
  @Override
81
  public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
82
      throws TemplateException, IOException {
83
    SimpleScalar name = (SimpleScalar) params.get("name");
84
    if (params.containsKey("value")) {
85
      Object valueObject = params.get("value");
86
      Object value;
87
      if (valueObject == null) {
88
        value = null;
89
      } else if (valueObject instanceof WrapperTemplateModel) {
90
        value = ((WrapperTemplateModel) valueObject).getWrappedObject();
91
      } else if (valueObject instanceof TemplateScalarModel) {
92
        value = ((TemplateScalarModel) valueObject).getAsString();
93
      } else if (valueObject instanceof TemplateNumberModel) {
94
        value = ((TemplateNumberModel) valueObject).getAsNumber();
95
      } else if (valueObject instanceof TemplateDateModel) {
96
        value = ((TemplateDateModel) valueObject).getAsDate();
97
      } else if (valueObject instanceof TemplateBooleanModel) {
98
        value = ((TemplateBooleanModel) valueObject).getAsBoolean();
99
      } else {
100
        throw new UnsupportedOperationException(
101
            String.format("Type %s is not supported yet in this context.", valueObject.getClass().getSimpleName()));
102
      }
103

104
      TemplateModel generatedParamsObject = env.getGlobalVariables().get(FreeMarkerSqlSource.GENERATED_PARAMS_KEY);
105
      List generatedParams;
106
      if (generatedParamsObject instanceof DefaultListAdapter) {
107
        generatedParams = (List) ((DefaultListAdapter) generatedParamsObject).getWrappedObject();
108
      } else {
109
        generatedParams = ((GeneratedParamsTemplateModel) generatedParamsObject).getGeneratedParams();
110
      }
111
      String generatedParamName = "_p" + generatedParams.size();
112
      env.getOut().write(String.format("#{%s}", generatedParamName));
113
      generatedParams.add(value);
114
    } else {
115
      env.getOut().write(String.format("#{%s}", name));
116
    }
117
  }
118
}
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