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