+
+ /**
+ * Returns the set of {@link NameTypeDesignation name type designations} that
+ * typify the {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group
+ * including the status of these designations.
+ *
+ * @see #getTypifiedNames()
+ * @see #getSpecimenTypeDesignations()
+ * @see #getTypeDesignations()
+ * @see TaxonNameBase#getNameTypeDesignations()
+ */
+ @Transient
+ public Set<NameTypeDesignation> getNameTypeDesignations(){
+ Set<NameTypeDesignation> result = new HashSet<NameTypeDesignation>();
+ for (TaxonNameBase taxonName : typifiedNames){
+ result.addAll(taxonName.getNameTypeDesignations());
+ }
+ return result;
+ }
+
+
+ /**
+ * Returns the set of all {@link TypeDesignationBase type designations} that
+ * typify the {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group
+ * (this includes either {@link NameTypeDesignation name type designations} or
+ * {@link SpecimenTypeDesignation specimen type designations}).
+ *
+ * @see #getTypifiedNames()
+ * @see #getNameTypeDesignations()
+ * @see #getSpecimenTypeDesignations()
+ * @see TaxonNameBase#getTypeDesignations()
+ */
+ @Transient
+ public Set<TypeDesignationBase> getTypeDesignations(){
+ Set<TypeDesignationBase> result = new HashSet<TypeDesignationBase>();
+ for (TaxonNameBase taxonName : typifiedNames){
+ result.addAll(taxonName.getTypeDesignations());
+ }
+ return result;
+ }
+
+// /**
+// * Returns the set of {@link SpecimenTypeDesignation specimen type designations} that
+// * typify <i>this</i> homotypical group including the status of these designations.
+// *
+// * @see #getTypifiedNames()
+// */
+// @OneToMany
+// @Cascade({CascadeType.SAVE_UPDATE})
+// public Set<SpecimenTypeDesignation> getSpecimenTypeDesignations() {
+// return specimenTypeDesignations;
+// }
+// /**
+// * @see #getSpecimenTypeDesignations()
+// */
+// protected void setSpecimenTypeDesignations(Set<SpecimenTypeDesignation> specimenTypeDesignations) {
+// this.specimenTypeDesignations = specimenTypeDesignations;
+// }
+// /**
+// * Adds a new {@link SpecimenTypeDesignation specimen type designation} to the set
+// * of specimen type designations assigned to <i>this</i> homotypical group and eventually
+// * (with a boolean parameter) also to the corresponding set of each of the
+// * {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group.
+// *
+// * @param specimenTypeDesignation the specimen type designation to be added
+// * @param addToAllNames the boolean flag indicating whether the addition will also
+// * carried out for each taxon name
+// *
+// * @see TaxonNameBase#getSpecimenTypeDesignations()
+// * @see SpecimenTypeDesignation
+// */
+// public void addSpecimenTypeDesignation(SpecimenTypeDesignation specimenTypeDesignation, boolean addToAllNames) {
+// if (specimenTypeDesignation != null){
+// specimenTypeDesignation.setHomotypicalGroup(this);
+// specimenTypeDesignations.add(specimenTypeDesignation);
+// }
+// if (addToAllNames){
+// for (TaxonNameBase taxonNameBase : this.typifiedNames){
+// taxonNameBase.addSpecimenTypeDesignation(specimenTypeDesignation);
+// }
+// }
+// }
+// /**
+// * Removes one element from the set of {@link SpecimenTypeDesignation specimen type designations} assigned to the
+// * {@link HomotypicalGroup homotypical group} to which this {@link TaxonNameBase taxon name} belongs.
+// * The same element will be removed from the corresponding set of each of
+// * the taxon names belonging to <i>this</i> homotypical group. Furthermore the
+// * homotypical group attribute of the specimen type designation will be
+// * nullified.
+// *
+// * @param specimenTypeDesignation the specimen type designation which should be deleted
+// * @see #getSpecimenTypeDesignations()
+// * @see #addSpecimenTypeDesignation(SpecimenTypeDesignation, boolean)
+// * @see TaxonNameBase#removeSpecimenTypeDesignation(SpecimenTypeDesignation)
+// * @see SpecimenTypeDesignation#getHomotypicalGroup()
+// */
+// public void removeSpecimenTypeDesignation(SpecimenTypeDesignation specimenTypeDesignation) {
+// if (specimenTypeDesignation != null){
+// specimenTypeDesignation.setHomotypicalGroup(null);
+// specimenTypeDesignations.remove(specimenTypeDesignation);
+// }
+// for (TaxonNameBase taxonNameBase : this.typifiedNames){
+// taxonNameBase.removeSpecimenTypeDesignation(specimenTypeDesignation);
+// }
+// }
+
+
+// /**
+// * Returns the set of {@link NameTypeDesignation name type designations} that
+// * typify <i>this</i> homotypical group including the status of these designations.
+// *
+// * @see #getTypifiedNames()
+// */
+// @OneToMany
+// @Cascade({CascadeType.SAVE_UPDATE})
+// public Set<NameTypeDesignation> getNameTypeDesignations() {
+// return nameTypeDesignations;
+// }
+// /**
+// * @see #getNameTypeDesignations()
+// */
+// protected void setNameTypeDesignations(Set<NameTypeDesignation> nameTypeDesignations) {
+// this.nameTypeDesignations = nameTypeDesignations;
+// }
+// /**
+// * Adds a new {@link NameTypeDesignation name type designation} to the set
+// * of name type designations assigned to <i>this</i> homotypical group and eventually
+// * (with a boolean parameter) also to the corresponding set of each of the
+// * {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group.
+// *
+// * @param nameTypeDesignation the name type designation to be added
+// * @param addToAllNames the boolean flag indicating whether the addition will also
+// * carried out for each taxon name
+// *
+// * @see TaxonNameBase#getNameTypeDesignations()
+// * @see NameTypeDesignation
+// */
+// public void addNameTypeDesignation(NameTypeDesignation nameTypeDesignation, boolean addToAllNames) {
+// if (nameTypeDesignation != null){
+// nameTypeDesignation.setHomotypicalGroup(this);
+// nameTypeDesignations.add(nameTypeDesignation);
+// }
+// if (addToAllNames){
+// for (TaxonNameBase taxonNameBase : this.typifiedNames){
+// taxonNameBase.addNameTypeDesignation(nameTypeDesignation);
+// }
+// }
+// }
+// /**
+// * Removes one element from the set of {@link NameTypeDesignation name type designations} assigned to the
+// * {@link HomotypicalGroup homotypical group} to which this {@link TaxonNameBase taxon name} belongs.
+// * The same element will be removed from the corresponding set of each of
+// * the taxon names belonging to <i>this</i> homotypical group. Furthermore the
+// * homotypical group attribute of the name type designation will be
+// * nullified.
+// *
+// * @param nameTypeDesignation the name type designation which should be deleted
+// * @see #getNameTypeDesignations()
+// * @see #addNameTypeDesignation(NameTypeDesignation, boolean)
+// * @see TaxonNameBase#removeNameTypeDesignation(NameTypeDesignation)
+// * @see NameTypeDesignation#getHomotypicalGroup()
+// */
+// public void removeNameTypeDesignation(NameTypeDesignation nameTypeDesignation) {
+// if (nameTypeDesignation != null){
+// nameTypeDesignation.setHomotypicalGroup(null);
+// nameTypeDesignations.remove(nameTypeDesignation);
+// }
+// for (TaxonNameBase taxonNameBase : this.typifiedNames){
+// taxonNameBase.removeNameTypeDesignation(nameTypeDesignation);
+// }
+// }
+
+
+ /**
+ * Retrieves the ordered list (depending on the date of publication) of
+ * {@link taxon.Synonym synonyms} (according to a given reference)
+ * the {@link TaxonNameBase taxon names} of which belong to <i>this</i> homotypical group.
+ * If other names are part of <i>this</i> group that are not considered synonyms
+ * according to the respective reference, then they will not be included in
+ * the result set.
+ *
+ * @param sec the reference whose treatment is to be considered
+ * @return the ordered list of synonyms
+ * @see TaxonNameBase#getSynonyms()
+ * @see TaxonNameBase#getTaxa()
+ * @see taxon.Synonym
+ */
+ public List<Synonym> getSynonymsInGroup(Reference sec){
+ List<Synonym> result = new ArrayList();
+ for (TaxonNameBase<?, ?>name : this.getTypifiedNames()){
+ for (Synonym synonym : name.getSynonyms()){
+ if ( (synonym.getSec() == null && sec == null) ||
+ synonym.getSec() != null && synonym.getSec().equals(sec)){
+ result.add(synonym);
+ }
+ }
+ }
+ Collections.sort(result, new TaxonComparator());
+ return result;
+ }
+
+
+ /**
+ * Creates a basionym relationship to all other names in this names homotypical
+ * group.
+ *
+ * @see HomotypicalGroup.setGroupBasionym(TaxonNameBase basionymName)
+ *
+ * @param basionymName
+ * @throws IllegalArgumentException if basionymName is not member in this homotypical group
+ */
+ public void setGroupBasionym(TaxonNameBase basionymName) throws IllegalArgumentException{
+ setGroupBasionym(basionymName, null, null, null);
+ }
+
+ public void setGroupBasionym(TaxonNameBase basionymName, Reference citation, String microCitation, String ruleConsidered)
+ throws IllegalArgumentException {
+ if (! typifiedNames.contains(basionymName)){
+ throw new IllegalArgumentException("Name to be set as basionym/original combination must be part of the homotypical group but is not");
+ }
+ if (typifiedNames.size() < 2){return;}
+//
+ //Add new relations
+ for (TaxonNameBase name : typifiedNames) {
+ if (!name.equals(basionymName)) {
+ name.addRelationshipFromName(basionymName, NameRelationshipType.BASIONYM(), citation, microCitation, ruleConsidered);
+ }
+ }
+ }
+
+ /**
+ * Removes all basionym relationships between basionymName and any other name
+ * in its homotypic group
+ *
+ * @param basionymName
+ */
+ public static void removeGroupBasionym(TaxonNameBase basionymName) {
+ HomotypicalGroup homotypicalGroup = basionymName.getHomotypicalGroup();
+ Set<NameRelationship> relations = basionymName.getRelationsFromThisName();
+ Set<NameRelationship> removeRelations = new HashSet<NameRelationship>();
+
+ for (NameRelationship relation : relations) {
+
+ // If this is a basionym relation, and toName is in the homotypical group,
+ // remove the relationship.
+ if (relation.getType().isBasionymRelation() &&
+ relation.getToName().getHomotypicalGroup().equals(homotypicalGroup)) {
+ removeRelations.add(relation);
+ }
+ }
+
+ // Removing relations from a set through which we are iterating causes a
+ // ConcurrentModificationException. Therefore, we delete the targeted
+ // relations in a second step.
+ for (NameRelationship relation : removeRelations) {
+ basionymName.removeNameRelationship(relation);
+ }
+ }
+
+
+ /**
+ * Returns all taxon names in the homotypical group that do not have an 'is_basionym_for' (zool.: 'is_original_combination_for')
+ * or a replaced synonym relationship.
+ * @return
+ */
+ @Transient
+ public Set<TaxonNameBase> getUnrelatedNames(){
+ Set<NameRelationship> set = getBasionymOrReplacedSynonymRelations(true, true);
+ Set<TaxonNameBase> result = new HashSet<TaxonNameBase>();
+ result.addAll(this.getTypifiedNames());
+ for (NameRelationship nameRelationship : set){
+ result.remove(nameRelationship.getFromName());
+ result.remove(nameRelationship.getToName());
+ }
+ return result;