Improve and add exceptions for singular method by slawekjaranowski · Pull Request #493 · codehaus-plexus/modello (original) (raw)
private static final Map<String, String> PLURAL_EXCEPTIONS = new HashMap<>();
static {
// Irregular plurals
PLURAL_EXCEPTIONS.put("men", "man");
PLURAL_EXCEPTIONS.put("women", "woman");
PLURAL_EXCEPTIONS.put("children", "child");
PLURAL_EXCEPTIONS.put("mice", "mouse");
PLURAL_EXCEPTIONS.put("people", "person");
PLURAL_EXCEPTIONS.put("teeth", "tooth");
PLURAL_EXCEPTIONS.put("feet", "foot");
PLURAL_EXCEPTIONS.put("geese", "goose");
// Invariant plurals
PLURAL_EXCEPTIONS.put("series", "series");
PLURAL_EXCEPTIONS.put("species", "species");
PLURAL_EXCEPTIONS.put("sheep", "sheep");
PLURAL_EXCEPTIONS.put("fish", "fish");
PLURAL_EXCEPTIONS.put("deer", "deer");
PLURAL_EXCEPTIONS.put("aircraft", "aircraft");
// Special "oes" exceptions
PLURAL_EXCEPTIONS.put("heroes", "hero");
PLURAL_EXCEPTIONS.put("potatoes", "potato");
PLURAL_EXCEPTIONS.put("tomatoes", "tomato");
PLURAL_EXCEPTIONS.put("echoes", "echo");
PLURAL_EXCEPTIONS.put("vetoes", "veto");
PLURAL_EXCEPTIONS.put("torpedoes", "torpedo");
PLURAL_EXCEPTIONS.put("cargoes", "cargo");
PLURAL_EXCEPTIONS.put("haloes", "halo");
PLURAL_EXCEPTIONS.put("mosquitoes", "mosquito");
PLURAL_EXCEPTIONS.put("buffaloes", "buffalo");
}
public static String singular(String plural) {
if (plural == null || plural.isEmpty()) return plural;
String lower = plural.toLowerCase();
if (PLURAL_EXCEPTIONS.containsKey(lower)) {
return PLURAL_EXCEPTIONS.get(lower);
}
// Suffix-based rules
if (lower.endsWith("ies") && plural.length() > 3) {
return plural.substring(0, plural.length() - 3) + "y";
}
if (lower.endsWith("ves")) {
return plural.substring(0, plural.length() - 3) + "f";
}
if (lower.endsWith("zzes")) {
return plural.substring(0, plural.length() - 2);
}
if (lower.endsWith("sses")) {
return plural.substring(0, plural.length() - 2);
}
if (lower.endsWith("ches") || lower.endsWith("shes")) {
return plural.substring(0, plural.length() - 2);
}
if (lower.endsWith("xes")) {
return plural.substring(0, plural.length() - 2);
}
if (lower.endsWith("oes")) {
return plural.substring(0, plural.length() - 1);
}
if (lower.endsWith("s") && plural.length() > 1) {
return plural.substring(0, plural.length() - 1);
}
return plural;
}
// Known exceptions
"men", "man",
"women", "woman",
"children", "child",
"mice", "mouse",
"people", "person",
"teeth", "tooth",
"feet", "foot",
"geese", "goose",
"series", "series",
"species", "species",
"sheep", "sheep",
"fish", "fish",
"deer", "deer",
"aircraft", "aircraft",
"heroes", "hero",
"potatoes", "potato",
"tomatoes", "tomato",
"echoes", "echo",
"vetoes", "veto",
"torpedoes", "torpedo",
"cargoes", "cargo",
"haloes", "halo",
"mosquitoes", "mosquito",
"buffaloes", "buffalo",
// Regular plural forms with suffixes
"voes", "voe",
"hoes", "hoe",
"canoes", "canoe",
"toes", "toe",
"foes", "foe",
"oboes", "oboe",
"noes", "no",
"boxes", "box",
"wishes", "wish",
"dishes", "dish",
"brushes", "brush",
"classes", "class",
"buzzes", "buzz",
"cars", "car",
"dogs", "dog",
"cats", "cat",
"horses", "horse",
// Some test cases with different rules
"wolves", "wolf",
"knives", "knife",
"leaves", "leaf",
"wives", "wife",
"lives", "life",
"babies", "baby",
"parties", "party",
"cities", "city",
"buses", "bus",
"boxes", "box",
"churches", "church",
"matches", "match",
"watches", "watch",
"riches", "rich",
"dresses", "dress",
"crosses", "cross",
// More edge cases
"heroes", "hero",
"vetoes", "veto",
"torpedoes", "torpedo",
"tomatoes", "tomato",
"potatoes", "potato",
"echoes", "echo",
"mosquitoes", "mosquito",
"buffaloes", "buffalo",
"volcanoes", "volcano",
"goes", "go"