OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 144 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
73 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.utils.i18n;
15
 
16
import java.text.Normalizer;
17
import java.text.Normalizer.Form;
18
import java.util.Arrays;
19
import java.util.Collection;
20
import java.util.Locale;
21
import java.util.regex.Matcher;
22
import java.util.regex.Pattern;
23
 
24
import net.jcip.annotations.Immutable;
25
 
26
@Immutable
27
public class Grammar_fr extends Grammar {
28
 
29
    static private final Grammar_fr INSTANCE = new Grammar_fr();
30
 
31
    public static Grammar_fr getInstance() {
32
        return INSTANCE;
33
    }
34
 
35
    private Grammar_fr() {
36
        this(Locale.FRENCH);
37
    }
38
 
39
    protected Grammar_fr(final Locale l) {
40
        super(l);
41
    }
42
 
43
    @Override
44
    protected Collection<? extends VariantKey> createVariantKeys() {
144 ilm 45
        return Arrays.asList(SINGULAR, PLURAL, INDEFINITE_ARTICLE_SINGULAR, INDEFINITE_ARTICLE_PLURAL, DEFINITE_ARTICLE_SINGULAR, DEFINITE_ARTICLE_PLURAL, DEMONSTRATIVE_SINGULAR, DEMONSTRATIVE_PLURAL,
46
                INDEFINITE_NUMERAL, DEFINITE_NUMERAL, DEMONSTRATIVE_NUMERAL, INDEFINITE_ORDINAL, DEFINITE_ORDINAL);
73 ilm 47
    }
48
 
49
    @Override
50
    protected Collection<? extends NounClass> createNounClasses() {
51
        return Arrays.asList(NounClass.FEMININE, NounClass.MASCULINE);
52
    }
53
 
54
    public final Phrase createPhrase(final NounClass nounClass, final String singular) {
55
        return this.createPhrase(nounClass, singular, null);
56
    }
57
 
58
    public final Phrase createPhrase(final NounClass nounClass, final String singular, final String plural) {
59
        if (!this.getNounClasses().contains(nounClass))
60
            throw new IllegalArgumentException("invalid nounClass : " + nounClass);
61
        final Phrase res = new Phrase(this, singular, nounClass);
62
        if (plural != null)
63
            res.putVariant(PLURAL, plural);
64
        return res;
65
    }
66
 
67
    @Override
68
    public String getVariant(Phrase noun, VariantKey key) {
69
        final String res;
144 ilm 70
        if (key.equals(SINGULAR)) {
73 ilm 71
            res = noun.getBase();
144 ilm 72
        } else if (key.equals(INDEFINITE_ARTICLE_SINGULAR)) {
73
            res = (noun.getNounClass() == NounClass.FEMININE ? "une " : "un ") + getSingular(noun);
74
        } else if (key.equals(DEFINITE_ARTICLE_SINGULAR)) {
73 ilm 75
            res = getDefiniteArticle(noun) + getSingular(noun);
144 ilm 76
        } else if (key.equals(DEMONSTRATIVE_SINGULAR)) {
73 ilm 77
            res = getCe(noun) + getSingular(noun);
144 ilm 78
        } else if (key.equals(PLURAL)) {
73 ilm 79
            res = getPlural(noun.getBase());
144 ilm 80
        } else if (key.equals(INDEFINITE_ARTICLE_PLURAL)) {
73 ilm 81
            res = "des " + getPlural(noun);
144 ilm 82
        } else if (key.equals(DEFINITE_ARTICLE_PLURAL)) {
73 ilm 83
            res = "les " + getPlural(noun);
144 ilm 84
        } else if (key.equals(DEMONSTRATIVE_PLURAL)) {
73 ilm 85
            res = "ces " + getPlural(noun);
144 ilm 86
        } else if (key.equals(INDEFINITE_NUMERAL)) {
156 ilm 87
            res = "{0, plural, =0 {auc" + noun.getVariant(INDEFINITE_ARTICLE_SINGULAR) + "} one {# " + getSingular(noun) + "} other {# " + getPlural(noun) + "}}";
144 ilm 88
        } else if (key.equals(DEFINITE_NUMERAL)) {
156 ilm 89
            res = "{0, plural, =0 {auc" + noun.getVariant(INDEFINITE_ARTICLE_SINGULAR) + "} one {" + noun.getVariant(DEFINITE_ARTICLE_SINGULAR) + "} other {les # " + getPlural(noun) + "}}";
144 ilm 90
        } else if (key.equals(DEMONSTRATIVE_NUMERAL)) {
156 ilm 91
            res = "{0, plural, =0 {auc" + noun.getVariant(INDEFINITE_ARTICLE_SINGULAR) + "} one {" + noun.getVariant(DEMONSTRATIVE_SINGULAR) + "} other {ces # " + getPlural(noun) + "}}";
144 ilm 92
        } else if (key.equals(DEFINITE_ORDINAL) || key.equals(INDEFINITE_ORDINAL)) {
93
            final boolean estFéminin = noun.getNounClass() == NounClass.FEMININE;
94
            final String article = key.equals(DEFINITE_ORDINAL) ? (estFéminin ? "la " : "le ") : "";
95
            res = article + "{0, ordinal, %digits-ordinal" + (estFéminin ? "-feminine" : "") + "} " + getSingular(noun);
96
        } else {
73 ilm 97
            res = null;
144 ilm 98
        }
99
 
73 ilm 100
        return res;
101
    }
102
 
103
    protected String getDefiniteArticle(Phrase noun) {
104
        if (startsWithVowel(noun.getBase()))
105
            return "l’";
106
        else if (noun.getNounClass() == NounClass.MASCULINE)
107
            return "le ";
108
        else
109
            return "la ";
110
    }
111
 
112
    protected boolean startsWithVowel(String s) {
113
        String firstLetter = s.substring(0, 1).toLowerCase(getLocale());
114
        // handle "habitude", MAYBE handle h aspiré (e.g. "haricot")
115
        if (firstLetter.equals("h"))
116
            firstLetter = s.substring(1, 2).toLowerCase(getLocale());
117
        // handle "éclairage"
118
        final char char0 = Normalizer.normalize(firstLetter, Form.NFD).charAt(0);
119
        return char0 == 'a' || char0 == 'e' || char0 == 'i' || char0 == 'o' || char0 == 'u' || char0 == 'y';
120
    }
121
 
122
    protected String getSingular(Phrase noun) {
123
        final String res = noun.getVariant(SINGULAR);
124
        return res == null ? noun.getBase() : res;
125
    }
126
 
127
    protected String getPlural(Phrase noun) {
128
        final String res = noun.getVariant(PLURAL);
129
        return res == null ? getPlural(noun.getBase()) : res;
130
    }
131
 
132
    protected String getPlural(String noun) {
133
        final int l = noun.length();
134
        final char lastChar = noun.charAt(l - 1);
135
        if (lastChar == 's' || lastChar == 'x' || lastChar == 'z')
136
            return noun;
137
        else if (noun.endsWith("al"))
138
            return noun.substring(0, l - 2) + "aux";
139
        else
140
            return noun + 's';
141
    }
142
 
143
    private String getCe(Phrase noun) {
144
        if (noun.getNounClass().equals(NounClass.FEMININE))
145
            return "cette ";
146
        else if (startsWithVowel(noun.getBase()))
147
            return "cet ";
148
        else
149
            return "ce ";
150
    }
151
 
152
    private static final Pattern LE_LES = Pattern.compile("(\\p{javaWhitespace}*)([Ll][Ee][Ss]?)\\p{javaWhitespace}+");
153
 
154
    public String de(final String phrase) {
155
        final Matcher matcher = LE_LES.matcher(phrase);
156
        if (matcher.lookingAt()) {
157
            final String le_les_group = matcher.group(2);
158
            final char d = le_les_group.charAt(0) == 'L' ? 'D' : 'd';
159
            final String de;
160
            if (le_les_group.length() == 3)
161
                de = d + le_les_group.substring(1);
162
            else
163
                de = d + (le_les_group.charAt(1) == 'E' ? "U" : "u");
164
            return matcher.group(1) + de + phrase.substring(matcher.end(2));
165
        } else if (startsWithVowel(phrase.trim())) {
166
            return "d’" + phrase;
167
        } else {
168
            return "de " + phrase;
169
        }
170
    }
171
 
172
    public String à(final String phrase) {
173
        final Matcher matcher = LE_LES.matcher(phrase);
174
        if (matcher.lookingAt()) {
175
            final String le_les_group = matcher.group(2);
176
            final String au = (le_les_group.charAt(0) == 'L' ? "A" : "a") + (le_les_group.charAt(1) == 'E' ? "U" : "u");
177
            final String de;
178
            if (le_les_group.length() == 3)
179
                de = au + (le_les_group.charAt(2) == 'S' ? "X" : "x");
180
            else
181
                de = au;
182
            return matcher.group(1) + de + phrase.substring(matcher.end(2));
183
        } else {
184
            return "à " + phrase;
185
        }
186
    }
187
}