EnumNamingStrategies.java
package com.fasterxml.jackson.databind;
import java.util.Locale;
import com.fasterxml.jackson.databind.util.NamingStrategyImpls;
/**
* A container class for implementations of the {@link EnumNamingStrategy} interface.
*
* @since 2.15
*/
public class EnumNamingStrategies
{
private EnumNamingStrategies() {}
/**
* Words other than first are capitalized and no separator is used between words.
* See {@link EnumNamingStrategies.LowerCamelCaseStrategy} for details.
* <p>
* Example "ENUM_NAME" would be converted to "enumName".
*
* @since 2.19
*/
public static final EnumNamingStrategy LOWER_CAMEL_CASE = LowerCamelCaseStrategy.INSTANCE;
/**
* Naming convention used in languages like Pascal, where all words are capitalized and no separator is used between
* words.
* See {@link EnumNamingStrategies.UpperCamelCaseStrategy} for details.
* <p>
* Example "ENUM_NAME" would be converted to "EnumName".
*
* @since 2.19
*/
public static final EnumNamingStrategy UPPER_CAMEL_CASE = UpperCamelCaseStrategy.INSTANCE;
/**
* Naming convention used in languages like C, where words are in lower-case letters, separated by underscores.
* See {@link EnumNamingStrategies.SnakeCaseStrategy} for details.
* <p>
* Example "ENUM_NAME" would be converted to "enum_name".
*
* @since 2.19
*/
public static final EnumNamingStrategy SNAKE_CASE = SnakeCaseStrategy.INSTANCE;
/**
* Naming convention in which the words are in upper-case letters, separated by underscores.
* See {@link EnumNamingStrategies.UpperSnakeCaseStrategy} for details.
* <p>
* Example "ENUM_NAME" would be converted to "ENUM_NAME", but "__ENUM_NAME_" would also be converted to "ENUM_NAME".
*
* @since 2.19
*/
public static final EnumNamingStrategy UPPER_SNAKE_CASE = UpperSnakeCaseStrategy.INSTANCE;
/**
* Naming convention in which all words of the logical name are in lower case, and no separator is used between words.
* See {@link EnumNamingStrategies.LowerCaseStrategy} for details.
* <p>
* Example "ENUM_NAME" would be converted to "enumname".
*
* @since 2.19
*/
public static final EnumNamingStrategy LOWER_CASE = LowerCaseStrategy.INSTANCE;
/**
* Naming convention used in languages like Lisp, where words are in lower-case letters, separated by hyphens.
* See {@link EnumNamingStrategies.KebabCaseStrategy} for details.
* <p>
* Example "ENUM_NAME" would be converted to "enum-name".
*
* @since 2.19
*/
public static final EnumNamingStrategy KEBAB_CASE = KebabCaseStrategy.INSTANCE;
/**
* Naming convention widely used as configuration properties name, where words are in lower-case letters,
* separated by dots.
* See {@link EnumNamingStrategies.LowerDotCaseStrategy} for details.
* <p>
* Example "ENUM_NAME" would be converted to "enum.name".
*
* @since 2.19
*/
public static final EnumNamingStrategy LOWER_DOT_CASE = LowerDotCaseStrategy.INSTANCE;
public abstract static class DelegatingEnumNamingStrategy implements EnumNamingStrategy {
private final NamingStrategyImpls strategy;
protected DelegatingEnumNamingStrategy(NamingStrategyImpls strategy) {
this.strategy = strategy;
}
@Override
public String convertEnumToExternalName(String enumName) {
return strategy.translate(toBeanName(enumName));
}
/**
* Normalizes the enum name to lower camel case in order to be further processed by a NamingStrategies
*
* @param enumName the enum name to be normalized
* @return the normalized enum name
*/
protected static String toBeanName(String enumName) {
if (enumName == null) {
return null;
}
final String UNDERSCORE = "_";
StringBuilder out = null;
int iterationCnt = 0;
int lastSeparatorIdx = -1;
do {
lastSeparatorIdx = nextIndexOfUnderscore(enumName, lastSeparatorIdx + 1);
if (lastSeparatorIdx != -1) {
if (iterationCnt == 0) {
out = new StringBuilder(enumName.length() + 4 * UNDERSCORE.length());
out.append(enumName.substring(iterationCnt, lastSeparatorIdx).toLowerCase(Locale.ROOT));
} else {
out.append(normalizeWord(enumName.substring(iterationCnt, lastSeparatorIdx)));
}
iterationCnt = lastSeparatorIdx + UNDERSCORE.length();
}
} while (lastSeparatorIdx != -1);
if (iterationCnt == 0) {
return enumName.toLowerCase(Locale.ROOT);
}
out.append(normalizeWord(enumName.substring(iterationCnt)));
return out.toString();
}
private static int nextIndexOfUnderscore(CharSequence sequence, int start) {
int length = sequence.length();
for (int i = start; i < length; i++) {
if ('_' == sequence.charAt(i)) {
return i;
}
}
return -1;
}
/**
* Converts the first letter of the word to uppercase and the rest of the word to lowercase.
*/
private static String normalizeWord(String word) {
int length = word.length();
if (length == 0) {
return word;
}
return Character.toUpperCase(word.charAt(0)) + word.substring(1).toLowerCase();
}
}
/**
* @since 2.15
* @deprecated Since 2.19 use {@link LowerCamelCaseStrategy} instead.
*/
@Deprecated
public static class CamelCaseStrategy extends DelegatingEnumNamingStrategy {
/**
* An instance of {@link CamelCaseStrategy} for reuse.
*
* @since 2.15
*/
public static final CamelCaseStrategy INSTANCE = new CamelCaseStrategy();
protected CamelCaseStrategy() {
super(NamingStrategyImpls.LOWER_CAMEL_CASE);
}
}
/**
* <p>
* An implementation of {@link EnumNamingStrategy} that converts enum names in the typical upper
* snake case format to lower camel case format. This implementation follows three rules
* described below.
*
* <ol>
* <li>converts any character preceded by an underscore into upper case character,
* regardless of its original case (upper or lower).</li>
* <li>converts any character NOT preceded by an underscore into a lower case character,
* regardless of its original case (upper or lower).</li>
* <li>removes all underscores.</li>
* </ol>
* <p>
* WARNING: Naming conversion conflicts caused by underscore usage should be handled by client.
* e.g. Both <code>PEANUT_BUTTER</code>, <code>PEANUT__BUTTER</code> are converted into "peanutButter".
* And "peanutButter" will be deserialized into enum with smaller <code>Enum.ordinal()</code> value.
*
* <p>
* This results in the following example conversions:
* <ul>
* <li>"USER_NAME" is converted into "userName"</li>
* <li>"USER______NAME" is converted into "userName"</li>
* <li>"USERNAME" is converted into "username"</li>
* <li>"User__Name" is converted into "userName"</li>
* <li>"_user_name" is converted into "UserName"</li>
* <li>"_user_name_s" is converted into "UserNameS"</li>
* <li>"__Username" is converted into "Username"</li>
* <li>"__username" is converted into "Username"</li>
* <li>"username" is converted into "username"</li>
* <li>"Username" is converted into "username"</li>
* </ul>
*
* @since 2.19
*/
public static class LowerCamelCaseStrategy extends DelegatingEnumNamingStrategy {
/**
* An instance of {@link LowerCamelCaseStrategy} for reuse.
*
* @since 2.19
*/
public static final LowerCamelCaseStrategy INSTANCE = new LowerCamelCaseStrategy();
protected LowerCamelCaseStrategy() {
super(NamingStrategyImpls.LOWER_CAMEL_CASE);
}
}
/**
* <p>
* An implementation of {@link EnumNamingStrategy} that converts enum names in the typical upper
* snake case format to upper camel case format.
* This implementation first normalizes to lower camel case using (see {@link LowerCamelCaseStrategy} for details)
* and then uses {@link PropertyNamingStrategies.UpperCamelCaseStrategy} to finish converting the name.
* <p>
* WARNING: Naming conversion conflicts caused by underscore usage should be handled by client.
* e.g. Both <code>PEANUT_BUTTER</code>, <code>PEANUT__BUTTER</code> are converted into "PeanutButter".
* And "PeanutButter" will be deserialized into enum with smaller <code>Enum.ordinal()</code> value.
*
* <p>
* This results in the following example conversions:
* <ul>
* <li>"USER_NAME" is converted into "UserName"</li>
* <li>"USER______NAME" is converted into "UserName"</li>
* <li>"USERNAME" is converted into "Username"</li>
* <li>"User__Name" is converted into "UserName"</li>
* <li>"_user_name" is converted into "UserName"</li>
* <li>"_user_name_s" is converted into "UserNameS"</li>
* <li>"__Username" is converted into "Username"</li>
* <li>"__username" is converted into "Username"</li>
* <li>"username" is converted into "Username"</li>
* <li>"Username" is converted into "Username"</li>
* </ul>
*
* @since 2.19
*/
public static class UpperCamelCaseStrategy extends DelegatingEnumNamingStrategy {
/**
* An instance of {@link LowerCamelCaseStrategy} for reuse.
*
* @since 2.19
*/
public static final UpperCamelCaseStrategy INSTANCE = new UpperCamelCaseStrategy();
protected UpperCamelCaseStrategy() {
super(NamingStrategyImpls.UPPER_CAMEL_CASE);
}
}
/**
* <p>
* An implementation of {@link EnumNamingStrategy} that converts enum names in the typical upper
* snake case format to upper camel case format.
* This implementation first normalizes to lower camel case using (see {@link LowerCamelCaseStrategy} for details)
* and then uses {@link PropertyNamingStrategies.SnakeCaseStrategy} to finish converting the name.
* <p>
* WARNING: Naming conversion conflicts caused by underscore usage should be handled by client.
* e.g. Both <code>PEANUT_BUTTER</code>, <code>PEANUT__BUTTER</code> are converted into "peanut_butter".
* And "peanut_butter" will be deserialized into enum with smaller <code>Enum.ordinal()</code> value.
*
* <p>
* This results in the following example conversions:
* <ul>
* <li>"USER_NAME" is converted into "user_name"</li>
* <li>"USER______NAME" is converted into "user_name"</li>
* <li>"USERNAME" is converted into "username"</li>
* <li>"User__Name" is converted into "user_name"</li>
* <li>"_user_name" is converted into "user_name"</li>
* <li>"_user_name_s" is converted into "user_name_s"</li>
* <li>"__Username" is converted into "username"</li>
* <li>"__username" is converted into "username"</li>
* <li>"username" is converted into "username"</li>
* <li>"Username" is converted into "username"</li>
* </ul>
*
* @since 2.19
*/
public static class SnakeCaseStrategy extends DelegatingEnumNamingStrategy {
/**
* An instance of {@link SnakeCaseStrategy} for reuse.
*
* @since 2.19
*/
public static final SnakeCaseStrategy INSTANCE = new SnakeCaseStrategy();
protected SnakeCaseStrategy() {
super(NamingStrategyImpls.SNAKE_CASE);
}
}
/**
* <p>
* An implementation of {@link EnumNamingStrategy} that converts enum names in the typical upper
* snake case format to upper camel case format.
* This implementation first normalizes to lower camel case using (see {@link LowerCamelCaseStrategy} for details)
* and then uses {@link PropertyNamingStrategies.UpperSnakeCaseStrategy} to finish converting the name.
* <p>
* WARNING: Naming conversion conflicts caused by underscore usage should be handled by client.
* e.g. Both <code>PEANUT_BUTTER</code>, <code>PEANUT__BUTTER</code> are converted into "PEANUT_BUTTER".
* And "PEANUT_BUTTER" will be deserialized into enum with smaller <code>Enum.ordinal()</code> value.
*
* <p>
* This results in the following example conversions:
* <ul>
* <li>"USER_NAME" is converted into "USER_NAME"</li>
* <li>"USER______NAME" is converted into "USER_NAME"</li>
* <li>"USERNAME" is converted into "USERNAME"</li>
* <li>"User__Name" is converted into "USER_NAME"</li>
* <li>"_user_name" is converted into "USER_NAME"</li>
* <li>"_user_name_s" is converted into "USER_NAME_S"</li>
* <li>"__Username" is converted into "USERNAME"</li>
* <li>"__username" is converted into "USERNAME"</li>
* <li>"username" is converted into "USERNAME"</li>
* <li>"Username" is converted into "USERNAME"</li>
* </ul>
*
* @since 2.19
*/
public static class UpperSnakeCaseStrategy extends DelegatingEnumNamingStrategy {
/**
* An instance of {@link UpperSnakeCaseStrategy} for reuse.
*
* @since 2.19
*/
public static final UpperSnakeCaseStrategy INSTANCE = new UpperSnakeCaseStrategy();
protected UpperSnakeCaseStrategy() {
super(NamingStrategyImpls.UPPER_SNAKE_CASE);
}
}
/**
* <p>
* An implementation of {@link EnumNamingStrategy} that converts enum names in the typical upper
* snake case format to upper camel case format.
* This implementation first normalizes to lower camel case using (see {@link LowerCamelCaseStrategy} for details)
* and then uses {@link PropertyNamingStrategies.LowerCaseStrategy} to finish converting the name.
* <p>
* WARNING: Naming conversion conflicts caused by underscore usage should be handled by client.
* e.g. Both <code>PEANUT_BUTTER</code>, <code>PEANUT__BUTTER</code> are converted into "peanutbutter".
* And "peanutbutter" will be deserialized into enum with smaller <code>Enum.ordinal()</code> value.
*
* <p>
* This results in the following example conversions:
* <ul>
* <li>"USER_NAME" is converted into "username"</li>
* <li>"USER______NAME" is converted into "username"</li>
* <li>"USERNAME" is converted into "username"</li>
* <li>"User__Name" is converted into "username"</li>
* <li>"_user_name" is converted into "username"</li>
* <li>"_user_name_s" is converted into "usernames"</li>
* <li>"__Username" is converted into "username"</li>
* <li>"__username" is converted into "username"</li>
* <li>"username" is converted into "username"</li>
* <li>"Username" is converted into "username"</li>
* </ul>
*
* @since 2.19
*/
public static class LowerCaseStrategy extends DelegatingEnumNamingStrategy {
/**
* An instance of {@link LowerCaseStrategy} for reuse.
*
* @since 2.19
*/
public static final LowerCaseStrategy INSTANCE = new LowerCaseStrategy();
protected LowerCaseStrategy() {
super(NamingStrategyImpls.LOWER_CASE);
}
}
/**
* <p>
* An implementation of {@link EnumNamingStrategy} that converts enum names in the typical upper
* snake case format to upper camel case format.
* This implementation first normalizes to lower camel case using (see {@link LowerCamelCaseStrategy} for details)
* and then uses {@link PropertyNamingStrategies.KebabCaseStrategy} to finish converting the name.
* <p>
* WARNING: Naming conversion conflicts caused by underscore usage should be handled by client.
* e.g. Both <code>PEANUT_BUTTER</code>, <code>PEANUT__BUTTER</code> are converted into "peanut-butter".
* And "peanut-butter" will be deserialized into enum with smaller <code>Enum.ordinal()</code> value.
*
* <p>
* This results in the following example conversions:
* <ul>
* <li>"USER_NAME" is converted into "user-name"</li>
* <li>"USER______NAME" is converted into "user-name"</li>
* <li>"USERNAME" is converted into "username"</li>
* <li>"User__Name" is converted into "user-name"</li>
* <li>"_user_name" is converted into "user-name"</li>
* <li>"_user_name_s" is converted into "user-name-s"</li>
* <li>"__Username" is converted into "username"</li>
* <li>"__username" is converted into "username"</li>
* <li>"username" is converted into "username"</li>
* <li>"Username" is converted into "username"</li>
* </ul>
*
* @since 2.19
*/
public static class KebabCaseStrategy extends DelegatingEnumNamingStrategy {
/**
* An instance of {@link KebabCaseStrategy} for reuse.
*
* @since 2.19
*/
public static final KebabCaseStrategy INSTANCE = new KebabCaseStrategy();
protected KebabCaseStrategy() {
super(NamingStrategyImpls.KEBAB_CASE);
}
}
/**
* <p>
* An implementation of {@link EnumNamingStrategy} that converts enum names in the typical upper
* snake case format to lower dot case format.
* This implementation first normalizes to lower camel case using (see {@link LowerCamelCaseStrategy} for details)
* and then uses {@link PropertyNamingStrategies.LowerDotCaseStrategy} to finish converting the name.
* <p>
* WARNING: Naming conversion conflicts caused by underscore usage should be handled by client.
* e.g. Both <code>PEANUT_BUTTER</code>, <code>PEANUT__BUTTER</code> are converted into "peanut.butter".
* And "peanut.butter" will be deserialized into enum with smaller <code>Enum.ordinal()</code> value.
*
* <p>
* This results in the following example conversions:
* <ul>
* <li>"USER_NAME" is converted into "user.name"</li>
* <li>"USER______NAME" is converted into "user.name"</li>
* <li>"USERNAME" is converted into "username"</li>
* <li>"User__Name" is converted into "user.name"</li>
* <li>"_user_name" is converted into "user.name"</li>
* <li>"_user_name_s" is converted into "user.name.s"</li>
* <li>"__Username" is converted into "username"</li>
* <li>"__username" is converted into "username"</li>
* <li>"username" is converted into "username"</li>
* <li>"Username" is converted into "username"</li>
* </ul>
*
* @since 2.19
*/
public static class LowerDotCaseStrategy extends DelegatingEnumNamingStrategy {
/**
* An instance of {@link LowerDotCaseStrategy} for reuse.
*
* @since 2.19
*/
public static final LowerDotCaseStrategy INSTANCE = new LowerDotCaseStrategy();
protected LowerDotCaseStrategy() {
super(NamingStrategyImpls.LOWER_DOT_CASE);
}
}
}