View Javadoc
1   /*
2    *    Copyright 2018-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 org.mybatis.scripting.thymeleaf;
17  
18  import java.util.Arrays;
19  import java.util.HashSet;
20  import java.util.Optional;
21  import java.util.Set;
22  
23  import org.mybatis.scripting.thymeleaf.expression.Likes;
24  import org.mybatis.scripting.thymeleaf.processor.BindVariableRender;
25  import org.mybatis.scripting.thymeleaf.processor.MyBatisBindTagProcessor;
26  import org.mybatis.scripting.thymeleaf.processor.MyBatisParamTagProcessor;
27  import org.thymeleaf.context.IExpressionContext;
28  import org.thymeleaf.dialect.AbstractProcessorDialect;
29  import org.thymeleaf.dialect.IExpressionObjectDialect;
30  import org.thymeleaf.expression.IExpressionObjectFactory;
31  import org.thymeleaf.processor.IProcessor;
32  import org.thymeleaf.standard.StandardDialect;
33  import org.thymeleaf.templatemode.TemplateMode;
34  
35  /**
36   * The Dialect for integrating with MyBatis. <br>
37   * This dialect provides following features. This dialect prefix is {@code "mb"} by default.
38   * <ul>
39   * <li>{@code #likes} expression : {@link Likes}</li>
40   * <li>{@code mb:p} attribute tag: {@link MyBatisParamTagProcessor}</li>
41   * <li>{@code mb:bind} attribute tag : {@link MyBatisBindTagProcessor}</li>
42   * </ul>
43   *
44   * @author Kazuki Shimizu
45   *
46   * @version 1.0.0
47   */
48  public class MyBatisDialect extends AbstractProcessorDialect implements IExpressionObjectDialect {
49  
50    private static final String DEFAULT_PREFIX = "mb";
51  
52    private Likes likes = Likes.newBuilder().build();
53  
54    private BindVariableRender bindVariableRender;
55  
56    /**
57     * Default constructor.
58     */
59    public MyBatisDialect() {
60      this(DEFAULT_PREFIX);
61    }
62  
63    /**
64     * Constructor that can be specified the dialect prefix.
65     *
66     * @param prefix
67     *          A dialect prefix
68     */
69    public MyBatisDialect(String prefix) {
70      super("MyBatis Dialect", prefix, StandardDialect.PROCESSOR_PRECEDENCE);
71    }
72  
73    /**
74     * Set an expression utility object that provide helper method for like feature. <br>
75     *
76     * @param likes
77     *          An expression utility object that provide helper method for like feature
78     */
79    public void setLikes(Likes likes) {
80      this.likes = likes;
81    }
82  
83    /**
84     * Set a bind variable render.
85     *
86     * @param bindVariableRender
87     *          a bind variable render
88     *
89     * @since 1.0.2
90     */
91    public void setBindVariableRender(BindVariableRender bindVariableRender) {
92      this.bindVariableRender = bindVariableRender;
93    }
94  
95    /**
96     * {@inheritDoc}
97     */
98    @Override
99    public Set<IProcessor> getProcessors(String dialectPrefix) {
100     return new HashSet<>(Arrays.asList(new MyBatisBindTagProcessor(TemplateMode.TEXT, dialectPrefix),
101         new MyBatisBindTagProcessor(TemplateMode.CSS, dialectPrefix),
102         configure(new MyBatisParamTagProcessor(TemplateMode.TEXT, dialectPrefix)),
103         configure(new MyBatisParamTagProcessor(TemplateMode.CSS, dialectPrefix))));
104   }
105 
106   private MyBatisParamTagProcessor configure(MyBatisParamTagProcessor processor) {
107     Optional.ofNullable(bindVariableRender).ifPresent(processor::setBindVariableRender);
108     return processor;
109   }
110 
111   /**
112    * {@inheritDoc}
113    */
114   @Override
115   public IExpressionObjectFactory getExpressionObjectFactory() {
116     return new MyBatisExpressionObjectFactory();
117   }
118 
119   private class MyBatisExpressionObjectFactory implements IExpressionObjectFactory {
120 
121     /**
122      * {@inheritDoc}
123      */
124     @Override
125     public Set<String> getAllExpressionObjectNames() {
126       return Set.of("likes");
127     }
128 
129     /**
130      * {@inheritDoc}
131      */
132     @Override
133     public Object buildObject(IExpressionContext context, String expressionObjectName) {
134       return likes;
135     }
136 
137     /**
138      * {@inheritDoc}
139      */
140     @Override
141     public boolean isCacheable(String expressionObjectName) {
142       return true;
143     }
144 
145   }
146 
147 }