52b8ebb5078c5a7ef94be30fd2b67df5909c8266
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / agent / Team.java
1 /**
2 * Copyright (C) 2007 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
10 package eu.etaxonomy.cdm.model.agent;
11
12 import java.util.ArrayList;
13 import java.util.List;
14
15 import javax.persistence.Entity;
16 import javax.persistence.FetchType;
17 import javax.persistence.ManyToMany;
18 import javax.persistence.Transient;
19 import javax.validation.constraints.NotNull;
20 import javax.xml.bind.annotation.XmlAccessType;
21 import javax.xml.bind.annotation.XmlAccessorType;
22 import javax.xml.bind.annotation.XmlElement;
23 import javax.xml.bind.annotation.XmlElementWrapper;
24 import javax.xml.bind.annotation.XmlIDREF;
25 import javax.xml.bind.annotation.XmlRootElement;
26 import javax.xml.bind.annotation.XmlSchemaType;
27 import javax.xml.bind.annotation.XmlType;
28
29 import org.apache.log4j.Logger;
30 import org.hibernate.annotations.Cascade;
31 import org.hibernate.annotations.CascadeType;
32 import org.hibernate.annotations.IndexColumn;
33 import org.hibernate.envers.Audited;
34 import org.hibernate.search.annotations.Indexed;
35 import org.springframework.beans.factory.annotation.Configurable;
36
37 import eu.etaxonomy.cdm.strategy.cache.agent.TeamDefaultCacheStrategy;
38 import eu.etaxonomy.cdm.strategy.match.Match;
39 import eu.etaxonomy.cdm.strategy.match.MatchMode;
40
41 /**
42 * This class represents teams of {@link Person persons}. A team exists either for itself
43 * or is built with the list of (distinct) persons who belong to it.
44 * In the first case the inherited attribute {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache() titleCache} is to be used.
45 * In the second case at least all abbreviated names
46 * (the inherited attributes {@link TeamOrPersonBase#getNomenclaturalTitle() nomenclaturalTitle})
47 * or all full names (the strings returned by Person.generateTitle)
48 * of the persons must exist. A team is a {@link java.util.List list} of persons.
49 * <P>
50 * This class corresponds to: <ul>
51 * <li> Team according to the TDWG ontology
52 * <li> AgentNames (partially) according to the TCS
53 * <li> MicroAgent (partially) according to the ABCD schema
54 * </ul>
55 *
56 * @author m.doering
57 * @version 1.0
58 * @created 08-Nov-2007 13:06:58
59 */
60 @XmlAccessorType(XmlAccessType.FIELD)
61 @XmlType(name = "Team", propOrder = {
62 "protectedNomenclaturalTitleCache",
63 "teamMembers"
64 })
65 @XmlRootElement
66 @Entity
67 @Indexed(index = "eu.etaxonomy.cdm.model.agent.AgentBase")
68 @Audited
69 @Configurable
70 public class Team extends TeamOrPersonBase<Team> {
71 private static final long serialVersionUID = 97640416905934622L;
72 public static final Logger logger = Logger.getLogger(Team.class);
73
74 @XmlElement(name = "ProtectedNomenclaturalTitleCache")
75 private boolean protectedNomenclaturalTitleCache = false;
76
77 //An abreviated name for the team (e. g. in case of nomenclatural authorteams). A non abreviated name for the team (e. g.
78 //in case of some bibliographical references)
79 @XmlElementWrapper(name = "TeamMembers")
80 @XmlElement(name = "TeamMember")
81 @XmlIDREF
82 @XmlSchemaType(name = "IDREF")
83 @IndexColumn(name="sortIndex", base = 0)
84 @ManyToMany(fetch = FetchType.LAZY)
85 @Cascade(CascadeType.SAVE_UPDATE)
86 @Match(MatchMode.MATCH)
87 @NotNull
88 private List<Person> teamMembers = new ArrayList<Person>();
89
90
91 /**
92 * Creates a new team instance without any concrete {@link Person members}.
93 */
94 static public Team NewInstance(){
95 return new Team();
96 }
97
98 /**
99 * Class constructor (including the cache strategy defined in
100 * {@link eu.etaxonomy.cdm.strategy.cache.agent.TeamDefaultCacheStrategy TeamDefaultCacheStrategy}).
101 */
102 public Team() {
103 super();
104 this.cacheStrategy = TeamDefaultCacheStrategy.NewInstance();
105 }
106
107 /**
108 * Returns the list of {@link Person members} belonging to <i>this</i> team.
109 * A person may be a member of several distinct teams.
110 */
111 public List<Person> getTeamMembers(){
112 if(teamMembers == null) {
113 this.teamMembers = new ArrayList<Person>();
114 }
115 return this.teamMembers;
116 }
117
118 /**
119 * Adds a new {@link Person person} to <i>this</i> team at the end of the members' list.
120 *
121 * @param person the person who should be added to the other team members
122 * @see #getTeamMembers()
123 * @see Person
124 */
125 public void addTeamMember(Person person){
126 this.teamMembers.add(person);
127 }
128
129 /**
130 * Adds a new {@link Person person} to <i>this</i> team
131 * at the given index place of the members' list. If the person is already
132 * a member of the list he will be moved to the given index place.
133 * The index must be a positive integer. If the index is bigger than
134 * the present number of members the person will be added at the end of the list.
135 *
136 * @param person the person who should be added to the other team members
137 * @param index the position at which the new person should be placed within the members' list
138 * @see #getTeamMembers()
139 * @see Person
140 */
141 public void addTeamMember(Person person, int index){
142 // TODO is still not fully implemented (range for index!)
143 logger.warn("not yet fully implemented (range for index!)");
144 int oldIndex = teamMembers.indexOf(person);
145 if (oldIndex != -1 ){
146 teamMembers.remove(person);
147 }
148 this.teamMembers.add(index, person);
149 }
150
151 /**
152 * Removes one person from the list of members of <i>this</i> team.
153 *
154 * @param person the person who should be deleted from <i>this</i> team
155 * @see #getTeamMembers()
156 */
157 public void removeTeamMember(Person person){
158 this.teamMembers.remove(person);
159 }
160
161 /**
162 * Generates an identification string for <i>this</i> team according to the strategy
163 * defined in {@link eu.etaxonomy.cdm.strategy.cache.agent.TeamDefaultCacheStrategy TeamDefaultCacheStrategy}. This string is built
164 * with the full names of all persons belonging to its (ordered) members' list.
165 * This method overrides {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle() generateTitle}.
166 * The result might be kept as {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#setTitleCache(String) titleCache} if the
167 * flag {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#protectedTitleCache protectedTitleCache} is not set.
168 *
169 * @return a string which identifies <i>this</i> team
170 */
171 // @Override
172 // public String generateTitle() {
173 // return cacheStrategy.getTitleCache(this);
174 // }
175
176
177 /**
178 * Generates or returns the {@link TeamOrPersonBase#getnomenclaturalTitle() nomenclatural identification} string for <i>this</i> team.
179 * This method overrides {@link TeamOrPersonBase#getNomenclaturalTitle() getNomenclaturalTitle}.
180 * This string is built with the {@link TeamOrPersonBase#getNomenclaturalTitle() abbreviated names}
181 * of all persons belonging to its (ordered) members' list if the flag
182 * {@link #protectedNomenclaturalTitleCache protectedNomenclaturalTitleCache} is not set.
183 * Otherwise this method returns the present nomenclatural abbreviation.
184 * In case the string is generated the cache strategy used is defined in
185 * {@link eu.etaxonomy.cdm.strategy.cache.agent.TeamDefaultCacheStrategy TeamDefaultCacheStrategy}.
186 * The result might be kept as nomenclatural abbreviation
187 * by using the {@link #setNomenclaturalTitle(String) setNomenclaturalTitle} method.
188 *
189 * @return a string which identifies <i>this</i> team for nomenclature
190 */
191 @Override
192 @Transient
193 public String getNomenclaturalTitle() {
194 if (protectedNomenclaturalTitleCache == PROTECTED){
195 return this.nomenclaturalTitle;
196 }
197 if (nomenclaturalTitle == null){
198 this.nomenclaturalTitle = cacheStrategy.getNomenclaturalTitle(this);
199 }else{
200 //as long as team members to not inform the team about changes the cache must be created new each time
201 nomenclaturalTitle = cacheStrategy.getNomenclaturalTitle(this);
202 }
203 return nomenclaturalTitle;
204 }
205
206 /**
207 * Assigns a {@link TeamOrPersonBase#nomenclaturalTitle nomenclatural identification} string to <i>this</i> team
208 * and protects it from overwriting.
209 * This method overrides {@link TeamOrPersonBase#setNomenclaturalTitle(String) setNomenclaturalTitle}.
210 *
211 * @see #getNomenclaturalTitle()
212 * @see #setNomenclaturalTitle(String, boolean)
213 */
214 @Override
215 public void setNomenclaturalTitle(String nomenclaturalTitle) {
216 this.setNomenclaturalTitle(nomenclaturalTitle, PROTECTED);
217 }
218
219 /**
220 * Assigns a {@link TeamOrPersonBase#nomenclaturalTitle nomenclatural identification} string to <i>this</i> team
221 * and a protection flag status to this string.
222 *
223 * @see #getNomenclaturalTitle()
224 */
225 public void setNomenclaturalTitle(String nomenclaturalTitle, boolean protectedNomenclaturalTitleCache) {
226 this.nomenclaturalTitle = nomenclaturalTitle;
227 this.protectedNomenclaturalTitleCache = protectedNomenclaturalTitleCache;
228 }
229
230 /* (non-Javadoc)
231 * @see eu.etaxonomy.cdm.model.agent.TeamOrPersonBase#getTitleCache()
232 */
233 @Override
234 @Transient
235 public String getTitleCache() {
236 isGeneratingTitleCache = true;
237 String result = "";
238 if (isProtectedTitleCache()){
239 result = this.titleCache;
240 }else{
241 result = generateTitle();
242 result = replaceEmptyTitleByNomTitle(result);
243 result = getTruncatedCache(result);
244 }
245 isGeneratingTitleCache = false;
246 return result;
247 }
248
249 public boolean isProtectedNomenclaturalTitleCache() {
250 return protectedNomenclaturalTitleCache;
251 }
252
253 public void setProtectedNomenclaturalTitleCache(
254 boolean protectedNomenclaturalTitleCache) {
255 this.protectedNomenclaturalTitleCache = protectedNomenclaturalTitleCache;
256 }
257
258
259 }