All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.force.i18n.grammar.impl.UnsupportedLanguageDeclension Maven / Gradle / Ivy

There is a newer version: 1.2.30
Show newest version
/*
 * Copyright (c) 2017, salesforce.com, inc.
 * All rights reserved.
 * Licensed under the BSD 3-Clause license.
 * For full license text, see LICENSE.txt file in the repo root  or https://opensource.org/licenses/BSD-3-Clause
 */

package com.force.i18n.grammar.impl;

import static com.force.i18n.commons.util.settings.IniFileUtil.intern;

import java.util.*;

import com.force.i18n.HumanLanguage;
import com.force.i18n.grammar.*;
import com.force.i18n.grammar.Noun.NounType;
import com.force.i18n.grammar.impl.SimpleDeclension.SimpleNoun;
import com.force.i18n.grammar.impl.SimpleDeclension.SimpleNounForm;
import com.google.common.collect.ImmutableList;

/**
 * For platform languages that aren't going to be supported, this class provides some simple mechanisms for
 * obtaining a bare minimum of values.
 * @author stamm
 */
abstract class UnsupportedLanguageDeclension extends ArticledDeclension {
	// All the forms you can request
    static final List ALL_FORMS = ImmutableList.copyOf(EnumSet.allOf(PluralNounForm.class));
    // All the forms you can set for "other" forms
    static final Set OTHER_FORMS = EnumSet.of(SimpleNounForm.SINGULAR);
    // Only the simplest of adjectives and articles
    static final List ADJECTIVE_FORMS = SimpleDeclension.ADJECTIVE_FORMS;
    static final List ARTICLE_FORMS = Collections.singletonList(SimpleModifierForm.SINGULAR);

    public UnsupportedLanguageDeclension(HumanLanguage language) {
		super(language);
	}

    @Override
    public List< ? extends NounForm> getAllNounForms() {
        return ALL_FORMS;
    }

    @Override
    public Collection getEntityForms() {
        return getAllNounForms();
    }

    @Override
    public Collection getFieldForms() {
        return getAllNounForms();
    }

    @Override
    public Collection getOtherForms() {
        return OTHER_FORMS;
    }

    @Override
    public List< ? extends AdjectiveForm> getAdjectiveForms() {
        return ADJECTIVE_FORMS;
    }

    @Override
    public boolean hasGender() {
        return true;
    }

    @Override
    public EnumSet getRequiredGenders() {
        return EnumSet.of(LanguageGender.FEMININE, LanguageGender.MASCULINE);
    }

    @Override
    public LanguageGender getDefaultGender() {
        return LanguageGender.FEMININE;
    }

    @Override
    public boolean hasStartsWith() {
        return false;
    }

    @Override
    public Adjective createAdjective(String name, LanguageStartsWith startsWith, LanguagePosition position) {
        return new SimpleAdjective(this, name);
    }

    @Override
    public Noun createNoun(String name, String pluralAlias, NounType type, String entityName, LanguageStartsWith startsWith, LanguageGender gender, String access, boolean isStandardField, boolean isCopied) {
        return new SimpleArticledPluralNoun(this, name, pluralAlias, type, entityName, startsWith, gender, access, isStandardField, isCopied);
    }

    @Override
    public Article createArticle(String name, LanguageArticle articleType) {
        return new SimpleArticle(this, name, articleType);
    }

    @Override
    public NounForm getExactNounForm(LanguageNumber number, LanguageCase _case, LanguagePossessive possessive, LanguageArticle article) {
        return number == LanguageNumber.PLURAL ? PluralNounForm.PLURAL : PluralNounForm.SINGULAR;
    }

    @Override
    public AdjectiveForm getAdjectiveForm(LanguageStartsWith startsWith, LanguageGender gender, LanguageNumber number,
            LanguageCase _case, LanguageArticle article, LanguagePossessive possessive) {
        return SimpleModifierForm.SINGULAR;
    }

    @Override
    public List getArticleForms() {
        return ARTICLE_FORMS;
    }

    @Override
    protected String getDefaultArticleString(ArticleForm form, LanguageArticle articleType) {
        return "";
    }

    /**
     * Abstract class representing the insular Celtic languages (Welsh, Irish, Gaelic)
     */
    static class CelticDeclension extends UnsupportedLanguageDeclension {
        public CelticDeclension(HumanLanguage language) {
			super(language);
		}

		@Override
        public boolean hasGender() {
            return true;
        }

        @Override
        public EnumSet getRequiredGenders() {
            return EnumSet.of(LanguageGender.MASCULINE, LanguageGender.FEMININE);
        }
        @Override
        public LanguagePosition getDefaultAdjectivePosition() {
            return LanguagePosition.POST;
        }
    }

