From fe521df984a4bf1f6627401716e6b4558235bfb2 Mon Sep 17 00:00:00 2001 From: bjculkin Date: Wed, 5 Apr 2017 10:06:58 -0400 Subject: Reorganize --- .../bjc/inflexion/examples/InflexionTester.java | 6 +- .../bjc/inflexion/CategoricalNounInflection.java | 192 ------------ .../java/bjc/inflexion/CompoundNounInflection.java | 244 --------------- .../java/bjc/inflexion/DefaultNounInflection.java | 68 ----- src/main/java/bjc/inflexion/InflectionAffix.java | 56 ---- src/main/java/bjc/inflexion/InflectionAffixes.java | 74 ----- .../java/bjc/inflexion/InflectionException.java | 49 --- .../bjc/inflexion/IrregularNounInflection.java | 197 ------------ src/main/java/bjc/inflexion/Noun.java | 121 -------- src/main/java/bjc/inflexion/NounInflection.java | 113 ------- src/main/java/bjc/inflexion/Nouns.java | 329 --------------------- src/main/java/bjc/inflexion/Prepositions.java | 71 ----- .../java/bjc/inflexion/SimpleInflectionAffix.java | 103 ------- .../inflexion/nouns/CategoricalNounInflection.java | 192 ++++++++++++ .../inflexion/nouns/CompoundNounInflection.java | 244 +++++++++++++++ .../bjc/inflexion/nouns/DefaultNounInflection.java | 68 +++++ .../java/bjc/inflexion/nouns/InflectionAffix.java | 56 ++++ .../bjc/inflexion/nouns/InflectionAffixes.java | 74 +++++ .../bjc/inflexion/nouns/InflectionException.java | 49 +++ .../inflexion/nouns/IrregularNounInflection.java | 197 ++++++++++++ src/main/java/bjc/inflexion/nouns/Noun.java | 121 ++++++++ .../java/bjc/inflexion/nouns/NounInflection.java | 113 +++++++ src/main/java/bjc/inflexion/nouns/Nouns.java | 329 +++++++++++++++++++++ .../java/bjc/inflexion/nouns/Prepositions.java | 71 +++++ .../bjc/inflexion/nouns/SimpleInflectionAffix.java | 103 +++++++ 25 files changed, 1620 insertions(+), 1620 deletions(-) delete mode 100644 src/main/java/bjc/inflexion/CategoricalNounInflection.java delete mode 100644 src/main/java/bjc/inflexion/CompoundNounInflection.java delete mode 100644 src/main/java/bjc/inflexion/DefaultNounInflection.java delete mode 100644 src/main/java/bjc/inflexion/InflectionAffix.java delete mode 100644 src/main/java/bjc/inflexion/InflectionAffixes.java delete mode 100644 src/main/java/bjc/inflexion/InflectionException.java delete mode 100644 src/main/java/bjc/inflexion/IrregularNounInflection.java delete mode 100644 src/main/java/bjc/inflexion/Noun.java delete mode 100644 src/main/java/bjc/inflexion/NounInflection.java delete mode 100644 src/main/java/bjc/inflexion/Nouns.java delete mode 100644 src/main/java/bjc/inflexion/Prepositions.java delete mode 100644 src/main/java/bjc/inflexion/SimpleInflectionAffix.java create mode 100644 src/main/java/bjc/inflexion/nouns/CategoricalNounInflection.java create mode 100644 src/main/java/bjc/inflexion/nouns/CompoundNounInflection.java create mode 100644 src/main/java/bjc/inflexion/nouns/DefaultNounInflection.java create mode 100644 src/main/java/bjc/inflexion/nouns/InflectionAffix.java create mode 100644 src/main/java/bjc/inflexion/nouns/InflectionAffixes.java create mode 100644 src/main/java/bjc/inflexion/nouns/InflectionException.java create mode 100644 src/main/java/bjc/inflexion/nouns/IrregularNounInflection.java create mode 100644 src/main/java/bjc/inflexion/nouns/Noun.java create mode 100644 src/main/java/bjc/inflexion/nouns/NounInflection.java create mode 100644 src/main/java/bjc/inflexion/nouns/Nouns.java create mode 100644 src/main/java/bjc/inflexion/nouns/Prepositions.java create mode 100644 src/main/java/bjc/inflexion/nouns/SimpleInflectionAffix.java diff --git a/src/examples/java/bjc/inflexion/examples/InflexionTester.java b/src/examples/java/bjc/inflexion/examples/InflexionTester.java index a54040d..829da97 100644 --- a/src/examples/java/bjc/inflexion/examples/InflexionTester.java +++ b/src/examples/java/bjc/inflexion/examples/InflexionTester.java @@ -29,9 +29,9 @@ import java.util.regex.Pattern; import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; -import bjc.inflexion.Noun; -import bjc.inflexion.Nouns; -import bjc.inflexion.Prepositions; +import bjc.inflexion.nouns.Noun; +import bjc.inflexion.nouns.Nouns; +import bjc.inflexion.nouns.Prepositions; /** * Test inflecting words. diff --git a/src/main/java/bjc/inflexion/CategoricalNounInflection.java b/src/main/java/bjc/inflexion/CategoricalNounInflection.java deleted file mode 100644 index a57a2e2..0000000 --- a/src/main/java/bjc/inflexion/CategoricalNounInflection.java +++ /dev/null @@ -1,192 +0,0 @@ -/** - * (C) Copyright 2017 Benjamin Culkin. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package bjc.inflexion; - -/** - * Implementation of {@link NounInflection} for nouns matched by a regular - * expression. - * - * @author EVE - * - */ -public class CategoricalNounInflection implements NounInflection { - private static final String TOSTRING_FMT = "CategoricalNounInflection [singular=%s, modernPlural=%s," - + " classicalPlural=%s]"; - - private InflectionAffix singular; - - private InflectionAffix modernPlural; - private InflectionAffix classicalPlural; - - /** - * Create a new categorical inflection. - * - * @param singlar - * The affix for the singular form. - * - * @param modrnPlural - * The affix for the modern plural. - * - * @param classiclPlural - * The affix for the classical plural. - */ - public CategoricalNounInflection(InflectionAffix singlar, InflectionAffix modrnPlural, - InflectionAffix classiclPlural) { - if(singlar == null) - throw new NullPointerException("Singular form must not be null"); - else if(modrnPlural == null && classiclPlural == null) - throw new NullPointerException("One of modern/classical plural forms must not be null"); - - singular = singlar; - modernPlural = modrnPlural; - classicalPlural = classiclPlural; - } - - @Override - public boolean matches(String noun) { - if(singular.hasAffix(noun)) - return true; - else if(modernPlural != null && modernPlural.hasAffix(noun)) - return true; - else if(classicalPlural != null && classicalPlural.hasAffix(noun)) - return true; - else - return false; - } - - @Override - public boolean isSingular(String noun) { - if(singular.hasAffix(noun)) - return true; - else if(matchesPlural(noun)) - return false; - else { - String msg = String.format("Noun '%s' doesn't belong to this inflection", noun, this); - - throw new InflectionException(msg); - } - } - - @Override - public boolean isPlural(String noun) { - if(singular.hasAffix(noun)) - return false; - else if(matchesPlural(noun)) - return true; - else { - String msg = String.format("Noun '%s' doesn't belong to this inflection", noun, this); - - throw new InflectionException(msg); - } - } - - @Override - public String singularize(String plural) { - if(singular.hasAffix(plural)) - return plural; - else if(modernPlural != null && modernPlural.hasAffix(plural)) - return singular.affix(modernPlural.deaffix(plural)); - else if(classicalPlural != null && classicalPlural.hasAffix(plural)) - return singular.affix(classicalPlural.deaffix(plural)); - else { - String msg = String.format("Noun '%s' doesn't belong to this inflection", plural, this); - - throw new InflectionException(msg); - } - } - - @Override - public String pluralize(String singlar) { - if(singular.hasAffix(singlar)) { - if(modernPlural == null) { - return classicalPlural.affix(singular.deaffix(singlar)); - } else { - return modernPlural.affix(singular.deaffix(singlar)); - } - } else if(matchesPlural(singlar)) { - return singlar; - } else { - String msg = String.format("Noun '%s' doesn't belong to this inflection", singlar, this); - - throw new InflectionException(msg); - } - } - - private boolean matchesPlural(String noun) { - boolean hasModernPlural = modernPlural != null && modernPlural.hasAffix(noun); - - return hasModernPlural || (classicalPlural != null && classicalPlural.hasAffix(noun)); - } - - @Override - public String toString() { - return String.format(TOSTRING_FMT, singular, modernPlural, classicalPlural); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - - result = prime * result + ((classicalPlural == null) ? 0 : classicalPlural.hashCode()); - result = prime * result + ((modernPlural == null) ? 0 : modernPlural.hashCode()); - - return result; - } - - @Override - public boolean equals(Object obj) { - if(this == obj) return true; - if(obj == null) return false; - if(!(obj instanceof CategoricalNounInflection)) return false; - - CategoricalNounInflection other = (CategoricalNounInflection) obj; - - if(classicalPlural == null) { - if(other.classicalPlural != null) return false; - } else if(!classicalPlural.equals(other.classicalPlural)) return false; - - if(modernPlural == null) { - if(other.modernPlural != null) return false; - } else if(!modernPlural.equals(other.modernPlural)) return false; - - return true; - } - - @Override - public String pluralizeModern(String singlar) { - if(modernPlural == null) return pluralizeClassical(singlar); - - String actSinglar = singlar; - if(isPlural(singlar)) { - actSinglar = singularize(singlar); - } - - return modernPlural.affix(singular.deaffix(actSinglar)); - } - - @Override - public String pluralizeClassical(String singlar) { - if(classicalPlural == null) return pluralizeModern(singlar); - - String actSinglar = singlar; - if(isPlural(singlar)) { - actSinglar = singularize(singlar); - } - - return classicalPlural.affix(singular.deaffix(actSinglar)); - } -} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/CompoundNounInflection.java b/src/main/java/bjc/inflexion/CompoundNounInflection.java deleted file mode 100644 index 85229f0..0000000 --- a/src/main/java/bjc/inflexion/CompoundNounInflection.java +++ /dev/null @@ -1,244 +0,0 @@ -/** - * (C) Copyright 2017 Benjamin Culkin. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package bjc.inflexion; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Implementation of {@link NounInflection} for words that don't inflect at the - * end. - * - * @author EVE - * - */ -public class CompoundNounInflection implements NounInflection { - private static final String TOSTRING_FMT = "CompoundNounInflection [compoundMatcher=%s, singularPattern=%s," - + " modernPluralPattern=%s, classicalPluralPattern=%s, hasPreposition=%s]"; - /* - * Data stores for use. - */ - private Nouns nounDB; - private Prepositions prepositionDB; - - private Pattern compoundMatcher; - - private String singularPattern; - - private String modernPluralPattern; - private String classicalPluralPattern; - - /* - * Whether or not this inflection takes a preposition. - */ - private boolean hasPreposition; - - /* - * Whether or not there is a scratch word in place. - */ - private boolean hasScratch; - - /** - * TODO fill in documentation. - * - * @param nounDB - * @param prepositionDB - * @param compoundMatcher - * @param singularPattern - * @param modernPluralPattern - * @param classicalPluralPattern - * @param hasPreposition - * @param hasScrtch - */ - public CompoundNounInflection(Nouns nounDB, Prepositions prepositionDB, Pattern compoundMatcher, - String singularPattern, String modernPluralPattern, String classicalPluralPattern, - boolean hasPreposition, boolean hasScrtch) { - this.nounDB = nounDB; - this.prepositionDB = prepositionDB; - this.compoundMatcher = compoundMatcher; - this.singularPattern = singularPattern; - this.modernPluralPattern = modernPluralPattern; - this.classicalPluralPattern = classicalPluralPattern; - this.hasPreposition = hasPreposition; - hasScratch = hasScrtch; - } - - @Override - public boolean matches(String noun) { - Matcher matcher = compoundMatcher.matcher(noun); - - if(matcher.matches()) { - Noun actNoun = nounDB.getNoun(matcher.group("noun")); - - if(actNoun == null) return false; - - if(hasPreposition) { - return prepositionDB.isPreposition(matcher.group("preposition")); - } else - return true; - } else { - return false; - } - } - - @Override - public boolean isSingular(String noun) { - Matcher matcher = compoundMatcher.matcher(noun); - Noun actNoun = nounDB.getNoun(matcher.group("noun")); - - return actNoun.isSingular(); - } - - @Override - public boolean isPlural(String noun) { - Matcher matcher = compoundMatcher.matcher(noun); - Noun actNoun = nounDB.getNoun(matcher.group("noun")); - - return actNoun.isPlural(); - } - - @Override - public String singularize(String plural) { - Matcher matcher = compoundMatcher.matcher(plural); - Noun actNoun = getNoun(matcher); - - if(hasPreposition && hasScratch) { - return String.format(singularPattern, actNoun.singular(), matcher.group("preposition"), - matcher.group("scratch")); - } else if(hasScratch) { - return String.format(singularPattern, actNoun.singular(), matcher.group("scratch")); - } else if(hasPreposition) { - return String.format(singularPattern, actNoun.singular(), matcher.group("preposition")); - } else { - return String.format(singularPattern, actNoun.singular()); - } - } - - @Override - public String pluralize(String singular) { - Matcher matcher = compoundMatcher.matcher(singular); - Noun actNoun = getNoun(matcher); - - String patt = modernPluralPattern == null ? classicalPluralPattern : modernPluralPattern; - - if(hasPreposition && hasScratch) { - return String.format(patt, actNoun.plural(), matcher.group("preposition"), - matcher.group("scratch")); - } else if(hasScratch) { - return String.format(patt, actNoun.plural(), matcher.group("scratch")); - } else if(hasPreposition) { - return String.format(patt, actNoun.plural(), matcher.group("preposition")); - } else { - return String.format(patt, actNoun.plural()); - } - } - - @Override - public String pluralizeModern(String singular) { - if(modernPluralPattern == null) return pluralizeClassical(singular); - - Matcher matcher = compoundMatcher.matcher(singular); - Noun actNoun = getNoun(matcher); - - if(hasPreposition && hasScratch) { - return String.format(modernPluralPattern, actNoun.modernPlural(), matcher.group("preposition"), - matcher.group("scratch")); - } else if(hasScratch) { - return String.format(modernPluralPattern, actNoun.modernPlural(), matcher.group("scratch")); - } else if(hasPreposition) { - return String.format(modernPluralPattern, actNoun.modernPlural(), matcher.group("preposition")); - } else { - return String.format(modernPluralPattern, actNoun.modernPlural()); - } - } - - @Override - public String pluralizeClassical(String singular) { - if(classicalPluralPattern == null) return pluralizeModern(singular); - - Matcher matcher = compoundMatcher.matcher(singular); - Noun actNoun = getNoun(matcher); - - if(hasPreposition && hasScratch) { - return String.format(classicalPluralPattern, actNoun.classicalPlural(), - matcher.group("preposition"), matcher.group("scratch")); - } else if(hasScratch) { - return String.format(classicalPluralPattern, actNoun.classicalPlural(), - matcher.group("scratch")); - } else if(hasPreposition) { - return String.format(classicalPluralPattern, actNoun.classicalPlural(), - matcher.group("preposition")); - } else { - return String.format(classicalPluralPattern, actNoun.classicalPlural()); - } - } - - private Noun getNoun(Matcher matcher) { - matcher.matches(); - - Noun actNoun = nounDB.getNoun(matcher.group("noun")); - return actNoun; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - - result = prime * result + ((classicalPluralPattern == null) ? 0 : classicalPluralPattern.hashCode()); - result = prime * result + ((compoundMatcher == null) ? 0 : compoundMatcher.hashCode()); - result = prime * result + (hasPreposition ? 1231 : 1237); - result = prime * result + ((modernPluralPattern == null) ? 0 : modernPluralPattern.hashCode()); - result = prime * result + ((singularPattern == null) ? 0 : singularPattern.hashCode()); - - return result; - } - - @Override - public boolean equals(Object obj) { - if(this == obj) return true; - if(obj == null) return false; - if(!(obj instanceof CompoundNounInflection)) return false; - - CompoundNounInflection other = (CompoundNounInflection) obj; - - if(singularPattern == null) { - if(other.singularPattern != null) return false; - } else if(!singularPattern.equals(other.singularPattern)) return false; - - if(classicalPluralPattern == null) { - if(other.classicalPluralPattern != null) return false; - } else if(!classicalPluralPattern.equals(other.classicalPluralPattern)) return false; - - if(hasPreposition != other.hasPreposition) return false; - - if(modernPluralPattern == null) { - if(other.modernPluralPattern != null) return false; - } else if(!modernPluralPattern.equals(other.modernPluralPattern)) return false; - - if(compoundMatcher == null) { - if(other.compoundMatcher != null) return false; - } else if(!compoundMatcher.equals(other.compoundMatcher)) return false; - - return true; - } - - @Override - public String toString() { - return String.format(TOSTRING_FMT, compoundMatcher, singularPattern, modernPluralPattern, - classicalPluralPattern, hasPreposition); - } -} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/DefaultNounInflection.java b/src/main/java/bjc/inflexion/DefaultNounInflection.java deleted file mode 100644 index 0d7be52..0000000 --- a/src/main/java/bjc/inflexion/DefaultNounInflection.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * (C) Copyright 2017 Benjamin Culkin. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package bjc.inflexion; - -/** - * Default noun inflection for english nouns. - * - * @author EVE - * - */ -public class DefaultNounInflection implements NounInflection { - @Override - public boolean matches(String noun) { - return true; - } - - @Override - public boolean isSingular(String noun) { - return !noun.endsWith("s"); - } - - @Override - public boolean isPlural(String noun) { - return noun.endsWith("s"); - } - - @Override - public String singularize(String plural) { - if(plural.endsWith("ses")) { - return plural.substring(0, plural.length() - 3); - } else if(plural.endsWith("s")) { - return plural.substring(0, plural.length() - 1); - } else - return plural; - } - - @Override - public String pluralize(String singular) { - if(singular.endsWith("s")) { - return singular + "es"; - } - - return singular + "s"; - } - - @Override - public String pluralizeModern(String singular) { - return pluralize(singular); - } - - @Override - public String pluralizeClassical(String singular) { - return pluralize(singular); - } -} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/InflectionAffix.java b/src/main/java/bjc/inflexion/InflectionAffix.java deleted file mode 100644 index f61ea79..0000000 --- a/src/main/java/bjc/inflexion/InflectionAffix.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * (C) Copyright 2017 Benjamin Culkin. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package bjc.inflexion; - -/** - * An affix attached to a word and used for inflection. - * - * @author EVE - * - */ -public interface InflectionAffix { - - /** - * Check if a word has this affix. - * - * @param word - * The word to check. - * - * @return Whether or not the word has the affix. - */ - boolean hasAffix(String word); - - /** - * Remove the affix from a word. - * - * @param word - * The word to remove the affix from. - * - * @return The word with the affix removed. - */ - String deaffix(String word); - - /** - * Apply this affix to a word. - * - * @param word - * The word to apply the affix to. - * - * @return The word with the affix applied. - */ - String affix(String word); - -} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/InflectionAffixes.java b/src/main/java/bjc/inflexion/InflectionAffixes.java deleted file mode 100644 index dad5c9e..0000000 --- a/src/main/java/bjc/inflexion/InflectionAffixes.java +++ /dev/null @@ -1,74 +0,0 @@ -/** - * (C) Copyright 2017 Benjamin Culkin. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package bjc.inflexion; - -import java.util.regex.Pattern; - -/** - * Utility methods for constructing inflection affixes. - * - * @author EVE - * - */ -public class InflectionAffixes { - /* - * Template for 'complete' affix patterns. - * - * Match the start of the word, followed by zero or more word - * characters, followed by the suffix, then the end of the string. - * - * The word is in a capturing group named 'stem'. - */ - private static final String COMPLETE_PATT_FMT = "(?\\w*)%s$"; - - /* - * Template for 'incomplete' affix patterns. - * - * Match the start of the word, followed by one or more word characters, - * followed by the suffix, then the end of the string. - * - * The word is in a capturing group named 'stem'. - */ - private static final String INCOMPLETE_PATT_FMT = "(?\\w+)%s$"; - - /** - * Create an affix that's a word by itself. - * - * @param suffix - * The suffix to use. - * - * @return A affix that represents the suffix. - */ - public static InflectionAffix complete(String suffix) { - Pattern patt = Pattern.compile(String.format(COMPLETE_PATT_FMT, suffix)); - - return new SimpleInflectionAffix("%s" + suffix, patt); - } - - /** - * Create an affix that's not a word by itself. - * - * @param suffix - * The suffix to use. - * - * @return An affix that represents the suffix. - */ - public static InflectionAffix incomplete(String suffix) { - Pattern patt = Pattern.compile(String.format(INCOMPLETE_PATT_FMT, suffix)); - - return new SimpleInflectionAffix("%s" + suffix, patt); - } -} diff --git a/src/main/java/bjc/inflexion/InflectionException.java b/src/main/java/bjc/inflexion/InflectionException.java deleted file mode 100644 index 5da518c..0000000 --- a/src/main/java/bjc/inflexion/InflectionException.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * (C) Copyright 2017 Benjamin Culkin. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package bjc.inflexion; - -/** - * Exception thrown when something goes wrong with inflection. - * - * @author EVE - * - */ -public class InflectionException extends RuntimeException { - private static final long serialVersionUID = 5680541587449153748L; - - /** - * Create a new inflection exception with the given message and cause. - * - * @param message - * The message of the exception. - * - * @param cause - * The cause of the exception. - */ - public InflectionException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Create a new inflection exception with the given message. - * - * @param message - * The message of the exception. - */ - public InflectionException(String message) { - super(message); - } -} diff --git a/src/main/java/bjc/inflexion/IrregularNounInflection.java b/src/main/java/bjc/inflexion/IrregularNounInflection.java deleted file mode 100644 index 6447db8..0000000 --- a/src/main/java/bjc/inflexion/IrregularNounInflection.java +++ /dev/null @@ -1,197 +0,0 @@ -/** - * (C) Copyright 2017 Benjamin Culkin. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package bjc.inflexion; - -/** - * Implementation of {@link NounInflection} for irregular nouns. - * - * @author EVE - * - */ -public class IrregularNounInflection implements NounInflection { - private static final String TOSTRING_FMT = "IrregularNounInflection [singular=%s, modernPlural=%s," - + " classicalPlural=%s, preferClassical=%s]"; - - private String singular; - - private String modernPlural; - private String classicalPlural; - - private boolean preferClassical; - - /** - * Create a new irregular noun inflection. - * - * @param singlar - * The singular form of the noun. - * - * @param modrnPlural - * The modern plural of the noun. - * - * @param classiclPlural - * The classical plural of the noun. - * - * @param prefrClassical - * Whether the classical form should be preferred if it - * is available. - */ - public IrregularNounInflection(String singlar, String modrnPlural, String classiclPlural, - boolean prefrClassical) { - if(singlar == null) throw new NullPointerException("Singular form must not be null"); - if(modrnPlural == null && classiclPlural == null) - throw new NullPointerException("One of modern/classical plural forms must not be null"); - - singular = singlar; - modernPlural = modrnPlural; - classicalPlural = classiclPlural; - preferClassical = prefrClassical; - } - - @Override - public boolean matches(String noun) { - if(noun.equalsIgnoreCase(singular)) - return true; - else if(noun.equalsIgnoreCase(modernPlural)) - return true; - else if(noun.equalsIgnoreCase(classicalPlural)) - return true; - else - return false; - } - - @Override - public boolean isSingular(String noun) { - if(noun.equalsIgnoreCase(singular)) - return true; - else if(matchesPlural(noun)) - return false; - else { - String msg = String.format("Noun '%s' doesn't belong to this inflection '%s'", noun, this); - - throw new InflectionException(msg); - } - } - - @Override - public boolean isPlural(String noun) { - if(noun.equalsIgnoreCase(singular)) - return false; - else if(matchesPlural(noun)) - return true; - else { - String msg = String.format("Noun '%s' doesn't belong to this inflection '%s'", noun, this); - - throw new InflectionException(msg); - } - } - - @Override - public String singularize(String plural) { - if(plural.equalsIgnoreCase(singular)) - return singular; - else if(matchesPlural(plural)) - return singular; - else { - String msg = String.format("Noun '%s' doesn't belong to this inflection '%s'", plural, this); - - throw new InflectionException(msg); - } - } - - @Override - public String pluralize(String singular) { - if(singular.equalsIgnoreCase(singular)) - return getPlural(); - else if(matchesPlural(singular)) - return getPlural(); - else { - String msg = String.format("Noun '%s' doesn't belong to this inflection '%s'", singular, this); - - throw new InflectionException(msg); - } - } - - private String getPlural() { - if(preferClassical) { - if(classicalPlural == null) - return modernPlural; - else - return classicalPlural; - } else if(modernPlural == null) { - return classicalPlural; - } else { - return modernPlural; - } - } - - private boolean matchesPlural(String noun) { - return noun.equalsIgnoreCase(modernPlural) || noun.equalsIgnoreCase(classicalPlural); - } - - @Override - public String toString() { - return String.format(TOSTRING_FMT, singular, modernPlural, classicalPlural, preferClassical); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - - result = prime * result + ((classicalPlural == null) ? 0 : classicalPlural.hashCode()); - result = prime * result + ((modernPlural == null) ? 0 : modernPlural.hashCode()); - result = prime * result + ((singular == null) ? 0 : singular.hashCode()); - - return result; - } - - @Override - public boolean equals(Object obj) { - if(this == obj) return true; - if(obj == null) return false; - if(!(obj instanceof IrregularNounInflection)) return false; - - IrregularNounInflection other = (IrregularNounInflection) obj; - - if(singular == null) { - if(other.singular != null) return false; - } else if(!singular.equals(other.singular)) return false; - - if(classicalPlural == null) { - if(other.classicalPlural != null) return false; - } else if(!classicalPlural.equals(other.classicalPlural)) return false; - - if(modernPlural == null) { - if(other.modernPlural != null) return false; - } else if(!modernPlural.equals(other.modernPlural)) return false; - - return true; - } - - @Override - public String pluralizeModern(String singular) { - if(modernPlural == null) return pluralizeClassical(singular); - - return modernPlural; - } - - @Override - public String pluralizeClassical(String singular) { - if(classicalPlural == null) return pluralizeModern(singular); - - return classicalPlural; - } -} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/Noun.java b/src/main/java/bjc/inflexion/Noun.java deleted file mode 100644 index 25e4698..0000000 --- a/src/main/java/bjc/inflexion/Noun.java +++ /dev/null @@ -1,121 +0,0 @@ -/** - * (C) Copyright 2017 Benjamin Culkin. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package bjc.inflexion; - -/** - * A noun attached to an inflection. - * - * @author EVE - * - */ -public class Noun { - private static final String TOSTRING_FMT = "Noun [word=%s, inflection=%s]"; - - private final String word; - - private final NounInflection inflection; - - /** - * Create a new noun from a word and inflection. - * - * @param wrd - * The word for the noun. - * - * @param inflction - * The inflection for the word. - */ - public Noun(String wrd, NounInflection inflction) { - word = wrd; - inflection = inflction; - } - - /** - * Get the input noun. - * - * @return The noun, as input. - */ - public String getWord() { - return word; - } - - /** - * Get the inflection for this noun. - * - * @return The inflection for this noun. - */ - public NounInflection getInflection() { - return inflection; - } - - /** - * Check if this noun is singular. - * - * @return Whether or not the noun is singular. - */ - public boolean isSingular() { - return inflection.isSingular(word); - } - - /** - * Check if this noun is plural. - * - * @return Whether or not this noun is plural. - */ - public boolean isPlural() { - return inflection.isPlural(word); - } - - /** - * Get the singular form of this noun. - * - * @return The singular form of this noun. - */ - public String singular() { - return inflection.singularize(word); - } - - /** - * Get the plural form of this noun. - * - * @return The plural form of this noun. - */ - public String plural() { - return inflection.pluralize(word); - } - - @Override - public String toString() { - return String.format(TOSTRING_FMT, word, inflection); - } - - /** - * Get the modern plural form of this noun. - * - * @return The modern plural form of this noun. - */ - public String modernPlural() { - return inflection.pluralizeModern(word); - } - - /** - * Get the classical plural form of this noun. - * - * @return The classical plural form of this noun. - */ - public String classicalPlural() { - return inflection.pluralizeClassical(word); - } -} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/NounInflection.java b/src/main/java/bjc/inflexion/NounInflection.java deleted file mode 100644 index f34b80c..0000000 --- a/src/main/java/bjc/inflexion/NounInflection.java +++ /dev/null @@ -1,113 +0,0 @@ -/** - * (C) Copyright 2017 Benjamin Culkin. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package bjc.inflexion; - -/** - * Interface for inflecting nouns. - * - * @author EVE - * - */ -public interface NounInflection { - /** - * Check if a noun matches this inflection. - * - * @param noun - * The noun to check on this inflection. - * - * @return Whether or not the noun belongs to the inflection. - */ - public boolean matches(String noun); - - /** - * Check if a noun for this inflection is singular or not. - * - * @param noun - * The noun to check for singularity. - * - * @return Whether or not the noun is singular. - * - * @throws InflectionException - * If the noun isn't part of this inflection. - */ - public boolean isSingular(String noun); - - /** - * Check if a noun for this inflection is plural or not. - * - * @param noun - * The noun to check for plurality. - * - * @return Whether or not the noun is plural. - * - * @throws InflectionException - * If the noun isn't part of this inflection. - */ - public boolean isPlural(String noun); - - /** - * Convert a singular noun to a plural noun. - * - * @param plural - * The plural noun to inflect to a singular form. - * - * @return The singular form of the noun. - * - * @throws InflectionException - * If the noun isn't part of the inflection. - */ - public String singularize(String plural); - - /** - * Convert a singular noun to a plural noun. - * - * @param singular - * The singular noun to inflect to a plural form. - * - * @return The plural form of the noun. - * - * @throws InflectionException - * If the noun isn't part of the inflection. - */ - public String pluralize(String singular); - - /** - * Convert a singular noun to a modern plural noun. - * - * @param singular - * The singular noun to inflect to a modern plural form. - * - * @return The modern plural form of the noun. - * - * @throws InflectionException - * If the noun isn't part of the inflection. - */ - public String pluralizeModern(String singular); - - /** - * Convert a singular noun to a classical plural noun. - * - * @param singular - * The singular noun to inflect to a classical plural - * form. - * - * @return The classical plural form of the noun. - * - * @throws InflectionException - * If the noun isn't part of the inflection. - */ - public String pluralizeClassical(String singular); -} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/Nouns.java b/src/main/java/bjc/inflexion/Nouns.java deleted file mode 100644 index 2fe4381..0000000 --- a/src/main/java/bjc/inflexion/Nouns.java +++ /dev/null @@ -1,329 +0,0 @@ -/** - * (C) Copyright 2017 Benjamin Culkin. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package bjc.inflexion; - -import static bjc.inflexion.InflectionAffixes.*; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Scanner; -import java.util.regex.Pattern; - -/** - * @author EVE - * - */ -public class Nouns { - private static final DefaultNounInflection DEFAULT_INFLECTION = new DefaultNounInflection(); - - private Prepositions prepositionDB; - - private Map userIrregulars; - private List userInflections; - - private Map predefinedIrregulars; - private List predefinedInflections; - - /** - * Create a new empty noun DB. - * - * @param prepDB - * The source for prepositions. - */ - public Nouns(Prepositions prepDB) { - prepositionDB = prepDB; - - userIrregulars = new HashMap<>(); - userInflections = new LinkedList<>(); - - predefinedIrregulars = new HashMap<>(); - predefinedInflections = new LinkedList<>(); - } - - /** - * Retrieve a noun with its inflection from the database of inflections. - * - * @param noun - * The noun to retrieve. - * - * @return The noun with its inflection. - * - * @throws InflectionException - * If the noun matched no inflection. - */ - public Noun getNoun(String noun) { - if(userIrregulars.containsKey(noun)) return new Noun(noun, userIrregulars.get(noun)); - for(NounInflection inflect : userInflections) { - if(inflect.matches(noun)) return new Noun(noun, inflect); - } - - if(predefinedIrregulars.containsKey(noun)) return new Noun(noun, predefinedIrregulars.get(noun)); - for(NounInflection inflect : predefinedInflections) { - if(inflect.matches(noun)) return new Noun(noun, inflect); - } - - return new Noun(noun, DEFAULT_INFLECTION); - } - - /** - * Load the contents of the stream into this DB. - * - * @param stream - * The stream to load from. - */ - public void loadFromStream(InputStream stream) { - try(Scanner scn = new Scanner(stream)) { - while(scn.hasNextLine()) { - String ln = scn.nextLine().trim(); - - /* - * Ignore comments and blank lines. - */ - if(ln.startsWith("#")) continue; - if(ln.equals("")) continue; - - if(ln.contains("-")) { - handleLine(ln); - handleLine(ln.replace('-', ' ')); - } else { - handleLine(ln); - } - } - } - } - - private void handleLine(String ln) { - String[] parts = ln.split(Pattern.quote("=>")); - - if(parts.length != 2) { - String msg = String.format("Improperly formatted noun defn '%s'", ln); - - throw new InflectionException(msg); - } - - String singular = parts[0].trim(); - String plural = parts[1].trim(); - - String modernPlural = ""; - String classicalPlural = ""; - - if(plural.contains("|")) { - String[] plurals = plural.split(Pattern.quote("|")); - - if(plurals.length == 1) { - modernPlural = plurals[0].trim(); - } else { - modernPlural = plurals[0].trim(); - classicalPlural = plurals[1].trim(); - } - - if(modernPlural.equals("")) modernPlural = null; - if(classicalPlural.equals("")) classicalPlural = null; - } else { - modernPlural = plural; - classicalPlural = null; - } - - if(singular.contains("(SING)")) { - handleCompoundPlural(singular, modernPlural, classicalPlural); - } else if(singular.startsWith("*")) { - handleCompletePlural(singular, modernPlural, classicalPlural); - } else if(singular.startsWith("-")) { - handleIncompletePlural(singular, modernPlural, classicalPlural); - } else { - handleIrregularPlural(singular, modernPlural, classicalPlural); - } - } - - private void handleCompoundPlural(String singular, String modernPlural, String classicalPlural) { - String actSingular = singular; - String actModern = modernPlural == null ? "" : modernPlural; - String actClassical = classicalPlural == null ? "" : classicalPlural; - - String singularPatt = actSingular.replaceAll(Pattern.quote("(SING)"), "(?\\\\w+)"); - String modernPatt = actModern.replaceAll(Pattern.quote("(PL)"), "(?\\\\w+)"); - String classicalPatt = actClassical.replaceAll(Pattern.quote("(PL)"), "(?\\\\w+)"); - - actSingular = actSingular.replaceAll(Pattern.quote("(SING)"), "%1\\$s"); - actModern = actModern.replaceAll(Pattern.quote("(PL)"), "%1\\$s"); - actClassical = actClassical.replaceAll(Pattern.quote("(PL)"), "%1\\$s"); - - List inflections = new ArrayList<>(3); - - if(singular.contains("(PREP)")) { - handleCompoundPreposition(actSingular, actModern, actClassical, singularPatt, modernPatt, - classicalPatt, inflections); - } else { - handleCompound(actSingular, actModern, actClassical, singularPatt, modernPatt, classicalPatt, - inflections); - } - - for(NounInflection inf : inflections) { - predefinedInflections.add(inf); - } - } - - private void handleCompound(String actSingular, String actModern, String actClassical, String singularPatt, - String modernPatt, String classicalPatt, List inflections) { - if(singularPatt.contains("*")) { - singularPatt = singularPatt.replaceAll(Pattern.quote("*"), "(?\\\\w+)"); - modernPatt = modernPatt.replaceAll(Pattern.quote("*"), "(?\\\\w+)"); - classicalPatt = classicalPatt.replaceAll(Pattern.quote("*"), "(?\\\\w+)"); - - actSingular = actSingular.replaceAll(Pattern.quote("*"), "%2\\$s"); - actModern = actModern.replaceAll(Pattern.quote("*"), "%2\\$s"); - actClassical = actClassical.replaceAll(Pattern.quote("*"), "%2\\$s"); - - handleNonpluralCompound(actSingular, actModern, actClassical, singularPatt, modernPatt, - classicalPatt, inflections, true); - } else { - handleNonpluralCompound(actSingular, actModern, actClassical, singularPatt, modernPatt, - classicalPatt, inflections, false); - } - } - - private void handleNonpluralCompound(String actSingular, String actModern, String actClassical, - String singularPatt, String modernPatt, String classicalPatt, - List inflections, boolean hasScratch) { - actModern = actModern.equals("") ? null : actModern; - actClassical = actClassical.equals("") ? null : actClassical; - - CompoundNounInflection singularInflection = new CompoundNounInflection(this, prepositionDB, - Pattern.compile(singularPatt), actSingular, actModern, actClassical, false, hasScratch); - - inflections.add(singularInflection); - - if(!modernPatt.equals("")) { - CompoundNounInflection modernInflection = new CompoundNounInflection(this, prepositionDB, - Pattern.compile(modernPatt), actSingular, actModern, actClassical, false, - hasScratch); - - inflections.add(modernInflection); - } - - if(!classicalPatt.equals("")) { - CompoundNounInflection classicalInflection = new CompoundNounInflection(this, prepositionDB, - Pattern.compile(classicalPatt), actSingular, actModern, actClassical, false, - hasScratch); - - inflections.add(classicalInflection); - } - } - - private void handleCompoundPreposition(String actSingular, String actModern, String actClassical, - String singularPatt, String modernPatt, String classicalPatt, - List inflections) { - singularPatt = singularPatt.replaceAll(Pattern.quote("(PREP)"), "(?\\\\w+)"); - modernPatt = modernPatt.replaceAll(Pattern.quote("(PREP)"), "(?\\\\w+)"); - classicalPatt = classicalPatt.replaceAll(Pattern.quote("(PREP)"), "(?\\\\w+)"); - - actSingular = actSingular.replaceAll(Pattern.quote("(PREP)"), "%2\\$s"); - actModern = actModern.replaceAll(Pattern.quote("(PREP)"), "%2\\$s"); - actClassical = actClassical.replaceAll(Pattern.quote("(PREP)"), "%2\\$s"); - - if(singularPatt.contains("*")) { - singularPatt = singularPatt.replaceAll(Pattern.quote("*"), "(?\\\\w+)"); - modernPatt = modernPatt.replaceAll(Pattern.quote("*"), "(?\\\\w+)"); - classicalPatt = classicalPatt.replaceAll(Pattern.quote("*"), "(?\\\\w+)"); - - actSingular = actSingular.replaceAll(Pattern.quote("*"), "%3\\$s"); - actModern = actModern.replaceAll(Pattern.quote("*"), "%3\\$s"); - actClassical = actClassical.replaceAll(Pattern.quote("*"), "%3\\$s"); - - actModern = actModern.equals("") ? null : actModern; - actClassical = actClassical.equals("") ? null : actClassical; - - addCompoundInflections(actSingular, actModern, actClassical, singularPatt, modernPatt, - classicalPatt, inflections, true); - } else { - addCompoundInflections(actSingular, actModern, actClassical, singularPatt, modernPatt, - classicalPatt, inflections, false); - } - } - - private void addCompoundInflections(String actSingular, String actModern, String actClassical, - String singularPatt, String modernPatt, String classicalPatt, - List inflections, boolean hasScratch) { - CompoundNounInflection singularInflection = new CompoundNounInflection(this, prepositionDB, - Pattern.compile(singularPatt), actSingular, actModern, actClassical, true, hasScratch); - - inflections.add(singularInflection); - - if(!modernPatt.equals("")) { - CompoundNounInflection modernInflection = new CompoundNounInflection(this, prepositionDB, - Pattern.compile(modernPatt), actSingular, actModern, actClassical, true, - hasScratch); - - inflections.add(modernInflection); - } - - if(!classicalPatt.equals("")) { - CompoundNounInflection classicalInflection = new CompoundNounInflection(this, prepositionDB, - Pattern.compile(classicalPatt), actSingular, actModern, actClassical, true, - hasScratch); - - inflections.add(classicalInflection); - } - } - - private void handleIncompletePlural(String singular, String modernPlural, String classicalPlural) { - InflectionAffix singularAffix = incomplete(singular.substring(1)); - - InflectionAffix modernAffix = null; - InflectionAffix classicalAffix = null; - - if(modernPlural != null) modernAffix = incomplete(modernPlural.substring(1)); - if(classicalPlural != null) classicalAffix = incomplete(classicalPlural.substring(1)); - - CategoricalNounInflection inflection = new CategoricalNounInflection(singularAffix, modernAffix, - classicalAffix); - - predefinedInflections.add(inflection); - } - - private void handleCompletePlural(String singular, String modernPlural, String classicalPlural) { - InflectionAffix singularAffix = complete(singular.substring(1)); - - InflectionAffix modernAffix = null; - InflectionAffix classicalAffix = null; - - if(modernPlural != null) modernAffix = complete(modernPlural.substring(1)); - if(classicalPlural != null) classicalAffix = complete(classicalPlural.substring(1)); - - CategoricalNounInflection inflection = new CategoricalNounInflection(singularAffix, modernAffix, - classicalAffix); - - predefinedInflections.add(inflection); - } - - private void handleIrregularPlural(String singular, String modernPlural, String classicalPlural) { - IrregularNounInflection inflection = new IrregularNounInflection(singular, modernPlural, - classicalPlural, false); - - if(!predefinedIrregulars.containsKey(singular)) { - predefinedIrregulars.put(singular, inflection); - } - - if(modernPlural != null && !predefinedIrregulars.containsKey(modernPlural)) - predefinedIrregulars.put(modernPlural, inflection); - if(classicalPlural != null && !predefinedIrregulars.containsKey(classicalPlural)) - predefinedIrregulars.put(classicalPlural, inflection); - } -} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/Prepositions.java b/src/main/java/bjc/inflexion/Prepositions.java deleted file mode 100644 index 18767d0..0000000 --- a/src/main/java/bjc/inflexion/Prepositions.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * (C) Copyright 2017 Benjamin Culkin. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package bjc.inflexion; - -import java.io.InputStream; -import java.util.HashSet; -import java.util.Scanner; -import java.util.Set; - -/** - * List of prepositions. - * - * @author EVE - * - */ -public class Prepositions { - private Set prepositions; - - /** - * Create an empty preposition DB. - */ - public Prepositions() { - prepositions = new HashSet<>(); - } - - /** - * Check if a word is a preposition. - * - * @param word - * The word as a preposition. - * - * @return Whether or not the word is a preposition. - */ - public boolean isPreposition(String word) { - return prepositions.contains(word); - } - - /** - * Load the contents of the stream into this DB. - * - * @param stream - * The stream to load from. - */ - public void loadFromStream(InputStream stream) { - try(Scanner scn = new Scanner(stream)) { - while(scn.hasNextLine()) { - String ln = scn.nextLine().trim(); - - /* - * Ignore comments - */ - if(ln.startsWith("#")) continue; - - prepositions.add(ln); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/SimpleInflectionAffix.java b/src/main/java/bjc/inflexion/SimpleInflectionAffix.java deleted file mode 100644 index 10376f9..0000000 --- a/src/main/java/bjc/inflexion/SimpleInflectionAffix.java +++ /dev/null @@ -1,103 +0,0 @@ -/** - * (C) Copyright 2017 Benjamin Culkin. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package bjc.inflexion; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Simple implementation of {@link InflectionAffix} - * - * @author EVE - * - */ -public class SimpleInflectionAffix implements InflectionAffix { - private static final String TOSTRING_FMT = "SimpleInflectionAffix [affixTemplate=%s, affixMatcher=%s]"; - - private String affixTemplate; - - private Pattern affixMatcher; - - /** - * Create a new inflection affix. - * - * @param affixTemplate - * The template for applying the affix, Should be a - * printf-style format string with a single string blank. - * - * @param affixMatcher - * The regular expression that matches the affix on - * strings. The 'stem' or word should be placed in a - * named capturing group named 'stem'. - */ - public SimpleInflectionAffix(String affixTemplate, Pattern affixMatcher) { - this.affixTemplate = affixTemplate; - this.affixMatcher = affixMatcher; - } - - @Override - public boolean hasAffix(String word) { - return affixMatcher.matcher(word).matches(); - } - - @Override - public String deaffix(String word) { - Matcher matcher = affixMatcher.matcher(word); - matcher.matches(); - - return matcher.group("stem"); - } - - @Override - public String affix(String word) { - return String.format(affixTemplate, word); - } - - @Override - public String toString() { - return String.format(TOSTRING_FMT, affixTemplate, affixMatcher); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - - result = prime * result + ((affixMatcher == null) ? 0 : affixMatcher.hashCode()); - result = prime * result + ((affixTemplate == null) ? 0 : affixTemplate.hashCode()); - - return result; - } - - @Override - public boolean equals(Object obj) { - if(this == obj) return true; - if(obj == null) return false; - if(!(obj instanceof SimpleInflectionAffix)) return false; - - SimpleInflectionAffix other = (SimpleInflectionAffix) obj; - - if(affixTemplate == null) { - if(other.affixTemplate != null) return false; - } else if(!affixTemplate.equals(other.affixTemplate)) return false; - - if(affixMatcher == null) { - if(other.affixMatcher != null) return false; - } else if(!affixMatcher.equals(other.affixMatcher)) return false; - - return true; - } -} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/nouns/CategoricalNounInflection.java b/src/main/java/bjc/inflexion/nouns/CategoricalNounInflection.java new file mode 100644 index 0000000..136d393 --- /dev/null +++ b/src/main/java/bjc/inflexion/nouns/CategoricalNounInflection.java @@ -0,0 +1,192 @@ +/** + * (C) Copyright 2017 Benjamin Culkin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package bjc.inflexion.nouns; + +/** + * Implementation of {@link NounInflection} for nouns matched by a regular + * expression. + * + * @author EVE + * + */ +public class CategoricalNounInflection implements NounInflection { + private static final String TOSTRING_FMT = "CategoricalNounInflection [singular=%s, modernPlural=%s," + + " classicalPlural=%s]"; + + private InflectionAffix singular; + + private InflectionAffix modernPlural; + private InflectionAffix classicalPlural; + + /** + * Create a new categorical inflection. + * + * @param singlar + * The affix for the singular form. + * + * @param modrnPlural + * The affix for the modern plural. + * + * @param classiclPlural + * The affix for the classical plural. + */ + public CategoricalNounInflection(InflectionAffix singlar, InflectionAffix modrnPlural, + InflectionAffix classiclPlural) { + if(singlar == null) + throw new NullPointerException("Singular form must not be null"); + else if(modrnPlural == null && classiclPlural == null) + throw new NullPointerException("One of modern/classical plural forms must not be null"); + + singular = singlar; + modernPlural = modrnPlural; + classicalPlural = classiclPlural; + } + + @Override + public boolean matches(String noun) { + if(singular.hasAffix(noun)) + return true; + else if(modernPlural != null && modernPlural.hasAffix(noun)) + return true; + else if(classicalPlural != null && classicalPlural.hasAffix(noun)) + return true; + else + return false; + } + + @Override + public boolean isSingular(String noun) { + if(singular.hasAffix(noun)) + return true; + else if(matchesPlural(noun)) + return false; + else { + String msg = String.format("Noun '%s' doesn't belong to this inflection", noun, this); + + throw new InflectionException(msg); + } + } + + @Override + public boolean isPlural(String noun) { + if(singular.hasAffix(noun)) + return false; + else if(matchesPlural(noun)) + return true; + else { + String msg = String.format("Noun '%s' doesn't belong to this inflection", noun, this); + + throw new InflectionException(msg); + } + } + + @Override + public String singularize(String plural) { + if(singular.hasAffix(plural)) + return plural; + else if(modernPlural != null && modernPlural.hasAffix(plural)) + return singular.affix(modernPlural.deaffix(plural)); + else if(classicalPlural != null && classicalPlural.hasAffix(plural)) + return singular.affix(classicalPlural.deaffix(plural)); + else { + String msg = String.format("Noun '%s' doesn't belong to this inflection", plural, this); + + throw new InflectionException(msg); + } + } + + @Override + public String pluralize(String singlar) { + if(singular.hasAffix(singlar)) { + if(modernPlural == null) { + return classicalPlural.affix(singular.deaffix(singlar)); + } else { + return modernPlural.affix(singular.deaffix(singlar)); + } + } else if(matchesPlural(singlar)) { + return singlar; + } else { + String msg = String.format("Noun '%s' doesn't belong to this inflection", singlar, this); + + throw new InflectionException(msg); + } + } + + private boolean matchesPlural(String noun) { + boolean hasModernPlural = modernPlural != null && modernPlural.hasAffix(noun); + + return hasModernPlural || (classicalPlural != null && classicalPlural.hasAffix(noun)); + } + + @Override + public String toString() { + return String.format(TOSTRING_FMT, singular, modernPlural, classicalPlural); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + + result = prime * result + ((classicalPlural == null) ? 0 : classicalPlural.hashCode()); + result = prime * result + ((modernPlural == null) ? 0 : modernPlural.hashCode()); + + return result; + } + + @Override + public boolean equals(Object obj) { + if(this == obj) return true; + if(obj == null) return false; + if(!(obj instanceof CategoricalNounInflection)) return false; + + CategoricalNounInflection other = (CategoricalNounInflection) obj; + + if(classicalPlural == null) { + if(other.classicalPlural != null) return false; + } else if(!classicalPlural.equals(other.classicalPlural)) return false; + + if(modernPlural == null) { + if(other.modernPlural != null) return false; + } else if(!modernPlural.equals(other.modernPlural)) return false; + + return true; + } + + @Override + public String pluralizeModern(String singlar) { + if(modernPlural == null) return pluralizeClassical(singlar); + + String actSinglar = singlar; + if(isPlural(singlar)) { + actSinglar = singularize(singlar); + } + + return modernPlural.affix(singular.deaffix(actSinglar)); + } + + @Override + public String pluralizeClassical(String singlar) { + if(classicalPlural == null) return pluralizeModern(singlar); + + String actSinglar = singlar; + if(isPlural(singlar)) { + actSinglar = singularize(singlar); + } + + return classicalPlural.affix(singular.deaffix(actSinglar)); + } +} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/nouns/CompoundNounInflection.java b/src/main/java/bjc/inflexion/nouns/CompoundNounInflection.java new file mode 100644 index 0000000..2eb0813 --- /dev/null +++ b/src/main/java/bjc/inflexion/nouns/CompoundNounInflection.java @@ -0,0 +1,244 @@ +/** + * (C) Copyright 2017 Benjamin Culkin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package bjc.inflexion.nouns; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Implementation of {@link NounInflection} for words that don't inflect at the + * end. + * + * @author EVE + * + */ +public class CompoundNounInflection implements NounInflection { + private static final String TOSTRING_FMT = "CompoundNounInflection [compoundMatcher=%s, singularPattern=%s," + + " modernPluralPattern=%s, classicalPluralPattern=%s, hasPreposition=%s]"; + /* + * Data stores for use. + */ + private Nouns nounDB; + private Prepositions prepositionDB; + + private Pattern compoundMatcher; + + private String singularPattern; + + private String modernPluralPattern; + private String classicalPluralPattern; + + /* + * Whether or not this inflection takes a preposition. + */ + private boolean hasPreposition; + + /* + * Whether or not there is a scratch word in place. + */ + private boolean hasScratch; + + /** + * TODO fill in documentation. + * + * @param nounDB + * @param prepositionDB + * @param compoundMatcher + * @param singularPattern + * @param modernPluralPattern + * @param classicalPluralPattern + * @param hasPreposition + * @param hasScrtch + */ + public CompoundNounInflection(Nouns nounDB, Prepositions prepositionDB, Pattern compoundMatcher, + String singularPattern, String modernPluralPattern, String classicalPluralPattern, + boolean hasPreposition, boolean hasScrtch) { + this.nounDB = nounDB; + this.prepositionDB = prepositionDB; + this.compoundMatcher = compoundMatcher; + this.singularPattern = singularPattern; + this.modernPluralPattern = modernPluralPattern; + this.classicalPluralPattern = classicalPluralPattern; + this.hasPreposition = hasPreposition; + hasScratch = hasScrtch; + } + + @Override + public boolean matches(String noun) { + Matcher matcher = compoundMatcher.matcher(noun); + + if(matcher.matches()) { + Noun actNoun = nounDB.getNoun(matcher.group("noun")); + + if(actNoun == null) return false; + + if(hasPreposition) { + return prepositionDB.isPreposition(matcher.group("preposition")); + } else + return true; + } else { + return false; + } + } + + @Override + public boolean isSingular(String noun) { + Matcher matcher = compoundMatcher.matcher(noun); + Noun actNoun = nounDB.getNoun(matcher.group("noun")); + + return actNoun.isSingular(); + } + + @Override + public boolean isPlural(String noun) { + Matcher matcher = compoundMatcher.matcher(noun); + Noun actNoun = nounDB.getNoun(matcher.group("noun")); + + return actNoun.isPlural(); + } + + @Override + public String singularize(String plural) { + Matcher matcher = compoundMatcher.matcher(plural); + Noun actNoun = getNoun(matcher); + + if(hasPreposition && hasScratch) { + return String.format(singularPattern, actNoun.singular(), matcher.group("preposition"), + matcher.group("scratch")); + } else if(hasScratch) { + return String.format(singularPattern, actNoun.singular(), matcher.group("scratch")); + } else if(hasPreposition) { + return String.format(singularPattern, actNoun.singular(), matcher.group("preposition")); + } else { + return String.format(singularPattern, actNoun.singular()); + } + } + + @Override + public String pluralize(String singular) { + Matcher matcher = compoundMatcher.matcher(singular); + Noun actNoun = getNoun(matcher); + + String patt = modernPluralPattern == null ? classicalPluralPattern : modernPluralPattern; + + if(hasPreposition && hasScratch) { + return String.format(patt, actNoun.plural(), matcher.group("preposition"), + matcher.group("scratch")); + } else if(hasScratch) { + return String.format(patt, actNoun.plural(), matcher.group("scratch")); + } else if(hasPreposition) { + return String.format(patt, actNoun.plural(), matcher.group("preposition")); + } else { + return String.format(patt, actNoun.plural()); + } + } + + @Override + public String pluralizeModern(String singular) { + if(modernPluralPattern == null) return pluralizeClassical(singular); + + Matcher matcher = compoundMatcher.matcher(singular); + Noun actNoun = getNoun(matcher); + + if(hasPreposition && hasScratch) { + return String.format(modernPluralPattern, actNoun.modernPlural(), matcher.group("preposition"), + matcher.group("scratch")); + } else if(hasScratch) { + return String.format(modernPluralPattern, actNoun.modernPlural(), matcher.group("scratch")); + } else if(hasPreposition) { + return String.format(modernPluralPattern, actNoun.modernPlural(), matcher.group("preposition")); + } else { + return String.format(modernPluralPattern, actNoun.modernPlural()); + } + } + + @Override + public String pluralizeClassical(String singular) { + if(classicalPluralPattern == null) return pluralizeModern(singular); + + Matcher matcher = compoundMatcher.matcher(singular); + Noun actNoun = getNoun(matcher); + + if(hasPreposition && hasScratch) { + return String.format(classicalPluralPattern, actNoun.classicalPlural(), + matcher.group("preposition"), matcher.group("scratch")); + } else if(hasScratch) { + return String.format(classicalPluralPattern, actNoun.classicalPlural(), + matcher.group("scratch")); + } else if(hasPreposition) { + return String.format(classicalPluralPattern, actNoun.classicalPlural(), + matcher.group("preposition")); + } else { + return String.format(classicalPluralPattern, actNoun.classicalPlural()); + } + } + + private Noun getNoun(Matcher matcher) { + matcher.matches(); + + Noun actNoun = nounDB.getNoun(matcher.group("noun")); + return actNoun; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + + result = prime * result + ((classicalPluralPattern == null) ? 0 : classicalPluralPattern.hashCode()); + result = prime * result + ((compoundMatcher == null) ? 0 : compoundMatcher.hashCode()); + result = prime * result + (hasPreposition ? 1231 : 1237); + result = prime * result + ((modernPluralPattern == null) ? 0 : modernPluralPattern.hashCode()); + result = prime * result + ((singularPattern == null) ? 0 : singularPattern.hashCode()); + + return result; + } + + @Override + public boolean equals(Object obj) { + if(this == obj) return true; + if(obj == null) return false; + if(!(obj instanceof CompoundNounInflection)) return false; + + CompoundNounInflection other = (CompoundNounInflection) obj; + + if(singularPattern == null) { + if(other.singularPattern != null) return false; + } else if(!singularPattern.equals(other.singularPattern)) return false; + + if(classicalPluralPattern == null) { + if(other.classicalPluralPattern != null) return false; + } else if(!classicalPluralPattern.equals(other.classicalPluralPattern)) return false; + + if(hasPreposition != other.hasPreposition) return false; + + if(modernPluralPattern == null) { + if(other.modernPluralPattern != null) return false; + } else if(!modernPluralPattern.equals(other.modernPluralPattern)) return false; + + if(compoundMatcher == null) { + if(other.compoundMatcher != null) return false; + } else if(!compoundMatcher.equals(other.compoundMatcher)) return false; + + return true; + } + + @Override + public String toString() { + return String.format(TOSTRING_FMT, compoundMatcher, singularPattern, modernPluralPattern, + classicalPluralPattern, hasPreposition); + } +} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/nouns/DefaultNounInflection.java b/src/main/java/bjc/inflexion/nouns/DefaultNounInflection.java new file mode 100644 index 0000000..458c3f2 --- /dev/null +++ b/src/main/java/bjc/inflexion/nouns/DefaultNounInflection.java @@ -0,0 +1,68 @@ +/** + * (C) Copyright 2017 Benjamin Culkin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package bjc.inflexion.nouns; + +/** + * Default noun inflection for english nouns. + * + * @author EVE + * + */ +public class DefaultNounInflection implements NounInflection { + @Override + public boolean matches(String noun) { + return true; + } + + @Override + public boolean isSingular(String noun) { + return !noun.endsWith("s"); + } + + @Override + public boolean isPlural(String noun) { + return noun.endsWith("s"); + } + + @Override + public String singularize(String plural) { + if(plural.endsWith("ses")) { + return plural.substring(0, plural.length() - 3); + } else if(plural.endsWith("s")) { + return plural.substring(0, plural.length() - 1); + } else + return plural; + } + + @Override + public String pluralize(String singular) { + if(singular.endsWith("s")) { + return singular + "es"; + } + + return singular + "s"; + } + + @Override + public String pluralizeModern(String singular) { + return pluralize(singular); + } + + @Override + public String pluralizeClassical(String singular) { + return pluralize(singular); + } +} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/nouns/InflectionAffix.java b/src/main/java/bjc/inflexion/nouns/InflectionAffix.java new file mode 100644 index 0000000..d8c8cb4 --- /dev/null +++ b/src/main/java/bjc/inflexion/nouns/InflectionAffix.java @@ -0,0 +1,56 @@ +/** + * (C) Copyright 2017 Benjamin Culkin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package bjc.inflexion.nouns; + +/** + * An affix attached to a word and used for inflection. + * + * @author EVE + * + */ +public interface InflectionAffix { + + /** + * Check if a word has this affix. + * + * @param word + * The word to check. + * + * @return Whether or not the word has the affix. + */ + boolean hasAffix(String word); + + /** + * Remove the affix from a word. + * + * @param word + * The word to remove the affix from. + * + * @return The word with the affix removed. + */ + String deaffix(String word); + + /** + * Apply this affix to a word. + * + * @param word + * The word to apply the affix to. + * + * @return The word with the affix applied. + */ + String affix(String word); + +} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/nouns/InflectionAffixes.java b/src/main/java/bjc/inflexion/nouns/InflectionAffixes.java new file mode 100644 index 0000000..4061776 --- /dev/null +++ b/src/main/java/bjc/inflexion/nouns/InflectionAffixes.java @@ -0,0 +1,74 @@ +/** + * (C) Copyright 2017 Benjamin Culkin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package bjc.inflexion.nouns; + +import java.util.regex.Pattern; + +/** + * Utility methods for constructing inflection affixes. + * + * @author EVE + * + */ +public class InflectionAffixes { + /* + * Template for 'complete' affix patterns. + * + * Match the start of the word, followed by zero or more word + * characters, followed by the suffix, then the end of the string. + * + * The word is in a capturing group named 'stem'. + */ + private static final String COMPLETE_PATT_FMT = "(?\\w*)%s$"; + + /* + * Template for 'incomplete' affix patterns. + * + * Match the start of the word, followed by one or more word characters, + * followed by the suffix, then the end of the string. + * + * The word is in a capturing group named 'stem'. + */ + private static final String INCOMPLETE_PATT_FMT = "(?\\w+)%s$"; + + /** + * Create an affix that's a word by itself. + * + * @param suffix + * The suffix to use. + * + * @return A affix that represents the suffix. + */ + public static InflectionAffix complete(String suffix) { + Pattern patt = Pattern.compile(String.format(COMPLETE_PATT_FMT, suffix)); + + return new SimpleInflectionAffix("%s" + suffix, patt); + } + + /** + * Create an affix that's not a word by itself. + * + * @param suffix + * The suffix to use. + * + * @return An affix that represents the suffix. + */ + public static InflectionAffix incomplete(String suffix) { + Pattern patt = Pattern.compile(String.format(INCOMPLETE_PATT_FMT, suffix)); + + return new SimpleInflectionAffix("%s" + suffix, patt); + } +} diff --git a/src/main/java/bjc/inflexion/nouns/InflectionException.java b/src/main/java/bjc/inflexion/nouns/InflectionException.java new file mode 100644 index 0000000..a2d92bc --- /dev/null +++ b/src/main/java/bjc/inflexion/nouns/InflectionException.java @@ -0,0 +1,49 @@ +/** + * (C) Copyright 2017 Benjamin Culkin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package bjc.inflexion.nouns; + +/** + * Exception thrown when something goes wrong with inflection. + * + * @author EVE + * + */ +public class InflectionException extends RuntimeException { + private static final long serialVersionUID = 5680541587449153748L; + + /** + * Create a new inflection exception with the given message and cause. + * + * @param message + * The message of the exception. + * + * @param cause + * The cause of the exception. + */ + public InflectionException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Create a new inflection exception with the given message. + * + * @param message + * The message of the exception. + */ + public InflectionException(String message) { + super(message); + } +} diff --git a/src/main/java/bjc/inflexion/nouns/IrregularNounInflection.java b/src/main/java/bjc/inflexion/nouns/IrregularNounInflection.java new file mode 100644 index 0000000..772c5a9 --- /dev/null +++ b/src/main/java/bjc/inflexion/nouns/IrregularNounInflection.java @@ -0,0 +1,197 @@ +/** + * (C) Copyright 2017 Benjamin Culkin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package bjc.inflexion.nouns; + +/** + * Implementation of {@link NounInflection} for irregular nouns. + * + * @author EVE + * + */ +public class IrregularNounInflection implements NounInflection { + private static final String TOSTRING_FMT = "IrregularNounInflection [singular=%s, modernPlural=%s," + + " classicalPlural=%s, preferClassical=%s]"; + + private String singular; + + private String modernPlural; + private String classicalPlural; + + private boolean preferClassical; + + /** + * Create a new irregular noun inflection. + * + * @param singlar + * The singular form of the noun. + * + * @param modrnPlural + * The modern plural of the noun. + * + * @param classiclPlural + * The classical plural of the noun. + * + * @param prefrClassical + * Whether the classical form should be preferred if it + * is available. + */ + public IrregularNounInflection(String singlar, String modrnPlural, String classiclPlural, + boolean prefrClassical) { + if(singlar == null) throw new NullPointerException("Singular form must not be null"); + if(modrnPlural == null && classiclPlural == null) + throw new NullPointerException("One of modern/classical plural forms must not be null"); + + singular = singlar; + modernPlural = modrnPlural; + classicalPlural = classiclPlural; + preferClassical = prefrClassical; + } + + @Override + public boolean matches(String noun) { + if(noun.equalsIgnoreCase(singular)) + return true; + else if(noun.equalsIgnoreCase(modernPlural)) + return true; + else if(noun.equalsIgnoreCase(classicalPlural)) + return true; + else + return false; + } + + @Override + public boolean isSingular(String noun) { + if(noun.equalsIgnoreCase(singular)) + return true; + else if(matchesPlural(noun)) + return false; + else { + String msg = String.format("Noun '%s' doesn't belong to this inflection '%s'", noun, this); + + throw new InflectionException(msg); + } + } + + @Override + public boolean isPlural(String noun) { + if(noun.equalsIgnoreCase(singular)) + return false; + else if(matchesPlural(noun)) + return true; + else { + String msg = String.format("Noun '%s' doesn't belong to this inflection '%s'", noun, this); + + throw new InflectionException(msg); + } + } + + @Override + public String singularize(String plural) { + if(plural.equalsIgnoreCase(singular)) + return singular; + else if(matchesPlural(plural)) + return singular; + else { + String msg = String.format("Noun '%s' doesn't belong to this inflection '%s'", plural, this); + + throw new InflectionException(msg); + } + } + + @Override + public String pluralize(String singular) { + if(singular.equalsIgnoreCase(singular)) + return getPlural(); + else if(matchesPlural(singular)) + return getPlural(); + else { + String msg = String.format("Noun '%s' doesn't belong to this inflection '%s'", singular, this); + + throw new InflectionException(msg); + } + } + + private String getPlural() { + if(preferClassical) { + if(classicalPlural == null) + return modernPlural; + else + return classicalPlural; + } else if(modernPlural == null) { + return classicalPlural; + } else { + return modernPlural; + } + } + + private boolean matchesPlural(String noun) { + return noun.equalsIgnoreCase(modernPlural) || noun.equalsIgnoreCase(classicalPlural); + } + + @Override + public String toString() { + return String.format(TOSTRING_FMT, singular, modernPlural, classicalPlural, preferClassical); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + + result = prime * result + ((classicalPlural == null) ? 0 : classicalPlural.hashCode()); + result = prime * result + ((modernPlural == null) ? 0 : modernPlural.hashCode()); + result = prime * result + ((singular == null) ? 0 : singular.hashCode()); + + return result; + } + + @Override + public boolean equals(Object obj) { + if(this == obj) return true; + if(obj == null) return false; + if(!(obj instanceof IrregularNounInflection)) return false; + + IrregularNounInflection other = (IrregularNounInflection) obj; + + if(singular == null) { + if(other.singular != null) return false; + } else if(!singular.equals(other.singular)) return false; + + if(classicalPlural == null) { + if(other.classicalPlural != null) return false; + } else if(!classicalPlural.equals(other.classicalPlural)) return false; + + if(modernPlural == null) { + if(other.modernPlural != null) return false; + } else if(!modernPlural.equals(other.modernPlural)) return false; + + return true; + } + + @Override + public String pluralizeModern(String singular) { + if(modernPlural == null) return pluralizeClassical(singular); + + return modernPlural; + } + + @Override + public String pluralizeClassical(String singular) { + if(classicalPlural == null) return pluralizeModern(singular); + + return classicalPlural; + } +} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/nouns/Noun.java b/src/main/java/bjc/inflexion/nouns/Noun.java new file mode 100644 index 0000000..4f785ad --- /dev/null +++ b/src/main/java/bjc/inflexion/nouns/Noun.java @@ -0,0 +1,121 @@ +/** + * (C) Copyright 2017 Benjamin Culkin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package bjc.inflexion.nouns; + +/** + * A noun attached to an inflection. + * + * @author EVE + * + */ +public class Noun { + private static final String TOSTRING_FMT = "Noun [word=%s, inflection=%s]"; + + private final String word; + + private final NounInflection inflection; + + /** + * Create a new noun from a word and inflection. + * + * @param wrd + * The word for the noun. + * + * @param inflction + * The inflection for the word. + */ + public Noun(String wrd, NounInflection inflction) { + word = wrd; + inflection = inflction; + } + + /** + * Get the input noun. + * + * @return The noun, as input. + */ + public String getWord() { + return word; + } + + /** + * Get the inflection for this noun. + * + * @return The inflection for this noun. + */ + public NounInflection getInflection() { + return inflection; + } + + /** + * Check if this noun is singular. + * + * @return Whether or not the noun is singular. + */ + public boolean isSingular() { + return inflection.isSingular(word); + } + + /** + * Check if this noun is plural. + * + * @return Whether or not this noun is plural. + */ + public boolean isPlural() { + return inflection.isPlural(word); + } + + /** + * Get the singular form of this noun. + * + * @return The singular form of this noun. + */ + public String singular() { + return inflection.singularize(word); + } + + /** + * Get the plural form of this noun. + * + * @return The plural form of this noun. + */ + public String plural() { + return inflection.pluralize(word); + } + + @Override + public String toString() { + return String.format(TOSTRING_FMT, word, inflection); + } + + /** + * Get the modern plural form of this noun. + * + * @return The modern plural form of this noun. + */ + public String modernPlural() { + return inflection.pluralizeModern(word); + } + + /** + * Get the classical plural form of this noun. + * + * @return The classical plural form of this noun. + */ + public String classicalPlural() { + return inflection.pluralizeClassical(word); + } +} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/nouns/NounInflection.java b/src/main/java/bjc/inflexion/nouns/NounInflection.java new file mode 100644 index 0000000..9e6f4d4 --- /dev/null +++ b/src/main/java/bjc/inflexion/nouns/NounInflection.java @@ -0,0 +1,113 @@ +/** + * (C) Copyright 2017 Benjamin Culkin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package bjc.inflexion.nouns; + +/** + * Interface for inflecting nouns. + * + * @author EVE + * + */ +public interface NounInflection { + /** + * Check if a noun matches this inflection. + * + * @param noun + * The noun to check on this inflection. + * + * @return Whether or not the noun belongs to the inflection. + */ + public boolean matches(String noun); + + /** + * Check if a noun for this inflection is singular or not. + * + * @param noun + * The noun to check for singularity. + * + * @return Whether or not the noun is singular. + * + * @throws InflectionException + * If the noun isn't part of this inflection. + */ + public boolean isSingular(String noun); + + /** + * Check if a noun for this inflection is plural or not. + * + * @param noun + * The noun to check for plurality. + * + * @return Whether or not the noun is plural. + * + * @throws InflectionException + * If the noun isn't part of this inflection. + */ + public boolean isPlural(String noun); + + /** + * Convert a singular noun to a plural noun. + * + * @param plural + * The plural noun to inflect to a singular form. + * + * @return The singular form of the noun. + * + * @throws InflectionException + * If the noun isn't part of the inflection. + */ + public String singularize(String plural); + + /** + * Convert a singular noun to a plural noun. + * + * @param singular + * The singular noun to inflect to a plural form. + * + * @return The plural form of the noun. + * + * @throws InflectionException + * If the noun isn't part of the inflection. + */ + public String pluralize(String singular); + + /** + * Convert a singular noun to a modern plural noun. + * + * @param singular + * The singular noun to inflect to a modern plural form. + * + * @return The modern plural form of the noun. + * + * @throws InflectionException + * If the noun isn't part of the inflection. + */ + public String pluralizeModern(String singular); + + /** + * Convert a singular noun to a classical plural noun. + * + * @param singular + * The singular noun to inflect to a classical plural + * form. + * + * @return The classical plural form of the noun. + * + * @throws InflectionException + * If the noun isn't part of the inflection. + */ + public String pluralizeClassical(String singular); +} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/nouns/Nouns.java b/src/main/java/bjc/inflexion/nouns/Nouns.java new file mode 100644 index 0000000..3b280eb --- /dev/null +++ b/src/main/java/bjc/inflexion/nouns/Nouns.java @@ -0,0 +1,329 @@ +/** + * (C) Copyright 2017 Benjamin Culkin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package bjc.inflexion.nouns; + +import static bjc.inflexion.nouns.InflectionAffixes.*; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.regex.Pattern; + +/** + * @author EVE + * + */ +public class Nouns { + private static final DefaultNounInflection DEFAULT_INFLECTION = new DefaultNounInflection(); + + private Prepositions prepositionDB; + + private Map userIrregulars; + private List userInflections; + + private Map predefinedIrregulars; + private List predefinedInflections; + + /** + * Create a new empty noun DB. + * + * @param prepDB + * The source for prepositions. + */ + public Nouns(Prepositions prepDB) { + prepositionDB = prepDB; + + userIrregulars = new HashMap<>(); + userInflections = new LinkedList<>(); + + predefinedIrregulars = new HashMap<>(); + predefinedInflections = new LinkedList<>(); + } + + /** + * Retrieve a noun with its inflection from the database of inflections. + * + * @param noun + * The noun to retrieve. + * + * @return The noun with its inflection. + * + * @throws InflectionException + * If the noun matched no inflection. + */ + public Noun getNoun(String noun) { + if(userIrregulars.containsKey(noun)) return new Noun(noun, userIrregulars.get(noun)); + for(NounInflection inflect : userInflections) { + if(inflect.matches(noun)) return new Noun(noun, inflect); + } + + if(predefinedIrregulars.containsKey(noun)) return new Noun(noun, predefinedIrregulars.get(noun)); + for(NounInflection inflect : predefinedInflections) { + if(inflect.matches(noun)) return new Noun(noun, inflect); + } + + return new Noun(noun, DEFAULT_INFLECTION); + } + + /** + * Load the contents of the stream into this DB. + * + * @param stream + * The stream to load from. + */ + public void loadFromStream(InputStream stream) { + try(Scanner scn = new Scanner(stream)) { + while(scn.hasNextLine()) { + String ln = scn.nextLine().trim(); + + /* + * Ignore comments and blank lines. + */ + if(ln.startsWith("#")) continue; + if(ln.equals("")) continue; + + if(ln.contains("-")) { + handleLine(ln); + handleLine(ln.replace('-', ' ')); + } else { + handleLine(ln); + } + } + } + } + + private void handleLine(String ln) { + String[] parts = ln.split(Pattern.quote("=>")); + + if(parts.length != 2) { + String msg = String.format("Improperly formatted noun defn '%s'", ln); + + throw new InflectionException(msg); + } + + String singular = parts[0].trim(); + String plural = parts[1].trim(); + + String modernPlural = ""; + String classicalPlural = ""; + + if(plural.contains("|")) { + String[] plurals = plural.split(Pattern.quote("|")); + + if(plurals.length == 1) { + modernPlural = plurals[0].trim(); + } else { + modernPlural = plurals[0].trim(); + classicalPlural = plurals[1].trim(); + } + + if(modernPlural.equals("")) modernPlural = null; + if(classicalPlural.equals("")) classicalPlural = null; + } else { + modernPlural = plural; + classicalPlural = null; + } + + if(singular.contains("(SING)")) { + handleCompoundPlural(singular, modernPlural, classicalPlural); + } else if(singular.startsWith("*")) { + handleCompletePlural(singular, modernPlural, classicalPlural); + } else if(singular.startsWith("-")) { + handleIncompletePlural(singular, modernPlural, classicalPlural); + } else { + handleIrregularPlural(singular, modernPlural, classicalPlural); + } + } + + private void handleCompoundPlural(String singular, String modernPlural, String classicalPlural) { + String actSingular = singular; + String actModern = modernPlural == null ? "" : modernPlural; + String actClassical = classicalPlural == null ? "" : classicalPlural; + + String singularPatt = actSingular.replaceAll(Pattern.quote("(SING)"), "(?\\\\w+)"); + String modernPatt = actModern.replaceAll(Pattern.quote("(PL)"), "(?\\\\w+)"); + String classicalPatt = actClassical.replaceAll(Pattern.quote("(PL)"), "(?\\\\w+)"); + + actSingular = actSingular.replaceAll(Pattern.quote("(SING)"), "%1\\$s"); + actModern = actModern.replaceAll(Pattern.quote("(PL)"), "%1\\$s"); + actClassical = actClassical.replaceAll(Pattern.quote("(PL)"), "%1\\$s"); + + List inflections = new ArrayList<>(3); + + if(singular.contains("(PREP)")) { + handleCompoundPreposition(actSingular, actModern, actClassical, singularPatt, modernPatt, + classicalPatt, inflections); + } else { + handleCompound(actSingular, actModern, actClassical, singularPatt, modernPatt, classicalPatt, + inflections); + } + + for(NounInflection inf : inflections) { + predefinedInflections.add(inf); + } + } + + private void handleCompound(String actSingular, String actModern, String actClassical, String singularPatt, + String modernPatt, String classicalPatt, List inflections) { + if(singularPatt.contains("*")) { + singularPatt = singularPatt.replaceAll(Pattern.quote("*"), "(?\\\\w+)"); + modernPatt = modernPatt.replaceAll(Pattern.quote("*"), "(?\\\\w+)"); + classicalPatt = classicalPatt.replaceAll(Pattern.quote("*"), "(?\\\\w+)"); + + actSingular = actSingular.replaceAll(Pattern.quote("*"), "%2\\$s"); + actModern = actModern.replaceAll(Pattern.quote("*"), "%2\\$s"); + actClassical = actClassical.replaceAll(Pattern.quote("*"), "%2\\$s"); + + handleNonpluralCompound(actSingular, actModern, actClassical, singularPatt, modernPatt, + classicalPatt, inflections, true); + } else { + handleNonpluralCompound(actSingular, actModern, actClassical, singularPatt, modernPatt, + classicalPatt, inflections, false); + } + } + + private void handleNonpluralCompound(String actSingular, String actModern, String actClassical, + String singularPatt, String modernPatt, String classicalPatt, + List inflections, boolean hasScratch) { + actModern = actModern.equals("") ? null : actModern; + actClassical = actClassical.equals("") ? null : actClassical; + + CompoundNounInflection singularInflection = new CompoundNounInflection(this, prepositionDB, + Pattern.compile(singularPatt), actSingular, actModern, actClassical, false, hasScratch); + + inflections.add(singularInflection); + + if(!modernPatt.equals("")) { + CompoundNounInflection modernInflection = new CompoundNounInflection(this, prepositionDB, + Pattern.compile(modernPatt), actSingular, actModern, actClassical, false, + hasScratch); + + inflections.add(modernInflection); + } + + if(!classicalPatt.equals("")) { + CompoundNounInflection classicalInflection = new CompoundNounInflection(this, prepositionDB, + Pattern.compile(classicalPatt), actSingular, actModern, actClassical, false, + hasScratch); + + inflections.add(classicalInflection); + } + } + + private void handleCompoundPreposition(String actSingular, String actModern, String actClassical, + String singularPatt, String modernPatt, String classicalPatt, + List inflections) { + singularPatt = singularPatt.replaceAll(Pattern.quote("(PREP)"), "(?\\\\w+)"); + modernPatt = modernPatt.replaceAll(Pattern.quote("(PREP)"), "(?\\\\w+)"); + classicalPatt = classicalPatt.replaceAll(Pattern.quote("(PREP)"), "(?\\\\w+)"); + + actSingular = actSingular.replaceAll(Pattern.quote("(PREP)"), "%2\\$s"); + actModern = actModern.replaceAll(Pattern.quote("(PREP)"), "%2\\$s"); + actClassical = actClassical.replaceAll(Pattern.quote("(PREP)"), "%2\\$s"); + + if(singularPatt.contains("*")) { + singularPatt = singularPatt.replaceAll(Pattern.quote("*"), "(?\\\\w+)"); + modernPatt = modernPatt.replaceAll(Pattern.quote("*"), "(?\\\\w+)"); + classicalPatt = classicalPatt.replaceAll(Pattern.quote("*"), "(?\\\\w+)"); + + actSingular = actSingular.replaceAll(Pattern.quote("*"), "%3\\$s"); + actModern = actModern.replaceAll(Pattern.quote("*"), "%3\\$s"); + actClassical = actClassical.replaceAll(Pattern.quote("*"), "%3\\$s"); + + actModern = actModern.equals("") ? null : actModern; + actClassical = actClassical.equals("") ? null : actClassical; + + addCompoundInflections(actSingular, actModern, actClassical, singularPatt, modernPatt, + classicalPatt, inflections, true); + } else { + addCompoundInflections(actSingular, actModern, actClassical, singularPatt, modernPatt, + classicalPatt, inflections, false); + } + } + + private void addCompoundInflections(String actSingular, String actModern, String actClassical, + String singularPatt, String modernPatt, String classicalPatt, + List inflections, boolean hasScratch) { + CompoundNounInflection singularInflection = new CompoundNounInflection(this, prepositionDB, + Pattern.compile(singularPatt), actSingular, actModern, actClassical, true, hasScratch); + + inflections.add(singularInflection); + + if(!modernPatt.equals("")) { + CompoundNounInflection modernInflection = new CompoundNounInflection(this, prepositionDB, + Pattern.compile(modernPatt), actSingular, actModern, actClassical, true, + hasScratch); + + inflections.add(modernInflection); + } + + if(!classicalPatt.equals("")) { + CompoundNounInflection classicalInflection = new CompoundNounInflection(this, prepositionDB, + Pattern.compile(classicalPatt), actSingular, actModern, actClassical, true, + hasScratch); + + inflections.add(classicalInflection); + } + } + + private void handleIncompletePlural(String singular, String modernPlural, String classicalPlural) { + InflectionAffix singularAffix = incomplete(singular.substring(1)); + + InflectionAffix modernAffix = null; + InflectionAffix classicalAffix = null; + + if(modernPlural != null) modernAffix = incomplete(modernPlural.substring(1)); + if(classicalPlural != null) classicalAffix = incomplete(classicalPlural.substring(1)); + + CategoricalNounInflection inflection = new CategoricalNounInflection(singularAffix, modernAffix, + classicalAffix); + + predefinedInflections.add(inflection); + } + + private void handleCompletePlural(String singular, String modernPlural, String classicalPlural) { + InflectionAffix singularAffix = complete(singular.substring(1)); + + InflectionAffix modernAffix = null; + InflectionAffix classicalAffix = null; + + if(modernPlural != null) modernAffix = complete(modernPlural.substring(1)); + if(classicalPlural != null) classicalAffix = complete(classicalPlural.substring(1)); + + CategoricalNounInflection inflection = new CategoricalNounInflection(singularAffix, modernAffix, + classicalAffix); + + predefinedInflections.add(inflection); + } + + private void handleIrregularPlural(String singular, String modernPlural, String classicalPlural) { + IrregularNounInflection inflection = new IrregularNounInflection(singular, modernPlural, + classicalPlural, false); + + if(!predefinedIrregulars.containsKey(singular)) { + predefinedIrregulars.put(singular, inflection); + } + + if(modernPlural != null && !predefinedIrregulars.containsKey(modernPlural)) + predefinedIrregulars.put(modernPlural, inflection); + if(classicalPlural != null && !predefinedIrregulars.containsKey(classicalPlural)) + predefinedIrregulars.put(classicalPlural, inflection); + } +} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/nouns/Prepositions.java b/src/main/java/bjc/inflexion/nouns/Prepositions.java new file mode 100644 index 0000000..356aa1c --- /dev/null +++ b/src/main/java/bjc/inflexion/nouns/Prepositions.java @@ -0,0 +1,71 @@ +/** + * (C) Copyright 2017 Benjamin Culkin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package bjc.inflexion.nouns; + +import java.io.InputStream; +import java.util.HashSet; +import java.util.Scanner; +import java.util.Set; + +/** + * List of prepositions. + * + * @author EVE + * + */ +public class Prepositions { + private Set prepositions; + + /** + * Create an empty preposition DB. + */ + public Prepositions() { + prepositions = new HashSet<>(); + } + + /** + * Check if a word is a preposition. + * + * @param word + * The word as a preposition. + * + * @return Whether or not the word is a preposition. + */ + public boolean isPreposition(String word) { + return prepositions.contains(word); + } + + /** + * Load the contents of the stream into this DB. + * + * @param stream + * The stream to load from. + */ + public void loadFromStream(InputStream stream) { + try(Scanner scn = new Scanner(stream)) { + while(scn.hasNextLine()) { + String ln = scn.nextLine().trim(); + + /* + * Ignore comments + */ + if(ln.startsWith("#")) continue; + + prepositions.add(ln); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/bjc/inflexion/nouns/SimpleInflectionAffix.java b/src/main/java/bjc/inflexion/nouns/SimpleInflectionAffix.java new file mode 100644 index 0000000..c9db8a1 --- /dev/null +++ b/src/main/java/bjc/inflexion/nouns/SimpleInflectionAffix.java @@ -0,0 +1,103 @@ +/** + * (C) Copyright 2017 Benjamin Culkin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package bjc.inflexion.nouns; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Simple implementation of {@link InflectionAffix} + * + * @author EVE + * + */ +public class SimpleInflectionAffix implements InflectionAffix { + private static final String TOSTRING_FMT = "SimpleInflectionAffix [affixTemplate=%s, affixMatcher=%s]"; + + private String affixTemplate; + + private Pattern affixMatcher; + + /** + * Create a new inflection affix. + * + * @param affixTemplate + * The template for applying the affix, Should be a + * printf-style format string with a single string blank. + * + * @param affixMatcher + * The regular expression that matches the affix on + * strings. The 'stem' or word should be placed in a + * named capturing group named 'stem'. + */ + public SimpleInflectionAffix(String affixTemplate, Pattern affixMatcher) { + this.affixTemplate = affixTemplate; + this.affixMatcher = affixMatcher; + } + + @Override + public boolean hasAffix(String word) { + return affixMatcher.matcher(word).matches(); + } + + @Override + public String deaffix(String word) { + Matcher matcher = affixMatcher.matcher(word); + matcher.matches(); + + return matcher.group("stem"); + } + + @Override + public String affix(String word) { + return String.format(affixTemplate, word); + } + + @Override + public String toString() { + return String.format(TOSTRING_FMT, affixTemplate, affixMatcher); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + + result = prime * result + ((affixMatcher == null) ? 0 : affixMatcher.hashCode()); + result = prime * result + ((affixTemplate == null) ? 0 : affixTemplate.hashCode()); + + return result; + } + + @Override + public boolean equals(Object obj) { + if(this == obj) return true; + if(obj == null) return false; + if(!(obj instanceof SimpleInflectionAffix)) return false; + + SimpleInflectionAffix other = (SimpleInflectionAffix) obj; + + if(affixTemplate == null) { + if(other.affixTemplate != null) return false; + } else if(!affixTemplate.equals(other.affixTemplate)) return false; + + if(affixMatcher == null) { + if(other.affixMatcher != null) return false; + } else if(!affixMatcher.equals(other.affixMatcher)) return false; + + return true; + } +} \ No newline at end of file -- cgit v1.2.3