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 }