1 /* 2 * Copyright (C) 2006 Google Inc. 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 * http://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 17 package com.google.common.base; 18 19 import java.util.Locale; 20 import java.util.regex.Matcher; 21 import java.util.regex.Pattern; 22 23 /** 24 * Utility class for converting between various case formats. 25 * 26 * @author Mike Bostock 27 * @since 2009.09.15 <b>tentative</b> 28 */ 29 public enum CaseFormat { 30 31 /** 32 * Hyphenated variable naming convention, e.g., "lower-hyphen". 33 */ 34 LOWER_HYPHEN(Pattern.compile("[-]"), "-"), 35 36 /** 37 * C++ variable naming convention, e.g., "lower_underscore". 38 */ 39 LOWER_UNDERSCORE(Pattern.compile("[_]"), "_"), 40 41 /** 42 * Java variable naming convention, e.g., "lowerCamel". 43 */ 44 LOWER_CAMEL(Pattern.compile("[A-Z]"), ""), 45 46 /** 47 * Java and C++ class naming convention, e.g., "UpperCamel". 48 */ 49 UPPER_CAMEL(Pattern.compile("[A-Z]"), ""), 50 51 /** 52 * Java and C++ constant naming convention, e.g., "UPPER_UNDERSCORE". 53 */ 54 UPPER_UNDERSCORE(Pattern.compile("[_]"), "_"); 55 56 private final Pattern wordBoundary; 57 private final String wordSeparator; 58 CaseFormat(Pattern wordBoundary, String wordSeparator)59 private CaseFormat(Pattern wordBoundary, String wordSeparator) { 60 this.wordBoundary = wordBoundary; 61 this.wordSeparator = wordSeparator; 62 } 63 64 /** 65 * Converts the specified {@code String s} from this format to the specified 66 * {@code format}. A "best effort" approach is taken; if {@code s} does not 67 * conform to the assumed format, then the behavior of this method is 68 * undefined but we make a reasonable effort at converting anyway. 69 */ to(CaseFormat format, String s)70 public String to(CaseFormat format, String s) { 71 if (format == null) { 72 throw new NullPointerException(); 73 } 74 if (s == null) { 75 throw new NullPointerException(); 76 } 77 78 /* optimize case where no conversion is required */ 79 if (format == this) { 80 return s; 81 } 82 83 /* optimize cases where no camel conversion is required */ 84 switch (this) { 85 case LOWER_HYPHEN: 86 switch (format) { 87 case LOWER_UNDERSCORE: return s.replace("-", "_"); 88 case UPPER_UNDERSCORE: return s.replace("-", "_").toUpperCase(Locale.US); 89 } 90 break; 91 case LOWER_UNDERSCORE: 92 switch (format) { 93 case LOWER_HYPHEN: return s.replace("_", "-"); 94 case UPPER_UNDERSCORE: return s.toUpperCase(Locale.US); 95 } 96 break; 97 case UPPER_UNDERSCORE: 98 switch (format) { 99 case LOWER_HYPHEN: return s.replace("_", "-").toLowerCase(Locale.US); 100 case LOWER_UNDERSCORE: return s.toLowerCase(Locale.US); 101 } 102 break; 103 } 104 105 /* otherwise, deal with camel conversion */ 106 StringBuilder out = null; 107 int i = 0; 108 for (Matcher matcher = wordBoundary.matcher(s); matcher.find();) { 109 int j = matcher.start(); 110 if (i == 0) { 111 /* include some extra space for separators */ 112 out = new StringBuilder(s.length() + 4 * wordSeparator.length()); 113 out.append(format.normalizeFirstWord(s.substring(i, j))); 114 } else { 115 out.append(format.normalizeWord(s.substring(i, j))); 116 } 117 out.append(format.wordSeparator); 118 i = j + wordSeparator.length(); 119 } 120 if (i == 0) { 121 return format.normalizeFirstWord(s); 122 } 123 out.append(format.normalizeWord(s.substring(i))); 124 return out.toString(); 125 } 126 normalizeFirstWord(String word)127 private String normalizeFirstWord(String word) { 128 switch (this) { 129 case LOWER_CAMEL: return word.toLowerCase(Locale.US); 130 default: return normalizeWord(word); 131 } 132 } 133 normalizeWord(String word)134 private String normalizeWord(String word) { 135 switch (this) { 136 case LOWER_HYPHEN: return word.toLowerCase(Locale.US); 137 case LOWER_UNDERSCORE: return word.toLowerCase(Locale.US); 138 case LOWER_CAMEL: return toTitleCase(word); 139 case UPPER_CAMEL: return toTitleCase(word); 140 case UPPER_UNDERSCORE: return word.toUpperCase(Locale.US); 141 } 142 throw new RuntimeException("unknown case: " + this); 143 } 144 toTitleCase(String word)145 private static String toTitleCase(String word) { 146 return (word.length() < 2) ? word.toUpperCase(Locale.US) 147 : (Character.toTitleCase(word.charAt(0)) 148 + word.substring(1).toLowerCase(Locale.US)); 149 } 150 151 } 152