    /**
     * Irish has been simplified from Old Irish and Celtic, but still has a case system
     * and a special way of handling the definite article for things that start with an S or Z sound (like italian)
     *
     * Note: we don't support the special form for nouns when used with the number ending in two (2 láimh vs 3 lámha)
     * taking the lenited singular noun.  Google translate as of 2017 does the same thing when using the number instead of (Dhá).
     */
    static class IrishDeclension extends CelticDeclension {
        public IrishDeclension(HumanLanguage language) {
            super(language);
        }

        static final List GA_ALL_FORMS = ImmutableList.copyOf(EnumSet.allOf(IrishNounForm.class));
        public static enum IrishNounForm implements NounForm {
            SINGULAR(LanguageNumber.SINGULAR, LanguageCase.NOMINATIVE),
            SINGULAR_GEN(LanguageNumber.SINGULAR, LanguageCase.GENITIVE),
            PLURAL(LanguageNumber.PLURAL, LanguageCase.NOMINATIVE),
            PLURAL_GEN(LanguageNumber.PLURAL, LanguageCase.GENITIVE),
            ;

            private final LanguageNumber number;
            private final LanguageCase caseType;
            private IrishNounForm(LanguageNumber number, LanguageCase caseType) {
                this.number = number;
                this.caseType = caseType;
            }

            @Override public LanguageArticle getArticle() { return LanguageArticle.ZERO;}
            @Override public LanguageCase getCase() { return this.caseType; }
            @Override public LanguageNumber getNumber() {return this.number;}
            @Override public LanguagePossessive getPossessive() { return LanguagePossessive.NONE; }
            @Override
            public String getKey() {
                return getNumber().getDbValue() + "-" + getCase().getDbValue();
            }
        }

        public static final class IrishNoun extends LegacyArticledNoun {
            private static final long serialVersionUID = 1L;

            private String singular;
            private String plural;
            private String singular_gen;
            private String plural_gen;

            IrishNoun(IrishDeclension declension, String name, String pluralAlias, NounType type, String entityName, LanguageStartsWith startsWith, LanguageGender gender,String access,  boolean isStandardField, boolean isCopiedFromDefault) {
                super(declension, name, pluralAlias, type, entityName, startsWith, gender, access, isStandardField, isCopiedFromDefault);
            }

            @Override
            public Map getAllDefinedValues() {
                return enumMapFilterNulls(IrishNounForm.SINGULAR, singular, IrishNounForm.PLURAL, plural, IrishNounForm.SINGULAR_GEN, singular_gen,
                        IrishNounForm.PLURAL_GEN, plural_gen);
            }

            @Override
            public String getDefaultString(boolean isPlural) {
                return isPlural ? (plural != null ? plural : singular) : singular;
            }

            @Override
            public String getExactString(NounForm form) {
                assert form instanceof IrishNounForm : "Trying to trick a leprechaun out of his gold with a non-irish noun form? " + form;
                return form.getCase() == LanguageCase.GENITIVE ? form.getNumber() == LanguageNumber.PLURAL ? plural_gen : singular_gen
                        : form.getNumber() == LanguageNumber.PLURAL ? plural : singular;
            }

            @Override
            public void setString(String value, NounForm form) {
                if (form.getCase() == LanguageCase.GENITIVE) {
                    if (form.getNumber().isPlural()) {
                        this.plural_gen = intern(value);
                    } else {
                        this.singular_gen = intern(value);
                    }
                } else {
                    if (form.getNumber().isPlural()) {
                        this.plural = intern(value);
                    } else {
                        this.singular = intern(value);
                    }
                }
            }

            @Override
            protected boolean validateValues(String name, LanguageCase _case) {
                if (this.singular == null) {
                    return false;
                }
                // Default the values for entity nouns, but not for others to make rename fields more specific.
                if (getNounType() == NounType.ENTITY) {
                    if (this.plural == null)
                     {
                        this.plural = this.singular;  // Default plural to singular.
                    }
                    // Default the singular/plural definitions to start
                    if (this.singular_gen == null) {
                        this.singular_gen = this.singular;
                    }
                    if (this.plural_gen == null) {
                        this.plural_gen = this.plural;
                    }
                }
                return true;
            }

            @Override
            protected Object readResolve() {
                super.readResolve();
                this.singular = intern(this.singular);
                this.plural = intern(this.plural);
                this.singular_gen = intern(this.singular_gen);
                this.plural_gen = intern(this.plural_gen);
                return this;
            }
        }


        @Override
        public List< ? extends NounForm> getAllNounForms() {
            return GA_ALL_FORMS;
        }

        @Override
        public NounForm getExactNounForm(LanguageNumber number, LanguageCase _case, LanguagePossessive possessive, LanguageArticle article) {
            return _case == LanguageCase.GENITIVE ?
                    (number == LanguageNumber.PLURAL ? IrishNounForm.PLURAL_GEN : IrishNounForm.SINGULAR_GEN) :
                    number == LanguageNumber.PLURAL ? IrishNounForm.PLURAL : IrishNounForm.SINGULAR;
        }

