OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 132 | Go to most recent revision | Details | 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.sql.element;
15
 
16
import org.openconcerto.sql.Log;
17
import org.openconcerto.utils.i18n.Grammar;
18
import org.openconcerto.utils.i18n.NounClass;
19
import org.openconcerto.utils.i18n.Phrase;
20
import org.openconcerto.utils.i18n.VariantKey;
21
import org.openconcerto.xml.JDOMUtils;
22
 
23
import java.io.IOException;
24
import java.io.InputStream;
25
import java.util.AbstractMap.SimpleEntry;
26
import java.util.List;
27
import java.util.Locale;
28
import java.util.Map.Entry;
29
import java.util.regex.Pattern;
30
 
31
import net.jcip.annotations.ThreadSafe;
32
 
33
import org.jdom.Document;
34
import org.jdom.Element;
35
import org.jdom.JDOMException;
36
import org.jdom.input.SAXBuilder;
37
 
38
/**
39
 * Parses XML to create phrases.
40
 *
41
 * <pre>
42
 *     &lt;element refid="elementCode">
43
 *         &lt;name base="elemName" nounClass="masculine">
44
 *             &lt;variant refids="singular,plural" value="elemNameBothSingularAndPlural" />
45
 *             &lt;variant idPattern="(singular|plural)" value="elemNameBothSingularAndPlural" />
46
 *         &lt;/name>
47
 *     &lt;/element>
48
 * </pre>
49
 *
50
 * @author Sylvain
51
 *
52
 */
53
@ThreadSafe
54
public class SQLElementNamesFromXML extends SQLElementNamesMap.ByCode {
55
 
56
    static public final Pattern SPLIT_PATTERN = Pattern.compile("\\s*,\\s*");
57
 
58
    public SQLElementNamesFromXML(Locale locale) {
59
        super(locale);
60
    }
61
 
62
    public final void load(final InputStream ins) throws JDOMException, IOException {
63
        final Grammar gr = Grammar.getInstance(getLocale());
64
        final Document doc = new SAXBuilder().build(ins);
65
        @SuppressWarnings("unchecked")
66
        final List<Element> elements = doc.getRootElement().getChildren("element");
67
        for (final Element elem : elements)
68
            this.load(gr, elem);
69
    }
70
 
71
    public final Entry<String, Phrase> createPhrase(final Element elem) throws IOException {
72
        return this.createPhrase(Grammar.getInstance(getLocale()), elem);
73
    }
74
 
75
    private Entry<String, Phrase> createPhrase(final Grammar gr, final Element elem) throws IOException {
76
        final String refid = elem.getAttributeValue("refid");
77
        if (refid == null)
78
            throw new IOException("No refid attribute");
79
 
80
        final Element nameElem = elem.getChild("name");
81
        final boolean hasChild = nameElem != null;
82
        final String nameAttr = elem.getAttributeValue("name");
83
        if (!hasChild && nameAttr == null) {
84
            Log.get().warning("No name for code : " + refid);
85
            return null;
86
        }
87
        if (hasChild && nameAttr != null) {
88
            Log.get().warning("Ignoring attribute : " + nameAttr);
89
        }
90
 
91
        final String base = hasChild ? nameElem.getAttributeValue("base") : nameAttr;
92
        if (base == null)
93
            throw new IOException("No base for the name of " + refid);
94
        final String nounClassName = hasChild ? nameElem.getAttributeValue("nounClass") : elem.getAttributeValue("nameClass");
95
        final NounClass nounClass = nounClassName == null ? null : gr.getNounClass(nounClassName);
96
 
97
        final Phrase res = new Phrase(gr, base, nounClass);
98
        if (!hasChild) {
99
            // most languages have at most 2 grammatical number
100
            final String plural = elem.getAttributeValue("namePlural");
101
            if (plural != null)
102
                res.putVariant(Grammar.PLURAL, plural);
103
        } else {
104
            @SuppressWarnings("unchecked")
105
            final List<Element> variantElems = nameElem.getChildren("variant");
106
            for (final Element variantElem : variantElems) {
107
                final String value = variantElem.getAttributeValue("value");
108
                if (value == null) {
109
                    warning(refid, variantElem, "No value");
110
                    continue;
111
                }
112
                final String variantIDs = variantElem.getAttributeValue("refids");
113
                final String variantPattern = variantElem.getAttributeValue("idPattern");
114
                if (variantIDs == null && variantPattern == null) {
115
                    warning(refid, variantElem, "No ID");
116
                } else if (variantIDs != null) {
117
                    if (variantPattern != null) {
118
                        warning(refid, variantElem, "Ignorig pattern " + variantPattern);
119
                    }
120
                    for (final String variantID : SPLIT_PATTERN.split(variantIDs)) {
121
                        final VariantKey variantKey = gr.getVariantKey(variantID);
122
                        if (variantKey == null) {
123
                            warning(refid, variantElem, "Ignorig " + variantID);
124
                        } else {
125
                            res.putVariant(variantKey, value);
126
                        }
127
                    }
128
                } else {
129
                    assert variantIDs == null && variantPattern != null;
130
                    final Pattern p = Pattern.compile(variantPattern);
131
                    for (final VariantKey vk : gr.getVariantKeys()) {
132
                        if (p.matcher(vk.getID()).matches()) {
133
                            res.putVariant(vk, value);
134
                        }
135
                    }
136
                }
137
            }
138
        }
139
        return new SimpleEntry<String, Phrase>(refid, res);
140
    }
141
 
142
    private void load(final Grammar gr, final Element elem) throws IOException {
143
        final Entry<String, Phrase> entry = this.createPhrase(gr, elem);
144
        if (entry != null)
145
            this.put(entry.getKey(), entry.getValue());
146
    }
147
 
148
    private void warning(final String refid, final Element variantElem, final String msg) {
149
        Log.get().warning(msg + " for variant of " + refid + " : " + JDOMUtils.output(variantElem));
150
    }
151
}