001    // This file is part of the Attempto Java Packages.
002    // Copyright 2008, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
003    //
004    // The Attempto Java Packages is free software: you can redistribute it and/or modify it under the
005    // terms of the GNU Lesser General Public License as published by the Free Software Foundation,
006    // either version 3 of the License, or (at your option) any later version.
007    //
008    // The Attempto Java Packages is distributed in the hope that it will be useful, but WITHOUT ANY
009    // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
010    // PURPOSE. See the GNU Lesser General Public License for more details.
011    //
012    // You should have received a copy of the GNU Lesser General Public License along with the Attempto
013    // Java Packages. If not, see http://www.gnu.org/licenses/.
014    
015    package ch.uzh.ifi.attempto.acewiki.core.ontology;
016    
017    import java.util.ArrayList;
018    import java.util.List;
019    
020    import ch.uzh.ifi.attempto.ape.Gender;
021    import ch.uzh.ifi.attempto.ape.LexiconEntry;
022    
023    /**
024     * This class represents an individual (in logic called "constant"). AceWiki supports only
025     * proper names to represent individuals (and no extensions are planned in this respect).
026     * For that reason, this class is proper name specific.
027     *<p>
028     * Proper names can be used with a definite article (e.g. "the Nile") or without (e.g. "Egypt").
029     *<p>
030     * Proper names have two word forms. The first one is the proper name with the definite
031     * article if there is one. The second one is just the bare proper name. In the case of
032     * proper names that do not use a definite article, both word forms are identical.
033     *<p>
034     * 0: proper name, preceded by "the" if used with definite article.
035     * 1: bare proper name.
036     *<p>
037     * Examples: ["the Nile", "Nile"]; ["Egypt", "Egypt"].
038     * 
039     * @author Tobias Kuhn
040     */
041    public class Individual extends OntologyElement {
042            
043            private String word;
044            private boolean hasDefiniteArticle;
045            
046            private List<Concept> conceptsCache;
047            private long conceptsCacheStateID = -1;
048            
049            /**
050             * Creates a new individual that has no name yet and is not registered to an ontology.
051             */
052            public Individual() {
053                    this.word = "";
054                    this.hasDefiniteArticle = false;
055            }
056            
057            public String[] getWords() {
058                    if (hasDefiniteArticle) {
059                            return new String[] {"the " + word, word};
060                    } else {
061                            return new String[] {word, word};
062                    }
063            }
064            
065            public String getHeadword() {
066                    return getPrettyWord(1);
067            }
068            
069            protected void changeWords(String... words) {
070                    if (words.length == 1) {
071                            word = words[0];
072                            hasDefiniteArticle = false;
073                    } else {
074                            word = words[1];
075                            hasDefiniteArticle = words[0].startsWith("the ");
076                    }
077            }
078    
079            List<LexiconEntry> getLexiconEntries() {
080                    List<LexiconEntry> entries = new ArrayList<LexiconEntry>();
081                    if (hasDefiniteArticle) {
082                            entries.add(LexiconEntry.createPropernameDefSgEntry(word, word, Gender.NEUTRAL));
083                    } else {
084                            entries.add(LexiconEntry.createPropernameSgEntry(word, word, Gender.NEUTRAL));
085                    }
086                    return entries;
087            }
088            
089            public String getType() {
090                    return "Proper Name";
091            }
092            
093            public String getInternalType() {
094                    return "propername";
095            }
096            
097            /**
098             * Returns true if the proper name has to be used with the definite article "the".
099             * 
100             * @return true if the definite article "the" has to be used.
101             */
102            public boolean hasDefiniteArticle() {
103                    return hasDefiniteArticle;
104            }
105            
106            public String getURISuffix() {
107                    return "#" + word;
108            }
109            
110            /**
111             * Returns all concepts this individual belongs to.
112             * 
113             * @return A list of all concepts of this individual.
114             * @see Ontology#getConcepts(Individual)
115             */
116            public List<Concept> getConcepts() {
117                    Ontology o = getOntology();
118                    if (conceptsCacheStateID != o.getStateID()) {
119                            conceptsCache = o.getConcepts(this);
120                            conceptsCacheStateID = o.getStateID();
121                    }
122                    return new ArrayList<Concept>(conceptsCache);
123            }
124    
125            /**
126             * Returns true if the concepts of this individual are cached and do not have
127             * to be recalculated.
128             * 
129             * @return true if the concepts are cached.
130             */
131            public boolean areConceptsCached() {
132                    return conceptsCacheStateID == getOntology().getStateID();
133            }
134    
135    }