Package grammar.model.nouns

Source Code of grammar.model.nouns.NounClass

package grammar.model.nouns;

import grammar.model.Language;
import grammar.model.MatchType;
import grammar.model.ReferenceData;
import grammar.model.ReferenceDataCategory;
import grammar.model.WordMatcher;
import grammar.model.factory.NounClassFactory;
import grammar.util.Utilities;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
* The category of a particular noun. In many languages, adjective and verbs
* change their forms according to the class of the noun. For instance, in
* Romance languages, there are typically two noun classes, referred to as
* 'masculine' and 'feminine'.
*
* @author Duncan Roberts
*/
public class NounClass implements ReferenceData<NounClass> {
  private static final Map<Language, Map<String, NounClass>> INSTANCES = new TreeMap<Language, Map<String, NounClass>>();
 
  private final int sequence;
  private final String name;
  private final String abbreviation;
  private final List<WordMatcher> nounMatchers;
  private final Language language;
 
  public NounClass(Language language, int sequence, String name, String abbreviation,
      List<WordMatcher> nounMatchers) {
    this.sequence = sequence;
    this.name = name;
    this.abbreviation = abbreviation;
    this.nounMatchers = Collections.unmodifiableList(nounMatchers);
    this.language = language;
    addNounClass(language, this);
  }
 
  public Language getLanguage() {
    return language;
  }

  public int ordinal()     {return sequence;}
  public String getName()  {return name;}
  public String toString() {return Utilities.asConstantName(name);}
 
  public static NounClass guessGender(Language language, String noun) {
    try {
      ReferenceDataCategory.NOUN_CLASS.load(language);
    }
    catch (IOException ioe) {
      throw new RuntimeException(ioe);
    }
    return NounClassFactory.getInstance(language).getClosestMatch(noun);
  }

  public boolean matches(String infinitive) {
    try {
      getNounMatcher(infinitive);
      return true;
    }
    catch (IllegalArgumentException e) {
      return false;
    }
  }
 
  public WordMatcher getNounMatcher(String noun) {
    for (WordMatcher nm : nounMatchers) {
      MatchType matchType = nm.getMatchType();
      switch (matchType) {
      case FULL_NAME:
        if (noun.equalsIgnoreCase(nm.getMatchString()))
          return nm;
        break;
      case SUFFIX:
        if (noun.endsWith(nm.getMatchString()))
          return nm;
        break;
      case PATTERN:
        if (noun.matches(nm.getMatchString()))
          return nm;
        break;
      case ALL:
        return nm;
      case NONE:
        return nm;
      default:
        throw new Error("Invalid match type: "+nm.getMatchType());
      }
    }
    throw new IllegalArgumentException("Word does not match this gender.");
  }

  public boolean isCloserMatch(String infinitive, NounClass other) {
    WordMatcher infinitiveMatcher = getNounMatcher(infinitive);
    WordMatcher otherMatcher = other.getNounMatcher(infinitive);
    if ((infinitiveMatcher.getMatchType() == MatchType.PATTERN || infinitiveMatcher.getMatchType() == MatchType.SUFFIX) &&
        (otherMatcher.getMatchType() == MatchType.PATTERN || otherMatcher.getMatchType() == MatchType.SUFFIX)) {
      return getMatchStringPointsValue(infinitiveMatcher) >
        getMatchStringPointsValue(otherMatcher);
    }
    if (infinitiveMatcher.getMatchType() != otherMatcher.getMatchType())
      return infinitiveMatcher.getMatchType().ordinal() > otherMatcher.getMatchType().ordinal();
    return false;
  }

  private int getMatchStringPointsValue(WordMatcher infinitiveMatcher) {
    if (infinitiveMatcher.getMatchType() == MatchType.PATTERN) {
      String points = infinitiveMatcher.getMatchString().replaceAll("\\[.+\\]", "[");
      points = points.replaceAll("\\(\\.\\*\\)", "");
      points = points.replaceAll("[()+*]", "");
      return points.length();
    }
    else if (infinitiveMatcher.getMatchType() == MatchType.SUFFIX) {
      return infinitiveMatcher.getMatchString().length();
    }
    else throw new Error();
  }

  private static void addNounClass(Language language, NounClass nounClass) {
    Utilities.initialiseIfReqd(language, INSTANCES).put(Utilities.asConstantName(nounClass.name), nounClass);
  }
 
  // PSEUDO-ENUM METHODS
 
  public static NounClass[] values(Language language) {
    try {
      ReferenceDataCategory.NOUN_CLASS.load(language);
    }
    catch (IOException ioe) {
      throw new RuntimeException(ioe);
    }
    return INSTANCES.get(language).values().toArray(new NounClass[]{});
  }
 
  public static NounClass valueOf(Language language, String key) {
    try {
      ReferenceDataCategory.NOUN_CLASS.load(language);
    }
    catch (IOException ioe) {
      throw new RuntimeException(ioe);
    }
    NounClass g = INSTANCES.get(language).get(Utilities.asConstantName(key));
    if (g == null)
      throw new IllegalArgumentException("No such Gender: '"+key+"'.");
    return g;
  }
 
  // BOILERPLATE
 
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((nounMatchers == null) ? 0 : nounMatchers.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (!(obj instanceof NounClass))
      return false;
    final NounClass other = (NounClass) obj;
    if (nounMatchers == null) {
      if (other.nounMatchers != null)
        return false;
    } else if (!nounMatchers.equals(other.nounMatchers))
      return false;
    return true;
  }

  @Override
  public int compareTo(NounClass o) {
    return sequence - o.sequence;
  }

  public String getAbbreviation() {
    return abbreviation;
  }
}
TOP

Related Classes of grammar.model.nouns.NounClass

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.