/**
* Aptana Studio
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions).
* Please see the license.html included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package org.radrails.rails.internal.ui.filter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.aptana.core.util.StringUtil;
abstract class Inflector
{
private static class Replacement
{
private Pattern rule;
private String replacement;
Replacement(Pattern rule, String replacement)
{
this.rule = rule;
this.replacement = replacement;
}
}
private static List<Replacement> plurals = new ArrayList<Replacement>();
private static List<Replacement> singulars = new ArrayList<Replacement>();
private static List<String> uncountables = new ArrayList<String>();
protected static String singularize(String plural)
{
if (uncountables.contains(plural.toLowerCase()))
{
return plural;
}
for (Replacement replacement : singulars)
{
Matcher matcher = replacement.rule.matcher(plural);
if (matcher.find())
{
return matcher.replaceFirst(replacement.replacement);
}
}
return plural;
}
protected static String pluralize(String singular)
{
if (uncountables.contains(singular.toLowerCase()))
{
return singular;
}
for (Replacement replacement : plurals)
{
Matcher matcher = replacement.rule.matcher(singular);
if (matcher.find())
{
return matcher.replaceFirst(replacement.replacement);
}
}
return singular;
}
private static void plural(Pattern rule, String replacement)
{
plurals.add(0, new Replacement(rule, replacement));
}
private static void singular(Pattern rule, String replacement)
{
singulars.add(0, new Replacement(rule, replacement));
}
private static void irregular(String singular, String plural)
{
plural(Pattern.compile("(" + singular.charAt(0) + ")" + singular.substring(1) + "$", Pattern.CASE_INSENSITIVE), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
"$1" + plural.substring(1)); //$NON-NLS-1$
singular(Pattern.compile("(" + plural.charAt(0) + ")" + plural.substring(1) + "$", Pattern.CASE_INSENSITIVE), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
"$1" + singular.substring(1)); //$NON-NLS-1$
}
private static void uncountable(String[] words)
{
for (int i = 0; i < words.length; i++)
{
uncountables.add(words[i]);
}
}
static
{
Inflector.plural(Pattern.compile("$"), "s"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("s$", Pattern.CASE_INSENSITIVE), "s"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("(ax|test)is$", Pattern.CASE_INSENSITIVE), "$1es"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("(octop|vir)us$", Pattern.CASE_INSENSITIVE), "$1i"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("(alias|status)$", Pattern.CASE_INSENSITIVE), "$1es"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("(bu)s$", Pattern.CASE_INSENSITIVE), "$1ses"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("(buffal|tomat)o$", Pattern.CASE_INSENSITIVE), "$1oes"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("([ti])um$", Pattern.CASE_INSENSITIVE), "$1a"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("sis$", Pattern.CASE_INSENSITIVE), "ses"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("(?:([^f])fe|([lr])f)$", Pattern.CASE_INSENSITIVE), "$1$2ves"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("(hive)$", Pattern.CASE_INSENSITIVE), "$1s"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("([^aeiouy]|qu)y$", Pattern.CASE_INSENSITIVE), "$1ies"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("(x|ch|ss|sh)$", Pattern.CASE_INSENSITIVE), "$1es"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("(matr|vert|ind)ix|ex$", Pattern.CASE_INSENSITIVE), "$1ices"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("([m|l])ouse$", Pattern.CASE_INSENSITIVE), "$1ice"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("^(ox)$", Pattern.CASE_INSENSITIVE), "$1en"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.plural(Pattern.compile("(quiz)$", Pattern.CASE_INSENSITIVE), "$1zes"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("s$", Pattern.CASE_INSENSITIVE), StringUtil.EMPTY); //$NON-NLS-1$
Inflector.singular(Pattern.compile("(n)ews$", Pattern.CASE_INSENSITIVE), "$1ews"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("([ti])a$", Pattern.CASE_INSENSITIVE), "$1um"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$", //$NON-NLS-1$
Pattern.CASE_INSENSITIVE), "$1$2sis"); //$NON-NLS-1$
Inflector.singular(Pattern.compile("(^analy)ses$", Pattern.CASE_INSENSITIVE), "$1sis"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("([^f])ves$", Pattern.CASE_INSENSITIVE), "$1fe"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(hive)s$", Pattern.CASE_INSENSITIVE), "$1"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(tive)s$", Pattern.CASE_INSENSITIVE), "$1"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("([lr])ves$", Pattern.CASE_INSENSITIVE), "$1f"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("([^aeiouy]|qu)ies$", Pattern.CASE_INSENSITIVE), "$1y"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(s)eries$", Pattern.CASE_INSENSITIVE), "$1eries"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(m)ovies$", Pattern.CASE_INSENSITIVE), "$1ovie"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(x|ch|ss|sh)es$", Pattern.CASE_INSENSITIVE), "$1"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("([m|l])ice$", Pattern.CASE_INSENSITIVE), "$1ouse"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(bus)es$", Pattern.CASE_INSENSITIVE), "$1"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(o)es$", Pattern.CASE_INSENSITIVE), "$1"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(shoe)s$", Pattern.CASE_INSENSITIVE), "$1"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(cris|ax|test)es$", Pattern.CASE_INSENSITIVE), "$1is"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(octop|vir)i$", Pattern.CASE_INSENSITIVE), "$1us"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(alias|status)es$", Pattern.CASE_INSENSITIVE), "$1"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("^(ox)en", Pattern.CASE_INSENSITIVE), "$1"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(vert|ind)ices$", Pattern.CASE_INSENSITIVE), "$1ex"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(matr)ices$", Pattern.CASE_INSENSITIVE), "$1ix"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.singular(Pattern.compile("(quiz)zes$", Pattern.CASE_INSENSITIVE), "$1"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.irregular("person", "people"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.irregular("man", "men"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.irregular("child", "children"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.irregular("sex", "sexes"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.irregular("move", "moves"); //$NON-NLS-1$ //$NON-NLS-2$
Inflector.uncountable(new String[] { "equipment", "information", "rice", "money", "species", "series", "fish", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
"sheep" }); //$NON-NLS-1$
}
}