| /* |
| * 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)); |
| } |
| |
| } |