package net.sf.jabref.util; /* Mp3dings - manage mp3 meta-information * Copyright (C) 2003 Moritz Ringler * $Id: CaseChanger.java 2900 2009-02-24 17:29:11Z mortenalver $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ import net.sf.jabref.Util; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.HashSet; /** * * Class with static methods for changing the case of strings and arrays of * strings. * * @author Moritz Ringler * * @version $Revision: 2900 $ ($Date: 2009-02-24 18:29:11 +0100 (Di, 24 Feb 2009) $) */ public class CaseChanger { /** Lowercase */ public final static int LOWER = 0; /** Uppercase */ public final static int UPPER = 1; /** First letter of string uppercase */ public final static int UPPER_FIRST = 2; /** First letter of each word uppercase */ public final static int UPPER_EACH_FIRST = 3; /** * I don't think it is thread-safe to use the same matcher at the same time for all calls. */ private final static Pattern UF_PATTERN = Pattern.compile("\\b\\w"); // private final static Matcher UF_MATCHER = // // Pattern.compile("(?i)\\b\\w").matcher(""); // Pattern.compile("\\b\\w").matcher(""); /* you can add more modes here */ private final static int numModes = 4; private final static String[] modeNames = { "lower", "UPPER", "Upper first", "Upper Each First" }; private final static HashSet<String> notToCapitalize = new HashSet<String>(); static { notToCapitalize.add("of"); notToCapitalize.add("and"); notToCapitalize.add("the"); } /** * Gets the name of a case changing mode * * @param mode * by default one of LOWER, UPPER, UPPER_FIRST or * UPPER_EACH_FIRST */ public static String getModeName(int mode) { return modeNames[mode]; } /** Gets the names of all available case changing modes */ public static String[] getModeNames() { return modeNames; } /** Gets the number of available case changing modes */ public static int getNumModes() { return numModes; } /** * Changes the case of the specified strings. wrapper for * {@link #changeCase(String input, int mode)} * * @see #changeCase(String input, int mode) */ public static String[] changeCase(String[] input, int mode) { int n = input.length; String[] output = new String[n]; for (int i = 0; i < n; i++) { output[i] = changeCase(input[i], mode); } return output; } /** * Changes the case of the specified string * * @param input * String to change * @param mode * by default one of LOWER, UPPER, UPPER_FIRST or * UPPER_EACH_FIRST * @return casechanged string */ public static String changeCase(String input, int mode) { return changeCase(input, mode, false); } /** * Changes the case of the specified string * * @param input * String to change * @param mode * by default one of LOWER, UPPER, UPPER_FIRST or * UPPER_EACH_FIRST * @param skipSmallWords * In UPPER_EACH_FIRST mode, do not capitalize words like of, the, and, * unless at the start of the string. * @return casechanged string */ public static String changeCase(String input, int mode, boolean skipSmallWords) { switch (mode) { case UPPER: return input.toUpperCase(); case LOWER: return input.toLowerCase(); case UPPER_FIRST: { String s = input.toLowerCase(); Matcher matcher = UF_PATTERN.matcher(s); if (matcher.find()) { return matcher.replaceFirst(matcher.group(0).toUpperCase()); } else { return input; } } case UPPER_EACH_FIRST: { String s = input.toLowerCase(); boolean found = false; String[] words = s.split("\\s+"); StringBuilder sb = new StringBuilder(); for (int i = 0; i < words.length; i++) { String word = words[i]; if ((i == 0) || !skipSmallWords || !notToCapitalize.contains(word)) sb.append(Util.nCase(word)); else sb.append(word); if (i < words.length-1) sb.append(" "); } return sb.toString(); } default: return input; } } }