001    // This file is part of AceWiki.
002    // Copyright 2008-2012, AceWiki developers.
003    // 
004    // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU
005    // Lesser General Public License as published by the Free Software Foundation, either version 3 of
006    // the License, or (at your option) any later version.
007    // 
008    // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009    // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
010    // Lesser General Public License for more details.
011    // 
012    // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If
013    // not, see http://www.gnu.org/licenses/.
014    
015    package ch.uzh.ifi.attempto.acewiki.aceowl;
016    
017    import java.util.ArrayList;
018    import java.util.List;
019    
020    import ch.uzh.ifi.attempto.acewiki.core.InvalidWordException;
021    import ch.uzh.ifi.attempto.acewiki.core.LanguageUtils;
022    import ch.uzh.ifi.attempto.acewiki.core.LexiconChanger;
023    import ch.uzh.ifi.attempto.acewiki.core.LexiconDetail;
024    import ch.uzh.ifi.attempto.acewiki.core.Ontology;
025    import ch.uzh.ifi.attempto.acewiki.core.OntologyElement;
026    import ch.uzh.ifi.attempto.acewiki.core.OntologyTextElement;
027    import ch.uzh.ifi.attempto.acewiki.core.Sentence;
028    import ch.uzh.ifi.attempto.ape.FunctionWords;
029    import ch.uzh.ifi.attempto.base.TextElement;
030    
031    /**
032     * This class is used to modify or create verbs.
033     * 
034     * @author Tobias Kuhn
035     */
036    public class VerbChanger implements LexiconChanger {
037            
038            public String getDescription() {
039                    return "Every verb represents a certain relation between things. " +
040                            "For example, the verb \"owns\" relates persons to their possessions.";
041            }
042            
043            public List<LexiconDetail> getDetails(OntologyElement el) {
044                    VerbRelation relation = (VerbRelation) el;
045                    List<LexiconDetail> l = new ArrayList<LexiconDetail>();
046                    l.add(new LexiconDetail(
047                                    "third singular",
048                                    "examples: owns, applies to, touches",
049                                    relation.getWord(0)
050                            ));
051                    l.add(new LexiconDetail(
052                                    "bare infinitive",
053                                    "examples: own, apply to, touch",
054                                    relation.getWord(1)
055                            ));
056                    l.add(new LexiconDetail(
057                                    "past participle",
058                                    "examples: owned, applied to, touched",
059                                    relation.getPastPart(),
060                                    false
061                            ));
062                    return l;
063            }
064            
065            public void save(OntologyElement el, int wordNumber, List<Object> newValues, Ontology ontology)
066                            throws InvalidWordException {
067                    VerbRelation relation = (VerbRelation) el;
068                    
069                    String thirdSg = ACEOWLLexicon.normalize((String) newValues.get(0));
070                    String inf = ACEOWLLexicon.normalize((String) newValues.get(1));
071                    String pastPart = ACEOWLLexicon.normalize((String) newValues.get(2));
072                    if (pastPart.toLowerCase().endsWith("_by")) {
073                            pastPart = pastPart.substring(0, pastPart.length()-3);
074                    }
075                    String thirdSgP = LanguageUtils.getPrettyPrinted(thirdSg);
076                    String infP = LanguageUtils.getPrettyPrinted(inf);
077                    String pastPartP = LanguageUtils.getPrettyPrinted(pastPart);
078                    
079                    // check whether all necessary fields are filled-in
080                    if (thirdSg.equals("")) {
081                            throw new InvalidWordException("No third singular defined: Please define the third " +
082                                    "singular form.");
083                    }
084                    if (inf.equals("")) {
085                            throw new InvalidWordException("No bare infinitive defined: Please define the bare " +
086                                    "infinitive form.");
087                    }
088                    if (pastPart.equals("") && wordNumber == 2) {
089                            throw new InvalidWordException("No past participle defined: Please define the past " +
090                                    "participle form.");
091                    }
092                    if (pastPart.equals("") && isPassiveUsed(ontology, relation)) {
093                            throw new InvalidWordException("The past participle form cannot be removed because " +
094                                    "there are sentences that are using it.");
095                    }
096                    
097                    // check whether the words contain only valid characters
098                    if (!ACEOWLLexicon.isValidWordOrEmpty(thirdSg) || !ACEOWLLexicon.isValidWordOrEmpty(inf) ||
099                                    !ACEOWLLexicon.isValidWordOrEmpty(pastPart)) {
100                            throw new InvalidWordException("Invalid character used: Only a-z, A-Z, 0-9, -, and " +
101                                    "spaces are allowed, and the first character must be one of a-z A-Z.");
102                    }
103                    
104                    // check whether a word is a predefined function word
105                    if (FunctionWords.isFunctionWord(thirdSg)) {
106                            throw new InvalidWordException("'" + thirdSgP + "' is a predefined word and cannot " +
107                                    "be used here.");
108                    }
109                    if (FunctionWords.isFunctionWord(inf)) {
110                            throw new InvalidWordException("'" + infP + "' is a predefined word and cannot be " +
111                                    "used here.");
112                    }
113                    if (FunctionWords.isFunctionWord(pastPart)) {
114                            throw new InvalidWordException("'" + pastPartP + "' is a predefined word and cannot " +
115                                    "be used here.");
116                    }
117                    
118                    // check whether all word forms are distinct
119                    if (thirdSg.equals(inf)) {
120                            throw new InvalidWordException("The singular and plural forms have to be distinct.");
121                    }
122                    
123                    // check whether a word is already defined
124                    OntologyElement oe1 = ontology.getElement(thirdSg);
125                    if (oe1 != null && oe1 != relation) {
126                            throw new InvalidWordException("The word '" + thirdSgP + "' is already used. Please " +
127                                    "use a different one.");
128                    }
129                    OntologyElement oe2 = ontology.getElement(inf);
130                    if (oe2 != null && oe2 != relation) {
131                            throw new InvalidWordException("The word '" + infP + "' is already used. Please use " +
132                                    "a different one.");
133                    }
134                    OntologyElement oe3 = ontology.getElement(pastPart);
135                    if (oe3 != null && oe3 != relation) {
136                            throw new InvalidWordException("The word '" + pastPartP + "' is already used. " +
137                                    "Please use a different one.");
138                    }
139                    
140                    ontology.change(relation, thirdSg + ";" + inf + ";" + pastPart);
141            }
142            
143            private static boolean isPassiveUsed(Ontology o, VerbRelation vr) {
144                    for (Sentence sentence : o.getReferences(vr)) {
145                            ACESentence s = (ACESentence) sentence;
146                            for (TextElement t : s.getTextElements()) {
147                                    if (t instanceof OntologyTextElement) {
148                                            OntologyTextElement ot = (OntologyTextElement) t;
149                                            if (vr == ot.getOntologyElement() && ot.getWordNumber() == 2) return true;
150                                    }
151                            }
152                    }
153                    return false;
154            }
155    
156    }