001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 */
021
022package org.biojava.nbio.ontology;
023
024import org.biojava.nbio.ontology.utils.Annotatable;
025import org.biojava.nbio.ontology.utils.Annotation;
026import org.biojava.nbio.ontology.utils.SmallAnnotation;
027
028import java.util.Arrays;
029import java.util.Set;
030import java.util.TreeSet;
031
032
033
034/**
035 * A term in an ontology.  This has an {@link org.biojava.nbio.Annotation Annotation}
036 * which can be used for storing additional human-displayable information.  It
037 * is strongly recommended that the Annotation is not used for any machine-readable
038 * data -- this should be represented by relations in the ontology instead.
039 *
040 * <p>
041 * Terms are things that represent things. They are the same sort of thing as a
042 * Java object or a prolog atom. A sub-set of terms are themselves relations.
043 * This means that they are used to describe associations between pairs of terms.
044 * Since all terms can be described, it is possible (and indeed encouraged) to
045 * describe relations. As a minimum, you should consider saying if they are
046 * identity or partial order relations, or if they are transitive, reflexive,
047 * symmetrical, anti-symmetrical or anything else you know about them. This gives
048 * the inference engine some chance of working out what is going on.
049 * </p>
050 *
051 * @author Thomas Down
052 * @author Matthew Pocock
053 * @since 1.4
054 * @see org.biojavax.ontology.ComparableTerm
055 */
056
057public interface Term extends Annotatable {
058        /**
059         * ChangeType which indicates that this term's ontology has been
060         * altered
061         */
062
063
064        /**
065         * Return the name of this term.
066         * @return the name of the term
067         */
068
069        public String getName();
070
071        /**
072         * Return a human-readable description of this term, or the empty string if
073         * none is available.
074         * @return the description of the term
075         */
076
077        public String getDescription();
078
079        /** set the description of the term;
080         *
081         * @param description
082         *
083         */
084        public void setDescription(String description);
085
086        /**
087         * Return the ontology in which this term exists.
088         * @return the ontology
089         */
090
091        public Ontology getOntology();
092
093        /**
094         * Return the synonyms for this term.
095         * @return the synonyms
096         */
097
098        public Object[] getSynonyms();
099
100        /**
101         * Add a synonym for this term.
102         * @param synonym the synonym
103         */
104
105        public void addSynonym(Object synonym);
106
107        /**
108         * Remove a synonym for this term.
109         * @param synonym
110         */
111
112        public void removeSynonym(Object synonym);
113
114        /**
115         * Simple in-memory implementation of an ontology term.
116         * @see org.biojavax.ontology.SimpleComparableTerm
117         * This can be used to implement Ontology.createTerm
118         */
119
120        public static class Impl
121        extends AbstractTerm
122        implements Term, java.io.Serializable {
123                /**
124                 *
125                 */
126                private static final long serialVersionUID = 6561668917514377417L;
127
128                private final String name;
129
130                private final Ontology ontology;
131                private Annotation annotation;
132                private Set<Object> synonyms;
133
134                public Impl(Ontology ontology, String name) {
135                        this(ontology,name,null,null);
136                }
137
138                public Impl(Ontology ontology, String name, String description) {
139                        this(ontology,name,description,null);
140                }
141
142                public Impl(Ontology ontology, String name, String description, Object[] synonyms) {
143                        if (name == null) {
144                                throw new NullPointerException("Name must not be null");
145                        }
146                        // by AP - description can change from now on...
147                        //if (description == null) {
148                        //    throw new NullPointerException("Description must not be null");
149                        //}
150                        if (ontology == null) {
151                                throw new NullPointerException("Ontology must not be null");
152                        }
153
154                        this.name = name;
155                        this.description = description;
156                        this.ontology = ontology;
157
158                        this.synonyms = new TreeSet<Object>();
159                        if (synonyms!=null) this.synonyms.addAll(Arrays.asList(synonyms));
160                }
161
162                @Override
163                public void addSynonym(Object synonym) {
164                        this.synonyms.add(synonym);
165                }
166
167                @Override
168                public void removeSynonym(Object synonym) {
169                        this.synonyms.remove(synonym);
170                }
171
172                @Override
173                public Object[] getSynonyms() {
174                        return this.synonyms.toArray();
175                }
176
177                @Override
178                public String getName() {
179                        return name;
180                }
181
182                public void setAnnotation(Annotation annotation) {
183                        this.annotation = annotation;
184                }
185
186                public void setSynonyms(Set<Object> synonyms) {
187                        this.synonyms = synonyms;
188                }
189
190                @Override
191                public String getDescription() {
192                        return description;
193                }
194
195                @Override
196                public Ontology getOntology() {
197                        return ontology;
198                }
199
200                @Override
201                public String toString() {
202                        return name;
203                }
204
205                @Override
206                public Annotation getAnnotation() {
207                        if (annotation == null) {
208                                annotation = new SmallAnnotation();
209                        }
210                        return annotation;
211                }
212
213          @Override
214        public int hashCode() {
215                int value = 17;
216                if(getName() != null)
217                  value *= 31 * getName().hashCode();
218                return 17 * value;
219          }
220
221          @Override
222        public boolean equals(Object obj)
223          {
224                if(obj == this) return true;
225                if(!(obj instanceof Term)) return false;
226
227                Term that = (Term) obj;
228
229                return this.getOntology() == that.getOntology() &&
230                                this.getName() == that.getName();
231          }
232        }
233}