        @Override
        public Noun createNoun(String name, String pluralAlias, NounType type, String entityName,
                LanguageStartsWith startsWith, LanguageGender gender, String access, boolean isStandardField, boolean isCopied) {
            return new IrishNoun(this, name, pluralAlias, type, entityName, startsWith, gender, access, isStandardField, isCopied);
        }

        /*
        @Override
        public EnumSet getRequiredStartsWith() {
            return EnumSet.of(LanguageStartsWith.CONSONANT, LanguageStartsWith.VOWEL, LanguageStartsWith.SPECIAL);  // Special = 's'
        }
        */
        @Override
        public EnumSet getRequiredCases() {
            return EnumSet.of(LanguageCase.NOMINATIVE, LanguageCase.GENITIVE);
        }
    }

    /**
     * Maltese is a language that is like Arabic, but differently complicated.  Furthermore, details about its grammar
     * are harder to come by.  But it is an official EU language
     */
    static class MalteseDeclension extends UnsupportedLanguageDeclension {
        public MalteseDeclension(HumanLanguage language) {
            super(language);
        }

        @Override
        public LanguagePosition getDefaultAdjectivePosition() {
            return LanguagePosition.POST;
        }
    }


    /**
     * Some languages have complicated grammars, but we will treat them as analytical/simple declension
     * for non-grammatical translation.
     * @author stamm
     */
    abstract static class UnsupportedAsSimpleDeclension extends UnsupportedLanguageDeclension {
        public UnsupportedAsSimpleDeclension(HumanLanguage language) {
            super(language);
        }

        // Unsupported language where plurals are formed using complicated aggutinations.
        @Override
        public List< ? extends NounForm> getAllNounForms() {
            return Collections.singletonList(SimpleNounForm.SINGULAR);
        }

        @Override
        public boolean hasPlural() {
            return false;
        }

        @Override
        public Noun createNoun(String name, String pluralAlias, NounType type, String entityName, LanguageStartsWith startsWith, LanguageGender gender, String access, boolean isStandardField, boolean isCopied) {
            return new SimpleNoun(this, name, pluralAlias, type, entityName, access, isStandardField, isCopied);
        }

        @Override
        public boolean hasGender() {
            return false;
        }

        @Override
        public EnumSet getRequiredGenders() {
            return null;
        }

        @Override
        public NounForm getExactNounForm(LanguageNumber number, LanguageCase _case, LanguagePossessive possessive, LanguageArticle article) {
            return SimpleNounForm.SINGULAR;
        }
    }


    /**
     * Haitian Creole is a language based on French, but creolized to remove some complexity from declensions, as it does not
     * have gender or plurals.
     * However, it has a definite article that is a very very complicated post-position based on 5 different ends-with variants.
     * So we consider it unsupported.
     */
    static class HaitianCreoleDeclension extends UnsupportedAsSimpleDeclension {
        public HaitianCreoleDeclension(HumanLanguage language) {
            super(language);
        }
    }


    /**
     * Basque is a language isolate that uses agglutination to form most of the words.  Our grammar
     * engine is not designed to handle it at this time.
     * Basque has an "unmarked" noun form, to which you add singular or plural endings.
     */
    static class BasqueDeclension extends UnsupportedAsSimpleDeclension {
        public BasqueDeclension(HumanLanguage language) {
            super(language);
        }
    }

