JavaBeansUtil.java
/*
* Copyright 2006-2026 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mybatis.generator.internal.util;
import java.util.Locale;
import java.util.Set;
import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.CompilationUnit;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.config.PropertyRegistry;
public class JavaBeansUtil {
private JavaBeansUtil() {
super();
}
/**
* Calculates a getter method name. Java record "getters" have a different naming convention.
*
* @param introspectedColumn the column
* @return the calculated getter method name (no parenthesis)
*/
public static String getCallingGetterMethodName(IntrospectedColumn introspectedColumn) {
if (introspectedColumn.getIntrospectedTable().isRecordBased()) {
return introspectedColumn.getJavaProperty();
} else {
return getGetterMethodName(introspectedColumn.getJavaProperty(),
introspectedColumn.getFullyQualifiedJavaType());
}
}
/**
* Computes a getter method name. Warning - does not check to see that the property is a valid
* property. Call getValidPropertyName first.
*
* @param property
* the property
* @param fullyQualifiedJavaType
* the fully qualified java type
* @return the getter method name
*/
public static String getGetterMethodName(String property, FullyQualifiedJavaType fullyQualifiedJavaType) {
String prefix;
if (fullyQualifiedJavaType.equals(FullyQualifiedJavaType
.getBooleanPrimitiveInstance())) {
prefix = "is"; //$NON-NLS-1$
} else {
prefix = "get"; //$NON-NLS-1$
}
return prefix + uppercaseFirstLetterIfNecessary(property);
}
public static String uppercaseFirstLetterIfNecessary(String property) {
StringBuilder sb = new StringBuilder(property);
if (Character.isLowerCase(sb.charAt(0))
&& (sb.length() == 1 || !Character.isUpperCase(sb.charAt(1)))) {
sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
}
return sb.toString();
}
/**
* Computes a setter method name. Warning - does not check to see that the property is a valid
* property. Call getValidPropertyName first.
*
* @param property
* the property
*
* @return the setter method name
*/
public static String getSetterMethodName(String property) {
return "set" + uppercaseFirstLetterIfNecessary(property); //$NON-NLS-1$
}
public static String getFirstCharacterUppercase(String inputString) {
StringBuilder sb = new StringBuilder(inputString);
sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
return sb.toString();
}
public static String getCamelCaseString(String inputString, boolean firstCharacterUppercase) {
StringBuilder sb = new StringBuilder();
boolean nextUpperCase = false;
for (int i = 0; i < inputString.length(); i++) {
char c = inputString.charAt(i);
switch (c) {
case '_', '-', '@', '$', '#', ' ', '/', '&':
if (!sb.isEmpty()) {
nextUpperCase = true;
}
break;
default:
if (nextUpperCase) {
sb.append(Character.toUpperCase(c));
nextUpperCase = false;
} else {
sb.append(Character.toLowerCase(c));
}
break;
}
}
if (firstCharacterUppercase) {
sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
}
return sb.toString();
}
/**
* This method ensures that the specified input string is a valid Java property name.
*
* <p>The rules are as follows:
*
* <ol>
* <li>If the first character is lower case, then OK</li>
* <li>If the first two characters are upper case, then OK</li>
* <li>If the first character is upper case, and the second character is lower case, then the first character
* should be made lower case</li>
* </ol>
*
* <p>For example:
*
* <ul>
* <li>eMail > eMail</li>
* <li>firstName > firstName</li>
* <li>URL > URL</li>
* <li>XAxis > XAxis</li>
* <li>a > a</li>
* <li>B > b</li>
* <li>Yaxis > yaxis</li>
* </ul>
*
* @param inputString
* the input string
* @return the valid property name
*/
public static String getValidPropertyName(String inputString) {
String answer;
if (inputString.length() < 2) {
answer = inputString.toLowerCase(Locale.US);
} else {
if (Character.isUpperCase(inputString.charAt(0))
&& !Character.isUpperCase(inputString.charAt(1))) {
answer = inputString.substring(0, 1).toLowerCase(Locale.US)
+ inputString.substring(1);
} else {
answer = inputString;
}
}
return answer;
}
public static Method getJavaBeansGetter(IntrospectedColumn introspectedColumn, CommentGenerator commentGenerator,
IntrospectedTable introspectedTable,
Set<FullyQualifiedJavaType> importedTypes) {
Method method = getBasicJavaBeansGetter(introspectedColumn);
commentGenerator.addGeneralMethodAnnotation(method, introspectedTable, introspectedColumn, importedTypes);
return method;
}
public static Method getJavaBeansGetterWithGeneratedAnnotation(IntrospectedColumn introspectedColumn,
CommentGenerator commentGenerator,
IntrospectedTable introspectedTable,
CompilationUnit compilationUnit) {
Method method = getBasicJavaBeansGetter(introspectedColumn);
commentGenerator.addGeneralMethodAnnotation(method, introspectedTable, introspectedColumn,
compilationUnit.getImportedTypes());
return method;
}
private static Method getBasicJavaBeansGetter(IntrospectedColumn introspectedColumn) {
FullyQualifiedJavaType fqjt = introspectedColumn
.getFullyQualifiedJavaType();
String property = introspectedColumn.getJavaProperty();
Method method = new Method(getGetterMethodName(property, fqjt));
method.setVisibility(JavaVisibility.PUBLIC);
method.setReturnType(fqjt);
String s = "return " + property + ';'; //$NON-NLS-1$
method.addBodyLine(s);
return method;
}
public static Field getJavaBeansField(IntrospectedColumn introspectedColumn, CommentGenerator commentGenerator,
IntrospectedTable introspectedTable,
Set<FullyQualifiedJavaType> importedTypes) {
Field field = getBasicJavaBeansField(introspectedColumn);
commentGenerator.addFieldAnnotation(field, introspectedTable, introspectedColumn, importedTypes);
return field;
}
public static Field getJavaBeansFieldWithGeneratedAnnotation(IntrospectedColumn introspectedColumn,
CommentGenerator commentGenerator,
IntrospectedTable introspectedTable,
CompilationUnit compilationUnit) {
Field field = getBasicJavaBeansField(introspectedColumn);
commentGenerator.addFieldAnnotation(field, introspectedTable, introspectedColumn,
compilationUnit.getImportedTypes());
return field;
}
private static Field getBasicJavaBeansField(IntrospectedColumn introspectedColumn) {
FullyQualifiedJavaType fqjt = introspectedColumn
.getFullyQualifiedJavaType();
String property = introspectedColumn.getJavaProperty();
Field field = new Field(property, fqjt);
field.setVisibility(JavaVisibility.PRIVATE);
return field;
}
public static Method getJavaBeansSetter(IntrospectedColumn introspectedColumn,
CommentGenerator commentGenerator, IntrospectedTable introspectedTable,
Set<FullyQualifiedJavaType> importedTypes) {
Method method = getBasicJavaBeansSetter(introspectedColumn);
commentGenerator.addGeneralMethodAnnotation(method, introspectedTable, introspectedColumn, importedTypes);
return method;
}
public static Method getJavaBeansSetterWithGeneratedAnnotation(IntrospectedColumn introspectedColumn,
CommentGenerator commentGenerator,
IntrospectedTable introspectedTable,
CompilationUnit compilationUnit) {
Method method = getBasicJavaBeansSetter(introspectedColumn);
commentGenerator.addGeneralMethodAnnotation(method, introspectedTable, introspectedColumn,
compilationUnit.getImportedTypes());
return method;
}
public static String generateFieldSetterForConstructor(IntrospectedColumn introspectedColumn) {
return "this." //$NON-NLS-1$
+ introspectedColumn.getJavaProperty()
+ " = " //$NON-NLS-1$
+ introspectedColumn.getJavaProperty()
+ ';';
}
private static Method getBasicJavaBeansSetter(IntrospectedColumn introspectedColumn) {
FullyQualifiedJavaType fqjt = introspectedColumn
.getFullyQualifiedJavaType();
String property = introspectedColumn.getJavaProperty();
Method method = new Method(getSetterMethodName(property));
method.setVisibility(JavaVisibility.PUBLIC);
method.addParameter(new Parameter(fqjt, property));
StringBuilder sb = new StringBuilder();
if (introspectedColumn.isStringColumn() && isTrimStringsEnabled(introspectedColumn)) {
sb.append("this."); //$NON-NLS-1$
sb.append(property);
sb.append(" = "); //$NON-NLS-1$
sb.append(property);
sb.append(" == null ? null : "); //$NON-NLS-1$
sb.append(property);
sb.append(".trim();"); //$NON-NLS-1$
method.addBodyLine(sb.toString());
} else {
sb.append("this."); //$NON-NLS-1$
sb.append(property);
sb.append(" = "); //$NON-NLS-1$
sb.append(property);
sb.append(';');
method.addBodyLine(sb.toString());
}
return method;
}
private static boolean isTrimStringsEnabled(IntrospectedTable table) {
return table.findTableOrModelGeneratorProperty(PropertyRegistry.MODEL_GENERATOR_TRIM_STRINGS)
.map(Boolean::parseBoolean)
.orElse(false);
}
private static boolean isTrimStringsEnabled(IntrospectedColumn column) {
String trimSpaces = column.getProperties().getProperty(PropertyRegistry.MODEL_GENERATOR_TRIM_STRINGS);
if (trimSpaces != null) {
return Boolean.parseBoolean(trimSpaces);
}
return isTrimStringsEnabled(column.getIntrospectedTable());
}
}