/* * Copyright (C) 2006 Google Inc. * * 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 * * http://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 com.google.common.base; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Utility class for converting between various case formats. * * @author Mike Bostock * @since 2009.09.15 <b>tentative</b> */ public enum CaseFormat { /** * Hyphenated variable naming convention, e.g., "lower-hyphen". */ LOWER_HYPHEN(Pattern.compile("[-]"), "-"), /** * C++ variable naming convention, e.g., "lower_underscore". */ LOWER_UNDERSCORE(Pattern.compile("[_]"), "_"), /** * Java variable naming convention, e.g., "lowerCamel". */ LOWER_CAMEL(Pattern.compile("[A-Z]"), ""), /** * Java and C++ class naming convention, e.g., "UpperCamel". */ UPPER_CAMEL(Pattern.compile("[A-Z]"), ""), /** * Java and C++ constant naming convention, e.g., "UPPER_UNDERSCORE". */ UPPER_UNDERSCORE(Pattern.compile("[_]"), "_"); private final Pattern wordBoundary; private final String wordSeparator; private CaseFormat(Pattern wordBoundary, String wordSeparator) { this.wordBoundary = wordBoundary; this.wordSeparator = wordSeparator; } /** * Converts the specified {@code String s} from this format to the specified * {@code format}. A "best effort" approach is taken; if {@code s} does not * conform to the assumed format, then the behavior of this method is * undefined but we make a reasonable effort at converting anyway. */ public String to(CaseFormat format, String s) { if (format == null) { throw new NullPointerException(); } if (s == null) { throw new NullPointerException(); } /* optimize case where no conversion is required */ if (format == this) { return s; } /* optimize cases where no camel conversion is required */ switch (this) { case LOWER_HYPHEN: switch (format) { case LOWER_UNDERSCORE: return s.replace("-", "_"); case UPPER_UNDERSCORE: return s.replace("-", "_").toUpperCase(Locale.US); } break; case LOWER_UNDERSCORE: switch (format) { case LOWER_HYPHEN: return s.replace("_", "-"); case UPPER_UNDERSCORE: return s.toUpperCase(Locale.US); } break; case UPPER_UNDERSCORE: switch (format) { case LOWER_HYPHEN: return s.replace("_", "-").toLowerCase(Locale.US); case LOWER_UNDERSCORE: return s.toLowerCase(Locale.US); } break; } /* otherwise, deal with camel conversion */ StringBuilder out = null; int i = 0; for (Matcher matcher = wordBoundary.matcher(s); matcher.find();) { int j = matcher.start(); if (i == 0) { /* include some extra space for separators */ out = new StringBuilder(s.length() + 4 * wordSeparator.length()); out.append(format.normalizeFirstWord(s.substring(i, j))); } else { out.append(format.normalizeWord(s.substring(i, j))); } out.append(format.wordSeparator); i = j + wordSeparator.length(); } if (i == 0) { return format.normalizeFirstWord(s); } out.append(format.normalizeWord(s.substring(i))); return out.toString(); } private String normalizeFirstWord(String word) { switch (this) { case LOWER_CAMEL: return word.toLowerCase(Locale.US); default: return normalizeWord(word); } } private String normalizeWord(String word) { switch (this) { case LOWER_HYPHEN: return word.toLowerCase(Locale.US); case LOWER_UNDERSCORE: return word.toLowerCase(Locale.US); case LOWER_CAMEL: return toTitleCase(word); case UPPER_CAMEL: return toTitleCase(word); case UPPER_UNDERSCORE: return word.toUpperCase(Locale.US); } throw new RuntimeException("unknown case: " + this); } private static String toTitleCase(String word) { return (word.length() < 2) ? word.toUpperCase(Locale.US) : (Character.toTitleCase(word.charAt(0)) + word.substring(1).toLowerCase(Locale.US)); } }