    /**
     * Greenlandic is member of Eskimo–Aleut (Inuit) that has highly synthetic with heavy suffixes. Our grammar engine
     * is not designed to handle it at this time therefore, provide just Singular form for now.
     * 

* For example, “They say that it is good”, is “pitsaanirarpaat” in Greenlandic. “There is no one at home” is * “angirlasimasuqanngilaq”, “She is good at singing” is “erinarsullaqqippoq”! *

* Greenlandic has 8 cases, two numbers, no gender/article, and with 8 moods. */ static class GreenlandicDeclension extends UnsupportedAsSimpleDeclension { public GreenlandicDeclension(HumanLanguage language) { super(language); } } /** * Persian is an Iranian language that has a lot of arabic words added to it, where the grammar of how * adjectives and plurals are made are based on the source of the word. * * We're going with a simplified system where we track single/plural, nom/accusative, and assume adjectives * are unmodified. There are circumstances with animate and human nouns that break this. Hence, unsupported. */ static class PersianDeclension extends AbstractLanguageDeclension { public PersianDeclension(HumanLanguage language) { super(language); } static final List FA_ALL_FORMS = ImmutableList.copyOf(EnumSet.allOf(PersianNounForm.class)); static final List FA_SING_FORMS = ImmutableList.of(PersianNounForm.SINGULAR); public static enum PersianNounForm implements NounForm { SINGULAR(LanguageNumber.SINGULAR, LanguageCase.NOMINATIVE), SINGULAR_ACC(LanguageNumber.SINGULAR, LanguageCase.ACCUSATIVE), PLURAL(LanguageNumber.PLURAL, LanguageCase.NOMINATIVE), PLURAL_ACC(LanguageNumber.PLURAL, LanguageCase.ACCUSATIVE), ; private final LanguageNumber number; private final LanguageCase caseType; private PersianNounForm(LanguageNumber number, LanguageCase caseType) { this.number = number; this.caseType = caseType; } @Override public LanguageArticle getArticle() { return LanguageArticle.ZERO;} @Override public LanguageCase getCase() { return this.caseType; } @Override public LanguageNumber getNumber() {return this.number;} @Override public LanguagePossessive getPossessive() { return LanguagePossessive.NONE; } @Override public String getKey() { return getNumber().getDbValue() + "-" + getCase().getDbValue(); } } public static final class PersianNoun extends Noun { private static final long serialVersionUID = 1L; private String singular; private String plural; private String singular_acc; private String plural_acc; PersianNoun(PersianDeclension declension, String name, String pluralAlias, NounType type, String entityName, LanguageStartsWith startsWith, LanguageGender gender,String access, boolean isStandardField, boolean isCopiedFromDefault) { super(declension, name, pluralAlias, type, entityName, startsWith, gender, access, isStandardField, isCopiedFromDefault); } @Override public Map getAllDefinedValues() { return enumMapFilterNulls(PersianNounForm.SINGULAR, singular, PersianNounForm.PLURAL, plural, PersianNounForm.SINGULAR_ACC, singular_acc, PersianNounForm.PLURAL_ACC, plural_acc); } @Override public String getDefaultString(boolean isPlural) { return isPlural ? (plural != null ? plural : singular) : singular; } @Override public String getString(NounForm form) { assert form instanceof PersianNounForm : "Persian only: " + form; return form.getCase() == LanguageCase.ACCUSATIVE ? form.getNumber() == LanguageNumber.PLURAL ? plural_acc : singular_acc : form.getNumber() == LanguageNumber.PLURAL ? plural : singular; } @Override public void setString(String value, NounForm form) { if (form.getCase() == LanguageCase.ACCUSATIVE) { if (form.getNumber().isPlural()) { this.plural_acc = intern(value); } else { this.singular_acc = intern(value); } } else { if (form.getNumber().isPlural()) { this.plural = intern(value); } else { this.singular = intern(value); } } } @Override protected boolean validateValues(String name, LanguageCase _case) { if (this.singular == null) { return false; } // Default the values for entity nouns, but not for others to make rename fields more specific. if (getNounType() == NounType.ENTITY) { if (this.plural == null) { this.plural = this.singular; // Default plural to singular. } // Default the singular/plural definitions to start if (this.singular_acc == null) { this.singular_acc = this.singular; } if (this.plural_acc == null) { this.plural_acc = this.plural; } } return true; } @Override protected Object readResolve() { super.readResolve(); this.singular = intern(this.singular); this.plural = intern(this.plural); this.singular_acc = intern(this.singular_acc); this.plural_acc = intern(this.plural_acc); return this; } } @Override public List< ? extends NounForm> getAllNounForms() { return FA_ALL_FORMS; } @Override public NounForm getExactNounForm(LanguageNumber number, LanguageCase _case, LanguagePossessive possessive, LanguageArticle article) { return _case == LanguageCase.ACCUSATIVE ? (number == LanguageNumber.PLURAL ? PersianNounForm.PLURAL_ACC : PersianNounForm.SINGULAR_ACC) : number == LanguageNumber.PLURAL ? PersianNounForm.PLURAL : PersianNounForm.SINGULAR; } @Override public Noun createNoun(String name, String pluralAlias, NounType type, String entityName, LanguageStartsWith startsWith, LanguageGender gender, String access, boolean isStandardField, boolean isCopied) { return new PersianNoun(this, name, pluralAlias, type, entityName, startsWith, gender, access, isStandardField, isCopied); } @Override public EnumSet getRequiredCases() { return EnumSet.of(LanguageCase.NOMINATIVE, LanguageCase.ACCUSATIVE); } @Override public boolean hasStartsWith() { return false; } @Override public boolean hasGender() { return false; } @Override public Collection getEntityForms() { return getAllNounForms(); } @Override public Collection getFieldForms() { return FA_SING_FORMS; } @Override public Collection getOtherForms() { return FA_SING_FORMS; } @Override public List getAdjectiveForms() { return SimpleDeclension.ADJECTIVE_FORMS; } @Override public Adjective createAdjective(String name, LanguageStartsWith startsWith, LanguagePosition position) { return new SimpleAdjective(this, name); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy