001/* 002 * Copyright 2011 Atteo. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * the License. 013 */ 014package org.atteo.evo.inflector; 015 016import java.util.ArrayList; 017import java.util.List; 018import java.util.regex.Matcher; 019import java.util.regex.Pattern; 020 021public abstract class TwoFormInflector { 022 private static class Rule { 023 private Pattern singular; 024 private String plural; 025 private Rule(Pattern singular, String plural) { 026 this.singular = singular; 027 this.plural = plural; 028 } 029 030 public Pattern getSingular() { 031 return singular; 032 } 033 034 public String getPlural() { 035 return plural; 036 } 037 } 038 039 private List<Rule> rules = new ArrayList<Rule>(); 040 041 protected String getPlural(String word) { 042 StringBuffer buffer = new StringBuffer(); 043 044 for (Rule rule : rules) { 045 Matcher matcher = rule.getSingular().matcher(word); 046 if (matcher.find()) { 047 matcher.appendReplacement(buffer, rule.getPlural()); 048 matcher.appendTail(buffer); 049 return buffer.toString(); 050 } 051 } 052 return null; 053 } 054 055 protected void uncountable(String word) { 056 rules.add(new Rule(Pattern.compile("(?i)(" + word + ")$"), "$1")); 057 } 058 059 protected void uncountable(String[] list) { 060 StringBuilder builder = new StringBuilder(); 061 builder.append("(?i)("); 062 builder.append(list[0]); 063 for (String word : list) { 064 builder.append("|").append(word); 065 } 066 builder.append(")$"); 067 rules.add(new Rule(Pattern.compile(builder.toString()), "$1")); 068 } 069 070 protected void irregular(String singular, String plural) { 071 if (singular.charAt(0) == plural.charAt(0)) { 072 rules.add(new Rule(Pattern.compile("(?i)(" + singular.charAt(0) + ")" + singular.substring(1) 073 + "$"), "$1" + plural.substring(1))); 074 } else { 075 rules.add(new Rule(Pattern.compile(Character.toUpperCase(singular.charAt(0)) + "(?i)" 076 + singular.substring(1) + "$"), Character.toUpperCase(plural.charAt(0)) 077 + plural.substring(1))); 078 rules.add(new Rule(Pattern.compile(Character.toLowerCase(singular.charAt(0)) + "(?i)" 079 + singular.substring(1) + "$"), Character.toLowerCase(plural.charAt(0)) 080 + plural.substring(1))); 081 } 082 } 083 084 protected void irregular(String[][] list) { 085 for (String[] pair : list) { 086 irregular(pair[0], pair[1]); 087 } 088 } 089 090 protected void rule(String singular, String plural) { 091 rules.add(new Rule(Pattern.compile(singular, Pattern.CASE_INSENSITIVE), plural)); 092 } 093 094 protected void rule(String[][] list) { 095 for (String[] pair : list) { 096 rules.add(new Rule(Pattern.compile(pair[0], Pattern.CASE_INSENSITIVE), pair[1])); 097 } 098 } 099 100 protected void categoryRule(String[] list, String singular, String plural) { 101 StringBuilder builder = new StringBuilder(); 102 103 builder.append("(?=").append(list[0]); 104 for (String word : list) { 105 builder.append("|").append(word); 106 } 107 builder.append(")"); 108 builder.append(singular); 109 rules.add(new Rule(Pattern.compile(builder.toString(), Pattern.CASE_INSENSITIVE), plural)); 110 } 111}