View Javadoc
1   /*
2    *    Copyright 2006-2023 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.generator.internal.rules;
17  
18  import org.mybatis.generator.api.IntrospectedTable;
19  import org.mybatis.generator.api.IntrospectedTable.TargetRuntime;
20  import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
21  import org.mybatis.generator.codegen.mybatis3.ListUtilities;
22  import org.mybatis.generator.config.PropertyRegistry;
23  import org.mybatis.generator.config.TableConfiguration;
24  import org.mybatis.generator.internal.util.StringUtility;
25  
26  /**
27   * This class centralizes all the rules related to code generation - including
28   * the methods and objects to create, and certain attributes related to those
29   * objects.
30   *
31   * @author Jeff Butler
32   */
33  public abstract class BaseRules implements Rules {
34  
35      protected final TableConfiguration tableConfiguration;
36  
37      protected final IntrospectedTable introspectedTable;
38  
39      protected final boolean isModelOnly;
40  
41      protected BaseRules(IntrospectedTable introspectedTable) {
42          super();
43          this.introspectedTable = introspectedTable;
44          this.tableConfiguration = introspectedTable.getTableConfiguration();
45          String modelOnly = tableConfiguration.getProperty(PropertyRegistry.TABLE_MODEL_ONLY);
46          isModelOnly = StringUtility.isTrue(modelOnly);
47      }
48  
49      /**
50       * Implements the rule for generating the insert SQL Map element and DAO
51       * method. If the insert statement is allowed, then generate the element and
52       * method.
53       *
54       * @return true if the element and method should be generated
55       */
56      @Override
57      public boolean generateInsert() {
58          if (isModelOnly) {
59              return false;
60          }
61  
62          return tableConfiguration.isInsertStatementEnabled();
63      }
64  
65      /**
66       * Implements the rule for generating the insert selective SQL Map element
67       * and DAO method. If the insert statement is allowed, then generate the
68       * element and method.
69       *
70       * @return true if the element and method should be generated
71       */
72      @Override
73      public boolean generateInsertSelective() {
74          return generateInsert();
75      }
76  
77      /**
78       * Calculates the class that contains all fields. This class is used as the
79       * insert statement parameter, as well as the returned value from the select
80       * by primary key method. The actual class depends on how the domain model
81       * is generated.
82       *
83       * @return the type of the class that holds all fields
84       */
85      @Override
86      public FullyQualifiedJavaType calculateAllFieldsClass() {
87  
88          String answer;
89  
90          if (generateRecordWithBLOBsClass()) {
91              answer = introspectedTable.getRecordWithBLOBsType();
92          } else if (generateBaseRecordClass()) {
93              answer = introspectedTable.getBaseRecordType();
94          } else {
95              answer = introspectedTable.getPrimaryKeyType();
96          }
97  
98          return new FullyQualifiedJavaType(answer);
99      }
100 
101     /**
102      * Implements the rule for generating the update by primary key without
103      * BLOBs SQL Map element and DAO method. If the table has a primary key as
104      * well as other non-BLOB fields, and the updateByPrimaryKey statement is
105      * allowed, then generate the element and method.
106      *
107      * @return true if the element and method should be generated
108      */
109     @Override
110     public boolean generateUpdateByPrimaryKeyWithoutBLOBs() {
111         if (isModelOnly) {
112             return false;
113         }
114 
115         if (ListUtilities.removeGeneratedAlwaysColumns(introspectedTable.getBaseColumns()).isEmpty()) {
116             return false;
117         }
118 
119         return tableConfiguration.isUpdateByPrimaryKeyStatementEnabled()
120                 && introspectedTable.hasPrimaryKeyColumns()
121                 && introspectedTable.hasBaseColumns();
122     }
123 
124     /**
125      * Implements the rule for generating the update by primary key with BLOBs
126      * SQL Map element and DAO method. If the table has a primary key as well as
127      * other BLOB fields, and the updateByPrimaryKey statement is allowed, then
128      * generate the element and method.
129      *
130      * @return true if the element and method should be generated
131      */
132     @Override
133     public boolean generateUpdateByPrimaryKeyWithBLOBs() {
134         if (isModelOnly) {
135             return false;
136         }
137 
138         if (ListUtilities.removeGeneratedAlwaysColumns(introspectedTable.getNonPrimaryKeyColumns()).isEmpty()) {
139             return false;
140         }
141 
142         return tableConfiguration.isUpdateByPrimaryKeyStatementEnabled()
143                 && introspectedTable.hasPrimaryKeyColumns()
144                 && introspectedTable.hasBLOBColumns();
145     }
146 
147     /**
148      * Implements the rule for generating the update by primary key selective
149      * SQL Map element and DAO method. If the table has a primary key as well as
150      * other fields, and the updateByPrimaryKey statement is allowed, then
151      * generate the element and method.
152      *
153      * @return true if the element and method should be generated
154      */
155     @Override
156     public boolean generateUpdateByPrimaryKeySelective() {
157         if (isModelOnly) {
158             return false;
159         }
160 
161         if (ListUtilities.removeGeneratedAlwaysColumns(introspectedTable.getNonPrimaryKeyColumns()).isEmpty()) {
162             return false;
163         }
164 
165         return tableConfiguration.isUpdateByPrimaryKeyStatementEnabled()
166                 && introspectedTable.hasPrimaryKeyColumns()
167                 && (introspectedTable.hasBLOBColumns() || introspectedTable
168                         .hasBaseColumns());
169     }
170 
171     /**
172      * Implements the rule for generating the delete by primary key SQL Map
173      * element and DAO method. If the table has a primary key, and the
174      * deleteByPrimaryKey statement is allowed, then generate the element and
175      * method.
176      *
177      * @return true if the element and method should be generated
178      */
179     @Override
180     public boolean generateDeleteByPrimaryKey() {
181         if (isModelOnly) {
182             return false;
183         }
184 
185         return tableConfiguration.isDeleteByPrimaryKeyStatementEnabled()
186                 && introspectedTable.hasPrimaryKeyColumns();
187     }
188 
189     /**
190      * Implements the rule for generating the delete by example SQL Map element
191      * and DAO method. If the deleteByExample statement is allowed, then
192      * generate the element and method.
193      *
194      * @return true if the element and method should be generated
195      */
196     @Override
197     public boolean generateDeleteByExample() {
198         if (isModelOnly) {
199             return false;
200         }
201 
202         return tableConfiguration.isDeleteByExampleStatementEnabled();
203     }
204 
205     /**
206      * Implements the rule for generating the result map without BLOBs. If
207      * either select method is allowed, then generate the result map.
208      *
209      * @return true if the result map should be generated
210      */
211     @Override
212     public boolean generateBaseResultMap() {
213         if (isModelOnly) {
214             return true;
215         }
216 
217         return tableConfiguration.isSelectByExampleStatementEnabled()
218                 || tableConfiguration.isSelectByPrimaryKeyStatementEnabled();
219     }
220 
221     /**
222      * Implements the rule for generating the result map with BLOBs. If the
223      * table has BLOB columns, and either select method is allowed, then
224      * generate the result map.
225      *
226      * @return true if the result map should be generated
227      */
228     @Override
229     public boolean generateResultMapWithBLOBs() {
230         boolean rc;
231 
232         if (introspectedTable.hasBLOBColumns()) {
233             if (isModelOnly) {
234                 rc = true;
235             } else {
236                 rc = tableConfiguration.isSelectByExampleStatementEnabled()
237                         || tableConfiguration.isSelectByPrimaryKeyStatementEnabled();
238             }
239         } else {
240             rc = false;
241         }
242 
243         return rc;
244     }
245 
246     /**
247      * Implements the rule for generating the SQL example where clause element.
248      *
249      * <p>In MyBatis3, generate the element if the selectByExample,
250      * deleteByExample, or countByExample statements are allowed.
251      *
252      * @return true if the SQL where clause element should be generated
253      */
254     @Override
255     public boolean generateSQLExampleWhereClause() {
256         if (isModelOnly) {
257             return false;
258         }
259 
260         return tableConfiguration.isSelectByExampleStatementEnabled()
261                 || tableConfiguration.isDeleteByExampleStatementEnabled()
262                 || tableConfiguration.isCountByExampleStatementEnabled();
263     }
264 
265     /**
266      * Implements the rule for generating the SQL example where clause element
267      * specifically for use in the update by example methods.
268      *
269      * <p>In MyBatis3, generate the element if the updateByExample statements are
270      * allowed.
271      *
272      * @return true if the SQL where clause element should be generated
273      */
274     @Override
275     public boolean generateMyBatis3UpdateByExampleWhereClause() {
276         if (isModelOnly) {
277             return false;
278         }
279 
280         return introspectedTable.getTargetRuntime() == TargetRuntime.MYBATIS3
281                 && tableConfiguration.isUpdateByExampleStatementEnabled();
282     }
283 
284     /**
285      * Implements the rule for generating the select by primary key SQL Map
286      * element and DAO method. If the table has a primary key as well as other
287      * fields, and the selectByPrimaryKey statement is allowed, then generate
288      * the element and method.
289      *
290      * @return true if the element and method should be generated
291      */
292     @Override
293     public boolean generateSelectByPrimaryKey() {
294         if (isModelOnly) {
295             return false;
296         }
297 
298         return tableConfiguration.isSelectByPrimaryKeyStatementEnabled()
299                 && introspectedTable.hasPrimaryKeyColumns()
300                 && (introspectedTable.hasBaseColumns() || introspectedTable
301                         .hasBLOBColumns());
302     }
303 
304     /**
305      * Implements the rule for generating the select by example without BLOBs
306      * SQL Map element and DAO method. If the selectByExample statement is
307      * allowed, then generate the element and method.
308      *
309      * @return true if the element and method should be generated
310      */
311     @Override
312     public boolean generateSelectByExampleWithoutBLOBs() {
313         if (isModelOnly) {
314             return false;
315         }
316 
317         return tableConfiguration.isSelectByExampleStatementEnabled();
318     }
319 
320     /**
321      * Implements the rule for generating the select by example with BLOBs SQL
322      * Map element and DAO method. If the table has BLOB fields and the
323      * selectByExample statement is allowed, then generate the element and
324      * method.
325      *
326      * @return true if the element and method should be generated
327      */
328     @Override
329     public boolean generateSelectByExampleWithBLOBs() {
330         if (isModelOnly) {
331             return false;
332         }
333 
334         return tableConfiguration.isSelectByExampleStatementEnabled()
335                 && introspectedTable.hasBLOBColumns();
336     }
337 
338     /**
339      * Implements the rule for generating an example class. The class should be
340      * generated if the selectByExample or deleteByExample or countByExample
341      * methods are allowed.
342      *
343      * @return true if the example class should be generated
344      */
345     @Override
346     public boolean generateExampleClass() {
347         if (introspectedTable.getContext().getSqlMapGeneratorConfiguration() == null
348                 && introspectedTable.getContext().getJavaClientGeneratorConfiguration() == null) {
349             // this is a model only context - don't generate the example class
350             return false;
351         }
352 
353         if (isModelOnly) {
354             return false;
355         }
356 
357         return tableConfiguration.isSelectByExampleStatementEnabled()
358                 || tableConfiguration.isDeleteByExampleStatementEnabled()
359                 || tableConfiguration.isCountByExampleStatementEnabled()
360                 || tableConfiguration.isUpdateByExampleStatementEnabled();
361     }
362 
363     @Override
364     public boolean generateCountByExample() {
365         if (isModelOnly) {
366             return false;
367         }
368 
369         return tableConfiguration.isCountByExampleStatementEnabled();
370     }
371 
372     @Override
373     public boolean generateUpdateByExampleSelective() {
374         if (isModelOnly) {
375             return false;
376         }
377 
378         return tableConfiguration.isUpdateByExampleStatementEnabled();
379     }
380 
381     @Override
382     public boolean generateUpdateByExampleWithoutBLOBs() {
383         if (isModelOnly) {
384             return false;
385         }
386 
387         return tableConfiguration.isUpdateByExampleStatementEnabled()
388                 && (introspectedTable.hasPrimaryKeyColumns() || introspectedTable
389                         .hasBaseColumns());
390     }
391 
392     @Override
393     public boolean generateUpdateByExampleWithBLOBs() {
394         if (isModelOnly) {
395             return false;
396         }
397 
398         return tableConfiguration.isUpdateByExampleStatementEnabled()
399                 && introspectedTable.hasBLOBColumns();
400     }
401 
402     @Override
403     public IntrospectedTable getIntrospectedTable() {
404         return introspectedTable;
405     }
406 
407     @Override
408     public boolean generateBaseColumnList() {
409         if (isModelOnly) {
410             return false;
411         }
412 
413         return generateSelectByPrimaryKey()
414                 || generateSelectByExampleWithoutBLOBs();
415     }
416 
417     @Override
418     public boolean generateBlobColumnList() {
419         if (isModelOnly) {
420             return false;
421         }
422 
423         return introspectedTable.hasBLOBColumns()
424                 && (tableConfiguration.isSelectByExampleStatementEnabled() || tableConfiguration
425                         .isSelectByPrimaryKeyStatementEnabled());
426     }
427 
428     @Override
429     public boolean generateJavaClient() {
430         return !isModelOnly;
431     }
432 }