root/trunk/cdmlib/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/RelationshipTermBase.java

Revision 13119, 8.1 kB (checked in by a.mueller, 8 months ago)

Symbols for relations (#2634)

  • Property svn:keywords set to Id
Line 
1/**
2* Copyright (C) 2009 EDIT
3* European Distributed Institute of Taxonomy
4* http://www.e-taxonomy.eu
5*
6* The contents of this file are subject to the Mozilla Public License Version 1.1
7* See LICENSE.TXT at the top of this package for the full license terms.
8*/ 
9
10package eu.etaxonomy.cdm.model.common;
11
12import java.util.HashSet;
13import java.util.Iterator;
14import java.util.List;
15import java.util.Map;
16import java.util.Set;
17import java.util.UUID;
18
19import javax.persistence.Column;
20import javax.persistence.Entity;
21import javax.persistence.FetchType;
22import javax.persistence.JoinTable;
23import javax.persistence.OneToMany;
24import javax.persistence.Transient;
25import javax.xml.bind.annotation.XmlAccessType;
26import javax.xml.bind.annotation.XmlAccessorType;
27import javax.xml.bind.annotation.XmlElement;
28import javax.xml.bind.annotation.XmlElementWrapper;
29import javax.xml.bind.annotation.XmlSeeAlso;
30import javax.xml.bind.annotation.XmlType;
31
32import org.apache.log4j.Logger;
33import org.hibernate.annotations.Cascade;
34import org.hibernate.annotations.CascadeType;
35import org.hibernate.envers.Audited;
36import org.hibernate.search.annotations.Field;
37import org.hibernate.search.annotations.Index;
38import org.hibernate.search.annotations.Indexed;
39import org.hibernate.search.annotations.IndexedEmbedded;
40
41import au.com.bytecode.opencsv.CSVWriter;
42import eu.etaxonomy.cdm.model.description.TextData;
43import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
44import eu.etaxonomy.cdm.model.name.NameRelationshipType;
45import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
46import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
47
48@XmlAccessorType(XmlAccessType.FIELD)
49@XmlType(name = "RelationshipTermBase", propOrder = {
50    "symmetric",
51    "transitive",
52    "inverseRepresentations"
53})
54@XmlSeeAlso({
55        HybridRelationshipType.class,
56        NameRelationshipType.class,
57        SynonymRelationshipType.class,
58        TaxonRelationshipType.class
59})
60@Entity
61@Indexed(index = "eu.etaxonomy.cdm.model.common.DefinedTermBase")
62@Audited
63public abstract class RelationshipTermBase<T extends RelationshipTermBase> extends OrderedTermBase<T> {
64        private static final long serialVersionUID = 5497187985269083971L;
65        @SuppressWarnings("unused")
66        private static final Logger logger = Logger.getLogger(RelationshipTermBase.class);
67       
68        @XmlElement(name = "Symmetrical")
69        @Field(index=Index.UN_TOKENIZED)
70        @Column(name="symmetrical") //to be compatible with PostGreSQL
71        private boolean symmetric;
72       
73        @XmlElement(name = "Transitive")
74        @Field(index=Index.UN_TOKENIZED)
75        private boolean transitive;
76       
77        @XmlElementWrapper(name = "InverseRepresentations")
78        @XmlElement(name = "Representation")
79        @OneToMany(fetch = FetchType.LAZY)
80        @JoinTable(name="RelationshipTermBase_inverseRepresentation")
81        @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE})
82        @IndexedEmbedded(depth = 2)
83        private Set<Representation> inverseRepresentations = new HashSet<Representation>();
84       
85        public RelationshipTermBase() {
86        }
87        public RelationshipTermBase(String term, String label, String labelAbbrev, boolean symmetric, boolean transitive) {
88                super(term, label, labelAbbrev);
89                setSymmetric(symmetric);
90                setTransitive(transitive);             
91        }
92       
93//************************** METHODS ********************************
94       
95        public boolean isSymmetric() {
96                return symmetric;
97        }
98        public void setSymmetric(boolean symmetric) {
99                this.symmetric = symmetric;
100        }
101       
102        public boolean isTransitive() {
103                return transitive;
104        }
105        public void setTransitive(boolean transitive) {
106                this.transitive = transitive;
107        }
108       
109        public Set<Representation> getInverseRepresentations() {
110                return inverseRepresentations;
111        }
112
113        public void addInverseRepresentation(Representation inverseRepresentation) {
114                this.inverseRepresentations.add(inverseRepresentation);
115        }
116        public void removeInverseRepresentation(Representation inverseRepresentation) {
117                this.inverseRepresentations.remove(inverseRepresentation);
118        }
119        public void addRepresentation(Representation representation, Representation inverseRepresentation) {
120                this.addRepresentation(representation);
121                this.addInverseRepresentation(inverseRepresentation);
122        }
123       
124        public Representation getInverseRepresentation(Language lang) {
125                Representation result = null;
126                if (this.isSymmetric()){
127                        for (Representation repr : this.getRepresentations()){
128                                if (lang.equals(repr.getLanguage())){
129                                        result = repr;
130                                }
131                        }
132                }else{
133                        for (Representation repr : this.getInverseRepresentations()){
134                                if (lang.equals(repr.getLanguage())){
135                                        result = repr;
136                                }
137                        }
138                }
139                return result;
140        }
141       
142        /**
143         * Returns the InverseRepresentation in the preferred language. Preferred languages
144         * are specified by the parameter languages, which receives a list of
145         * Language instances in the order of preference. If no representation in
146         * any preferred languages is found the method falls back to return the
147         * Representation in Language.DEFAULT() and if necessary further falls back
148         * to return the first element found if any.
149         *
150         * TODO think about this fall-back strategy &
151         * see also {@link TextData#getPreferredLanguageString(List)}
152         * see also {@link TermBase#getPreferredRepresentation(List)}
153         *
154         * @param languages
155         * @return
156         */
157        public Representation getPreferredInverseRepresentation(List<Language> languages) {
158                Representation repr = null;
159                if(languages != null){
160                        for(Language language : languages) {
161                                repr = getInverseRepresentation(language); 
162                                if(repr != null){
163                                        return repr;
164                                }
165                        }
166                }
167                if(repr == null){
168                        repr = getInverseRepresentation(Language.DEFAULT());
169                }
170                if(repr == null){
171                        Iterator<Representation> it = getInverseRepresentations().iterator();
172                        if(it.hasNext()){
173                                repr = getInverseRepresentations().iterator().next();
174                        }
175                }
176                return repr;
177        }
178       
179        /*
180         * Inverse representation convenience methods similar to TermBase.xxx
181         * @see eu.etaxonomy.cdm.model.common.TermBase#getLabel()
182         */
183        @Transient
184        public String getInverseLabel() {
185                if(getInverseLabel(Language.DEFAULT())!=null){
186                        return this.getInverseRepresentation(Language.DEFAULT()).getLabel();
187                }else{
188                        for (Representation r : inverseRepresentations){
189                                return r.getLabel();
190                        }                       
191                }
192                return super.getUuid().toString();
193        }
194
195        public String getInverseLabel(Language lang) {
196                Representation r = this.getInverseRepresentation(lang);
197                if(r==null){
198                        return null;
199                }else{
200                        return r.getLabel();
201                }
202        }
203       
204        @Transient
205        public String getInverseDescription() {
206                return this.getInverseRepresentation(Language.DEFAULT()).getDescription();
207        }
208
209        public String getInverseDescription(Language lang) {
210                return this.getInverseRepresentation(lang).getDescription();
211        }
212       
213        @Override
214        public T readCsvLine(Class<T> termClass, List<String> csvLine, Map<UUID,DefinedTermBase> terms) {
215                T newInstance = super.readCsvLine(termClass, csvLine, terms);
216
217                String inverseText = csvLine.get(6).trim();
218                String inverseLabel = csvLine.get(5).trim();
219                String inverseLabelAbbrev = csvLine.get(7).trim();
220                newInstance.addInverseRepresentation(new Representation(inverseText, inverseLabel, inverseLabelAbbrev, Language.CSV_LANGUAGE()) );
221                newInstance.setSymmetric(Boolean.parseBoolean(csvLine.get(8)));
222                newInstance.setTransitive(Boolean.parseBoolean(csvLine.get(9)));
223                return newInstance;
224        }
225       
226        @Override
227        public void writeCsvLine(CSVWriter writer,T term) {
228                String [] line = new String[8];
229                line[0] = term.getUuid().toString();
230                line[1] = term.getUri().toString();
231                line[2] = term.getLabel();
232                line[3] = term.getDescription();
233                line[4] = term.getDescription();
234                line[5] = term.getInverseLabel();
235                line[6] = term.getInverseDescription();
236                line[7] = String.valueOf(term.isSymmetric());
237                line[8] = String.valueOf(term.isTransitive());
238                writer.writeNext(line);
239        }
240        //*********************************** CLONE *********************************************************/
241       
242        /* (non-Javadoc)
243         * @see eu.etaxonomy.cdm.model.common.DefinedTermBase#clone()
244         * @see java.lang.Object#clone()
245         */
246        @Override
247        public Object clone() {
248                RelationshipTermBase result = (RelationshipTermBase)super.clone();
249               
250                result.inverseRepresentations = new HashSet<Representation>();
251                for (Representation rep: this.inverseRepresentations){
252                        result.addInverseRepresentation((Representation)rep.clone());
253                }
254               
255                //no changes to: symmetric, transitiv
256                return result;
257        }
258
259       
260}
Note: See TracBrowser for help on using the browser.