X-Git-Url: https://dev.e-taxonomy.eu/gitweb/cdmlib.git/blobdiff_plain/961ee94bf5d3df4c68ac72ec2afbbbd903451110..85b82fb647a5e9aaf676496d783da5968d1897c5:/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/agent/Team.java
diff --git a/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/agent/Team.java b/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/agent/Team.java
index 3169200f6c..bf359bf01e 100644
--- a/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/agent/Team.java
+++ b/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/agent/Team.java
@@ -1,18 +1,21 @@
/**
* Copyright (C) 2007 EDIT
-* European Distributed Institute of Taxonomy
+* European Distributed Institute of Taxonomy
* http://www.e-taxonomy.eu
-*
+*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* See LICENSE.TXT at the top of this package for the full license terms.
*/
package eu.etaxonomy.cdm.model.agent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
+import javax.persistence.FetchType;
import javax.persistence.ManyToMany;
import javax.persistence.Transient;
import javax.xml.bind.annotation.XmlAccessType;
@@ -27,8 +30,14 @@ import javax.xml.bind.annotation.XmlType;
import org.apache.log4j.Logger;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
+import org.hibernate.annotations.IndexColumn;
+import org.hibernate.envers.Audited;
+import org.hibernate.search.annotations.Indexed;
+import org.springframework.beans.factory.annotation.Configurable;
import eu.etaxonomy.cdm.strategy.cache.agent.TeamDefaultCacheStrategy;
+import eu.etaxonomy.cdm.strategy.match.Match;
+import eu.etaxonomy.cdm.strategy.match.MatchMode;
/**
* This class represents teams of {@link Person persons}. A team exists either for itself
@@ -44,7 +53,7 @@ import eu.etaxonomy.cdm.strategy.cache.agent.TeamDefaultCacheStrategy;
*
AgentNames (partially) according to the TCS
* MicroAgent (partially) according to the ABCD schema
*
- *
+ *
* @author m.doering
* @version 1.0
* @created 08-Nov-2007 13:06:58
@@ -54,117 +63,162 @@ import eu.etaxonomy.cdm.strategy.cache.agent.TeamDefaultCacheStrategy;
"protectedNomenclaturalTitleCache",
"teamMembers"
})
-@XmlRootElement
+@XmlRootElement(name = "Team")
@Entity
+@Indexed(index = "eu.etaxonomy.cdm.model.agent.AgentBase")
+@Audited
+@Configurable
public class Team extends TeamOrPersonBase {
private static final long serialVersionUID = 97640416905934622L;
public static final Logger logger = Logger.getLogger(Team.class);
-
+
@XmlElement(name = "ProtectedNomenclaturalTitleCache")
- private boolean protectedNomenclaturalTitleCache;
+ private boolean protectedNomenclaturalTitleCache = false;
//An abreviated name for the team (e. g. in case of nomenclatural authorteams). A non abreviated name for the team (e. g.
//in case of some bibliographical references)
- @XmlElementWrapper(name = "TeamMembers")
+ @XmlElementWrapper(name = "TeamMembers", nillable = true)
@XmlElement(name = "TeamMember")
@XmlIDREF
@XmlSchemaType(name = "IDREF")
- private List teamMembers = new ArrayList();
-
-
- /**
+ @IndexColumn(name="sortIndex", base = 0)
+ @ManyToMany(fetch = FetchType.LAZY)
+ @Cascade(CascadeType.SAVE_UPDATE)
+ @Match(MatchMode.MATCH)
+ private List teamMembers;
+
+
+ /**
* Creates a new team instance without any concrete {@link Person members}.
*/
static public Team NewInstance(){
return new Team();
}
-
- /**
+
+ /**
+ * Creates a new team instance with a bibliographic and nomenclatural title
+ * but without any {@link Person members}. The caches are set to protected.
+ */
+ static public Team NewTitledInstance(String title, String nomTitle){
+ Team result = new Team();
+ result.setTitleCache(title, true);
+ result.setNomenclaturalTitle(nomTitle, true);
+ return result;
+ }
+
+ /**
* Class constructor (including the cache strategy defined in
* {@link eu.etaxonomy.cdm.strategy.cache.agent.TeamDefaultCacheStrategy TeamDefaultCacheStrategy}).
*/
public Team() {
super();
this.cacheStrategy = TeamDefaultCacheStrategy.NewInstance();
+ addListenersToMembers();
+ }
+
+ /**
+ * Adds a property change listener to all team members.
+ */
+ private void addListenersToMembers() {
+ List members = getTeamMembers();
+ for (Person member : members){
+ addListenerForTeamMember(member);
+ }
+ }
+
+ /**
+ * @return
+ */
+ private void addListenerForTeamMember(Person member) {
+ PropertyChangeListener listener = new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent e) {
+
+// ---- code with no effect below -----
+// if (! isProtectedTitleCache()){
+// titleCache = titleCache;
+// }
+// if (! isProtectedNomenclaturalTitleCache()){
+// nomenclaturalTitle = nomenclaturalTitle;
+// }
+ }
+ };
+ member.addPropertyChangeListener(listener);
}
- /**
- * Returns the list of {@link Person members} belonging to this team.
- * A person may be a member of several distinct teams.
+ /**
+ * Returns the list of {@link Person members} belonging to this team.
+ * A person may be a member of several distinct teams.
*/
- @ManyToMany
- //@IndexColumn(name="sortIndex", base = 0)
- //@JoinColumn (name = "representation_id", nullable=false)
- @Cascade({CascadeType.SAVE_UPDATE})
public List getTeamMembers(){
+ if(teamMembers == null) {
+ this.teamMembers = new ArrayList();
+ }
return this.teamMembers;
}
- /**
- * @see #getTeamMembers()
- */
- protected void setTeamMembers(List teamMembers){
+
+ protected void setTeamMembers(List teamMembers) {
this.teamMembers = teamMembers;
+ addListenersToMembers();
}
-
- /**
- * Adds a new {@link Person person} to this team at the end of the members' list.
+
+ /**
+ * Adds a new {@link Person person} to this team at the end of the members' list.
*
* @param person the person who should be added to the other team members
* @see #getTeamMembers()
* @see Person
*/
public void addTeamMember(Person person){
- this.teamMembers.add(person);
+ if (person != null){
+ getTeamMembers().add(person);
+ firePropertyChange("teamMember", null, person);
+ addListenerForTeamMember(person);
+ }
}
-
- /**
+
+ /**
* Adds a new {@link Person person} to this team
* at the given index place of the members' list. If the person is already
- * a member of the list he will be moved to the given index place.
- * The index must be a positive integer. If the index is bigger than
+ * a member of the list he will be moved to the given index place.
+ * The index must be an integer (>=0). If the index is larger than
* the present number of members the person will be added at the end of the list.
*
* @param person the person who should be added to the other team members
- * @param index the position at which the new person should be placed within the members' list
+ * @param index the position at which the person should be placed within the members' list (starting with 0)
* @see #getTeamMembers()
* @see Person
*/
public void addTeamMember(Person person, int index){
- // TODO is still not fully implemented (range for index!)
- logger.warn("not yet fully implemented (range for index!)");
- int oldIndex = teamMembers.indexOf(person);
- if (oldIndex != -1 ){
- teamMembers.remove(person);
+ if (person != null){
+ int oldIndex = getTeamMembers().indexOf(person);
+ if (oldIndex != -1 ){
+ getTeamMembers().remove(person);
+ }
+ if (index >= getTeamMembers().size()){
+ index = getTeamMembers().size();
+ }
+ getTeamMembers().add(index, person);
+ addListenerForTeamMember(person);
+ firePropertyChange("teamMember", null, person);
}
- this.teamMembers.add(index, person);
}
-
- /**
+
+ /**
* Removes one person from the list of members of this team.
*
* @param person the person who should be deleted from this team
* @see #getTeamMembers()
*/
public void removeTeamMember(Person person){
- this.teamMembers.remove(person);
- }
+ boolean wasMember = getTeamMembers().remove(person);
+ if (wasMember){
+ firePropertyChange("teamMember", person, null);
+ }
- /**
- * Generates an identification string for this team according to the strategy
- * defined in {@link eu.etaxonomy.cdm.strategy.cache.agent.TeamDefaultCacheStrategy TeamDefaultCacheStrategy}. This string is built
- * with the full names of all persons belonging to its (ordered) members' list.
- * This method overrides {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle() generateTitle}.
- * The result might be kept as {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#setTitleCache(String) titleCache} if the
- * flag {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#protectedTitleCache protectedTitleCache} is not set.
- *
- * @return a string which identifies this team
- */
- @Override
- public String generateTitle() {
- return cacheStrategy.getTitleCache(this);
}
-
-
+
+
/**
* Generates or returns the {@link TeamOrPersonBase#getnomenclaturalTitle() nomenclatural identification} string for this team.
* This method overrides {@link TeamOrPersonBase#getNomenclaturalTitle() getNomenclaturalTitle}.
@@ -176,7 +230,7 @@ public class Team extends TeamOrPersonBase {
* {@link eu.etaxonomy.cdm.strategy.cache.agent.TeamDefaultCacheStrategy TeamDefaultCacheStrategy}.
* The result might be kept as nomenclatural abbreviation
* by using the {@link #setNomenclaturalTitle(String) setNomenclaturalTitle} method.
- *
+ *
* @return a string which identifies this team for nomenclature
*/
@Override
@@ -187,37 +241,95 @@ public class Team extends TeamOrPersonBase {
}
if (nomenclaturalTitle == null){
this.nomenclaturalTitle = cacheStrategy.getNomenclaturalTitle(this);
+ }else{
+ //as long as team members to not inform the team about changes the cache must be created new each time
+ nomenclaturalTitle = cacheStrategy.getNomenclaturalTitle(this);
}
- return nomenclaturalTitle;
+ return nomenclaturalTitle;
}
-
+
/**
* Assigns a {@link TeamOrPersonBase#nomenclaturalTitle nomenclatural identification} string to this team
* and protects it from overwriting.
* This method overrides {@link TeamOrPersonBase#setNomenclaturalTitle(String) setNomenclaturalTitle}.
- *
+ *
* @see #getNomenclaturalTitle()
* @see #setNomenclaturalTitle(String, boolean)
*/
@Override
public void setNomenclaturalTitle(String nomenclaturalTitle) {
- setNomenclaturalTitle(nomenclaturalTitle, PROTECTED);
- this.nomenclaturalTitle = nomenclaturalTitle;
+ this.setNomenclaturalTitle(nomenclaturalTitle, PROTECTED);
}
/**
* Assigns a {@link TeamOrPersonBase#nomenclaturalTitle nomenclatural identification} string to this team
* and a protection flag status to this string.
- *
+ *
* @see #getNomenclaturalTitle()
*/
public void setNomenclaturalTitle(String nomenclaturalTitle, boolean protectedNomenclaturalTitleCache) {
+ firePropertyChange("nomenclaturalTitle", this.nomenclaturalTitle, nomenclaturalTitle);
this.nomenclaturalTitle = nomenclaturalTitle;
this.protectedNomenclaturalTitleCache = protectedNomenclaturalTitleCache;
}
-
-
-
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.cdm.model.agent.TeamOrPersonBase#getTitleCache()
+ */
+ @Override
+ //@Transient //TODO a.kohlbecker remove??
+ public String getTitleCache() {
+ isGeneratingTitleCache = true;
+ String result = "";
+ if (isProtectedTitleCache()){
+ result = this.titleCache;
+ }else{
+ result = generateTitle();
+ result = replaceEmptyTitleByNomTitle(result);
+ result = getTruncatedCache(result);
+ this.titleCache = result;
+ }
+ isGeneratingTitleCache = false;
+ return result;
+ }
+
+ public boolean isProtectedNomenclaturalTitleCache() {
+ return protectedNomenclaturalTitleCache;
+ }
+
+ public void setProtectedNomenclaturalTitleCache(
+ boolean protectedNomenclaturalTitleCache) {
+ this.protectedNomenclaturalTitleCache = protectedNomenclaturalTitleCache;
+ }
+
+//*********************** CLONE ********************************************************/
+
+ /**
+ * Clones this Team. This is a shortcut that enables to create
+ * a new instance that differs only slightly from this Team.
+ * The corresponding person is cloned.
+ *
+ * @see eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity#clone()
+ * @see java.lang.Object#clone()
+ */
+ @Override
+ public Object clone() {
+ try{
+ Team result = (Team)super.clone();
+ result.teamMembers = new ArrayList();
+ for (Person teamMember: this.teamMembers){
+ result.addTeamMember(teamMember);
+ }
+ //no changes to protectedNomenclaturalTitleCache
+ return result;
+ } catch (CloneNotSupportedException e){
+ logger.warn("Object does not implement cloneable");
+ e.printStackTrace();
+ return null;
+ }
+
+
+ }
+
}
\ No newline at end of file